From 5751466d7818c84cca2f01a733b93a6cd1682b6f Mon Sep 17 00:00:00 2001 From: Joaquin Matres <4514346+joamatab@users.noreply.github.com> Date: Sat, 30 Jul 2022 07:43:16 -0700 Subject: [PATCH] blacken notebooks, add flake8 config and script for adding type annotations (#2177) --- .flake8 | 24 ++ add_type_hints.xonsh | 11 + monkeytype.sqlite3 | Bin 0 -> 36864 bytes python/examples/3rd-harm-1d.ipynb | 161 +++++---- python/examples/absorbed_power_density.ipynb | 121 ++++--- .../01-Introduction.ipynb | 143 ++++---- .../02-Waveguide_Bend.ipynb | 120 ++++--- .../03-Filtered_Waveguide_Bend.ipynb | 286 +++++++++------- .../adjoint_optimization/04-Splitter.ipynb | 294 ++++++++++------ .../adjoint_optimization/05-Near2Far.ipynb | 201 ++++++----- .../06-Near2Far-Epigraph.ipynb | 307 ++++++++++------- .../adjoint_optimization/Bend Minimax.ipynb | 302 ++++++++++------- .../ConnectivityConstraint.ipynb | 50 +-- .../adjoint_optimization/Fourier-Bend.ipynb | 253 ++++++++------ python/examples/antenna-radiation.ipynb | 121 ++++--- python/examples/bend-flux.ipynb | 104 +++--- python/examples/bent-waveguide.ipynb | 91 +++-- python/examples/binary_grating.ipynb | 314 ++++++++++------- python/examples/binary_grating_n2f.ipynb | 243 +++++++++----- python/examples/binary_grating_oblique.ipynb | 183 ++++++---- python/examples/binary_grating_phasemap.ipynb | 181 ++++++---- python/examples/cavity-farfield.ipynb | 94 ++++-- python/examples/coupler.ipynb | 139 +++++--- python/examples/cylinder_cross_section.ipynb | 148 +++++--- .../examples/differential_cross_section.ipynb | 177 ++++++---- python/examples/finite_grating.ipynb | 168 ++++++---- python/examples/holey-wvg-bands.ipynb | 104 +++--- python/examples/holey-wvg-cavity.ipynb | 221 ++++++------ python/examples/metal-cavity-ldos.ipynb | 69 ++-- python/examples/metasurface_lens.ipynb | 317 +++++++++++------- python/examples/mie_scattering.ipynb | 196 +++++++---- python/examples/mode-decomposition.ipynb | 141 ++++---- python/examples/oblique-planewave.ipynb | 54 +-- python/examples/oblique-source.ipynb | 175 ++++++---- python/examples/parallel-wvgs-force.ipynb | 190 ++++++----- python/examples/perturbation_theory.ipynb | 202 +++++++---- python/examples/polarization_grating.ipynb | 201 ++++++----- python/examples/refl-angular.ipynb | 171 ++++++---- python/examples/refl-quartz.ipynb | 85 +++-- python/examples/ring.ipynb | 77 +++-- python/examples/solve-cw.ipynb | 119 ++++--- python/examples/stochastic_emitter.ipynb | 171 ++++++---- python/examples/straight-waveguide.ipynb | 38 ++- python/examples/zone_plate.ipynb | 176 ++++++---- 44 files changed, 4277 insertions(+), 2666 deletions(-) create mode 100644 .flake8 create mode 100644 add_type_hints.xonsh create mode 100644 monkeytype.sqlite3 diff --git a/.flake8 b/.flake8 new file mode 100644 index 000000000..97f834470 --- /dev/null +++ b/.flake8 @@ -0,0 +1,24 @@ +[flake8] +max-line-length = 88 +max-complexity = 57 +select = B,C,E,F,W,T4,B9 +ignore = E501, E503, E722, W503, W503, E203, B950, B305, B018, B902, B020 + +extend-ignore = + RST303 + +exclude = + .git, + __pycache__, + lib/, + docs/source/conf.py, + build, + dist, + .ipynb_checkpoints, + .tox, + extra, + deprecated, + gdslib, + .tox, + .mypy_cache, + venv diff --git a/add_type_hints.xonsh b/add_type_hints.xonsh new file mode 100644 index 000000000..24272a522 --- /dev/null +++ b/add_type_hints.xonsh @@ -0,0 +1,11 @@ +#!/usr/bin/env python +from tqdm.auto import tqdm + + +py.test --monkeytype-output=./monkeytype.sqlite3 + +for i, m in enumerate(tqdm($(monkeytype list-modules).split('\n'))): + if m.startswith(''): + print(i, m) + monkeytype stub @(m) + monkeytype apply @(m) diff --git a/monkeytype.sqlite3 b/monkeytype.sqlite3 new file mode 100644 index 0000000000000000000000000000000000000000..baead08bff2c3a9fb83a4b89cfe24a3d46e0a853 GIT binary patch literal 36864 zcmeHQ&2QVt6_;$slAPGuba(6Rel%LP+iV(}Aw^POg}c={-Xv(!ZP!Y+MX?}gX(ThI zM1`ah8-{^0_HJ6Y*B<&8EKp#Nz4un2hoYBWyFf3!6a{+er9ja~Qj|neBT`BlTh0*v z5I=@|^P4yC&HKF>YV$|8WdmjEs@9Z@3>SMT7LUiim&wFpu_gFT!LPf;;lrG}1OKi4 zux%+ui?1!hRq^!Y82pfpAV3fx2oMAa0t5kq06~BtKoB4Z5CjMUrx^kBUOcf}EXE(- zFr+O7HPzM*+B5drNUTbVA{v@hMf&igGwUC1lq(yVO8NcU8=2wPWZqrKWU3mH3{(># z4$o9Jeq33BV@y0Xf6A2@7SJPjK>u*v#@$vb=i3d{vHRnQV5I$**RM8I~;xT!}5x*>HzJnN4b3irGZE3Dg2(RK4@E#sJ1j8l z{xpi^=nDRcCArNsLqQ67WVzMwx6f@^cdEGeyq-0#?JFcfk+~6y%;s{ol^B55qjh1% zZ=jqX9nXEn)?SlKB+A#me;^IbE zilEex88DEh?^A}|P+{#V-asv+$54OR8PKrnUSvbh*(I zHPnDz_@}E1gz=FhbJw}lHT0l^T2(nT%)kx#CJB`rQb*Ti$&y;;hX);u5qJb z&G?po=nM8CwRM!1F)^7bjlGgS7(ctP4wf(TF)oHf({7AQIlBP*} zHa+aHt^EQadO7Ck-(2|$XdG)MszV(%XdLLAU*lk{@FNLw0e!R9bJKPV=MNo6*D;dB zUFUn4z8IoFg*-zPh_d0z@y|tpUJ6qnmN`8N^f;Y{5$Y8)@%S1};q&=`ylyXdZ0S=f zJDzMD+D`_WaxkGY^xB@?7{ljS@&EkHo3Vx8FD#}$n46znfE}_C1ONeZ=Pe8k&6jwF z=9%16Fthl6fOB#E*f^4YyXlE=-`OSI_ujN>`#2Hcb$hkV2|?yGS{4ppTVNg(d5hjv zq&}7J9}sNpqH4!pcoc1b>yU<#JgZapyz#ISOa_LZ7G` z&29s?;?IhWE)a$8i;YZ;s?<4bm12*q4?C0KtN4RK|}mBG@B0j2@;luTpsEkq(A z#n}%j4wIL#uFT0L6$?B|T-oz*Wp?~O^E;UTpAzPO zId=;_l8qp6x)C_MxMJInwLr2oUt&0#FET=wpGy1TEHU!uORYqyXN~76%$gp(cQsk& z?mSrxET3@OgfBX;UvsCxI&}@yjrN{@n&noIfjgOn|L|R^S%^;uS8UFqlMtRWEz@OvlnDX6UJE$0)m9C4<0T=pe=n%ghvNq zpI-iU%GRLZ;=G;;@!r*_M1?FCL$!7cSQ7 zGd718uZ2+Ax$Ja(afz3{olYv74xzFI_gj=aZ&?hgnHLK}WxHR0<$=wwB4>iiUJawN a1$dbhq;*8EiVziYzsl^aW 0:\n", " grad[:] = np.squeeze(dJ_du)\n", " evaluation_history.append(np.real(f0))\n", @@ -277,10 +297,10 @@ ], "source": [ "plt.figure()\n", - "plt.plot(evaluation_history,'o-')\n", + "plt.plot(evaluation_history, \"o-\")\n", "plt.grid(True)\n", - "plt.xlabel('Iteration')\n", - "plt.ylabel('FOM')\n", + "plt.xlabel(\"Iteration\")\n", + "plt.ylabel(\"FOM\")\n", "plt.show()" ] }, @@ -311,7 +331,11 @@ ], "source": [ "opt.update_design([x])\n", - "opt.plot2D(True,plot_monitors_flag=False,output_plane=mp.Volume(center=(0,0,0),size=(2,2,0)))\n", + "opt.plot2D(\n", + " True,\n", + " plot_monitors_flag=False,\n", + " output_plane=mp.Volume(center=(0, 0, 0), size=(2, 2, 0)),\n", + ")\n", "plt.axis(\"off\");" ] }, @@ -330,11 +354,15 @@ "metadata": {}, "outputs": [], "source": [ - "TE0 = mpa.EigenmodeCoefficient(sim,mp.Volume(center=mp.Vector3(-1,0,0),size=mp.Vector3(y=2)),mode=1)\n", - "ob_list = [TE0,TE_top]\n", + "TE0 = mpa.EigenmodeCoefficient(\n", + " sim, mp.Volume(center=mp.Vector3(-1, 0, 0), size=mp.Vector3(y=2)), mode=1\n", + ")\n", + "ob_list = [TE0, TE_top]\n", + "\n", + "\n", + "def J(source, top):\n", + " return npa.abs(top / source) ** 2\n", "\n", - "def J(source,top):\n", - " return npa.abs(top/source) ** 2\n", "\n", "opt.objective_functions = [J]\n", "opt.objective_arguments = ob_list\n", @@ -427,10 +455,10 @@ ], "source": [ "plt.figure()\n", - "plt.plot(np.array(evaluation_history)*100,'o-')\n", + "plt.plot(np.array(evaluation_history) * 100, \"o-\")\n", "plt.grid(True)\n", - "plt.xlabel('Iteration')\n", - "plt.ylabel('Transmission (%)')\n", + "plt.xlabel(\"Iteration\")\n", + "plt.ylabel(\"Transmission (%)\")\n", "plt.show()" ] }, @@ -486,7 +514,11 @@ ], "source": [ "opt.update_design([x])\n", - "opt.plot2D(True,plot_monitors_flag=False,output_plane=mp.Volume(center=(0,0,0),size=(2,2,0)))\n", + "opt.plot2D(\n", + " True,\n", + " plot_monitors_flag=False,\n", + " output_plane=mp.Volume(center=(0, 0, 0), size=(2, 2, 0)),\n", + ")\n", "plt.axis(\"off\");" ] }, @@ -516,7 +548,7 @@ } ], "source": [ - "plt.imshow(np.rot90(np.squeeze(np.abs(sensitivity[0].reshape(Nx,Ny)))));" + "plt.imshow(np.rot90(np.squeeze(np.abs(sensitivity[0].reshape(Nx, Ny)))));" ] } ], diff --git a/python/examples/adjoint_optimization/03-Filtered_Waveguide_Bend.ipynb b/python/examples/adjoint_optimization/03-Filtered_Waveguide_Bend.ipynb index b7f61e4f7..ba833ce4c 100644 --- a/python/examples/adjoint_optimization/03-Filtered_Waveguide_Bend.ipynb +++ b/python/examples/adjoint_optimization/03-Filtered_Waveguide_Bend.ipynb @@ -38,6 +38,7 @@ "from matplotlib import pyplot as plt\n", "from matplotlib.patches import Circle\n", "from scipy import special, signal\n", + "\n", "mp.verbosity(0)\n", "Si = mp.Medium(index=3.4)\n", "SiO2 = mp.Medium(index=1.44)" @@ -66,7 +67,7 @@ "\n", "resolution = 20\n", "\n", - "frequencies = 1/np.linspace(1.5,1.6,10)" + "frequencies = 1 / np.linspace(1.5, 1.6, 10)" ] }, { @@ -92,13 +93,15 @@ } ], "source": [ - "minimum_length = 0.09 # minimum length scale (microns)\n", - "eta_i = 0.5 # blueprint (or intermediate) design field thresholding point (between 0 and 1)\n", - "eta_e = 0.55 # erosion design field thresholding point (between 0 and 1)\n", - "eta_d = 1-eta_e # dilation design field thresholding point (between 0 and 1)\n", - "filter_radius = mpa.get_conic_radius_from_eta_e(minimum_length,eta_e)\n", + "minimum_length = 0.09 # minimum length scale (microns)\n", + "eta_i = (\n", + " 0.5 # blueprint (or intermediate) design field thresholding point (between 0 and 1)\n", + ")\n", + "eta_e = 0.55 # erosion design field thresholding point (between 0 and 1)\n", + "eta_d = 1 - eta_e # dilation design field thresholding point (between 0 and 1)\n", + "filter_radius = mpa.get_conic_radius_from_eta_e(minimum_length, eta_e)\n", "print(filter_radius)\n", - "design_region_resolution = int(1*resolution)" + "design_region_resolution = int(1 * resolution)" ] }, { @@ -114,25 +117,29 @@ "metadata": {}, "outputs": [], "source": [ - "Sx = 2*pml_size + 2*waveguide_length + design_region_width\n", - "Sy = 2*pml_size + design_region_height + 0.5\n", - "cell_size = mp.Vector3(Sx,Sy)\n", + "Sx = 2 * pml_size + 2 * waveguide_length + design_region_width\n", + "Sy = 2 * pml_size + design_region_height + 0.5\n", + "cell_size = mp.Vector3(Sx, Sy)\n", "\n", "pml_layers = [mp.PML(pml_size)]\n", "\n", - "fcen = 1/1.55\n", + "fcen = 1 / 1.55\n", "width = 0.1\n", "fwidth = width * fcen\n", - "source_center = [-Sx/2 + pml_size + waveguide_length/3,0,0]\n", - "source_size = mp.Vector3(0,Sy,0)\n", - "kpoint = mp.Vector3(1,0,0)\n", - "src = mp.GaussianSource(frequency=fcen,fwidth=fwidth)\n", - "source = [mp.EigenModeSource(src,\n", - " eig_band = 1,\n", - " direction=mp.NO_DIRECTION,\n", - " eig_kpoint=kpoint,\n", - " size = source_size,\n", - " center=source_center)]" + "source_center = [-Sx / 2 + pml_size + waveguide_length / 3, 0, 0]\n", + "source_size = mp.Vector3(0, Sy, 0)\n", + "kpoint = mp.Vector3(1, 0, 0)\n", + "src = mp.GaussianSource(frequency=fcen, fwidth=fwidth)\n", + "source = [\n", + " mp.EigenModeSource(\n", + " src,\n", + " eig_band=1,\n", + " direction=mp.NO_DIRECTION,\n", + " eig_kpoint=kpoint,\n", + " size=source_size,\n", + " center=source_center,\n", + " )\n", + "]" ] }, { @@ -148,11 +155,17 @@ "metadata": {}, "outputs": [], "source": [ - "Nx = int(design_region_resolution*design_region_width)\n", - "Ny = int(design_region_resolution*design_region_height)\n", + "Nx = int(design_region_resolution * design_region_width)\n", + "Ny = int(design_region_resolution * design_region_height)\n", "\n", - "design_variables = mp.MaterialGrid(mp.Vector3(Nx,Ny),SiO2,Si,grid_type='U_MEAN')\n", - "design_region = mpa.DesignRegion(design_variables,volume=mp.Volume(center=mp.Vector3(), size=mp.Vector3(design_region_width, design_region_height, 0)))" + "design_variables = mp.MaterialGrid(mp.Vector3(Nx, Ny), SiO2, Si, grid_type=\"U_MEAN\")\n", + "design_region = mpa.DesignRegion(\n", + " design_variables,\n", + " volume=mp.Volume(\n", + " center=mp.Vector3(),\n", + " size=mp.Vector3(design_region_width, design_region_height, 0),\n", + " ),\n", + ")" ] }, { @@ -168,18 +181,20 @@ "metadata": {}, "outputs": [], "source": [ - "x_g = np.linspace(-design_region_width/2,design_region_width/2,Nx)\n", - "y_g = np.linspace(-design_region_height/2,design_region_height/2,Ny)\n", - "X_g, Y_g = np.meshgrid(x_g,y_g,sparse=True,indexing='ij')\n", + "x_g = np.linspace(-design_region_width / 2, design_region_width / 2, Nx)\n", + "y_g = np.linspace(-design_region_height / 2, design_region_height / 2, Ny)\n", + "X_g, Y_g = np.meshgrid(x_g, y_g, sparse=True, indexing=\"ij\")\n", "\n", - "left_wg_mask = (X_g == -design_region_width/2) & (np.abs(Y_g) <= waveguide_width/2)\n", - "top_wg_mask = (Y_g == design_region_width/2) & (np.abs(X_g) <= waveguide_width/2)\n", + "left_wg_mask = (X_g == -design_region_width / 2) & (np.abs(Y_g) <= waveguide_width / 2)\n", + "top_wg_mask = (Y_g == design_region_width / 2) & (np.abs(X_g) <= waveguide_width / 2)\n", "Si_mask = left_wg_mask | top_wg_mask\n", "\n", - "border_mask = ((X_g == -design_region_width/2) | \n", - " (X_g == design_region_width/2) | \n", - " (Y_g == -design_region_height/2) | \n", - " (Y_g == design_region_height/2))\n", + "border_mask = (\n", + " (X_g == -design_region_width / 2)\n", + " | (X_g == design_region_width / 2)\n", + " | (Y_g == -design_region_height / 2)\n", + " | (Y_g == design_region_height / 2)\n", + ")\n", "SiO2_mask = border_mask.copy()\n", "SiO2_mask[Si_mask] = False" ] @@ -197,17 +212,25 @@ "metadata": {}, "outputs": [], "source": [ - "def mapping(x,eta,beta):\n", - " x = npa.where(Si_mask.flatten(),1,npa.where(SiO2_mask.flatten(),0,x))\n", - " \n", + "def mapping(x, eta, beta):\n", + " x = npa.where(Si_mask.flatten(), 1, npa.where(SiO2_mask.flatten(), 0, x))\n", + "\n", " # filter\n", - " filtered_field = mpa.conic_filter(x,filter_radius,design_region_width,design_region_height,design_region_resolution)\n", - " \n", + " filtered_field = mpa.conic_filter(\n", + " x,\n", + " filter_radius,\n", + " design_region_width,\n", + " design_region_height,\n", + " design_region_resolution,\n", + " )\n", + "\n", " # projection\n", - " projected_field = mpa.tanh_projection(filtered_field,beta,eta)\n", - " \n", - " projected_field = (npa.rot90(projected_field.T, 2) + projected_field)/2 # 90-degree symmetry\n", - " \n", + " projected_field = mpa.tanh_projection(filtered_field, beta, eta)\n", + "\n", + " projected_field = (\n", + " npa.rot90(projected_field.T, 2) + projected_field\n", + " ) / 2 # 90-degree symmetry\n", + "\n", " # interpolate to actual materials\n", " return projected_field.flatten()" ] @@ -228,22 +251,30 @@ "outputs": [], "source": [ "geometry = [\n", - " mp.Block(center=mp.Vector3(x=-Sx/4), material=Si, size=mp.Vector3(Sx/2, 0.5, 0)), # horizontal waveguide\n", - " mp.Block(center=mp.Vector3(y=Sy/4), material=Si, size=mp.Vector3(0.5, Sy/2, 0)), # vertical waveguide\n", - " mp.Block(center=design_region.center, size=design_region.size, material=design_variables), # design region\n", - " #mp.Block(center=design_region.center, size=design_region.size, material=design_variables,\n", + " mp.Block(\n", + " center=mp.Vector3(x=-Sx / 4), material=Si, size=mp.Vector3(Sx / 2, 0.5, 0)\n", + " ), # horizontal waveguide\n", + " mp.Block(\n", + " center=mp.Vector3(y=Sy / 4), material=Si, size=mp.Vector3(0.5, Sy / 2, 0)\n", + " ), # vertical waveguide\n", + " mp.Block(\n", + " center=design_region.center, size=design_region.size, material=design_variables\n", + " ), # design region\n", + " # mp.Block(center=design_region.center, size=design_region.size, material=design_variables,\n", " # e1=mp.Vector3(x=-1).rotate(mp.Vector3(z=1), np.pi/2), e2=mp.Vector3(y=1).rotate(mp.Vector3(z=1), np.pi/2))\n", - " # \n", + " #\n", " # The commented lines above impose symmetry by overlapping design region with the same design variable. However,\n", " # currently there is an issue of doing that; instead, we use an alternative approach to impose symmetry.\n", " # See https://github.com/NanoComp/meep/issues/1984 and https://github.com/NanoComp/meep/issues/2093\n", "]\n", - "sim = mp.Simulation(cell_size=cell_size,\n", - " boundary_layers=pml_layers,\n", - " geometry=geometry,\n", - " sources=source,\n", - " default_material=SiO2,\n", - " resolution=resolution)" + "sim = mp.Simulation(\n", + " cell_size=cell_size,\n", + " boundary_layers=pml_layers,\n", + " geometry=geometry,\n", + " sources=source,\n", + " default_material=SiO2,\n", + " resolution=resolution,\n", + ")" ] }, { @@ -261,11 +292,27 @@ "source": [ "mode = 1\n", "\n", - "TE0 = mpa.EigenmodeCoefficient(sim,mp.Volume(center=mp.Vector3(x=-Sx/2 + pml_size + 2*waveguide_length/3),size=mp.Vector3(y=Sy)),mode)\n", - "TE_top = mpa.EigenmodeCoefficient(sim,mp.Volume(center=mp.Vector3(0,Sx/2 - pml_size - 2*waveguide_length/3,0),size=mp.Vector3(x=Sx)),mode)\n", - "ob_list = [TE0,TE_top]\n", - "def J(source,top):\n", - " power = npa.abs(top/source)**2\n", + "TE0 = mpa.EigenmodeCoefficient(\n", + " sim,\n", + " mp.Volume(\n", + " center=mp.Vector3(x=-Sx / 2 + pml_size + 2 * waveguide_length / 3),\n", + " size=mp.Vector3(y=Sy),\n", + " ),\n", + " mode,\n", + ")\n", + "TE_top = mpa.EigenmodeCoefficient(\n", + " sim,\n", + " mp.Volume(\n", + " center=mp.Vector3(0, Sx / 2 - pml_size - 2 * waveguide_length / 3, 0),\n", + " size=mp.Vector3(x=Sx),\n", + " ),\n", + " mode,\n", + ")\n", + "ob_list = [TE0, TE_top]\n", + "\n", + "\n", + "def J(source, top):\n", + " power = npa.abs(top / source) ** 2\n", " return npa.mean(power)" ] }, @@ -276,10 +323,10 @@ "outputs": [], "source": [ "opt = mpa.OptimizationProblem(\n", - " simulation = sim,\n", - " objective_functions = J,\n", - " objective_arguments = ob_list,\n", - " design_regions = [design_region],\n", + " simulation=sim,\n", + " objective_functions=J,\n", + " objective_arguments=ob_list,\n", + " design_regions=[design_region],\n", " frequencies=frequencies,\n", ")" ] @@ -310,9 +357,9 @@ } ], "source": [ - "rho_vector = np.random.rand(Nx*Ny)\n", - "opt.update_design([mapping(rho_vector,eta_i,1e3)])\n", - "opt.plot2D(True,output_plane=mp.Volume(center=(0,0,0),size=(3,3,0)))\n", + "rho_vector = np.random.rand(Nx * Ny)\n", + "opt.update_design([mapping(rho_vector, eta_i, 1e3)])\n", + "opt.plot2D(True, output_plane=mp.Volume(center=(0, 0, 0), size=(3, 3, 0)))\n", "plt.show()" ] }, @@ -345,19 +392,19 @@ "beta = 2048\n", "\n", "plt.figure()\n", - "ax1 = plt.subplot(1,3,1)\n", - "opt.update_design([mapping(rho_vector,0.498,beta)])\n", - "opt.plot2D(True,ax=ax1,output_plane=mp.Volume(center=(0,0,0),size=(3,3,0)))\n", + "ax1 = plt.subplot(1, 3, 1)\n", + "opt.update_design([mapping(rho_vector, 0.498, beta)])\n", + "opt.plot2D(True, ax=ax1, output_plane=mp.Volume(center=(0, 0, 0), size=(3, 3, 0)))\n", "plt.title(\"Dilation\")\n", "\n", - "ax2 = plt.subplot(1,3,2)\n", - "opt.update_design([mapping(rho_vector,0.5,beta)])\n", - "opt.plot2D(True,ax=ax2,output_plane=mp.Volume(center=(0,0,0),size=(3,3,0)))\n", + "ax2 = plt.subplot(1, 3, 2)\n", + "opt.update_design([mapping(rho_vector, 0.5, beta)])\n", + "opt.plot2D(True, ax=ax2, output_plane=mp.Volume(center=(0, 0, 0), size=(3, 3, 0)))\n", "plt.title(\"Intermediate\")\n", "\n", - "ax3 = plt.subplot(1,3,3)\n", - "opt.update_design([mapping(rho_vector,0.502,beta)])\n", - "opt.plot2D(True,ax=ax3,output_plane=mp.Volume(center=(0,0,0),size=(3,3,0)))\n", + "ax3 = plt.subplot(1, 3, 3)\n", + "opt.update_design([mapping(rho_vector, 0.502, beta)])\n", + "opt.plot2D(True, ax=ax3, output_plane=mp.Volume(center=(0, 0, 0), size=(3, 3, 0)))\n", "plt.title(\"Erosion\")\n", "\n", "plt.tight_layout()\n", @@ -379,27 +426,36 @@ "source": [ "evaluation_history = []\n", "cur_iter = [0]\n", + "\n", + "\n", "def f(v, gradient, cur_beta):\n", - " print(\"Current iteration: {}\".format(cur_iter[0]+1))\n", - " \n", - " f0, dJ_du = opt([mapping(v,eta_i,cur_beta)]) # compute objective and gradient\n", - " \n", + " print(\"Current iteration: {}\".format(cur_iter[0] + 1))\n", + "\n", + " f0, dJ_du = opt([mapping(v, eta_i, cur_beta)]) # compute objective and gradient\n", + "\n", " if gradient.size > 0:\n", - " gradient[:] = tensor_jacobian_product(mapping,0)(v,eta_i,cur_beta,np.sum(dJ_du,axis=1)) # backprop\n", - " \n", - " \n", + " gradient[:] = tensor_jacobian_product(mapping, 0)(\n", + " v, eta_i, cur_beta, np.sum(dJ_du, axis=1)\n", + " ) # backprop\n", + "\n", " evaluation_history.append(np.real(f0))\n", - " \n", + "\n", " plt.figure()\n", " ax = plt.gca()\n", - " opt.plot2D(False,ax=ax,plot_sources_flag=False,plot_monitors_flag=False,plot_boundaries_flag=False)\n", - " circ = Circle((2,2),minimum_length/2)\n", + " opt.plot2D(\n", + " False,\n", + " ax=ax,\n", + " plot_sources_flag=False,\n", + " plot_monitors_flag=False,\n", + " plot_boundaries_flag=False,\n", + " )\n", + " circ = Circle((2, 2), minimum_length / 2)\n", " ax.add_patch(circ)\n", - " ax.axis('off')\n", + " ax.axis(\"off\")\n", " plt.show()\n", - " \n", + "\n", " cur_iter[0] = cur_iter[0] + 1\n", - " \n", + "\n", " return np.real(f0)" ] }, @@ -2002,17 +2058,17 @@ ], "source": [ "algorithm = nlopt.LD_MMA\n", - "n = Nx * Ny # number of parameters\n", + "n = Nx * Ny # number of parameters\n", "\n", "# Initial guess\n", "x = np.ones((n,)) * 0.5\n", - "x[Si_mask.flatten()] = 1 # set the edges of waveguides to silicon\n", - "x[SiO2_mask.flatten()] = 0 # set the other edges to SiO2\n", + "x[Si_mask.flatten()] = 1 # set the edges of waveguides to silicon\n", + "x[SiO2_mask.flatten()] = 0 # set the other edges to SiO2\n", "\n", "# lower and upper bounds\n", - "lb = np.zeros((Nx*Ny,))\n", + "lb = np.zeros((Nx * Ny,))\n", "lb[Si_mask.flatten()] = 1\n", - "ub = np.ones((Nx*Ny,))\n", + "ub = np.ones((Nx * Ny,))\n", "ub[SiO2_mask.flatten()] = 0\n", "\n", "cur_beta = 4\n", @@ -2023,10 +2079,10 @@ " solver = nlopt.opt(algorithm, n)\n", " solver.set_lower_bounds(lb)\n", " solver.set_upper_bounds(ub)\n", - " solver.set_max_objective(lambda a,g: f(a,g,cur_beta))\n", + " solver.set_max_objective(lambda a, g: f(a, g, cur_beta))\n", " solver.set_maxeval(update_factor)\n", " x[:] = solver.optimize(x)\n", - " cur_beta = cur_beta*beta_scale" + " cur_beta = cur_beta * beta_scale" ] }, { @@ -2056,10 +2112,10 @@ ], "source": [ "plt.figure()\n", - "plt.plot(10*np.log10(evaluation_history),'o-')\n", + "plt.plot(10 * np.log10(evaluation_history), \"o-\")\n", "plt.grid(True)\n", - "plt.xlabel('Iteration')\n", - "plt.ylabel('Average Insertion Loss (dB)')\n", + "plt.xlabel(\"Iteration\")\n", + "plt.ylabel(\"Average Insertion Loss (dB)\")\n", "plt.show()" ] }, @@ -2089,13 +2145,19 @@ } ], "source": [ - "opt.update_design([mapping(x,eta_i,cur_beta)])\n", + "opt.update_design([mapping(x, eta_i, cur_beta)])\n", "plt.figure()\n", "ax = plt.gca()\n", - "opt.plot2D(False,ax=ax,plot_sources_flag=False,plot_monitors_flag=False,plot_boundaries_flag=False)\n", - "circ = Circle((2,2),minimum_length/2)\n", + "opt.plot2D(\n", + " False,\n", + " ax=ax,\n", + " plot_sources_flag=False,\n", + " plot_monitors_flag=False,\n", + " plot_boundaries_flag=False,\n", + ")\n", + "circ = Circle((2, 2), minimum_length / 2)\n", "ax.add_patch(circ)\n", - "ax.axis('off')\n", + "ax.axis(\"off\")\n", "plt.show()" ] }, @@ -2120,11 +2182,11 @@ } ], "source": [ - "f0, dJ_du = opt([mapping(x,eta_i,cur_beta//2)],need_gradient = False)\n", + "f0, dJ_du = opt([mapping(x, eta_i, cur_beta // 2)], need_gradient=False)\n", "frequencies = opt.frequencies\n", "source_coef, top_coef = opt.get_objective_arguments()\n", "\n", - "top_profile = np.abs(top_coef/source_coef) ** 2" + "top_profile = np.abs(top_coef / source_coef) ** 2" ] }, { @@ -2159,19 +2221,19 @@ ], "source": [ "plt.figure()\n", - "plt.plot(1/frequencies,top_profile*100,'-o')\n", + "plt.plot(1 / frequencies, top_profile * 100, \"-o\")\n", "plt.grid(True)\n", - "plt.xlabel('Wavelength (microns)')\n", - "plt.ylabel('Transmission (%)')\n", - "#plt.ylim(98,100)\n", + "plt.xlabel(\"Wavelength (microns)\")\n", + "plt.ylabel(\"Transmission (%)\")\n", + "# plt.ylim(98,100)\n", "plt.show()\n", "\n", "plt.figure()\n", - "plt.plot(1/frequencies,10*np.log10(top_profile),'-o')\n", + "plt.plot(1 / frequencies, 10 * np.log10(top_profile), \"-o\")\n", "plt.grid(True)\n", - "plt.xlabel('Wavelength (microns)')\n", - "plt.ylabel('Insertion Loss (dB)')\n", - "#plt.ylim(-0.1,0)\n", + "plt.xlabel(\"Wavelength (microns)\")\n", + "plt.ylabel(\"Insertion Loss (dB)\")\n", + "# plt.ylim(-0.1,0)\n", "plt.show()" ] }, diff --git a/python/examples/adjoint_optimization/04-Splitter.ipynb b/python/examples/adjoint_optimization/04-Splitter.ipynb index 4518401a7..ff4b04f57 100644 --- a/python/examples/adjoint_optimization/04-Splitter.ipynb +++ b/python/examples/adjoint_optimization/04-Splitter.ipynb @@ -41,6 +41,7 @@ "from matplotlib import pyplot as plt\n", "from matplotlib.patches import Circle\n", "import nlopt\n", + "\n", "seed = 240\n", "np.random.seed(seed)\n", "mp.quiet(quietval=True)\n", @@ -71,13 +72,13 @@ "\n", "minimum_length = 0.09\n", "eta_e = 0.55\n", - "filter_radius = mpa.get_conic_radius_from_eta_e(minimum_length,eta_e)\n", + "filter_radius = mpa.get_conic_radius_from_eta_e(minimum_length, eta_e)\n", "eta_i = 0.5\n", - "eta_d = 1-eta_e\n", - "design_region_resolution = int(5*resolution)\n", + "eta_d = 1 - eta_e\n", + "design_region_resolution = int(5 * resolution)\n", "\n", - "frequencies = 1/np.linspace(1.5,1.6,10)\n", - "#print(1/frequencies)" + "frequencies = 1 / np.linspace(1.5, 1.6, 10)\n", + "# print(1/frequencies)" ] }, { @@ -93,25 +94,29 @@ "metadata": {}, "outputs": [], "source": [ - "Sx = 2*pml_size + 2*waveguide_length + design_region_width\n", - "Sy = 2*pml_size + design_region_height + 0.5\n", - "cell_size = mp.Vector3(Sx,Sy)\n", + "Sx = 2 * pml_size + 2 * waveguide_length + design_region_width\n", + "Sy = 2 * pml_size + design_region_height + 0.5\n", + "cell_size = mp.Vector3(Sx, Sy)\n", "\n", "pml_layers = [mp.PML(pml_size)]\n", "\n", - "fcen = 1/1.56\n", + "fcen = 1 / 1.56\n", "width = 0.2\n", "fwidth = width * fcen\n", - "source_center = [-Sx/2 + pml_size + waveguide_length/3,0,0]\n", - "source_size = mp.Vector3(0,2,0)\n", - "kpoint = mp.Vector3(1,0,0)\n", - "src = mp.GaussianSource(frequency=fcen,fwidth=fwidth)\n", - "source = [mp.EigenModeSource(src,\n", - " eig_band = 1,\n", - " direction=mp.NO_DIRECTION,\n", - " eig_kpoint=kpoint,\n", - " size = source_size,\n", - " center=source_center)]" + "source_center = [-Sx / 2 + pml_size + waveguide_length / 3, 0, 0]\n", + "source_size = mp.Vector3(0, 2, 0)\n", + "kpoint = mp.Vector3(1, 0, 0)\n", + "src = mp.GaussianSource(frequency=fcen, fwidth=fwidth)\n", + "source = [\n", + " mp.EigenModeSource(\n", + " src,\n", + " eig_band=1,\n", + " direction=mp.NO_DIRECTION,\n", + " eig_kpoint=kpoint,\n", + " size=source_size,\n", + " center=source_center,\n", + " )\n", + "]" ] }, { @@ -127,11 +132,17 @@ "metadata": {}, "outputs": [], "source": [ - "Nx = int(design_region_resolution*design_region_width)\n", - "Ny = int(design_region_resolution*design_region_height)\n", + "Nx = int(design_region_resolution * design_region_width)\n", + "Ny = int(design_region_resolution * design_region_height)\n", "\n", - "design_variables = mp.MaterialGrid(mp.Vector3(Nx,Ny),SiO2,Si,grid_type='U_MEAN')\n", - "design_region = mpa.DesignRegion(design_variables,volume=mp.Volume(center=mp.Vector3(), size=mp.Vector3(design_region_width, design_region_height, 0)))" + "design_variables = mp.MaterialGrid(mp.Vector3(Nx, Ny), SiO2, Si, grid_type=\"U_MEAN\")\n", + "design_region = mpa.DesignRegion(\n", + " design_variables,\n", + " volume=mp.Volume(\n", + " center=mp.Vector3(),\n", + " size=mp.Vector3(design_region_width, design_region_height, 0),\n", + " ),\n", + ")" ] }, { @@ -147,16 +158,24 @@ "metadata": {}, "outputs": [], "source": [ - "def mapping(x,eta,beta):\n", - " \n", + "def mapping(x, eta, beta):\n", + "\n", " # filter\n", - " filtered_field = mpa.conic_filter(x,filter_radius,design_region_width,design_region_height,design_region_resolution)\n", - " \n", + " filtered_field = mpa.conic_filter(\n", + " x,\n", + " filter_radius,\n", + " design_region_width,\n", + " design_region_height,\n", + " design_region_resolution,\n", + " )\n", + "\n", " # projection\n", - " projected_field = mpa.tanh_projection(filtered_field,beta,eta)\n", - " \n", - " projected_field = (npa.fliplr(projected_field) + projected_field)/2 # up-down symmetry\n", - " \n", + " projected_field = mpa.tanh_projection(filtered_field, beta, eta)\n", + "\n", + " projected_field = (\n", + " npa.fliplr(projected_field) + projected_field\n", + " ) / 2 # up-down symmetry\n", + "\n", " # interpolate to actual materials\n", " return projected_field.flatten()" ] @@ -175,21 +194,27 @@ "outputs": [], "source": [ "# Define spatial arrays used to generate bit masks\n", - "x_g = np.linspace(-design_region_width/2,design_region_width/2,Nx)\n", - "y_g = np.linspace(-design_region_height/2,design_region_height/2,Ny)\n", - "X_g, Y_g = np.meshgrid(x_g,y_g,sparse=True,indexing='ij')\n", + "x_g = np.linspace(-design_region_width / 2, design_region_width / 2, Nx)\n", + "y_g = np.linspace(-design_region_height / 2, design_region_height / 2, Ny)\n", + "X_g, Y_g = np.meshgrid(x_g, y_g, sparse=True, indexing=\"ij\")\n", "\n", "# Define the core mask\n", - "left_wg_mask = (X_g == -design_region_width/2) & (np.abs(Y_g) <= waveguide_width/2)\n", - "top_right_wg_mask = (X_g == design_region_width/2) & (np.abs(Y_g + arm_separation/2) <= waveguide_width/2)\n", - "bottom_right_wg_mask = (X_g == design_region_width/2) & (np.abs(Y_g - arm_separation/2) <= waveguide_width/2)\n", + "left_wg_mask = (X_g == -design_region_width / 2) & (np.abs(Y_g) <= waveguide_width / 2)\n", + "top_right_wg_mask = (X_g == design_region_width / 2) & (\n", + " np.abs(Y_g + arm_separation / 2) <= waveguide_width / 2\n", + ")\n", + "bottom_right_wg_mask = (X_g == design_region_width / 2) & (\n", + " np.abs(Y_g - arm_separation / 2) <= waveguide_width / 2\n", + ")\n", "Si_mask = left_wg_mask | top_right_wg_mask | bottom_right_wg_mask\n", "\n", "# Define the cladding mask\n", - "border_mask = ((X_g == -design_region_width/2) | \n", - " (X_g == design_region_width/2) | \n", - " (Y_g == -design_region_height/2) | \n", - " (Y_g == design_region_height/2))\n", + "border_mask = (\n", + " (X_g == -design_region_width / 2)\n", + " | (X_g == design_region_width / 2)\n", + " | (Y_g == -design_region_height / 2)\n", + " | (Y_g == design_region_height / 2)\n", + ")\n", "SiO2_mask = border_mask.copy()\n", "SiO2_mask[Si_mask] = False" ] @@ -208,24 +233,40 @@ "outputs": [], "source": [ "geometry = [\n", - " mp.Block(center=mp.Vector3(x=-Sx/4), material=Si, size=mp.Vector3(Sx/2+1, waveguide_width, 0)), # left waveguide\n", - " mp.Block(center=mp.Vector3(x=Sx/4, y=arm_separation/2), material=Si, size=mp.Vector3(Sx/2+1, waveguide_width, 0)), # top right waveguide\n", - " mp.Block(center=mp.Vector3(x=Sx/4, y=-arm_separation/2), material=Si, size=mp.Vector3(Sx/2+1, waveguide_width, 0)), # bottom right waveguide\n", - " mp.Block(center=design_region.center, size=design_region.size, material=design_variables),\n", - " #mp.Block(center=design_region.center, size=design_region.size, material=design_variables, e2=mp.Vector3(y=-1))\n", - " # \n", + " mp.Block(\n", + " center=mp.Vector3(x=-Sx / 4),\n", + " material=Si,\n", + " size=mp.Vector3(Sx / 2 + 1, waveguide_width, 0),\n", + " ), # left waveguide\n", + " mp.Block(\n", + " center=mp.Vector3(x=Sx / 4, y=arm_separation / 2),\n", + " material=Si,\n", + " size=mp.Vector3(Sx / 2 + 1, waveguide_width, 0),\n", + " ), # top right waveguide\n", + " mp.Block(\n", + " center=mp.Vector3(x=Sx / 4, y=-arm_separation / 2),\n", + " material=Si,\n", + " size=mp.Vector3(Sx / 2 + 1, waveguide_width, 0),\n", + " ), # bottom right waveguide\n", + " mp.Block(\n", + " center=design_region.center, size=design_region.size, material=design_variables\n", + " ),\n", + " # mp.Block(center=design_region.center, size=design_region.size, material=design_variables, e2=mp.Vector3(y=-1))\n", + " #\n", " # The commented line above impose symmetry by overlapping design region with the same design variable. However,\n", " # currently there is an issue of doing that; instead, we use an alternative approach to impose symmetry.\n", " # See https://github.com/NanoComp/meep/issues/1984 and https://github.com/NanoComp/meep/issues/2093\n", "]\n", "\n", - "sim = mp.Simulation(cell_size=cell_size,\n", - " boundary_layers=pml_layers,\n", - " geometry=geometry,\n", - " sources=source,\n", - " symmetries=[mp.Mirror(direction=mp.Y)],\n", - " default_material=SiO2,\n", - " resolution=resolution)" + "sim = mp.Simulation(\n", + " cell_size=cell_size,\n", + " boundary_layers=pml_layers,\n", + " geometry=geometry,\n", + " sources=source,\n", + " symmetries=[mp.Mirror(direction=mp.Y)],\n", + " default_material=SiO2,\n", + " resolution=resolution,\n", + ")" ] }, { @@ -243,22 +284,49 @@ "source": [ "mode = 1\n", "\n", - "TE0 = mpa.EigenmodeCoefficient(sim,mp.Volume(center=mp.Vector3(x=-Sx/2 + pml_size + 2*waveguide_length/3),size=mp.Vector3(y=1.5)),mode)\n", - "TE_top = mpa.EigenmodeCoefficient(sim,mp.Volume(center=mp.Vector3(Sx/2 - pml_size - 2*waveguide_length/3,arm_separation/2,0),size=mp.Vector3(y=arm_separation)),mode)\n", - "TE_bottom = mpa.EigenmodeCoefficient(sim,mp.Volume(center=mp.Vector3(Sx/2 - pml_size - 2*waveguide_length/3,-arm_separation/2,0),size=mp.Vector3(y=arm_separation)),mode)\n", - "ob_list = [TE0,TE_top,TE_bottom]\n", + "TE0 = mpa.EigenmodeCoefficient(\n", + " sim,\n", + " mp.Volume(\n", + " center=mp.Vector3(x=-Sx / 2 + pml_size + 2 * waveguide_length / 3),\n", + " size=mp.Vector3(y=1.5),\n", + " ),\n", + " mode,\n", + ")\n", + "TE_top = mpa.EigenmodeCoefficient(\n", + " sim,\n", + " mp.Volume(\n", + " center=mp.Vector3(\n", + " Sx / 2 - pml_size - 2 * waveguide_length / 3, arm_separation / 2, 0\n", + " ),\n", + " size=mp.Vector3(y=arm_separation),\n", + " ),\n", + " mode,\n", + ")\n", + "TE_bottom = mpa.EigenmodeCoefficient(\n", + " sim,\n", + " mp.Volume(\n", + " center=mp.Vector3(\n", + " Sx / 2 - pml_size - 2 * waveguide_length / 3, -arm_separation / 2, 0\n", + " ),\n", + " size=mp.Vector3(y=arm_separation),\n", + " ),\n", + " mode,\n", + ")\n", + "ob_list = [TE0, TE_top, TE_bottom]\n", "\n", - "def J(source,top,bottom):\n", - " power = npa.abs(top/source) ** 2 + npa.abs(bottom/source) ** 2\n", + "\n", + "def J(source, top, bottom):\n", + " power = npa.abs(top / source) ** 2 + npa.abs(bottom / source) ** 2\n", " return npa.mean(power)\n", "\n", + "\n", "opt = mpa.OptimizationProblem(\n", - " simulation = sim,\n", - " objective_functions = J,\n", - " objective_arguments = ob_list,\n", - " design_regions = [design_region],\n", + " simulation=sim,\n", + " objective_functions=J,\n", + " objective_arguments=ob_list,\n", + " design_regions=[design_region],\n", " frequencies=frequencies,\n", - " decay_by = 1e-5,\n", + " decay_by=1e-5,\n", ")" ] }, @@ -289,7 +357,13 @@ ], "source": [ "plt.figure()\n", - "x0 = mapping(np.random.rand(Nx*Ny,),eta_i,128)\n", + "x0 = mapping(\n", + " np.random.rand(\n", + " Nx * Ny,\n", + " ),\n", + " eta_i,\n", + " 128,\n", + ")\n", "opt.update_design([x0])\n", "opt.plot2D(True)\n", "plt.show()" @@ -310,26 +384,36 @@ "source": [ "evaluation_history = []\n", "cur_iter = [0]\n", + "\n", + "\n", "def f(v, gradient, cur_beta):\n", - " print(\"Current iteration: {}\".format(cur_iter[0]+1))\n", - " \n", - " f0, dJ_du = opt([mapping(v,eta_i,cur_beta)])\n", - " \n", + " print(\"Current iteration: {}\".format(cur_iter[0] + 1))\n", + "\n", + " f0, dJ_du = opt([mapping(v, eta_i, cur_beta)])\n", + "\n", " plt.figure()\n", " ax = plt.gca()\n", - " opt.plot2D(False,ax=ax,plot_sources_flag=False,plot_monitors_flag=False,plot_boundaries_flag=False)\n", - " circ = Circle((2,2),minimum_length/2)\n", + " opt.plot2D(\n", + " False,\n", + " ax=ax,\n", + " plot_sources_flag=False,\n", + " plot_monitors_flag=False,\n", + " plot_boundaries_flag=False,\n", + " )\n", + " circ = Circle((2, 2), minimum_length / 2)\n", " ax.add_patch(circ)\n", - " ax.axis('off')\n", + " ax.axis(\"off\")\n", " plt.show()\n", - " \n", + "\n", " if gradient.size > 0:\n", - " gradient[:] = tensor_jacobian_product(mapping,0)(v,eta_i,cur_beta,np.sum(dJ_du,axis=1))\n", - " \n", + " gradient[:] = tensor_jacobian_product(mapping, 0)(\n", + " v, eta_i, cur_beta, np.sum(dJ_du, axis=1)\n", + " )\n", + "\n", " evaluation_history.append(np.max(np.real(f0)))\n", - " \n", + "\n", " cur_iter[0] = cur_iter[0] + 1\n", - " \n", + "\n", " return np.real(f0)" ] }, @@ -1938,17 +2022,17 @@ ], "source": [ "algorithm = nlopt.LD_MMA\n", - "n = Nx * Ny # number of parameters\n", + "n = Nx * Ny # number of parameters\n", "\n", "# Initial guess\n", "x = np.ones((n,)) * 0.5\n", - "x[Si_mask.flatten()] = 1 # set the edges of waveguides to silicon\n", - "x[SiO2_mask.flatten()] = 0 # set the other edges to SiO2\n", + "x[Si_mask.flatten()] = 1 # set the edges of waveguides to silicon\n", + "x[SiO2_mask.flatten()] = 0 # set the other edges to SiO2\n", "\n", "# lower and upper bounds\n", - "lb = np.zeros((Nx*Ny,))\n", + "lb = np.zeros((Nx * Ny,))\n", "lb[Si_mask.flatten()] = 1\n", - "ub = np.ones((Nx*Ny,))\n", + "ub = np.ones((Nx * Ny,))\n", "ub[SiO2_mask.flatten()] = 0\n", "\n", "cur_beta = 4\n", @@ -1956,15 +2040,15 @@ "num_betas = 6\n", "update_factor = 12\n", "for iters in range(num_betas):\n", - " print(\"current beta: \",cur_beta)\n", - " \n", + " print(\"current beta: \", cur_beta)\n", + "\n", " solver = nlopt.opt(algorithm, n)\n", " solver.set_lower_bounds(lb)\n", " solver.set_upper_bounds(ub)\n", - " solver.set_max_objective(lambda a,g: f(a,g,cur_beta))\n", + " solver.set_max_objective(lambda a, g: f(a, g, cur_beta))\n", " solver.set_maxeval(update_factor)\n", " x[:] = solver.optimize(x)\n", - " cur_beta = cur_beta*beta_scale" + " cur_beta = cur_beta * beta_scale" ] }, { @@ -1994,10 +2078,10 @@ ], "source": [ "plt.figure()\n", - "plt.plot(10*np.log10(0.5*np.array(evaluation_history)),'o-')\n", + "plt.plot(10 * np.log10(0.5 * np.array(evaluation_history)), \"o-\")\n", "plt.grid(True)\n", - "plt.xlabel('Iteration')\n", - "plt.ylabel('Mean Splitting Ratio (dB)')\n", + "plt.xlabel(\"Iteration\")\n", + "plt.ylabel(\"Mean Splitting Ratio (dB)\")\n", "plt.show()" ] }, @@ -2022,12 +2106,12 @@ } ], "source": [ - "f0, dJ_du = opt([mapping(x,eta_i,cur_beta)],need_gradient = False)\n", + "f0, dJ_du = opt([mapping(x, eta_i, cur_beta)], need_gradient=False)\n", "frequencies = opt.frequencies\n", "source_coef, top_coef, bottom_ceof = opt.get_objective_arguments()\n", "\n", - "top_profile = np.abs(top_coef/source_coef) ** 2\n", - "bottom_profile = np.abs(bottom_ceof/source_coef) ** 2" + "top_profile = np.abs(top_coef / source_coef) ** 2\n", + "bottom_profile = np.abs(bottom_ceof / source_coef) ** 2" ] }, { @@ -2050,13 +2134,13 @@ ], "source": [ "plt.figure()\n", - "plt.plot(1/frequencies,top_profile*100,'-o' ,label = 'Top Arm')\n", - "plt.plot(1/frequencies,bottom_profile*100,'--o',label = 'Bottom Arm')\n", + "plt.plot(1 / frequencies, top_profile * 100, \"-o\", label=\"Top Arm\")\n", + "plt.plot(1 / frequencies, bottom_profile * 100, \"--o\", label=\"Bottom Arm\")\n", "plt.legend()\n", "plt.grid(True)\n", - "plt.xlabel('Wavelength (microns)')\n", - "plt.ylabel('Splitting Ratio (%)')\n", - "#plt.ylim(46.5,50)\n", + "plt.xlabel(\"Wavelength (microns)\")\n", + "plt.ylabel(\"Splitting Ratio (%)\")\n", + "# plt.ylim(46.5,50)\n", "plt.show()" ] }, @@ -2086,13 +2170,19 @@ } ], "source": [ - "opt.update_design([mapping(x,eta_i,cur_beta)])\n", + "opt.update_design([mapping(x, eta_i, cur_beta)])\n", "plt.figure()\n", "ax = plt.gca()\n", - "opt.plot2D(False,ax=ax,plot_sources_flag=False,plot_monitors_flag=False,plot_boundaries_flag=False)\n", - "circ = Circle((2,2),minimum_length/2)\n", + "opt.plot2D(\n", + " False,\n", + " ax=ax,\n", + " plot_sources_flag=False,\n", + " plot_monitors_flag=False,\n", + " plot_boundaries_flag=False,\n", + ")\n", + "circ = Circle((2, 2), minimum_length / 2)\n", "ax.add_patch(circ)\n", - "ax.axis('off')\n", + "ax.axis(\"off\")\n", "plt.show()" ] } diff --git a/python/examples/adjoint_optimization/05-Near2Far.ipynb b/python/examples/adjoint_optimization/05-Near2Far.ipynb index b1396e9b6..676d68bb5 100644 --- a/python/examples/adjoint_optimization/05-Near2Far.ipynb +++ b/python/examples/adjoint_optimization/05-Near2Far.ipynb @@ -32,6 +32,7 @@ "from matplotlib import pyplot as plt\n", "from matplotlib.patches import Circle\n", "from scipy import special, signal\n", + "\n", "mp.verbosity(0)\n", "Si = mp.Medium(index=3.4)\n", "Air = mp.Medium(index=1.0)" @@ -57,68 +58,87 @@ "\n", "resolution = 30\n", "\n", - "Sx = 2*pml_size + design_region_width\n", - "Sy = 2*pml_size + design_region_height + 5\n", - "cell_size = mp.Vector3(Sx,Sy)\n", + "Sx = 2 * pml_size + design_region_width\n", + "Sy = 2 * pml_size + design_region_height + 5\n", + "cell_size = mp.Vector3(Sx, Sy)\n", "\n", "nf = 3\n", - "frequencies = np.array([1/1.5, 1/1.55, 1/1.6])\n", + "frequencies = np.array([1 / 1.5, 1 / 1.55, 1 / 1.6])\n", "\n", - "minimum_length = 0.09 # minimum length scale (microns)\n", - "eta_i = 0.5 # blueprint (or intermediate) design field thresholding point (between 0 and 1)\n", - "eta_e = 0.55 # erosion design field thresholding point (between 0 and 1)\n", - "eta_d = 1-eta_e # dilation design field thresholding point (between 0 and 1)\n", - "filter_radius = mpa.get_conic_radius_from_eta_e(minimum_length,eta_e)\n", + "minimum_length = 0.09 # minimum length scale (microns)\n", + "eta_i = (\n", + " 0.5 # blueprint (or intermediate) design field thresholding point (between 0 and 1)\n", + ")\n", + "eta_e = 0.55 # erosion design field thresholding point (between 0 and 1)\n", + "eta_d = 1 - eta_e # dilation design field thresholding point (between 0 and 1)\n", + "filter_radius = mpa.get_conic_radius_from_eta_e(minimum_length, eta_e)\n", "design_region_resolution = int(resolution)\n", "\n", "pml_layers = [mp.PML(pml_size)]\n", "\n", - "fcen = 1/1.55\n", + "fcen = 1 / 1.55\n", "width = 0.2\n", "fwidth = width * fcen\n", - "source_center = [0,-(design_region_height/2 + 1.5),0]\n", - "source_size = mp.Vector3(design_region_width,0,0)\n", - "src = mp.GaussianSource(frequency=fcen,fwidth=fwidth)\n", - "source = [mp.Source(src,\n", - " component=mp.Ez,\n", - " size = source_size,\n", - " center=source_center)]\n", + "source_center = [0, -(design_region_height / 2 + 1.5), 0]\n", + "source_size = mp.Vector3(design_region_width, 0, 0)\n", + "src = mp.GaussianSource(frequency=fcen, fwidth=fwidth)\n", + "source = [mp.Source(src, component=mp.Ez, size=source_size, center=source_center)]\n", + "\n", + "Nx = int(design_region_resolution * design_region_width)\n", + "Ny = int(design_region_resolution * design_region_height)\n", "\n", - "Nx = int(design_region_resolution*design_region_width)\n", - "Ny = int(design_region_resolution*design_region_height)\n", + "design_variables = mp.MaterialGrid(mp.Vector3(Nx, Ny), Air, Si, grid_type=\"U_MEAN\")\n", + "design_region = mpa.DesignRegion(\n", + " design_variables,\n", + " volume=mp.Volume(\n", + " center=mp.Vector3(),\n", + " size=mp.Vector3(design_region_width, design_region_height, 0),\n", + " ),\n", + ")\n", "\n", - "design_variables = mp.MaterialGrid(mp.Vector3(Nx,Ny),Air,Si,grid_type='U_MEAN')\n", - "design_region = mpa.DesignRegion(design_variables,volume=mp.Volume(center=mp.Vector3(), size=mp.Vector3(design_region_width, design_region_height, 0)))\n", "\n", - "def mapping(x,eta,beta):\n", + "def mapping(x, eta, beta):\n", "\n", " # filter\n", - " filtered_field = mpa.conic_filter(x,filter_radius,design_region_width,design_region_height,design_region_resolution)\n", - " \n", + " filtered_field = mpa.conic_filter(\n", + " x,\n", + " filter_radius,\n", + " design_region_width,\n", + " design_region_height,\n", + " design_region_resolution,\n", + " )\n", + "\n", " # projection\n", - " projected_field = mpa.tanh_projection(filtered_field,beta,eta)\n", - " \n", - " projected_field = (npa.flipud(projected_field) + projected_field)/2 # left-right symmetry\n", - " \n", + " projected_field = mpa.tanh_projection(filtered_field, beta, eta)\n", + "\n", + " projected_field = (\n", + " npa.flipud(projected_field) + projected_field\n", + " ) / 2 # left-right symmetry\n", + "\n", " # interpolate to actual materials\n", " return projected_field.flatten()\n", "\n", + "\n", "geometry = [\n", - " mp.Block(center=design_region.center, size=design_region.size, material=design_variables),\n", - " #mp.Block(center=design_region.center, size=design_region.size, material=design_variables, e1=mp.Vector3(x=-1))\n", - " # \n", + " mp.Block(\n", + " center=design_region.center, size=design_region.size, material=design_variables\n", + " ),\n", + " # mp.Block(center=design_region.center, size=design_region.size, material=design_variables, e1=mp.Vector3(x=-1))\n", + " #\n", " # The commented lines above impose symmetry by overlapping design region with the same design variable. However,\n", " # currently there is an issue of doing that; instead, we use an alternative approach to impose symmetry.\n", " # See https://github.com/NanoComp/meep/issues/1984 and https://github.com/NanoComp/meep/issues/2093\n", "]\n", "kpoint = mp.Vector3()\n", - "sim = mp.Simulation(cell_size=cell_size,\n", - " boundary_layers=pml_layers,\n", - " geometry=geometry,\n", - " sources=source,\n", - " default_material=Air,\n", - " symmetries=[mp.Mirror(direction=mp.X)],\n", - " resolution=resolution)" + "sim = mp.Simulation(\n", + " cell_size=cell_size,\n", + " boundary_layers=pml_layers,\n", + " geometry=geometry,\n", + " sources=source,\n", + " default_material=Air,\n", + " symmetries=[mp.Mirror(direction=mp.X)],\n", + " resolution=resolution,\n", + ")" ] }, { @@ -138,12 +158,20 @@ "metadata": {}, "outputs": [], "source": [ - "far_x = [mp.Vector3(0,15,0)]\n", - "NearRegions = [mp.Near2FarRegion(center=mp.Vector3(0,design_region_height/2+1.5), size=mp.Vector3(design_region_width,0), weight=+1)]\n", - "FarFields = mpa.Near2FarFields(sim, NearRegions ,far_x)\n", + "far_x = [mp.Vector3(0, 15, 0)]\n", + "NearRegions = [\n", + " mp.Near2FarRegion(\n", + " center=mp.Vector3(0, design_region_height / 2 + 1.5),\n", + " size=mp.Vector3(design_region_width, 0),\n", + " weight=+1,\n", + " )\n", + "]\n", + "FarFields = mpa.Near2FarFields(sim, NearRegions, far_x)\n", "ob_list = [FarFields]\n", + "\n", + "\n", "def J1(FF):\n", - " return npa.mean(npa.abs(FF[0,:,2])**2)" + " return npa.mean(npa.abs(FF[0, :, 2]) ** 2)" ] }, { @@ -166,12 +194,12 @@ ], "source": [ "opt = mpa.OptimizationProblem(\n", - " simulation = sim,\n", - " objective_functions = [J1],\n", - " objective_arguments = ob_list,\n", - " design_regions = [design_region],\n", + " simulation=sim,\n", + " objective_functions=[J1],\n", + " objective_arguments=ob_list,\n", + " design_regions=[design_region],\n", " frequencies=frequencies,\n", - " maximum_run_time = 2000\n", + " maximum_run_time=2000,\n", ")\n", "opt.plot2D(True)" ] @@ -184,27 +212,36 @@ "source": [ "evaluation_history = []\n", "cur_iter = [0]\n", + "\n", + "\n", "def f(v, gradient, cur_beta):\n", - " print(\"Current iteration: {}\".format(cur_iter[0]+1))\n", - " \n", - " f0, dJ_du = opt([mapping(v,eta_i,cur_beta)]) # compute objective and gradient\n", - " \n", + " print(\"Current iteration: {}\".format(cur_iter[0] + 1))\n", + "\n", + " f0, dJ_du = opt([mapping(v, eta_i, cur_beta)]) # compute objective and gradient\n", + "\n", " if gradient.size > 0:\n", - " gradient[:] = tensor_jacobian_product(mapping,0)(v,eta_i,cur_beta,np.sum(dJ_du,axis=1)) # backprop\n", - " \n", - " \n", + " gradient[:] = tensor_jacobian_product(mapping, 0)(\n", + " v, eta_i, cur_beta, np.sum(dJ_du, axis=1)\n", + " ) # backprop\n", + "\n", " evaluation_history.append(np.real(f0))\n", - " \n", + "\n", " plt.figure()\n", " ax = plt.gca()\n", - " opt.plot2D(False,ax=ax,plot_sources_flag=False,plot_monitors_flag=False,plot_boundaries_flag=False)\n", - " circ = Circle((2,2),minimum_length/2)\n", + " opt.plot2D(\n", + " False,\n", + " ax=ax,\n", + " plot_sources_flag=False,\n", + " plot_monitors_flag=False,\n", + " plot_boundaries_flag=False,\n", + " )\n", + " circ = Circle((2, 2), minimum_length / 2)\n", " ax.add_patch(circ)\n", - " ax.axis('off')\n", + " ax.axis(\"off\")\n", " plt.show()\n", - " \n", + "\n", " cur_iter[0] = cur_iter[0] + 1\n", - " \n", + "\n", " return np.real(f0)" ] }, @@ -1807,14 +1844,14 @@ ], "source": [ "algorithm = nlopt.LD_MMA\n", - "n = Nx * Ny # number of parameters\n", + "n = Nx * Ny # number of parameters\n", "\n", "# Initial guess\n", "x = np.ones((n,)) * 0.5\n", "\n", "# lower and upper bounds\n", - "lb = np.zeros((Nx*Ny,))\n", - "ub = np.ones((Nx*Ny,))\n", + "lb = np.zeros((Nx * Ny,))\n", + "ub = np.ones((Nx * Ny,))\n", "\n", "\n", "cur_beta = 4\n", @@ -1826,11 +1863,11 @@ " solver = nlopt.opt(algorithm, n)\n", " solver.set_lower_bounds(lb)\n", " solver.set_upper_bounds(ub)\n", - " solver.set_max_objective(lambda a,g: f(a,g,cur_beta))\n", + " solver.set_max_objective(lambda a, g: f(a, g, cur_beta))\n", " solver.set_maxeval(update_factor)\n", " solver.set_ftol_rel(ftol)\n", " x[:] = solver.optimize(x)\n", - " cur_beta = cur_beta*beta_scale" + " cur_beta = cur_beta * beta_scale" ] }, { @@ -1854,14 +1891,12 @@ } ], "source": [ - "\n", - "\n", "plt.figure()\n", "\n", - "plt.plot(evaluation_history,'o-')\n", + "plt.plot(evaluation_history, \"o-\")\n", "plt.grid(True)\n", - "plt.xlabel('Iteration')\n", - "plt.ylabel('FOM')\n", + "plt.xlabel(\"Iteration\")\n", + "plt.ylabel(\"FOM\")\n", "plt.show()" ] }, @@ -1891,13 +1926,19 @@ } ], "source": [ - "opt.update_design([mapping(x,eta_i,cur_beta)])\n", + "opt.update_design([mapping(x, eta_i, cur_beta)])\n", "plt.figure()\n", "ax = plt.gca()\n", - "opt.plot2D(False,ax=ax,plot_sources_flag=False,plot_monitors_flag=False,plot_boundaries_flag=False)\n", - "circ = Circle((2,2),minimum_length/2)\n", + "opt.plot2D(\n", + " False,\n", + " ax=ax,\n", + " plot_sources_flag=False,\n", + " plot_monitors_flag=False,\n", + " plot_boundaries_flag=False,\n", + ")\n", + "circ = Circle((2, 2), minimum_length / 2)\n", "ax.add_patch(circ)\n", - "ax.axis('off')\n", + "ax.axis(\"off\")\n", "plt.show()" ] }, @@ -1922,11 +1963,11 @@ } ], "source": [ - "f0, dJ_du = opt([mapping(x,eta_i,cur_beta//2)],need_gradient = False)\n", + "f0, dJ_du = opt([mapping(x, eta_i, cur_beta // 2)], need_gradient=False)\n", "frequencies = opt.frequencies\n", "\n", "\n", - "intensities = np.abs(opt.get_objective_arguments()[0][0,:,2])**2" + "intensities = np.abs(opt.get_objective_arguments()[0][0, :, 2]) ** 2" ] }, { @@ -1948,13 +1989,11 @@ } ], "source": [ - "\n", - "\n", "plt.figure()\n", - "plt.plot(1/frequencies,intensities,'-o')\n", + "plt.plot(1 / frequencies, intensities, \"-o\")\n", "plt.grid(True)\n", - "plt.xlabel('Wavelength (microns)')\n", - "plt.ylabel('|Ez|^2 Intensities')\n", + "plt.xlabel(\"Wavelength (microns)\")\n", + "plt.ylabel(\"|Ez|^2 Intensities\")\n", "plt.show()" ] }, diff --git a/python/examples/adjoint_optimization/06-Near2Far-Epigraph.ipynb b/python/examples/adjoint_optimization/06-Near2Far-Epigraph.ipynb index 3e552be49..f30f97f89 100644 --- a/python/examples/adjoint_optimization/06-Near2Far-Epigraph.ipynb +++ b/python/examples/adjoint_optimization/06-Near2Far-Epigraph.ipynb @@ -32,6 +32,7 @@ "from matplotlib import pyplot as plt\n", "from matplotlib.patches import Circle\n", "from scipy import special, signal\n", + "\n", "mp.verbosity(0)\n", "Si = mp.Medium(index=3.4)\n", "Air = mp.Medium(index=1.0)" @@ -57,68 +58,87 @@ "\n", "resolution = 30\n", "\n", - "Sx = 2*pml_size + design_region_width\n", - "Sy = 2*pml_size + design_region_height + 5\n", - "cell_size = mp.Vector3(Sx,Sy)\n", + "Sx = 2 * pml_size + design_region_width\n", + "Sy = 2 * pml_size + design_region_height + 5\n", + "cell_size = mp.Vector3(Sx, Sy)\n", "\n", "nf = 3\n", - "frequencies = np.array([1/1.5, 1/1.55, 1/1.6])\n", + "frequencies = np.array([1 / 1.5, 1 / 1.55, 1 / 1.6])\n", "\n", - "minimum_length = 0.09 # minimum length scale (microns)\n", - "eta_i = 0.5 # blueprint (or intermediate) design field thresholding point (between 0 and 1)\n", - "eta_e = 0.55 # erosion design field thresholding point (between 0 and 1)\n", - "eta_d = 1-eta_e # dilation design field thresholding point (between 0 and 1)\n", - "filter_radius = mpa.get_conic_radius_from_eta_e(minimum_length,eta_e)\n", + "minimum_length = 0.09 # minimum length scale (microns)\n", + "eta_i = (\n", + " 0.5 # blueprint (or intermediate) design field thresholding point (between 0 and 1)\n", + ")\n", + "eta_e = 0.55 # erosion design field thresholding point (between 0 and 1)\n", + "eta_d = 1 - eta_e # dilation design field thresholding point (between 0 and 1)\n", + "filter_radius = mpa.get_conic_radius_from_eta_e(minimum_length, eta_e)\n", "design_region_resolution = int(resolution)\n", "\n", "pml_layers = [mp.PML(pml_size)]\n", "\n", - "fcen = 1/1.55\n", + "fcen = 1 / 1.55\n", "width = 0.2\n", "fwidth = width * fcen\n", - "source_center = [0,-(design_region_height/2 + 1.5),0]\n", - "source_size = mp.Vector3(design_region_width,0,0)\n", - "src = mp.GaussianSource(frequency=fcen,fwidth=fwidth)\n", - "source = [mp.Source(src,\n", - " component=mp.Ez,\n", - " size = source_size,\n", - " center=source_center)]\n", + "source_center = [0, -(design_region_height / 2 + 1.5), 0]\n", + "source_size = mp.Vector3(design_region_width, 0, 0)\n", + "src = mp.GaussianSource(frequency=fcen, fwidth=fwidth)\n", + "source = [mp.Source(src, component=mp.Ez, size=source_size, center=source_center)]\n", + "\n", + "Nx = int(design_region_resolution * design_region_width)\n", + "Ny = int(design_region_resolution * design_region_height)\n", "\n", - "Nx = int(design_region_resolution*design_region_width)\n", - "Ny = int(design_region_resolution*design_region_height)\n", + "design_variables = mp.MaterialGrid(mp.Vector3(Nx, Ny), Air, Si, grid_type=\"U_MEAN\")\n", + "design_region = mpa.DesignRegion(\n", + " design_variables,\n", + " volume=mp.Volume(\n", + " center=mp.Vector3(),\n", + " size=mp.Vector3(design_region_width, design_region_height, 0),\n", + " ),\n", + ")\n", "\n", - "design_variables = mp.MaterialGrid(mp.Vector3(Nx,Ny),Air,Si,grid_type='U_MEAN')\n", - "design_region = mpa.DesignRegion(design_variables,volume=mp.Volume(center=mp.Vector3(), size=mp.Vector3(design_region_width, design_region_height, 0)))\n", "\n", - "def mapping(x,eta,beta):\n", + "def mapping(x, eta, beta):\n", "\n", " # filter\n", - " filtered_field = mpa.conic_filter(x,filter_radius,design_region_width,design_region_height,design_region_resolution)\n", - " \n", + " filtered_field = mpa.conic_filter(\n", + " x,\n", + " filter_radius,\n", + " design_region_width,\n", + " design_region_height,\n", + " design_region_resolution,\n", + " )\n", + "\n", " # projection\n", - " projected_field = mpa.tanh_projection(filtered_field,beta,eta)\n", - " \n", - " projected_field = (npa.flipud(projected_field) + projected_field)/2 # left-right symmetry\n", - " \n", + " projected_field = mpa.tanh_projection(filtered_field, beta, eta)\n", + "\n", + " projected_field = (\n", + " npa.flipud(projected_field) + projected_field\n", + " ) / 2 # left-right symmetry\n", + "\n", " # interpolate to actual materials\n", " return projected_field.flatten()\n", "\n", + "\n", "geometry = [\n", - " mp.Block(center=design_region.center, size=design_region.size, material=design_variables),\n", - " #mp.Block(center=design_region.center, size=design_region.size, material=design_variables, e1=mp.Vector3(x=-1))\n", - " # \n", + " mp.Block(\n", + " center=design_region.center, size=design_region.size, material=design_variables\n", + " ),\n", + " # mp.Block(center=design_region.center, size=design_region.size, material=design_variables, e1=mp.Vector3(x=-1))\n", + " #\n", " # The commented lines above impose symmetry by overlapping design region with the same design variable. However,\n", " # currently there is an issue of doing that; instead, we use an alternative approach to impose symmetry.\n", " # See https://github.com/NanoComp/meep/issues/1984 and https://github.com/NanoComp/meep/issues/2093\n", "]\n", "kpoint = mp.Vector3()\n", - "sim = mp.Simulation(cell_size=cell_size,\n", - " boundary_layers=pml_layers,\n", - " geometry=geometry,\n", - " sources=source,\n", - " default_material=Air,\n", - " symmetries=[mp.Mirror(direction=mp.X)],\n", - " resolution=resolution)" + "sim = mp.Simulation(\n", + " cell_size=cell_size,\n", + " boundary_layers=pml_layers,\n", + " geometry=geometry,\n", + " sources=source,\n", + " default_material=Air,\n", + " symmetries=[mp.Mirror(direction=mp.X)],\n", + " resolution=resolution,\n", + ")" ] }, { @@ -138,12 +158,20 @@ "metadata": {}, "outputs": [], "source": [ - "far_x = [mp.Vector3(0,15,0)]\n", - "NearRegions = [mp.Near2FarRegion(center=mp.Vector3(0,design_region_height/2+1.5), size=mp.Vector3(design_region_width,0), weight=+1)]\n", - "FarFields = mpa.Near2FarFields(sim, NearRegions ,far_x)\n", + "far_x = [mp.Vector3(0, 15, 0)]\n", + "NearRegions = [\n", + " mp.Near2FarRegion(\n", + " center=mp.Vector3(0, design_region_height / 2 + 1.5),\n", + " size=mp.Vector3(design_region_width, 0),\n", + " weight=+1,\n", + " )\n", + "]\n", + "FarFields = mpa.Near2FarFields(sim, NearRegions, far_x)\n", "ob_list = [FarFields]\n", + "\n", + "\n", "def J1(FF):\n", - " return -npa.abs(FF[0,:,2])**2" + " return -npa.abs(FF[0, :, 2]) ** 2" ] }, { @@ -166,12 +194,12 @@ ], "source": [ "opt = mpa.OptimizationProblem(\n", - " simulation = sim,\n", - " objective_functions = [J1],\n", - " objective_arguments = ob_list,\n", - " design_regions = [design_region],\n", + " simulation=sim,\n", + " objective_functions=[J1],\n", + " objective_arguments=ob_list,\n", + " design_regions=[design_region],\n", " frequencies=frequencies,\n", - " maximum_run_time = 2000\n", + " maximum_run_time=2000,\n", ")\n", "opt.plot2D(True)" ] @@ -191,9 +219,11 @@ "source": [ "evaluation_history = []\n", "cur_iter = [0]\n", + "\n", + "\n", "def f(x, grad):\n", - " t = x[0] # \"dummy\" parameter\n", - " v = x[1:] # design parameters\n", + " t = x[0] # \"dummy\" parameter\n", + " v = x[1:] # design parameters\n", " if grad.size > 0:\n", " grad[0] = 1\n", " grad[1:] = 0\n", @@ -223,40 +253,50 @@ "metadata": {}, "outputs": [], "source": [ - "def c(result,x,gradient,eta,beta):\n", - " print(\"Current iteration: {}; current eta: {}, current beta: {}\".format(cur_iter[0],eta,beta))\n", - " \n", - " t = x[0] # dummy parameter\n", - " v = x[1:] # design parameters\n", + "def c(result, x, gradient, eta, beta):\n", + " print(\n", + " \"Current iteration: {}; current eta: {}, current beta: {}\".format(\n", + " cur_iter[0], eta, beta\n", + " )\n", + " )\n", + "\n", + " t = x[0] # dummy parameter\n", + " v = x[1:] # design parameters\n", "\n", - " f0, dJ_du = opt([mapping(v,eta,beta)])\n", + " f0, dJ_du = opt([mapping(v, eta, beta)])\n", "\n", " # Backprop the gradients through our mapping function\n", " my_grad = np.zeros(dJ_du.shape)\n", - " for k in range(opt.nf): \n", - " my_grad[:,k] = tensor_jacobian_product(mapping,0)(v,eta,beta,dJ_du[:,k]) \n", - " #Note that we now backpropogate the gradients at individual frequencies\n", + " for k in range(opt.nf):\n", + " my_grad[:, k] = tensor_jacobian_product(mapping, 0)(v, eta, beta, dJ_du[:, k])\n", + " # Note that we now backpropogate the gradients at individual frequencies\n", "\n", " # Assign gradients\n", " if gradient.size > 0:\n", - " gradient[:,0] = -1 # gradient w.r.t. \"t\"\n", - " gradient[:,1:] = my_grad.T # gradient w.r.t. each frequency objective\n", - " \n", + " gradient[:, 0] = -1 # gradient w.r.t. \"t\"\n", + " gradient[:, 1:] = my_grad.T # gradient w.r.t. each frequency objective\n", + "\n", " result[:] = np.real(f0) - t\n", - " \n", + "\n", " # store results\n", " evaluation_history.append(np.real(f0))\n", - " \n", + "\n", " # visualize\n", " plt.figure()\n", " ax = plt.gca()\n", - " opt.plot2D(False,ax=ax,plot_sources_flag=False,plot_monitors_flag=False,plot_boundaries_flag=False)\n", - " circ = Circle((2,2),minimum_length/2)\n", + " opt.plot2D(\n", + " False,\n", + " ax=ax,\n", + " plot_sources_flag=False,\n", + " plot_monitors_flag=False,\n", + " plot_boundaries_flag=False,\n", + " )\n", + " circ = Circle((2, 2), minimum_length / 2)\n", " ax.add_patch(circ)\n", - " ax.axis('off')\n", + " ax.axis(\"off\")\n", " plt.show()\n", - " \n", - " cur_iter[0] = cur_iter[0] + 1\n" + "\n", + " cur_iter[0] = cur_iter[0] + 1" ] }, { @@ -1704,19 +1744,19 @@ ], "source": [ "algorithm = nlopt.LD_MMA\n", - "n = Nx * Ny # number of parameters\n", + "n = Nx * Ny # number of parameters\n", "\n", "# Initial guess\n", "x = np.ones((n,)) * 0.5\n", "\n", "# lower and upper bounds\n", - "lb = np.zeros((Nx*Ny,))\n", - "ub = np.ones((Nx*Ny,))\n", + "lb = np.zeros((Nx * Ny,))\n", + "ub = np.ones((Nx * Ny,))\n", "\n", "# insert dummy parameter bounds and variable\n", - "x = np.insert(x,0,-1) # our initial guess for the worst error\n", - "lb = np.insert(lb,0,-np.inf)\n", - "ub = np.insert(ub,0,0)\n", + "x = np.insert(x, 0, -1) # our initial guess for the worst error\n", + "lb = np.insert(lb, 0, -np.inf)\n", + "ub = np.insert(ub, 0, 0)\n", "\n", "cur_beta = 4\n", "beta_scale = 2\n", @@ -1724,15 +1764,17 @@ "update_factor = 12\n", "ftol = 1e-5\n", "for iters in range(num_betas):\n", - " solver = nlopt.opt(algorithm, n+1)\n", + " solver = nlopt.opt(algorithm, n + 1)\n", " solver.set_lower_bounds(lb)\n", " solver.set_upper_bounds(ub)\n", " solver.set_min_objective(f)\n", " solver.set_maxeval(update_factor)\n", " solver.set_ftol_rel(ftol)\n", - " solver.add_inequality_mconstraint(lambda r,x,g: c(r,x,g,eta_i,cur_beta), np.array([1e-3]*nf))\n", + " solver.add_inequality_mconstraint(\n", + " lambda r, x, g: c(r, x, g, eta_i, cur_beta), np.array([1e-3] * nf)\n", + " )\n", " x[:] = solver.optimize(x)\n", - " cur_beta = cur_beta*beta_scale" + " cur_beta = cur_beta * beta_scale" ] }, { @@ -1756,18 +1798,18 @@ } ], "source": [ - "lb = -np.min(evaluation_history,axis=1)\n", - "ub = -np.max(evaluation_history,axis=1)\n", - "mean = -np.mean(evaluation_history,axis=1)\n", + "lb = -np.min(evaluation_history, axis=1)\n", + "ub = -np.max(evaluation_history, axis=1)\n", + "mean = -np.mean(evaluation_history, axis=1)\n", "\n", "num_iters = lb.size\n", "\n", "plt.figure()\n", - "plt.fill_between(np.arange(num_iters),ub,lb,alpha=0.3)\n", - "plt.plot(mean,'o-')\n", + "plt.fill_between(np.arange(num_iters), ub, lb, alpha=0.3)\n", + "plt.plot(mean, \"o-\")\n", "plt.grid(True)\n", - "plt.xlabel('Iteration')\n", - "plt.ylabel('FOM')\n", + "plt.xlabel(\"Iteration\")\n", + "plt.ylabel(\"FOM\")\n", "plt.show()" ] }, @@ -1797,13 +1839,19 @@ } ], "source": [ - "opt.update_design([mapping(x[1:],eta_i,cur_beta)])\n", + "opt.update_design([mapping(x[1:], eta_i, cur_beta)])\n", "plt.figure()\n", "ax = plt.gca()\n", - "opt.plot2D(False,ax=ax,plot_sources_flag=False,plot_monitors_flag=False,plot_boundaries_flag=False)\n", - "circ = Circle((2,2),minimum_length/2)\n", + "opt.plot2D(\n", + " False,\n", + " ax=ax,\n", + " plot_sources_flag=False,\n", + " plot_monitors_flag=False,\n", + " plot_boundaries_flag=False,\n", + ")\n", + "circ = Circle((2, 2), minimum_length / 2)\n", "ax.add_patch(circ)\n", - "ax.axis('off')\n", + "ax.axis(\"off\")\n", "plt.show()" ] }, @@ -1828,7 +1876,7 @@ } ], "source": [ - "f0, dJ_du = opt([mapping(x[1:],eta_i,cur_beta//2)],need_gradient = False)\n", + "f0, dJ_du = opt([mapping(x[1:], eta_i, cur_beta // 2)], need_gradient=False)\n", "frequencies = opt.frequencies" ] }, @@ -1851,14 +1899,13 @@ } ], "source": [ - "\n", - "intensities = np.abs(opt.get_objective_arguments()[0][0,:,2])**2\n", + "intensities = np.abs(opt.get_objective_arguments()[0][0, :, 2]) ** 2\n", "\n", "plt.figure()\n", - "plt.plot(1/frequencies,intensities,'-o')\n", + "plt.plot(1 / frequencies, intensities, \"-o\")\n", "plt.grid(True)\n", - "plt.xlabel('Wavelength (microns)')\n", - "plt.ylabel('|Ez|^2 Intensities')\n", + "plt.xlabel(\"Wavelength (microns)\")\n", + "plt.ylabel(\"|Ez|^2 Intensities\")\n", "plt.show()" ] }, @@ -1898,21 +1945,21 @@ } ], "source": [ - "opt.sim = mp.Simulation(cell_size=mp.Vector3(Sx,40),\n", - " boundary_layers=pml_layers,\n", - " k_point=kpoint,\n", - " geometry=geometry,\n", - " sources=source,\n", - " default_material=Air,\n", - " resolution=resolution)\n", - "src = mp.ContinuousSource(frequency=1/1.5,fwidth=fwidth)\n", - "source = [mp.Source(src, component = mp.Ez,\n", - " size = source_size,\n", - " center=source_center)]\n", + "opt.sim = mp.Simulation(\n", + " cell_size=mp.Vector3(Sx, 40),\n", + " boundary_layers=pml_layers,\n", + " k_point=kpoint,\n", + " geometry=geometry,\n", + " sources=source,\n", + " default_material=Air,\n", + " resolution=resolution,\n", + ")\n", + "src = mp.ContinuousSource(frequency=1 / 1.5, fwidth=fwidth)\n", + "source = [mp.Source(src, component=mp.Ez, size=source_size, center=source_center)]\n", "opt.sim.change_sources(source)\n", "\n", "opt.sim.run(until=200)\n", - "plt.figure(figsize=(10,20))\n", + "plt.figure(figsize=(10, 20))\n", "opt.sim.plot2D(fields=mp.Ez)" ] }, @@ -1945,21 +1992,21 @@ } ], "source": [ - "opt.sim = mp.Simulation(cell_size=mp.Vector3(Sx,40),\n", - " boundary_layers=pml_layers,\n", - " k_point=kpoint,\n", - " geometry=geometry,\n", - " sources=source,\n", - " default_material=Air,\n", - " resolution=resolution)\n", - "src = mp.ContinuousSource(frequency=1/1.55,fwidth=fwidth)\n", - "source = [mp.Source(src, component = mp.Ez,\n", - " size = source_size,\n", - " center=source_center)]\n", + "opt.sim = mp.Simulation(\n", + " cell_size=mp.Vector3(Sx, 40),\n", + " boundary_layers=pml_layers,\n", + " k_point=kpoint,\n", + " geometry=geometry,\n", + " sources=source,\n", + " default_material=Air,\n", + " resolution=resolution,\n", + ")\n", + "src = mp.ContinuousSource(frequency=1 / 1.55, fwidth=fwidth)\n", + "source = [mp.Source(src, component=mp.Ez, size=source_size, center=source_center)]\n", "opt.sim.change_sources(source)\n", "\n", "opt.sim.run(until=200)\n", - "plt.figure(figsize=(10,20))\n", + "plt.figure(figsize=(10, 20))\n", "opt.sim.plot2D(fields=mp.Ez)" ] }, @@ -1992,21 +2039,21 @@ } ], "source": [ - "opt.sim = mp.Simulation(cell_size=mp.Vector3(Sx,40),\n", - " boundary_layers=pml_layers,\n", - " k_point=kpoint,\n", - " geometry=geometry,\n", - " sources=source,\n", - " default_material=Air,\n", - " resolution=resolution)\n", - "src = mp.ContinuousSource(frequency=1/1.6,fwidth=fwidth)\n", - "source = [mp.Source(src, component = mp.Ez,\n", - " size = source_size,\n", - " center=source_center)]\n", + "opt.sim = mp.Simulation(\n", + " cell_size=mp.Vector3(Sx, 40),\n", + " boundary_layers=pml_layers,\n", + " k_point=kpoint,\n", + " geometry=geometry,\n", + " sources=source,\n", + " default_material=Air,\n", + " resolution=resolution,\n", + ")\n", + "src = mp.ContinuousSource(frequency=1 / 1.6, fwidth=fwidth)\n", + "source = [mp.Source(src, component=mp.Ez, size=source_size, center=source_center)]\n", "opt.sim.change_sources(source)\n", "\n", "opt.sim.run(until=200)\n", - "plt.figure(figsize=(10,20))\n", + "plt.figure(figsize=(10, 20))\n", "opt.sim.plot2D(fields=mp.Ez)" ] }, diff --git a/python/examples/adjoint_optimization/Bend Minimax.ipynb b/python/examples/adjoint_optimization/Bend Minimax.ipynb index 1253d83df..ea883612e 100644 --- a/python/examples/adjoint_optimization/Bend Minimax.ipynb +++ b/python/examples/adjoint_optimization/Bend Minimax.ipynb @@ -38,6 +38,7 @@ "from matplotlib import pyplot as plt\n", "from matplotlib.patches import Circle\n", "from scipy import special, signal\n", + "\n", "mp.verbosity(0)\n", "Si = mp.Medium(index=3.4)\n", "SiO2 = mp.Medium(index=1.44)" @@ -75,89 +76,121 @@ "resolution = 20\n", "\n", "nf = 10\n", - "frequencies = 1/np.linspace(1.5,1.6,nf)\n", + "frequencies = 1 / np.linspace(1.5, 1.6, nf)\n", "\n", - "minimum_length = 0.09 # minimum length scale (microns)\n", - "eta_i = 0.5 # blueprint (or intermediate) design field thresholding point (between 0 and 1)\n", - "eta_e = 0.55 # erosion design field thresholding point (between 0 and 1)\n", - "eta_d = 1-eta_e # dilation design field thresholding point (between 0 and 1)\n", - "filter_radius = mpa.get_conic_radius_from_eta_e(minimum_length,eta_e)\n", + "minimum_length = 0.09 # minimum length scale (microns)\n", + "eta_i = (\n", + " 0.5 # blueprint (or intermediate) design field thresholding point (between 0 and 1)\n", + ")\n", + "eta_e = 0.55 # erosion design field thresholding point (between 0 and 1)\n", + "eta_d = 1 - eta_e # dilation design field thresholding point (between 0 and 1)\n", + "filter_radius = mpa.get_conic_radius_from_eta_e(minimum_length, eta_e)\n", "print(filter_radius)\n", - "design_region_resolution = int(1*resolution)\n", + "design_region_resolution = int(1 * resolution)\n", "\n", - "Sx = 2*pml_size + 2*waveguide_length + design_region_width\n", - "Sy = 2*pml_size + design_region_height + 0.5\n", - "cell_size = mp.Vector3(Sx,Sy)\n", + "Sx = 2 * pml_size + 2 * waveguide_length + design_region_width\n", + "Sy = 2 * pml_size + design_region_height + 0.5\n", + "cell_size = mp.Vector3(Sx, Sy)\n", "\n", "pml_layers = [mp.PML(pml_size)]\n", "\n", - "fcen = 1/1.55\n", + "fcen = 1 / 1.55\n", "width = 0.2\n", "fwidth = width * fcen\n", - "source_center = [-Sx/2 + pml_size + waveguide_length/3,0,0]\n", - "source_size = mp.Vector3(0,Sy,0)\n", - "kpoint = mp.Vector3(1,0,0)\n", - "src = mp.GaussianSource(frequency=fcen,fwidth=fwidth)\n", - "source = [mp.EigenModeSource(src,\n", - " eig_band = 1,\n", - " direction=mp.NO_DIRECTION,\n", - " eig_kpoint=kpoint,\n", - " size = source_size,\n", - " center=source_center)]\n", + "source_center = [-Sx / 2 + pml_size + waveguide_length / 3, 0, 0]\n", + "source_size = mp.Vector3(0, Sy, 0)\n", + "kpoint = mp.Vector3(1, 0, 0)\n", + "src = mp.GaussianSource(frequency=fcen, fwidth=fwidth)\n", + "source = [\n", + " mp.EigenModeSource(\n", + " src,\n", + " eig_band=1,\n", + " direction=mp.NO_DIRECTION,\n", + " eig_kpoint=kpoint,\n", + " size=source_size,\n", + " center=source_center,\n", + " )\n", + "]\n", "\n", - "Nx = int(design_region_resolution*design_region_width)\n", - "Ny = int(design_region_resolution*design_region_height)\n", + "Nx = int(design_region_resolution * design_region_width)\n", + "Ny = int(design_region_resolution * design_region_height)\n", "\n", - "design_variables = mp.MaterialGrid(mp.Vector3(Nx,Ny),SiO2,Si,grid_type='U_MEAN')\n", - "design_region = mpa.DesignRegion(design_variables,volume=mp.Volume(center=mp.Vector3(), size=mp.Vector3(design_region_width, design_region_height, 0)))\n", + "design_variables = mp.MaterialGrid(mp.Vector3(Nx, Ny), SiO2, Si, grid_type=\"U_MEAN\")\n", + "design_region = mpa.DesignRegion(\n", + " design_variables,\n", + " volume=mp.Volume(\n", + " center=mp.Vector3(),\n", + " size=mp.Vector3(design_region_width, design_region_height, 0),\n", + " ),\n", + ")\n", "\n", - "x_g = np.linspace(-design_region_width/2,design_region_width/2,Nx)\n", - "y_g = np.linspace(-design_region_height/2,design_region_height/2,Ny)\n", - "X_g, Y_g = np.meshgrid(x_g,y_g,sparse=True,indexing='ij')\n", + "x_g = np.linspace(-design_region_width / 2, design_region_width / 2, Nx)\n", + "y_g = np.linspace(-design_region_height / 2, design_region_height / 2, Ny)\n", + "X_g, Y_g = np.meshgrid(x_g, y_g, sparse=True, indexing=\"ij\")\n", "\n", - "left_wg_mask = (X_g == -design_region_width/2) & (np.abs(Y_g) <= waveguide_width/2)\n", - "top_wg_mask = (Y_g == design_region_width/2) & (np.abs(X_g) <= waveguide_width/2)\n", + "left_wg_mask = (X_g == -design_region_width / 2) & (np.abs(Y_g) <= waveguide_width / 2)\n", + "top_wg_mask = (Y_g == design_region_width / 2) & (np.abs(X_g) <= waveguide_width / 2)\n", "Si_mask = left_wg_mask | top_wg_mask\n", "\n", - "border_mask = ((X_g == -design_region_width/2) | \n", - " (X_g == design_region_width/2) | \n", - " (Y_g == -design_region_height/2) | \n", - " (Y_g == design_region_height/2))\n", + "border_mask = (\n", + " (X_g == -design_region_width / 2)\n", + " | (X_g == design_region_width / 2)\n", + " | (Y_g == -design_region_height / 2)\n", + " | (Y_g == design_region_height / 2)\n", + ")\n", "SiO2_mask = border_mask.copy()\n", "SiO2_mask[Si_mask] = False\n", "\n", - "def mapping(x,eta,beta):\n", - " x = npa.where(Si_mask.flatten(),1,npa.where(SiO2_mask.flatten(),0,x))\n", - " \n", + "\n", + "def mapping(x, eta, beta):\n", + " x = npa.where(Si_mask.flatten(), 1, npa.where(SiO2_mask.flatten(), 0, x))\n", + "\n", " # filter\n", - " filtered_field = mpa.conic_filter(x,filter_radius,design_region_width,design_region_height,design_region_resolution)\n", - " \n", + " filtered_field = mpa.conic_filter(\n", + " x,\n", + " filter_radius,\n", + " design_region_width,\n", + " design_region_height,\n", + " design_region_resolution,\n", + " )\n", + "\n", " # projection\n", - " projected_field = mpa.tanh_projection(filtered_field,beta,eta)\n", - " \n", - " projected_field = (npa.rot90(projected_field.T, 2) + projected_field)/2 # 90-degree symmetry\n", - " \n", + " projected_field = mpa.tanh_projection(filtered_field, beta, eta)\n", + "\n", + " projected_field = (\n", + " npa.rot90(projected_field.T, 2) + projected_field\n", + " ) / 2 # 90-degree symmetry\n", + "\n", " # interpolate to actual materials\n", " return projected_field.flatten()\n", "\n", + "\n", "geometry = [\n", - " mp.Block(center=mp.Vector3(x=-Sx/4), material=Si, size=mp.Vector3(Sx/2, 0.5, 0)), # horizontal waveguide\n", - " mp.Block(center=mp.Vector3(y=Sy/4), material=Si, size=mp.Vector3(0.5, Sy/2, 0)), # vertical waveguide\n", - " mp.Block(center=design_region.center, size=design_region.size, material=design_variables), # design region\n", - " #mp.Block(center=design_region.center, size=design_region.size, material=design_variables,\n", + " mp.Block(\n", + " center=mp.Vector3(x=-Sx / 4), material=Si, size=mp.Vector3(Sx / 2, 0.5, 0)\n", + " ), # horizontal waveguide\n", + " mp.Block(\n", + " center=mp.Vector3(y=Sy / 4), material=Si, size=mp.Vector3(0.5, Sy / 2, 0)\n", + " ), # vertical waveguide\n", + " mp.Block(\n", + " center=design_region.center, size=design_region.size, material=design_variables\n", + " ), # design region\n", + " # mp.Block(center=design_region.center, size=design_region.size, material=design_variables,\n", " # e1=mp.Vector3(x=-1).rotate(mp.Vector3(z=1), np.pi/2), e2=mp.Vector3(y=1).rotate(mp.Vector3(z=1), np.pi/2))\n", - " # \n", + " #\n", " # The commented lines above impose symmetry by overlapping design region with the same design variable. However,\n", " # currently there is an issue of doing that; instead, we use an alternative approach to impose symmetry.\n", " # See https://github.com/NanoComp/meep/issues/1984 and https://github.com/NanoComp/meep/issues/2093\n", "]\n", "\n", - "sim = mp.Simulation(cell_size=cell_size,\n", - " boundary_layers=pml_layers,\n", - " geometry=geometry,\n", - " sources=source,\n", - " default_material=SiO2,\n", - " resolution=resolution)" + "sim = mp.Simulation(\n", + " cell_size=cell_size,\n", + " boundary_layers=pml_layers,\n", + " geometry=geometry,\n", + " sources=source,\n", + " default_material=SiO2,\n", + " resolution=resolution,\n", + ")" ] }, { @@ -175,13 +208,28 @@ "source": [ "mode = 1\n", "\n", - "TE0 = mpa.EigenmodeCoefficient(sim,mp.Volume(center=mp.Vector3(x=-Sx/2 + pml_size + 2*waveguide_length/3),size=mp.Vector3(y=Sy)),mode)\n", - "TE_top = mpa.EigenmodeCoefficient(sim,mp.Volume(center=mp.Vector3(0,Sx/2 - pml_size - 2*waveguide_length/3,0),size=mp.Vector3(x=Sx)),mode)\n", - "ob_list = [TE0,TE_top]\n", + "TE0 = mpa.EigenmodeCoefficient(\n", + " sim,\n", + " mp.Volume(\n", + " center=mp.Vector3(x=-Sx / 2 + pml_size + 2 * waveguide_length / 3),\n", + " size=mp.Vector3(y=Sy),\n", + " ),\n", + " mode,\n", + ")\n", + "TE_top = mpa.EigenmodeCoefficient(\n", + " sim,\n", + " mp.Volume(\n", + " center=mp.Vector3(0, Sx / 2 - pml_size - 2 * waveguide_length / 3, 0),\n", + " size=mp.Vector3(x=Sx),\n", + " ),\n", + " mode,\n", + ")\n", + "ob_list = [TE0, TE_top]\n", "\n", - "def J(source,top):\n", - " power = npa.abs(top/source)**2\n", - " return 1-power" + "\n", + "def J(source, top):\n", + " power = npa.abs(top / source) ** 2\n", + " return 1 - power" ] }, { @@ -191,10 +239,10 @@ "outputs": [], "source": [ "opt = mpa.OptimizationProblem(\n", - " simulation = sim,\n", - " objective_functions = J,\n", - " objective_arguments = ob_list,\n", - " design_regions = [design_region],\n", + " simulation=sim,\n", + " objective_functions=J,\n", + " objective_arguments=ob_list,\n", + " design_regions=[design_region],\n", " frequencies=frequencies,\n", ")" ] @@ -214,9 +262,11 @@ "source": [ "evaluation_history = []\n", "cur_iter = [0]\n", + "\n", + "\n", "def f(x, grad):\n", - " t = x[0] # \"dummy\" parameter\n", - " v = x[1:] # design parameters\n", + " t = x[0] # \"dummy\" parameter\n", + " v = x[1:] # design parameters\n", " if grad.size > 0:\n", " grad[0] = 1\n", " grad[1:] = 0\n", @@ -246,38 +296,48 @@ "metadata": {}, "outputs": [], "source": [ - "def c(result,x,gradient,eta,beta):\n", - " print(\"Current iteration: {}; current eta: {}, current beta: {}\".format(cur_iter[0],eta,beta))\n", - " \n", - " t = x[0] # dummy parameter\n", - " v = x[1:] # design parameters\n", + "def c(result, x, gradient, eta, beta):\n", + " print(\n", + " \"Current iteration: {}; current eta: {}, current beta: {}\".format(\n", + " cur_iter[0], eta, beta\n", + " )\n", + " )\n", + "\n", + " t = x[0] # dummy parameter\n", + " v = x[1:] # design parameters\n", + "\n", + " f0, dJ_du = opt([mapping(v, eta, beta)])\n", "\n", - " f0, dJ_du = opt([mapping(v,eta,beta)])\n", - " \n", " # Backprop the gradients through our mapping function\n", " my_grad = np.zeros(dJ_du.shape)\n", - " for k in range(opt.nf): \n", - " my_grad[:,k] = tensor_jacobian_product(mapping,0)(v,eta,beta,dJ_du[:,k])\n", + " for k in range(opt.nf):\n", + " my_grad[:, k] = tensor_jacobian_product(mapping, 0)(v, eta, beta, dJ_du[:, k])\n", "\n", " # Assign gradients\n", " if gradient.size > 0:\n", - " gradient[:,0] = -1 # gradient w.r.t. \"t\"\n", - " gradient[:,1:] = my_grad.T # gradient w.r.t. each frequency objective\n", - " \n", + " gradient[:, 0] = -1 # gradient w.r.t. \"t\"\n", + " gradient[:, 1:] = my_grad.T # gradient w.r.t. each frequency objective\n", + "\n", " result[:] = np.real(f0) - t\n", - " \n", + "\n", " # store results\n", " evaluation_history.append(np.real(f0))\n", - " \n", + "\n", " # visualize\n", " plt.figure()\n", " ax = plt.gca()\n", - " opt.plot2D(False,ax=ax,plot_sources_flag=False,plot_monitors_flag=False,plot_boundaries_flag=False)\n", - " circ = Circle((2,2),minimum_length/2)\n", + " opt.plot2D(\n", + " False,\n", + " ax=ax,\n", + " plot_sources_flag=False,\n", + " plot_monitors_flag=False,\n", + " plot_boundaries_flag=False,\n", + " )\n", + " circ = Circle((2, 2), minimum_length / 2)\n", " ax.add_patch(circ)\n", - " ax.axis('off')\n", + " ax.axis(\"off\")\n", " plt.show()\n", - " \n", + "\n", " cur_iter[0] = cur_iter[0] + 1" ] }, @@ -1880,37 +1940,39 @@ ], "source": [ "algorithm = nlopt.LD_MMA\n", - "n = Nx * Ny # number of parameters\n", + "n = Nx * Ny # number of parameters\n", "\n", "# Initial guess\n", "x = np.ones((n,)) * 0.5\n", - "x[Si_mask.flatten()] = 1 # set the edges of waveguides to silicon\n", - "x[SiO2_mask.flatten()] = 0 # set the other edges to SiO2\n", + "x[Si_mask.flatten()] = 1 # set the edges of waveguides to silicon\n", + "x[SiO2_mask.flatten()] = 0 # set the other edges to SiO2\n", "\n", "# lower and upper bounds\n", - "lb = np.zeros((Nx*Ny,))\n", + "lb = np.zeros((Nx * Ny,))\n", "lb[Si_mask.flatten()] = 1\n", - "ub = np.ones((Nx*Ny,))\n", + "ub = np.ones((Nx * Ny,))\n", "ub[SiO2_mask.flatten()] = 0\n", "\n", "# insert dummy parameter bounds and variable\n", - "x = np.insert(x,0,0.5) # our initial guess for the worst error\n", - "lb = np.insert(lb,0,0) # we can't get less than 0 error!\n", - "ub = np.insert(ub,0,1) # we can't get more than 1 error!\n", + "x = np.insert(x, 0, 0.5) # our initial guess for the worst error\n", + "lb = np.insert(lb, 0, 0) # we can't get less than 0 error!\n", + "ub = np.insert(ub, 0, 1) # we can't get more than 1 error!\n", "\n", "cur_beta = 4\n", "beta_scale = 2\n", "num_betas = 6\n", "update_factor = 12\n", "for iters in range(num_betas):\n", - " solver = nlopt.opt(algorithm, n+1)\n", + " solver = nlopt.opt(algorithm, n + 1)\n", " solver.set_lower_bounds(lb)\n", " solver.set_upper_bounds(ub)\n", " solver.set_min_objective(f)\n", " solver.set_maxeval(update_factor)\n", - " solver.add_inequality_mconstraint(lambda r,x,g: c(r,x,g,eta_i,cur_beta), np.array([1e-6]*nf))\n", + " solver.add_inequality_mconstraint(\n", + " lambda r, x, g: c(r, x, g, eta_i, cur_beta), np.array([1e-6] * nf)\n", + " )\n", " x[:] = solver.optimize(x)\n", - " cur_beta = cur_beta*beta_scale" + " cur_beta = cur_beta * beta_scale" ] }, { @@ -1941,18 +2003,20 @@ } ], "source": [ - "lb = 1-np.min(evaluation_history,axis=1)\n", - "ub = 1-np.max(evaluation_history,axis=1)\n", - "mean = 1-np.mean(evaluation_history,axis=1)\n", + "lb = 1 - np.min(evaluation_history, axis=1)\n", + "ub = 1 - np.max(evaluation_history, axis=1)\n", + "mean = 1 - np.mean(evaluation_history, axis=1)\n", "\n", "num_iters = lb.size\n", "\n", "plt.figure()\n", - "plt.fill_between(np.arange(1,num_iters+1),10*np.log10(lb),10*np.log10(ub),alpha=0.3)\n", - "plt.plot(10*np.log10(mean),'o-')\n", + "plt.fill_between(\n", + " np.arange(1, num_iters + 1), 10 * np.log10(lb), 10 * np.log10(ub), alpha=0.3\n", + ")\n", + "plt.plot(10 * np.log10(mean), \"o-\")\n", "plt.grid(True)\n", - "plt.xlabel('Iteration')\n", - "plt.ylabel('Average Insertion Loss (dB)')\n", + "plt.xlabel(\"Iteration\")\n", + "plt.ylabel(\"Average Insertion Loss (dB)\")\n", "plt.show()" ] }, @@ -1982,13 +2046,19 @@ } ], "source": [ - "opt.update_design([mapping(x[1:],eta_i,cur_beta)])\n", + "opt.update_design([mapping(x[1:], eta_i, cur_beta)])\n", "plt.figure()\n", "ax = plt.gca()\n", - "opt.plot2D(False,ax=ax,plot_sources_flag=False,plot_monitors_flag=False,plot_boundaries_flag=False)\n", - "circ = Circle((2,2),minimum_length/2)\n", + "opt.plot2D(\n", + " False,\n", + " ax=ax,\n", + " plot_sources_flag=False,\n", + " plot_monitors_flag=False,\n", + " plot_boundaries_flag=False,\n", + ")\n", + "circ = Circle((2, 2), minimum_length / 2)\n", "ax.add_patch(circ)\n", - "ax.axis('off')\n", + "ax.axis(\"off\")\n", "plt.show()" ] }, @@ -2013,11 +2083,11 @@ } ], "source": [ - "f0, dJ_du = opt([mapping(x[1:],eta_i,cur_beta//2)],need_gradient = False)\n", + "f0, dJ_du = opt([mapping(x[1:], eta_i, cur_beta // 2)], need_gradient=False)\n", "frequencies = opt.frequencies\n", "source_coef, top_coef = opt.get_objective_arguments()\n", "\n", - "top_profile = np.abs(top_coef/source_coef) ** 2" + "top_profile = np.abs(top_coef / source_coef) ** 2" ] }, { @@ -2052,19 +2122,19 @@ ], "source": [ "plt.figure()\n", - "plt.plot(1/frequencies,top_profile*100,'-o')\n", + "plt.plot(1 / frequencies, top_profile * 100, \"-o\")\n", "plt.grid(True)\n", - "plt.xlabel('Wavelength (microns)')\n", - "plt.ylabel('Transmission (%)')\n", - "#plt.ylim(70,100)\n", + "plt.xlabel(\"Wavelength (microns)\")\n", + "plt.ylabel(\"Transmission (%)\")\n", + "# plt.ylim(70,100)\n", "plt.show()\n", "\n", "plt.figure()\n", - "plt.plot(1/frequencies,10*np.log10(top_profile),'-o')\n", + "plt.plot(1 / frequencies, 10 * np.log10(top_profile), \"-o\")\n", "plt.grid(True)\n", - "plt.xlabel('Wavelength (microns)')\n", - "plt.ylabel('Insertion Loss (dB)')\n", - "#plt.ylim(-0.1,0)\n", + "plt.xlabel(\"Wavelength (microns)\")\n", + "plt.ylabel(\"Insertion Loss (dB)\")\n", + "# plt.ylim(-0.1,0)\n", "plt.show()" ] }, diff --git a/python/examples/adjoint_optimization/ConnectivityConstraint.ipynb b/python/examples/adjoint_optimization/ConnectivityConstraint.ipynb index 56279b124..9978da26d 100644 --- a/python/examples/adjoint_optimization/ConnectivityConstraint.ipynb +++ b/python/examples/adjoint_optimization/ConnectivityConstraint.ipynb @@ -69,25 +69,25 @@ } ], "source": [ - "nz, ny, nx =25, 1, 25\n", - "c = mpa.ConnectivityConstraint(nx, ny, nz,sp_solver=cg)\n", + "nz, ny, nx = 25, 1, 25\n", + "c = mpa.ConnectivityConstraint(nx, ny, nz, sp_solver=cg)\n", "\n", - "r = np.zeros((nz, ny,nx))+0.0001\n", - "r[:10,0, 8]=0.999\n", - "r[7,0,5:20]=0.999\n", - "r[5:,0, 18]=0.999\n", - "r[7,0,11:16]=0.0001\n", - "r[17:18,0,9:10]=0.999\n", + "r = np.zeros((nz, ny, nx)) + 0.0001\n", + "r[:10, 0, 8] = 0.999\n", + "r[7, 0, 5:20] = 0.999\n", + "r[5:, 0, 18] = 0.999\n", + "r[7, 0, 11:16] = 0.0001\n", + "r[17:18, 0, 9:10] = 0.999\n", "\n", - "r=r.flatten()#flatten the structure before pass in\n", + "r = r.flatten() # flatten the structure before pass in\n", "f = c.forward(r)\n", "ag = c.calculate_grad()\n", "\n", - "print(\"foward value\", f) \n", + "print(\"foward value\", f)\n", "\n", "plt.figure()\n", "plt.pcolormesh(r.reshape((nz, nx)))\n", - "plt.show()\n" + "plt.show()" ] }, { @@ -116,10 +116,12 @@ } ], "source": [ - "#padding to show the side with Dirichlet BC\n", - "fullT = np.pad(c.T, (0, c.nx*c.ny), 'constant', constant_values=1).reshape((nz, ny, nx)) \n", + "# padding to show the side with Dirichlet BC\n", + "fullT = np.pad(c.T, (0, c.nx * c.ny), \"constant\", constant_values=1).reshape(\n", + " (nz, ny, nx)\n", + ")\n", "plt.figure()\n", - "plt.contourf(fullT[:,0,:], 100, cmap=\"RdBu\")\n", + "plt.contourf(fullT[:, 0, :], 100, cmap=\"RdBu\")\n", "plt.colorbar()\n", "plt.show()" ] @@ -213,29 +215,31 @@ } ], "source": [ - "r = np.zeros((nz, ny,nx))+0.0001\n", - "r[:10,0, 8]=0.999\n", - "r[7,0,5:20]=0.999\n", - "r[5:,0, 18]=0.999\n", + "r = np.zeros((nz, ny, nx)) + 0.0001\n", + "r[:10, 0, 8] = 0.999\n", + "r[7, 0, 5:20] = 0.999\n", + "r[5:, 0, 18] = 0.999\n", "\n", - "r=r.flatten()#flatten the structure before pass in\n", + "r = r.flatten() # flatten the structure before pass in\n", "f = c.forward(r)\n", "ag = c.calculate_grad()\n", "\n", - "print(\"foward value\", f) \n", + "print(\"foward value\", f)\n", "\n", "plt.figure()\n", "plt.pcolormesh(r.reshape((nz, nx)))\n", "plt.show()\n", "\n", - "fullT = np.pad(c.T, (0, c.nx*c.ny), 'constant', constant_values=1).reshape((nz, ny, nx)) \n", + "fullT = np.pad(c.T, (0, c.nx * c.ny), \"constant\", constant_values=1).reshape(\n", + " (nz, ny, nx)\n", + ")\n", "plt.figure()\n", - "plt.contourf(fullT[:,0,:], 100,cmap=\"RdBu\")\n", + "plt.contourf(fullT[:, 0, :], 100, cmap=\"RdBu\")\n", "plt.colorbar()\n", "plt.show()\n", "\n", "plt.figure()\n", - "plt.contourf(ag.reshape((nz, nx)), 100,cmap=\"RdBu\")\n", + "plt.contourf(ag.reshape((nz, nx)), 100, cmap=\"RdBu\")\n", "plt.colorbar()\n", "plt.show()" ] diff --git a/python/examples/adjoint_optimization/Fourier-Bend.ipynb b/python/examples/adjoint_optimization/Fourier-Bend.ipynb index c1b1cc45d..d0ec785b0 100644 --- a/python/examples/adjoint_optimization/Fourier-Bend.ipynb +++ b/python/examples/adjoint_optimization/Fourier-Bend.ipynb @@ -25,6 +25,7 @@ "from matplotlib import pyplot as plt\n", "from matplotlib.patches import Circle\n", "from scipy import special, signal\n", + "\n", "mp.quiet(quietval=True)\n", "Si = mp.Medium(index=3.4)\n", "SiO2 = mp.Medium(index=1.44)" @@ -53,7 +54,7 @@ "\n", "resolution = 40\n", "\n", - "frequencies = 1/np.linspace(1.5,1.6,3)" + "frequencies = 1 / np.linspace(1.5, 1.6, 3)" ] }, { @@ -70,13 +71,15 @@ } ], "source": [ - "minimum_length = 0.09 # minimum length scale (microns)\n", - "eta_i = 0.5 # blueprint (or intermediate) design field thresholding point (between 0 and 1)\n", - "eta_e = 0.55 # erosion design field thresholding point (between 0 and 1)\n", - "eta_d = 1-eta_e # dilation design field thresholding point (between 0 and 1)\n", - "filter_radius = mpa.get_conic_radius_from_eta_e(minimum_length,eta_e)\n", + "minimum_length = 0.09 # minimum length scale (microns)\n", + "eta_i = (\n", + " 0.5 # blueprint (or intermediate) design field thresholding point (between 0 and 1)\n", + ")\n", + "eta_e = 0.55 # erosion design field thresholding point (between 0 and 1)\n", + "eta_d = 1 - eta_e # dilation design field thresholding point (between 0 and 1)\n", + "filter_radius = mpa.get_conic_radius_from_eta_e(minimum_length, eta_e)\n", "print(filter_radius)\n", - "design_region_resolution = int(1*resolution)" + "design_region_resolution = int(1 * resolution)" ] }, { @@ -85,25 +88,29 @@ "metadata": {}, "outputs": [], "source": [ - "Sx = 2*pml_size + 2*waveguide_length + design_region_width + 2\n", - "Sy = 2*pml_size + design_region_height + 2\n", - "cell_size = mp.Vector3(Sx,Sy)\n", + "Sx = 2 * pml_size + 2 * waveguide_length + design_region_width + 2\n", + "Sy = 2 * pml_size + design_region_height + 2\n", + "cell_size = mp.Vector3(Sx, Sy)\n", "\n", "pml_layers = [mp.PML(pml_size)]\n", "\n", - "fcen = 1/1.55\n", + "fcen = 1 / 1.55\n", "width = 0.2\n", "fwidth = width * fcen\n", - "source_center = [-Sx/2 + pml_size + waveguide_length/3,0,0]\n", - "source_size = mp.Vector3(0,Sy,0)\n", - "kpoint = mp.Vector3(1,0,0)\n", - "src = mp.GaussianSource(frequency=fcen,fwidth=fwidth)\n", - "source = [mp.EigenModeSource(src,\n", - " eig_band = 1,\n", - " direction=mp.NO_DIRECTION,\n", - " eig_kpoint=kpoint,\n", - " size = source_size,\n", - " center=source_center)]" + "source_center = [-Sx / 2 + pml_size + waveguide_length / 3, 0, 0]\n", + "source_size = mp.Vector3(0, Sy, 0)\n", + "kpoint = mp.Vector3(1, 0, 0)\n", + "src = mp.GaussianSource(frequency=fcen, fwidth=fwidth)\n", + "source = [\n", + " mp.EigenModeSource(\n", + " src,\n", + " eig_band=1,\n", + " direction=mp.NO_DIRECTION,\n", + " eig_kpoint=kpoint,\n", + " size=source_size,\n", + " center=source_center,\n", + " )\n", + "]" ] }, { @@ -112,11 +119,17 @@ "metadata": {}, "outputs": [], "source": [ - "Nx = int(design_region_resolution*design_region_width)\n", - "Ny = int(design_region_resolution*design_region_height)\n", + "Nx = int(design_region_resolution * design_region_width)\n", + "Ny = int(design_region_resolution * design_region_height)\n", "\n", - "design_variables = mp.MaterialGrid(mp.Vector3(Nx,Ny),SiO2,Si)\n", - "design_region = mpa.DesignRegion(design_variables,volume=mp.Volume(center=mp.Vector3(), size=mp.Vector3(design_region_width, design_region_height, 0)))" + "design_variables = mp.MaterialGrid(mp.Vector3(Nx, Ny), SiO2, Si)\n", + "design_region = mpa.DesignRegion(\n", + " design_variables,\n", + " volume=mp.Volume(\n", + " center=mp.Vector3(),\n", + " size=mp.Vector3(design_region_width, design_region_height, 0),\n", + " ),\n", + ")" ] }, { @@ -125,18 +138,20 @@ "metadata": {}, "outputs": [], "source": [ - "x_g = np.linspace(-design_region_width/2,design_region_width/2,Nx)\n", - "y_g = np.linspace(-design_region_height/2,design_region_height/2,Ny)\n", - "X_g, Y_g = np.meshgrid(x_g,y_g,sparse=True,indexing='ij')\n", + "x_g = np.linspace(-design_region_width / 2, design_region_width / 2, Nx)\n", + "y_g = np.linspace(-design_region_height / 2, design_region_height / 2, Ny)\n", + "X_g, Y_g = np.meshgrid(x_g, y_g, sparse=True, indexing=\"ij\")\n", "\n", - "left_wg_mask = (X_g == -design_region_width/2) & (np.abs(Y_g) <= waveguide_width/2)\n", - "top_wg_mask = (Y_g == design_region_width/2) & (np.abs(X_g) <= waveguide_width/2)\n", + "left_wg_mask = (X_g == -design_region_width / 2) & (np.abs(Y_g) <= waveguide_width / 2)\n", + "top_wg_mask = (Y_g == design_region_width / 2) & (np.abs(X_g) <= waveguide_width / 2)\n", "Si_mask = left_wg_mask | top_wg_mask\n", "\n", - "border_mask = ((X_g == -design_region_width/2) | \n", - " (X_g == design_region_width/2) | \n", - " (Y_g == -design_region_height/2) | \n", - " (Y_g == design_region_height/2))\n", + "border_mask = (\n", + " (X_g == -design_region_width / 2)\n", + " | (X_g == design_region_width / 2)\n", + " | (Y_g == -design_region_height / 2)\n", + " | (Y_g == design_region_height / 2)\n", + ")\n", "SiO2_mask = border_mask.copy()\n", "SiO2_mask[Si_mask] = False" ] @@ -147,14 +162,20 @@ "metadata": {}, "outputs": [], "source": [ - "def mapping(x,eta,beta):\n", - " x = npa.where(Si_mask.flatten(),1,npa.where(SiO2_mask.flatten(),0,x))\n", + "def mapping(x, eta, beta):\n", + " x = npa.where(Si_mask.flatten(), 1, npa.where(SiO2_mask.flatten(), 0, x))\n", " # filter\n", - " filtered_field = mpa.conic_filter(x,filter_radius,design_region_width,design_region_height,design_region_resolution)\n", - " \n", + " filtered_field = mpa.conic_filter(\n", + " x,\n", + " filter_radius,\n", + " design_region_width,\n", + " design_region_height,\n", + " design_region_resolution,\n", + " )\n", + "\n", " # projection\n", - " projected_field = mpa.tanh_projection(filtered_field,beta,eta)\n", - " \n", + " projected_field = mpa.tanh_projection(filtered_field, beta, eta)\n", + "\n", " # interpolate to actual materials\n", " return projected_field.flatten()" ] @@ -173,17 +194,25 @@ "outputs": [], "source": [ "geometry = [\n", - " mp.Block(center=mp.Vector3(x=-Sx/4), material=Si, size=mp.Vector3(Sx/2, 0.5, 0)), # horizontal waveguide\n", - " mp.Block(center=mp.Vector3(y=Sy/4), material=Si, size=mp.Vector3(0.5, Sy/2, 0)), # vertical waveguide\n", - " mp.Block(center=design_region.center, size=design_region.size, material=design_variables) # design region\n", + " mp.Block(\n", + " center=mp.Vector3(x=-Sx / 4), material=Si, size=mp.Vector3(Sx / 2, 0.5, 0)\n", + " ), # horizontal waveguide\n", + " mp.Block(\n", + " center=mp.Vector3(y=Sy / 4), material=Si, size=mp.Vector3(0.5, Sy / 2, 0)\n", + " ), # vertical waveguide\n", + " mp.Block(\n", + " center=design_region.center, size=design_region.size, material=design_variables\n", + " ), # design region\n", "]\n", "\n", - "sim = mp.Simulation(cell_size=cell_size,\n", - " boundary_layers=pml_layers,\n", - " geometry=geometry,\n", - " sources=source,\n", - " default_material=SiO2,\n", - " resolution=resolution)" + "sim = mp.Simulation(\n", + " cell_size=cell_size,\n", + " boundary_layers=pml_layers,\n", + " geometry=geometry,\n", + " sources=source,\n", + " default_material=SiO2,\n", + " resolution=resolution,\n", + ")" ] }, { @@ -205,11 +234,20 @@ "metadata": {}, "outputs": [], "source": [ - "Ez_top = mpa.FourierFields(sim,mp.Volume(center=mp.Vector3(0,Sy/2 - pml_size - 0.1 ,0),size=mp.Vector3(x=waveguide_width)),mp.Ez)\n", + "Ez_top = mpa.FourierFields(\n", + " sim,\n", + " mp.Volume(\n", + " center=mp.Vector3(0, Sy / 2 - pml_size - 0.1, 0),\n", + " size=mp.Vector3(x=waveguide_width),\n", + " ),\n", + " mp.Ez,\n", + ")\n", "ob_list = [Ez_top]\n", + "\n", + "\n", "def J(top):\n", - " power = npa.abs(top[1,7])**2\n", - " return power\n" + " power = npa.abs(top[1, 7]) ** 2\n", + " return power" ] }, { @@ -226,13 +264,13 @@ "outputs": [], "source": [ "opt = mpa.OptimizationProblem(\n", - " simulation = sim,\n", - " objective_functions = J,\n", - " objective_arguments = ob_list,\n", - " design_regions = [design_region],\n", + " simulation=sim,\n", + " objective_functions=J,\n", + " objective_arguments=ob_list,\n", + " design_regions=[design_region],\n", " frequencies=frequencies,\n", - " decay_by = 1e-6,\n", - " decay_fields=[mp.Ez]\n", + " decay_by=1e-6,\n", + " decay_fields=[mp.Ez],\n", ")" ] }, @@ -255,8 +293,8 @@ } ], "source": [ - "rho_vector = np.random.rand(Nx*Ny)\n", - "opt.update_design([mapping(rho_vector,eta_i,1e3)])\n", + "rho_vector = np.random.rand(Nx * Ny)\n", + "opt.update_design([mapping(rho_vector, eta_i, 1e3)])\n", "opt.plot2D(True)\n", "plt.show()" ] @@ -269,28 +307,37 @@ "source": [ "evaluation_history = []\n", "cur_iter = [0]\n", + "\n", + "\n", "def f(v, gradient, cur_beta):\n", - " print(\"Current iteration: {}\".format(cur_iter[0]+1))\n", - " \n", - " f0, dJ_du = opt([mapping(v,eta_i,cur_beta)]) # compute objective and gradient\n", - " \n", + " print(\"Current iteration: {}\".format(cur_iter[0] + 1))\n", + "\n", + " f0, dJ_du = opt([mapping(v, eta_i, cur_beta)]) # compute objective and gradient\n", + "\n", " if gradient.size > 0:\n", - " gradient[:] = tensor_jacobian_product(mapping,0)(v,eta_i,cur_beta,np.sum(dJ_du,axis=1)) # backprop\n", - " \n", - " \n", + " gradient[:] = tensor_jacobian_product(mapping, 0)(\n", + " v, eta_i, cur_beta, np.sum(dJ_du, axis=1)\n", + " ) # backprop\n", + "\n", " evaluation_history.append(np.real(f0))\n", - " \n", + "\n", " plt.figure()\n", " ax = plt.gca()\n", - " opt.plot2D(False,ax=ax,plot_sources_flag=False,plot_monitors_flag=False,plot_boundaries_flag=False)\n", - " circ = Circle((2,2),minimum_length/2)\n", + " opt.plot2D(\n", + " False,\n", + " ax=ax,\n", + " plot_sources_flag=False,\n", + " plot_monitors_flag=False,\n", + " plot_boundaries_flag=False,\n", + " )\n", + " circ = Circle((2, 2), minimum_length / 2)\n", " ax.add_patch(circ)\n", - " ax.axis('off')\n", - " #plt.savefig('media/bend_{:03d}.png'.format(cur_iter[0]),dpi=300)\n", + " ax.axis(\"off\")\n", + " # plt.savefig('media/bend_{:03d}.png'.format(cur_iter[0]),dpi=300)\n", " plt.show()\n", - " \n", + "\n", " cur_iter[0] = cur_iter[0] + 1\n", - " \n", + "\n", " return np.real(f0)" ] }, @@ -2298,17 +2345,17 @@ ], "source": [ "algorithm = nlopt.LD_MMA\n", - "n = Nx * Ny # number of parameters\n", + "n = Nx * Ny # number of parameters\n", "\n", "# Initial guess\n", "x = np.ones((n,)) * 0.5\n", - "x[Si_mask.flatten()] = 1 # set the edges of waveguides to silicon\n", - "x[SiO2_mask.flatten()] = 0 # set the other edges to SiO2\n", + "x[Si_mask.flatten()] = 1 # set the edges of waveguides to silicon\n", + "x[SiO2_mask.flatten()] = 0 # set the other edges to SiO2\n", "\n", "# lower and upper bounds\n", - "lb = np.zeros((Nx*Ny,))\n", + "lb = np.zeros((Nx * Ny,))\n", "lb[Si_mask.flatten()] = 1\n", - "ub = np.ones((Nx*Ny,))\n", + "ub = np.ones((Nx * Ny,))\n", "ub[SiO2_mask.flatten()] = 0\n", "\n", "cur_beta = 4\n", @@ -2319,11 +2366,11 @@ " solver = nlopt.opt(algorithm, n)\n", " solver.set_lower_bounds(lb)\n", " solver.set_upper_bounds(ub)\n", - " solver.set_max_objective(lambda a,g: f(a,g,cur_beta))\n", + " solver.set_max_objective(lambda a, g: f(a, g, cur_beta))\n", " solver.set_maxeval(update_factor)\n", " solver.set_xtol_rel(1e-4)\n", " x[:] = solver.optimize(x)\n", - " cur_beta = cur_beta*beta_scale" + " cur_beta = cur_beta * beta_scale" ] }, { @@ -2353,10 +2400,10 @@ ], "source": [ "plt.figure()\n", - "plt.plot((evaluation_history),'o-')\n", + "plt.plot((evaluation_history), \"o-\")\n", "plt.grid(True)\n", - "plt.xlabel('Iteration')\n", - "plt.ylabel('FOM')\n", + "plt.xlabel(\"Iteration\")\n", + "plt.ylabel(\"FOM\")\n", "plt.show()" ] }, @@ -2379,13 +2426,19 @@ } ], "source": [ - "opt.update_design([mapping(x,eta_i,cur_beta)])\n", + "opt.update_design([mapping(x, eta_i, cur_beta)])\n", "plt.figure()\n", "ax = plt.gca()\n", - "opt.plot2D(False,ax=ax,plot_sources_flag=False,plot_monitors_flag=False,plot_boundaries_flag=False)\n", - "circ = Circle((2,2),minimum_length/2)\n", + "opt.plot2D(\n", + " False,\n", + " ax=ax,\n", + " plot_sources_flag=False,\n", + " plot_monitors_flag=False,\n", + " plot_boundaries_flag=False,\n", + ")\n", + "circ = Circle((2, 2), minimum_length / 2)\n", "ax.add_patch(circ)\n", - "ax.axis('off')\n", + "ax.axis(\"off\")\n", "plt.show()" ] }, @@ -2415,10 +2468,10 @@ } ], "source": [ - "f0, dJ_du = opt([mapping(x,eta_i,cur_beta)],need_gradient = False)\n", + "f0, dJ_du = opt([mapping(x, eta_i, cur_beta)], need_gradient=False)\n", "Ez_coef = opt.get_objective_arguments()[0]\n", "plt.figure()\n", - "plt.plot(np.abs(Ez_coef[1,:])**2,'-o')\n", + "plt.plot(np.abs(Ez_coef[1, :]) ** 2, \"-o\")\n", "plt.show()" ] }, @@ -2451,16 +2504,20 @@ } ], "source": [ - "src = mp.ContinuousSource(frequency=1/1.55,fwidth=fwidth)\n", - "source = [mp.EigenModeSource(src,\n", - " eig_band = 1,\n", - " direction=mp.NO_DIRECTION,\n", - " eig_kpoint=kpoint,\n", - " size = source_size,\n", - " center=source_center)]\n", + "src = mp.ContinuousSource(frequency=1 / 1.55, fwidth=fwidth)\n", + "source = [\n", + " mp.EigenModeSource(\n", + " src,\n", + " eig_band=1,\n", + " direction=mp.NO_DIRECTION,\n", + " eig_kpoint=kpoint,\n", + " size=source_size,\n", + " center=source_center,\n", + " )\n", + "]\n", "opt.sim.change_sources(source)\n", "opt.sim.run(until=500)\n", - "opt.sim.plot2D(fields=mp.Ez)\n" + "opt.sim.plot2D(fields=mp.Ez)" ] }, { diff --git a/python/examples/antenna-radiation.ipynb b/python/examples/antenna-radiation.ipynb index bf2498020..177d2fa83 100644 --- a/python/examples/antenna-radiation.ipynb +++ b/python/examples/antenna-radiation.ipynb @@ -53,44 +53,53 @@ "\n", "sxy = 4\n", "dpml = 1\n", - "cell = mp.Vector3(sxy+2*dpml,sxy+2*dpml)\n", + "cell = mp.Vector3(sxy + 2 * dpml, sxy + 2 * dpml)\n", "\n", "pml_layers = [mp.PML(dpml)]\n", "\n", "fcen = 1.0\n", "df = 0.4\n", "src_cmpt = mp.Ey\n", - "sources = [mp.Source(src=mp.GaussianSource(fcen,fwidth=df),\n", - " center=mp.Vector3(),\n", - " component=src_cmpt)]\n", + "sources = [\n", + " mp.Source(\n", + " src=mp.GaussianSource(fcen, fwidth=df), center=mp.Vector3(), component=src_cmpt\n", + " )\n", + "]\n", "\n", "if src_cmpt == mp.Ex:\n", - " symmetries = [mp.Mirror(mp.X,phase=-1),\n", - " mp.Mirror(mp.Y,phase=+1)]\n", + " symmetries = [mp.Mirror(mp.X, phase=-1), mp.Mirror(mp.Y, phase=+1)]\n", "elif src_cmpt == mp.Ey:\n", - " symmetries = [mp.Mirror(mp.X,phase=+1),\n", - " mp.Mirror(mp.Y,phase=-1)]\n", + " symmetries = [mp.Mirror(mp.X, phase=+1), mp.Mirror(mp.Y, phase=-1)]\n", "elif src_cmpt == mp.Ez:\n", - " symmetries = [mp.Mirror(mp.X,phase=+1),\n", - " mp.Mirror(mp.Y,phase=+1)]\n", + " symmetries = [mp.Mirror(mp.X, phase=+1), mp.Mirror(mp.Y, phase=+1)]\n", "\n", - "sim = mp.Simulation(cell_size=cell,\n", - " resolution=resolution,\n", - " sources=sources,\n", - " symmetries=symmetries,\n", - " boundary_layers=pml_layers)\n", + "sim = mp.Simulation(\n", + " cell_size=cell,\n", + " resolution=resolution,\n", + " sources=sources,\n", + " symmetries=symmetries,\n", + " boundary_layers=pml_layers,\n", + ")\n", "\n", - "nearfield_box = sim.add_near2far(fcen, 0, 1,\n", - " mp.Near2FarRegion(mp.Vector3(y=0.5*sxy), size=mp.Vector3(sxy)),\n", - " mp.Near2FarRegion(mp.Vector3(y=-0.5*sxy), size=mp.Vector3(sxy), weight=-1),\n", - " mp.Near2FarRegion(mp.Vector3(0.5*sxy), size=mp.Vector3(y=sxy)),\n", - " mp.Near2FarRegion(mp.Vector3(-0.5*sxy), size=mp.Vector3(y=sxy), weight=-1))\n", + "nearfield_box = sim.add_near2far(\n", + " fcen,\n", + " 0,\n", + " 1,\n", + " mp.Near2FarRegion(mp.Vector3(y=0.5 * sxy), size=mp.Vector3(sxy)),\n", + " mp.Near2FarRegion(mp.Vector3(y=-0.5 * sxy), size=mp.Vector3(sxy), weight=-1),\n", + " mp.Near2FarRegion(mp.Vector3(0.5 * sxy), size=mp.Vector3(y=sxy)),\n", + " mp.Near2FarRegion(mp.Vector3(-0.5 * sxy), size=mp.Vector3(y=sxy), weight=-1),\n", + ")\n", "\n", - "flux_box = sim.add_flux(fcen, 0, 1,\n", - " mp.FluxRegion(mp.Vector3(y=0.5*sxy), size=mp.Vector3(sxy)),\n", - " mp.FluxRegion(mp.Vector3(y=-0.5*sxy), size=mp.Vector3(sxy), weight=-1),\n", - " mp.FluxRegion(mp.Vector3(0.5*sxy), size=mp.Vector3(y=sxy)),\n", - " mp.FluxRegion(mp.Vector3(-0.5*sxy), size=mp.Vector3(y=sxy), weight=-1))" + "flux_box = sim.add_flux(\n", + " fcen,\n", + " 0,\n", + " 1,\n", + " mp.FluxRegion(mp.Vector3(y=0.5 * sxy), size=mp.Vector3(sxy)),\n", + " mp.FluxRegion(mp.Vector3(y=-0.5 * sxy), size=mp.Vector3(sxy), weight=-1),\n", + " mp.FluxRegion(mp.Vector3(0.5 * sxy), size=mp.Vector3(y=sxy)),\n", + " mp.FluxRegion(mp.Vector3(-0.5 * sxy), size=mp.Vector3(y=sxy), weight=-1),\n", + ")" ] }, { @@ -155,7 +164,9 @@ } ], "source": [ - "sim.run(until_after_sources=mp.stop_when_fields_decayed(50, src_cmpt, mp.Vector3(), 1e-8))" + "sim.run(\n", + " until_after_sources=mp.stop_when_fields_decayed(50, src_cmpt, mp.Vector3(), 1e-8)\n", + ")" ] }, { @@ -187,12 +198,24 @@ "metadata": {}, "outputs": [], "source": [ - "r = 1000/fcen # half side length of far-field square box OR radius of far-field circle\n", - "res_ff = 1 # resolution of far fields (points/μm)\n", - "far_flux_box = (nearfield_box.flux(mp.Y, mp.Volume(center=mp.Vector3(y=r), size=mp.Vector3(2*r)), res_ff)[0]\n", - " - nearfield_box.flux(mp.Y, mp.Volume(center=mp.Vector3(y=-r), size=mp.Vector3(2*r)), res_ff)[0]\n", - " + nearfield_box.flux(mp.X, mp.Volume(center=mp.Vector3(r), size=mp.Vector3(y=2*r)), res_ff)[0]\n", - " - nearfield_box.flux(mp.X, mp.Volume(center=mp.Vector3(-r), size=mp.Vector3(y=2*r)), res_ff)[0])" + "r = (\n", + " 1000 / fcen\n", + ") # half side length of far-field square box OR radius of far-field circle\n", + "res_ff = 1 # resolution of far fields (points/μm)\n", + "far_flux_box = (\n", + " nearfield_box.flux(\n", + " mp.Y, mp.Volume(center=mp.Vector3(y=r), size=mp.Vector3(2 * r)), res_ff\n", + " )[0]\n", + " - nearfield_box.flux(\n", + " mp.Y, mp.Volume(center=mp.Vector3(y=-r), size=mp.Vector3(2 * r)), res_ff\n", + " )[0]\n", + " + nearfield_box.flux(\n", + " mp.X, mp.Volume(center=mp.Vector3(r), size=mp.Vector3(y=2 * r)), res_ff\n", + " )[0]\n", + " - nearfield_box.flux(\n", + " mp.X, mp.Volume(center=mp.Vector3(-r), size=mp.Vector3(y=2 * r)), res_ff\n", + " )[0]\n", + ")" ] }, { @@ -216,25 +239,25 @@ } ], "source": [ - "npts = 100 # number of points in [0,2*pi) range of angles\n", - "angles = 2*math.pi/npts*np.arange(npts)\n", + "npts = 100 # number of points in [0,2*pi) range of angles\n", + "angles = 2 * math.pi / npts * np.arange(npts)\n", "\n", - "E = np.zeros((npts,3),dtype=np.complex128)\n", - "H = np.zeros((npts,3),dtype=np.complex128)\n", + "E = np.zeros((npts, 3), dtype=np.complex128)\n", + "H = np.zeros((npts, 3), dtype=np.complex128)\n", "for n in range(npts):\n", - " ff = sim.get_farfield(nearfield_box,\n", - " mp.Vector3(r*math.cos(angles[n]),\n", - " r*math.sin(angles[n])))\n", - " E[n,:] = [np.conj(ff[j]) for j in range(3)]\n", - " H[n,:] = [ff[j+3] for j in range(3)]\n", + " ff = sim.get_farfield(\n", + " nearfield_box, mp.Vector3(r * math.cos(angles[n]), r * math.sin(angles[n]))\n", + " )\n", + " E[n, :] = [np.conj(ff[j]) for j in range(3)]\n", + " H[n, :] = [ff[j + 3] for j in range(3)]\n", "\n", - "Px = np.real(np.multiply(E[:,1],H[:,2])-np.multiply(E[:,2],H[:,1]))\n", - "Py = np.real(np.multiply(E[:,2],H[:,0])-np.multiply(E[:,0],H[:,2]))\n", - "Pr = np.sqrt(np.square(Px)+np.square(Py))\n", + "Px = np.real(np.multiply(E[:, 1], H[:, 2]) - np.multiply(E[:, 2], H[:, 1]))\n", + "Py = np.real(np.multiply(E[:, 2], H[:, 0]) - np.multiply(E[:, 0], H[:, 2]))\n", + "Pr = np.sqrt(np.square(Px) + np.square(Py))\n", "\n", - "far_flux_circle = np.sum(Pr)*2*np.pi*r/len(Pr)\n", + "far_flux_circle = np.sum(Pr) * 2 * np.pi * r / len(Pr)\n", "\n", - "print(\"flux:, {:.6f}, {:.6f}, {:.6f}\".format(near_flux,far_flux_box,far_flux_circle))" + "print(\"flux:, {:.6f}, {:.6f}, {:.6f}\".format(near_flux, far_flux_box, far_flux_circle))" ] }, { @@ -266,10 +289,10 @@ ], "source": [ "plt.figure(dpi=200)\n", - "ax = plt.subplot(111, projection='polar')\n", - "ax.plot(angles,Pr/max(Pr),'b-')\n", + "ax = plt.subplot(111, projection=\"polar\")\n", + "ax.plot(angles, Pr / max(Pr), \"b-\")\n", "ax.set_rmax(1)\n", - "ax.set_rticks([0,0.5,1])\n", + "ax.set_rticks([0, 0.5, 1])\n", "ax.grid(True)\n", "ax.set_rlabel_position(22)" ] diff --git a/python/examples/bend-flux.ipynb b/python/examples/bend-flux.ipynb index df16d007f..bf9a54c7e 100644 --- a/python/examples/bend-flux.ipynb +++ b/python/examples/bend-flux.ipynb @@ -34,11 +34,11 @@ "import numpy as np\n", "import matplotlib.pyplot as plt\n", "\n", - "resolution = 10 # pixels/um\n", + "resolution = 10 # pixels/um\n", "\n", "sx = 16 # size of cell in X direction\n", "sy = 32 # size of cell in Y direction\n", - "cell = mp.Vector3(sx,sy,0)\n", + "cell = mp.Vector3(sx, sy, 0)\n", "\n", "dpml = 1.0\n", "pml_layers = [mp.PML(dpml)]" @@ -58,7 +58,7 @@ "outputs": [], "source": [ "pad = 4 # padding distance between waveguide and cell edge\n", - "w = 1 # width of waveguide" + "w = 1 # width of waveguide" ] }, { @@ -74,8 +74,8 @@ "metadata": {}, "outputs": [], "source": [ - "wvg_xcen = 0.5*(sx-w-2*pad) # x center of horiz. wvg\n", - "wvg_ycen = -0.5*(sy-w-2*pad) # y center of vert. wvg" + "wvg_xcen = 0.5 * (sx - w - 2 * pad) # x center of horiz. wvg\n", + "wvg_ycen = -0.5 * (sy - w - 2 * pad) # y center of vert. wvg" ] }, { @@ -91,9 +91,13 @@ "metadata": {}, "outputs": [], "source": [ - "geometry = [mp.Block(size=mp.Vector3(mp.inf,w,mp.inf),\n", - " center=mp.Vector3(0,wvg_ycen,0),\n", - " material=mp.Medium(epsilon=12))]" + "geometry = [\n", + " mp.Block(\n", + " size=mp.Vector3(mp.inf, w, mp.inf),\n", + " center=mp.Vector3(0, wvg_ycen, 0),\n", + " material=mp.Medium(epsilon=12),\n", + " )\n", + "]" ] }, { @@ -110,11 +114,15 @@ "outputs": [], "source": [ "fcen = 0.15 # pulse center frequency\n", - "df = 0.1 # pulse width (in frequency)\n", - "sources = [mp.Source(mp.GaussianSource(fcen,fwidth=df),\n", - " component=mp.Ez,\n", - " center=mp.Vector3(-0.5*sx+dpml,wvg_ycen,0),\n", - " size=mp.Vector3(0,w,0))]" + "df = 0.1 # pulse width (in frequency)\n", + "sources = [\n", + " mp.Source(\n", + " mp.GaussianSource(fcen, fwidth=df),\n", + " component=mp.Ez,\n", + " center=mp.Vector3(-0.5 * sx + dpml, wvg_ycen, 0),\n", + " size=mp.Vector3(0, w, 0),\n", + " )\n", + "]" ] }, { @@ -156,25 +164,31 @@ } ], "source": [ - "sim = mp.Simulation(cell_size=cell,\n", - " boundary_layers=pml_layers,\n", - " geometry=geometry,\n", - " sources=sources,\n", - " resolution=resolution)\n", + "sim = mp.Simulation(\n", + " cell_size=cell,\n", + " boundary_layers=pml_layers,\n", + " geometry=geometry,\n", + " sources=sources,\n", + " resolution=resolution,\n", + ")\n", "\n", "nfreq = 100 # number of frequencies at which to compute flux\n", "\n", "# reflected flux\n", - "refl_fr = mp.FluxRegion(center=mp.Vector3(-0.5*sx+dpml+0.5,wvg_ycen,0), size=mp.Vector3(0,2*w,0)) \n", + "refl_fr = mp.FluxRegion(\n", + " center=mp.Vector3(-0.5 * sx + dpml + 0.5, wvg_ycen, 0), size=mp.Vector3(0, 2 * w, 0)\n", + ")\n", "refl = sim.add_flux(fcen, df, nfreq, refl_fr)\n", "\n", "# transmitted flux\n", - "tran_fr = mp.FluxRegion(center=mp.Vector3(0.5*sx-dpml,wvg_ycen,0), size=mp.Vector3(0,2*w,0))\n", + "tran_fr = mp.FluxRegion(\n", + " center=mp.Vector3(0.5 * sx - dpml, wvg_ycen, 0), size=mp.Vector3(0, 2 * w, 0)\n", + ")\n", "tran = sim.add_flux(fcen, df, nfreq, tran_fr)\n", "\n", "plt.figure(dpi=150)\n", "sim.plot2D()\n", - "plt.show()\n" + "plt.show()" ] }, { @@ -206,9 +220,9 @@ } ], "source": [ - "pt = mp.Vector3(0.5*sx-dpml-0.5,wvg_ycen)\n", + "pt = mp.Vector3(0.5 * sx - dpml - 0.5, wvg_ycen)\n", "\n", - "sim.run(until_after_sources=mp.stop_when_fields_decayed(50,mp.Ez,pt,1e-3))\n", + "sim.run(until_after_sources=mp.stop_when_fields_decayed(50, mp.Ez, pt, 1e-3))\n", "\n", "# for normalization run, save flux fields data for reflection plane\n", "straight_refl_data = sim.get_flux_data(refl)" @@ -284,25 +298,39 @@ "source": [ "sim.reset_meep()\n", "\n", - "geometry = [mp.Block(mp.Vector3(sx-pad,w,mp.inf), center=mp.Vector3(-0.5*pad,wvg_ycen), material=mp.Medium(epsilon=12)),\n", - " mp.Block(mp.Vector3(w,sy-pad,mp.inf), center=mp.Vector3(wvg_xcen,0.5*pad), material=mp.Medium(epsilon=12))]\n", + "geometry = [\n", + " mp.Block(\n", + " mp.Vector3(sx - pad, w, mp.inf),\n", + " center=mp.Vector3(-0.5 * pad, wvg_ycen),\n", + " material=mp.Medium(epsilon=12),\n", + " ),\n", + " mp.Block(\n", + " mp.Vector3(w, sy - pad, mp.inf),\n", + " center=mp.Vector3(wvg_xcen, 0.5 * pad),\n", + " material=mp.Medium(epsilon=12),\n", + " ),\n", + "]\n", "\n", - "sim = mp.Simulation(cell_size=cell,\n", - " boundary_layers=pml_layers,\n", - " geometry=geometry,\n", - " sources=sources,\n", - " resolution=resolution)\n", + "sim = mp.Simulation(\n", + " cell_size=cell,\n", + " boundary_layers=pml_layers,\n", + " geometry=geometry,\n", + " sources=sources,\n", + " resolution=resolution,\n", + ")\n", "\n", "# reflected flux\n", "refl = sim.add_flux(fcen, df, nfreq, refl_fr)\n", "\n", - "tran_fr = mp.FluxRegion(center=mp.Vector3(wvg_xcen,0.5*sy-dpml-0.5,0), size=mp.Vector3(2*w,0,0))\n", + "tran_fr = mp.FluxRegion(\n", + " center=mp.Vector3(wvg_xcen, 0.5 * sy - dpml - 0.5, 0), size=mp.Vector3(2 * w, 0, 0)\n", + ")\n", "tran = sim.add_flux(fcen, df, nfreq, tran_fr)\n", "\n", "# for normal run, load negated fields to subtract incident from refl. fields\n", "sim.load_minus_flux_data(refl, straight_refl_data)\n", "\n", - "pt = mp.Vector3(wvg_xcen,0.5*sy-dpml-0.5)\n", + "pt = mp.Vector3(wvg_xcen, 0.5 * sy - dpml - 0.5)\n", "\n", "sim.run(until_after_sources=mp.stop_when_fields_decayed(50, mp.Ez, pt, 1e-3))\n", "\n", @@ -346,15 +374,15 @@ "Rs = []\n", "Ts = []\n", "for i in range(nfreq):\n", - " wl = np.append(wl, 1/flux_freqs[i])\n", - " Rs = np.append(Rs,-bend_refl_flux[i]/straight_tran_flux[i])\n", - " Ts = np.append(Ts,bend_tran_flux[i]/straight_tran_flux[i]) \n", + " wl = np.append(wl, 1 / flux_freqs[i])\n", + " Rs = np.append(Rs, -bend_refl_flux[i] / straight_tran_flux[i])\n", + " Ts = np.append(Ts, bend_tran_flux[i] / straight_tran_flux[i])\n", "\n", "if mp.am_master():\n", " plt.figure(dpi=150)\n", - " plt.plot(wl,Rs,'bo-',label='reflectance')\n", - " plt.plot(wl,Ts,'ro-',label='transmittance')\n", - " plt.plot(wl,1-Rs-Ts,'go-',label='loss')\n", + " plt.plot(wl, Rs, \"bo-\", label=\"reflectance\")\n", + " plt.plot(wl, Ts, \"ro-\", label=\"transmittance\")\n", + " plt.plot(wl, 1 - Rs - Ts, \"go-\", label=\"loss\")\n", " plt.axis([5.0, 10.0, 0, 1])\n", " plt.xlabel(\"wavelength (μm)\")\n", " plt.legend(loc=\"upper right\")\n", diff --git a/python/examples/bent-waveguide.ipynb b/python/examples/bent-waveguide.ipynb index ca9d4e5d0..f03241857 100644 --- a/python/examples/bent-waveguide.ipynb +++ b/python/examples/bent-waveguide.ipynb @@ -34,6 +34,7 @@ "from matplotlib import pyplot as plt\n", "import numpy as np\n", "from IPython.display import Video\n", + "\n", "%matplotlib inline" ] }, @@ -50,13 +51,19 @@ "metadata": {}, "outputs": [], "source": [ - "cell = mp.Vector3(16,16,0)\n", - "geometry = [mp.Block(mp.Vector3(12,1,mp.inf),\n", - " center=mp.Vector3(-2.5,-3.5),\n", - " material=mp.Medium(epsilon=12)),\n", - " mp.Block(mp.Vector3(1,12,mp.inf),\n", - " center=mp.Vector3(3.5,2),\n", - " material=mp.Medium(epsilon=12))]\n", + "cell = mp.Vector3(16, 16, 0)\n", + "geometry = [\n", + " mp.Block(\n", + " mp.Vector3(12, 1, mp.inf),\n", + " center=mp.Vector3(-2.5, -3.5),\n", + " material=mp.Medium(epsilon=12),\n", + " ),\n", + " mp.Block(\n", + " mp.Vector3(1, 12, mp.inf),\n", + " center=mp.Vector3(3.5, 2),\n", + " material=mp.Medium(epsilon=12),\n", + " ),\n", + "]\n", "pml_layers = [mp.PML(1.0)]\n", "resolution = 10" ] @@ -81,10 +88,14 @@ "metadata": {}, "outputs": [], "source": [ - "sources = [mp.Source(mp.ContinuousSource(wavelength=2*(11**0.5), width=20),\n", - " component=mp.Ez,\n", - " center=mp.Vector3(-7,-3.5),\n", - " size=mp.Vector3(0,1))]" + "sources = [\n", + " mp.Source(\n", + " mp.ContinuousSource(wavelength=2 * (11**0.5), width=20),\n", + " component=mp.Ez,\n", + " center=mp.Vector3(-7, -3.5),\n", + " size=mp.Vector3(0, 1),\n", + " )\n", + "]" ] }, { @@ -100,11 +111,13 @@ "metadata": {}, "outputs": [], "source": [ - "sim = mp.Simulation(cell_size=cell,\n", - " boundary_layers=pml_layers,\n", - " geometry=geometry,\n", - " sources=sources,\n", - " resolution=resolution)" + "sim = mp.Simulation(\n", + " cell_size=cell,\n", + " boundary_layers=pml_layers,\n", + " geometry=geometry,\n", + " sources=sources,\n", + " resolution=resolution,\n", + ")" ] }, { @@ -141,7 +154,7 @@ ], "source": [ "f = plt.figure(dpi=150)\n", - "sim.plot2D(ax = f.gca())\n", + "sim.plot2D(ax=f.gca())\n", "plt.show()" ] }, @@ -169,7 +182,7 @@ "source": [ "f = plt.figure(dpi=150)\n", "Animate = mp.Animate2D(sim, fields=mp.Ez, f=f, realtime=False, normalize=True)\n", - "sim.run(mp.at_every(0.5,Animate),until=100)\n", + "sim.run(mp.at_every(0.5, Animate), until=100)\n", "plt.close()" ] }, @@ -204,7 +217,7 @@ "source": [ "filename = \"media/bent_waveguide.mp4\"\n", "fps = 10\n", - "Animate.to_mp4(fps,filename)\n", + "Animate.to_mp4(fps, filename)\n", "Video(filename)" ] }, @@ -253,16 +266,22 @@ ], "source": [ "sim.reset_meep()\n", - "cell = mp.Vector3(16,40,0)\n", - "geometry = [mp.Block(mp.Vector3(12,1,mp.inf),\n", - " center=mp.Vector3(-2.5,-3.5),\n", - " material=mp.Medium(epsilon=12)),\n", - " mp.Block(mp.Vector3(1,42,mp.inf),\n", - " center=mp.Vector3(3.5,17),\n", - " material=mp.Medium(epsilon=12))]\n", + "cell = mp.Vector3(16, 40, 0)\n", + "geometry = [\n", + " mp.Block(\n", + " mp.Vector3(12, 1, mp.inf),\n", + " center=mp.Vector3(-2.5, -3.5),\n", + " material=mp.Medium(epsilon=12),\n", + " ),\n", + " mp.Block(\n", + " mp.Vector3(1, 42, mp.inf),\n", + " center=mp.Vector3(3.5, 17),\n", + " material=mp.Medium(epsilon=12),\n", + " ),\n", + "]\n", "sim.cell_size = cell\n", "sim.geometry = geometry\n", - "sim.geometry_center = mp.Vector3(0,12,0)\n", + "sim.geometry_center = mp.Vector3(0, 12, 0)\n", "\n", "sim.run(until=400)\n", "\n", @@ -314,18 +333,22 @@ "source": [ "vals = []\n", "\n", + "\n", "def get_slice(sim):\n", - " vals.append(sim.get_array(center=mp.Vector3(0,-3.5), size=mp.Vector3(16,0), component=mp.Ez))\n", + " vals.append(\n", + " sim.get_array(\n", + " center=mp.Vector3(0, -3.5), size=mp.Vector3(16, 0), component=mp.Ez\n", + " )\n", + " )\n", + "\n", "\n", "sim.reset_meep()\n", - "sim.run(mp.at_beginning(mp.output_epsilon),\n", - " mp.at_every(0.6, get_slice),\n", - " until=200)\n", + "sim.run(mp.at_beginning(mp.output_epsilon), mp.at_every(0.6, get_slice), until=200)\n", "\n", "plt.figure(dpi=150)\n", - "plt.imshow(vals, interpolation='spline36', cmap='RdBu')\n", - "plt.axis('off')\n", - "plt.show()\n" + "plt.imshow(vals, interpolation=\"spline36\", cmap=\"RdBu\")\n", + "plt.axis(\"off\")\n", + "plt.show()" ] } ], diff --git a/python/examples/binary_grating.ipynb b/python/examples/binary_grating.ipynb index 670528df6..a49b08fe1 100644 --- a/python/examples/binary_grating.ipynb +++ b/python/examples/binary_grating.ipynb @@ -80,46 +80,57 @@ "source": [ "fused_quartz = mp.Medium(index=1.5)\n", "\n", - "resolution = 50 # pixels/μm\n", + "resolution = 50 # pixels/μm\n", "\n", - "dpml = 1.0 # PML thickness\n", - "dsub = 3.0 # substrate thickness\n", - "dpad = 3.0 # padding between grating and PML\n", - "gp = 10.0 # grating period\n", - "gh = 0.5 # grating height\n", - "gdc = 0.5 # grating duty cycle\n", + "dpml = 1.0 # PML thickness\n", + "dsub = 3.0 # substrate thickness\n", + "dpad = 3.0 # padding between grating and PML\n", + "gp = 10.0 # grating period\n", + "gh = 0.5 # grating height\n", + "gdc = 0.5 # grating duty cycle\n", "\n", - "sx = dpml+dsub+gh+dpad+dpml\n", + "sx = dpml + dsub + gh + dpad + dpml\n", "sy = gp\n", "\n", - "cell_size = mp.Vector3(sx,sy,0)\n", - "pml_layers = [mp.PML(thickness=dpml,direction=mp.X)]\n", - "\n", - "wvl_min = 0.4 # min wavelength\n", - "wvl_max = 0.6 # max wavelength\n", - "fmin = 1/wvl_max # min frequency\n", - "fmax = 1/wvl_min # max frequency\n", - "fcen = 0.5*(fmin+fmax) # center frequency\n", - "df = fmax-fmin # frequency width\n", - "\n", - "src_pt = mp.Vector3(-0.5*sx+dpml+0.5*dsub)\n", - "sources = [mp.Source(mp.GaussianSource(fcen, fwidth=df), component=mp.Ez, center=src_pt, size=mp.Vector3(y=sy))]\n", - "\n", - "k_point = mp.Vector3(0,0,0)\n", - "\n", - "symmetries=[mp.Mirror(mp.Y)]\n", - "\n", - "sim = mp.Simulation(resolution=resolution,\n", - " cell_size=cell_size,\n", - " boundary_layers=pml_layers,\n", - " k_point=k_point,\n", - " default_material=fused_quartz,\n", - " sources=sources,\n", - " symmetries=symmetries)\n", + "cell_size = mp.Vector3(sx, sy, 0)\n", + "pml_layers = [mp.PML(thickness=dpml, direction=mp.X)]\n", + "\n", + "wvl_min = 0.4 # min wavelength\n", + "wvl_max = 0.6 # max wavelength\n", + "fmin = 1 / wvl_max # min frequency\n", + "fmax = 1 / wvl_min # max frequency\n", + "fcen = 0.5 * (fmin + fmax) # center frequency\n", + "df = fmax - fmin # frequency width\n", + "\n", + "src_pt = mp.Vector3(-0.5 * sx + dpml + 0.5 * dsub)\n", + "sources = [\n", + " mp.Source(\n", + " mp.GaussianSource(fcen, fwidth=df),\n", + " component=mp.Ez,\n", + " center=src_pt,\n", + " size=mp.Vector3(y=sy),\n", + " )\n", + "]\n", + "\n", + "k_point = mp.Vector3(0, 0, 0)\n", + "\n", + "symmetries = [mp.Mirror(mp.Y)]\n", + "\n", + "sim = mp.Simulation(\n", + " resolution=resolution,\n", + " cell_size=cell_size,\n", + " boundary_layers=pml_layers,\n", + " k_point=k_point,\n", + " default_material=fused_quartz,\n", + " sources=sources,\n", + " symmetries=symmetries,\n", + ")\n", "\n", "nfreq = 21\n", - "mon_pt = mp.Vector3(0.5*sx-dpml-0.5*dpad)\n", - "flux_mon = sim.add_flux(fcen, df, nfreq, mp.FluxRegion(center=mon_pt, size=mp.Vector3(y=sy)))\n", + "mon_pt = mp.Vector3(0.5 * sx - dpml - 0.5 * dpad)\n", + "flux_mon = sim.add_flux(\n", + " fcen, df, nfreq, mp.FluxRegion(center=mon_pt, size=mp.Vector3(y=sy))\n", + ")\n", "\n", "f = plt.figure(dpi=120)\n", "sim.plot2D(ax=f.gca())\n", @@ -203,18 +214,32 @@ "source": [ "sim.reset_meep()\n", "\n", - "geometry = [mp.Block(material=fused_quartz, size=mp.Vector3(dpml+dsub,mp.inf,mp.inf), center=mp.Vector3(-0.5*sx+0.5*(dpml+dsub))),\n", - " mp.Block(material=fused_quartz, size=mp.Vector3(gh,gdc*gp,mp.inf), center=mp.Vector3(-0.5*sx+dpml+dsub+0.5*gh))]\n", - "\n", - "sim = mp.Simulation(resolution=resolution,\n", - " cell_size=cell_size,\n", - " boundary_layers=pml_layers,\n", - " geometry=geometry,\n", - " k_point=k_point,\n", - " sources=sources,\n", - " symmetries=symmetries)\n", - "\n", - "mode_mon = sim.add_flux(fcen, df, nfreq, mp.FluxRegion(center=mon_pt, size=mp.Vector3(y=sy)))\n", + "geometry = [\n", + " mp.Block(\n", + " material=fused_quartz,\n", + " size=mp.Vector3(dpml + dsub, mp.inf, mp.inf),\n", + " center=mp.Vector3(-0.5 * sx + 0.5 * (dpml + dsub)),\n", + " ),\n", + " mp.Block(\n", + " material=fused_quartz,\n", + " size=mp.Vector3(gh, gdc * gp, mp.inf),\n", + " center=mp.Vector3(-0.5 * sx + dpml + dsub + 0.5 * gh),\n", + " ),\n", + "]\n", + "\n", + "sim = mp.Simulation(\n", + " resolution=resolution,\n", + " cell_size=cell_size,\n", + " boundary_layers=pml_layers,\n", + " geometry=geometry,\n", + " k_point=k_point,\n", + " sources=sources,\n", + " symmetries=symmetries,\n", + ")\n", + "\n", + "mode_mon = sim.add_flux(\n", + " fcen, df, nfreq, mp.FluxRegion(center=mon_pt, size=mp.Vector3(y=sy))\n", + ")\n", "\n", "f2 = plt.figure(dpi=120)\n", "sim.plot2D(ax=f2.gca())\n", @@ -270,7 +295,9 @@ "freqs = mp.get_eigenmode_freqs(mode_mon)\n", "\n", "nmode = 10\n", - "res = sim.get_eigenmode_coefficients(mode_mon, range(1,nmode+1), eig_parity=mp.ODD_Z+mp.EVEN_Y)\n", + "res = sim.get_eigenmode_coefficients(\n", + " mode_mon, range(1, nmode + 1), eig_parity=mp.ODD_Z + mp.EVEN_Y\n", + ")\n", "coeffs = res.alpha\n", "kdom = res.kdom\n", "\n", @@ -279,13 +306,13 @@ "mode_tran = []\n", "\n", "for nm in range(nmode):\n", - " for nf in range(nfreq):\n", - " mode_wvl.append(1/freqs[nf])\n", - " mode_angle.append(math.degrees(math.acos(kdom[nm*nfreq+nf].x/freqs[nf])))\n", - " tran = abs(coeffs[nm,nf,0])**2/input_flux[nf]\n", - " mode_tran.append(0.5*tran if nm != 0 else tran)\n", + " for nf in range(nfreq):\n", + " mode_wvl.append(1 / freqs[nf])\n", + " mode_angle.append(math.degrees(math.acos(kdom[nm * nfreq + nf].x / freqs[nf])))\n", + " tran = abs(coeffs[nm, nf, 0]) ** 2 / input_flux[nf]\n", + " mode_tran.append(0.5 * tran if nm != 0 else tran)\n", "\n", - "tran_max = round(max(mode_tran),1)" + "tran_max = round(max(mode_tran), 1)" ] }, { @@ -317,22 +344,24 @@ ], "source": [ "plt.figure(dpi=200)\n", - "plt.pcolormesh(np.reshape(mode_wvl,(nmode,nfreq)),\n", - " np.reshape(mode_angle,(nmode,nfreq)),\n", - " np.reshape(mode_tran,(nmode,nfreq)),\n", - " cmap='Blues',\n", - " shading='flat',\n", - " vmin=0,\n", - " vmax=tran_max)\n", + "plt.pcolormesh(\n", + " np.reshape(mode_wvl, (nmode, nfreq)),\n", + " np.reshape(mode_angle, (nmode, nfreq)),\n", + " np.reshape(mode_tran, (nmode, nfreq)),\n", + " cmap=\"Blues\",\n", + " shading=\"flat\",\n", + " vmin=0,\n", + " vmax=tran_max,\n", + ")\n", "plt.axis([min(mode_wvl), max(mode_wvl), min(mode_angle), max(mode_angle)])\n", "plt.xlabel(\"wavelength (μm)\")\n", "plt.ylabel(\"diffraction angle (degrees)\")\n", - "plt.xticks([t for t in np.linspace(wvl_min,wvl_max,3)])\n", - "plt.yticks([t for t in range(0,35,5)])\n", + "plt.xticks([t for t in np.linspace(wvl_min, wvl_max, 3)])\n", + "plt.yticks([t for t in range(0, 35, 5)])\n", "plt.title(\"transmittance of diffraction orders\")\n", "cbar = plt.colorbar()\n", - "cbar.set_ticks([t for t in np.arange(0,tran_max+0.1,0.1)])\n", - "cbar.set_ticklabels([\"{:.1f}\".format(t) for t in np.arange(0,tran_max+0.1,0.1)])" + "cbar.set_ticks([t for t in np.arange(0, tran_max + 0.1, 0.1)])\n", + "cbar.set_ticklabels([\"{:.1f}\".format(t) for t in np.arange(0, tran_max + 0.1, 0.1)])" ] }, { @@ -413,46 +442,57 @@ "source": [ "from meep.materials import fused_quartz\n", "\n", - "resolution = 50 # pixels/μm\n", + "resolution = 50 # pixels/μm\n", "\n", - "dpml = 1.0 # PML thickness\n", - "dsub = 3.0 # substrate thickness\n", - "dpad = 3.0 # padding between grating and PML\n", - "gp = 10.0 # grating period\n", - "gh = 0.5 # grating height\n", - "gdc = 0.5 # grating duty cycle\n", + "dpml = 1.0 # PML thickness\n", + "dsub = 3.0 # substrate thickness\n", + "dpad = 3.0 # padding between grating and PML\n", + "gp = 10.0 # grating period\n", + "gh = 0.5 # grating height\n", + "gdc = 0.5 # grating duty cycle\n", "\n", - "sx = dpml+dsub+gh+dpad+dpml\n", + "sx = dpml + dsub + gh + dpad + dpml\n", "sy = gp\n", "\n", - "cell_size = mp.Vector3(sx,sy,0)\n", - "pml_layers = [mp.PML(thickness=dpml,direction=mp.X)]\n", - "\n", - "wvl_min = 0.4 # min wavelength\n", - "wvl_max = 0.6 # max wavelength\n", - "fmin = 1/wvl_max # min frequency\n", - "fmax = 1/wvl_min # max frequency\n", - "fcen = 0.5*(fmin+fmax) # center frequency\n", - "df = fmax-fmin # frequency width\n", - "\n", - "src_pt = mp.Vector3(-0.5*sx+dpml+0.5*dsub)\n", - "sources = [mp.Source(mp.GaussianSource(fcen, fwidth=df), component=mp.Ez, center=src_pt, size=mp.Vector3(y=sy))]\n", - "\n", - "k_point = mp.Vector3(0,0,0)\n", - "\n", - "symmetries=[mp.Mirror(mp.Y)]\n", - "\n", - "sim = mp.Simulation(resolution=resolution,\n", - " cell_size=cell_size,\n", - " boundary_layers=pml_layers,\n", - " k_point=k_point,\n", - " default_material=fused_quartz,\n", - " sources=sources,\n", - " symmetries=symmetries)\n", + "cell_size = mp.Vector3(sx, sy, 0)\n", + "pml_layers = [mp.PML(thickness=dpml, direction=mp.X)]\n", + "\n", + "wvl_min = 0.4 # min wavelength\n", + "wvl_max = 0.6 # max wavelength\n", + "fmin = 1 / wvl_max # min frequency\n", + "fmax = 1 / wvl_min # max frequency\n", + "fcen = 0.5 * (fmin + fmax) # center frequency\n", + "df = fmax - fmin # frequency width\n", + "\n", + "src_pt = mp.Vector3(-0.5 * sx + dpml + 0.5 * dsub)\n", + "sources = [\n", + " mp.Source(\n", + " mp.GaussianSource(fcen, fwidth=df),\n", + " component=mp.Ez,\n", + " center=src_pt,\n", + " size=mp.Vector3(y=sy),\n", + " )\n", + "]\n", + "\n", + "k_point = mp.Vector3(0, 0, 0)\n", + "\n", + "symmetries = [mp.Mirror(mp.Y)]\n", + "\n", + "sim = mp.Simulation(\n", + " resolution=resolution,\n", + " cell_size=cell_size,\n", + " boundary_layers=pml_layers,\n", + " k_point=k_point,\n", + " default_material=fused_quartz,\n", + " sources=sources,\n", + " symmetries=symmetries,\n", + ")\n", "\n", "nfreq = 21\n", - "mon_pt = mp.Vector3(0.5*sx-dpml-0.5*dpad)\n", - "flux_mon = sim.add_flux(fcen, df, nfreq, mp.FluxRegion(center=mon_pt, size=mp.Vector3(y=sy)))\n", + "mon_pt = mp.Vector3(0.5 * sx - dpml - 0.5 * dpad)\n", + "flux_mon = sim.add_flux(\n", + " fcen, df, nfreq, mp.FluxRegion(center=mon_pt, size=mp.Vector3(y=sy))\n", + ")\n", "\n", "sim.run(until_after_sources=mp.stop_when_fields_decayed(50, mp.Ez, mon_pt, 1e-9))\n", "\n", @@ -460,25 +500,41 @@ "\n", "sim.reset_meep()\n", "\n", - "geometry = [mp.Block(material=fused_quartz, size=mp.Vector3(dpml+dsub,mp.inf,mp.inf), center=mp.Vector3(-0.5*sx+0.5*(dpml+dsub))),\n", - " mp.Block(material=fused_quartz, size=mp.Vector3(gh,gdc*gp,mp.inf), center=mp.Vector3(-0.5*sx+dpml+dsub+0.5*gh))]\n", - "\n", - "sim = mp.Simulation(resolution=resolution,\n", - " cell_size=cell_size,\n", - " boundary_layers=pml_layers,\n", - " geometry=geometry,\n", - " k_point=k_point,\n", - " sources=sources,\n", - " symmetries=symmetries)\n", - "\n", - "mode_mon = sim.add_flux(fcen, df, nfreq, mp.FluxRegion(center=mon_pt, size=mp.Vector3(y=sy)))\n", + "geometry = [\n", + " mp.Block(\n", + " material=fused_quartz,\n", + " size=mp.Vector3(dpml + dsub, mp.inf, mp.inf),\n", + " center=mp.Vector3(-0.5 * sx + 0.5 * (dpml + dsub)),\n", + " ),\n", + " mp.Block(\n", + " material=fused_quartz,\n", + " size=mp.Vector3(gh, gdc * gp, mp.inf),\n", + " center=mp.Vector3(-0.5 * sx + dpml + dsub + 0.5 * gh),\n", + " ),\n", + "]\n", + "\n", + "sim = mp.Simulation(\n", + " resolution=resolution,\n", + " cell_size=cell_size,\n", + " boundary_layers=pml_layers,\n", + " geometry=geometry,\n", + " k_point=k_point,\n", + " sources=sources,\n", + " symmetries=symmetries,\n", + ")\n", + "\n", + "mode_mon = sim.add_flux(\n", + " fcen, df, nfreq, mp.FluxRegion(center=mon_pt, size=mp.Vector3(y=sy))\n", + ")\n", "\n", "sim.run(until_after_sources=mp.stop_when_fields_decayed(50, mp.Ez, mon_pt, 1e-9))\n", "\n", "freqs = mp.get_eigenmode_freqs(mode_mon)\n", "\n", "nmode = 10\n", - "res = sim.get_eigenmode_coefficients(mode_mon, range(1,nmode+1), eig_parity=mp.ODD_Z+mp.EVEN_Y)\n", + "res = sim.get_eigenmode_coefficients(\n", + " mode_mon, range(1, nmode + 1), eig_parity=mp.ODD_Z + mp.EVEN_Y\n", + ")\n", "coeffs = res.alpha\n", "kdom = res.kdom\n", "\n", @@ -487,31 +543,33 @@ "mode_tran = []\n", "\n", "for nm in range(nmode):\n", - " for nf in range(nfreq):\n", - " mode_wvl.append(1/freqs[nf])\n", - " mode_angle.append(math.degrees(math.acos(kdom[nm*nfreq+nf].x/freqs[nf])))\n", - " tran = abs(coeffs[nm,nf,0])**2/input_flux[nf]\n", - " mode_tran.append(0.5*tran if nm != 0 else tran)\n", + " for nf in range(nfreq):\n", + " mode_wvl.append(1 / freqs[nf])\n", + " mode_angle.append(math.degrees(math.acos(kdom[nm * nfreq + nf].x / freqs[nf])))\n", + " tran = abs(coeffs[nm, nf, 0]) ** 2 / input_flux[nf]\n", + " mode_tran.append(0.5 * tran if nm != 0 else tran)\n", "\n", - "tran_max = round(max(mode_tran),1)\n", + "tran_max = round(max(mode_tran), 1)\n", "\n", "plt.figure(dpi=200)\n", - "plt.pcolormesh(np.reshape(mode_wvl,(nmode,nfreq)),\n", - " np.reshape(mode_angle,(nmode,nfreq)),\n", - " np.reshape(mode_tran,(nmode,nfreq)),\n", - " cmap='Blues',\n", - " shading='flat',\n", - " vmin=0,\n", - " vmax=tran_max)\n", + "plt.pcolormesh(\n", + " np.reshape(mode_wvl, (nmode, nfreq)),\n", + " np.reshape(mode_angle, (nmode, nfreq)),\n", + " np.reshape(mode_tran, (nmode, nfreq)),\n", + " cmap=\"Blues\",\n", + " shading=\"flat\",\n", + " vmin=0,\n", + " vmax=tran_max,\n", + ")\n", "plt.axis([min(mode_wvl), max(mode_wvl), min(mode_angle), max(mode_angle)])\n", "plt.xlabel(\"wavelength (μm)\")\n", "plt.ylabel(\"diffraction angle (degrees)\")\n", - "plt.xticks([t for t in np.linspace(wvl_min,wvl_max,3)])\n", - "plt.yticks([t for t in range(0,35,5)])\n", + "plt.xticks([t for t in np.linspace(wvl_min, wvl_max, 3)])\n", + "plt.yticks([t for t in range(0, 35, 5)])\n", "plt.title(\"transmittance of diffraction orders\")\n", "cbar = plt.colorbar()\n", - "cbar.set_ticks([t for t in np.arange(0,tran_max+0.1,0.1)])\n", - "cbar.set_ticklabels([\"{:.1f}\".format(t) for t in np.arange(0,tran_max+0.1,0.1)])" + "cbar.set_ticks([t for t in np.arange(0, tran_max + 0.1, 0.1)])\n", + "cbar.set_ticklabels([\"{:.1f}\".format(t) for t in np.arange(0, tran_max + 0.1, 0.1)])" ] }, { diff --git a/python/examples/binary_grating_n2f.ipynb b/python/examples/binary_grating_n2f.ipynb index 771b5c682..892af4622 100644 --- a/python/examples/binary_grating_n2f.ipynb +++ b/python/examples/binary_grating_n2f.ipynb @@ -229,123 +229,190 @@ "from numpy import linalg as LA\n", "import matplotlib.pyplot as plt\n", "\n", - "resolution = 25 # pixels/μm\n", + "resolution = 25 # pixels/μm\n", "\n", - "dpml = 1.0 # PML thickness\n", - "dsub = 3.0 # substrate thickness\n", - "dpad = 3.0 # padding between grating and PML\n", - "gp = 10.0 # grating period\n", - "gh = 0.5 # grating height\n", - "gdc = 0.5 # grating duty cycle\n", + "dpml = 1.0 # PML thickness\n", + "dsub = 3.0 # substrate thickness\n", + "dpad = 3.0 # padding between grating and PML\n", + "gp = 10.0 # grating period\n", + "gh = 0.5 # grating height\n", + "gdc = 0.5 # grating duty cycle\n", "\n", - "nperiods = 10 # number of unit cells in finite periodic grating\n", + "nperiods = 10 # number of unit cells in finite periodic grating\n", "\n", - "ff_distance = 1e8 # far-field distance from near-field monitor\n", - "ff_angle = 20 # far-field cone angle\n", - "ff_npts = 500 # number of far-field points\n", + "ff_distance = 1e8 # far-field distance from near-field monitor\n", + "ff_angle = 20 # far-field cone angle\n", + "ff_npts = 500 # number of far-field points\n", "\n", - "ff_length = ff_distance*math.tan(math.radians(ff_angle))\n", - "ff_res = ff_npts/ff_length\n", + "ff_length = ff_distance * math.tan(math.radians(ff_angle))\n", + "ff_res = ff_npts / ff_length\n", "\n", - "sx = dpml+dsub+gh+dpad+dpml\n", + "sx = dpml + dsub + gh + dpad + dpml\n", "cell_size = mp.Vector3(sx)\n", "\n", - "pml_layers = [mp.PML(thickness=dpml,direction=mp.X)]\n", + "pml_layers = [mp.PML(thickness=dpml, direction=mp.X)]\n", "\n", "symmetries = [mp.Mirror(mp.Y)]\n", "\n", - "wvl_min = 0.4 # min wavelength\n", - "wvl_max = 0.6 # max wavelength\n", - "fmin = 1/wvl_max # min frequency\n", - "fmax = 1/wvl_min # max frequency\n", - "fcen = 0.5*(fmin+fmax) # center frequency\n", - "df = fmax-fmin # frequency width\n", + "wvl_min = 0.4 # min wavelength\n", + "wvl_max = 0.6 # max wavelength\n", + "fmin = 1 / wvl_max # min frequency\n", + "fmax = 1 / wvl_min # max frequency\n", + "fcen = 0.5 * (fmin + fmax) # center frequency\n", + "df = fmax - fmin # frequency width\n", "\n", - "src_pt = mp.Vector3(-0.5*sx+dpml+0.5*dsub)\n", - "sources = [mp.Source(mp.GaussianSource(fcen, fwidth=df), component=mp.Ez, center=src_pt)]\n", + "src_pt = mp.Vector3(-0.5 * sx + dpml + 0.5 * dsub)\n", + "sources = [\n", + " mp.Source(mp.GaussianSource(fcen, fwidth=df), component=mp.Ez, center=src_pt)\n", + "]\n", "\n", "k_point = mp.Vector3()\n", "\n", "glass = mp.Medium(index=1.5)\n", "\n", - "sim = mp.Simulation(resolution=resolution,\n", - " cell_size=cell_size,\n", - " boundary_layers=pml_layers,\n", - " k_point=k_point,\n", - " default_material=glass,\n", - " sources=sources)\n", + "sim = mp.Simulation(\n", + " resolution=resolution,\n", + " cell_size=cell_size,\n", + " boundary_layers=pml_layers,\n", + " k_point=k_point,\n", + " default_material=glass,\n", + " sources=sources,\n", + ")\n", "\n", "nfreq = 21\n", - "n2f_pt = mp.Vector3(0.5*sx-dpml-0.5*dpad)\n", + "n2f_pt = mp.Vector3(0.5 * sx - dpml - 0.5 * dpad)\n", "n2f_obj = sim.add_near2far(fcen, df, nfreq, mp.Near2FarRegion(center=n2f_pt))\n", "\n", "sim.run(until_after_sources=mp.stop_when_fields_decayed(50, mp.Ez, n2f_pt, 1e-9))\n", "\n", - "ff_source = sim.get_farfields(n2f_obj, ff_res, center=mp.Vector3(ff_distance,0.5*ff_length), size=mp.Vector3(y=ff_length))\n", + "ff_source = sim.get_farfields(\n", + " n2f_obj,\n", + " ff_res,\n", + " center=mp.Vector3(ff_distance, 0.5 * ff_length),\n", + " size=mp.Vector3(y=ff_length),\n", + ")\n", "\n", "sim.reset_meep()\n", "\n", "### unit cell with periodic boundaries\n", "\n", "sy = gp\n", - "cell_size = mp.Vector3(sx,sy)\n", - "\n", - "sources = [mp.Source(mp.GaussianSource(fcen, fwidth=df), component=mp.Ez, center=src_pt, size=mp.Vector3(y=sy))]\n", - "\n", - "geometry = [mp.Block(material=glass, size=mp.Vector3(dpml+dsub,mp.inf,mp.inf), center=mp.Vector3(-0.5*sx+0.5*(dpml+dsub))),\n", - " mp.Block(material=glass, size=mp.Vector3(gh,gdc*gp,mp.inf), center=mp.Vector3(-0.5*sx+dpml+dsub+0.5*gh))]\n", - "\n", - "sim = mp.Simulation(resolution=resolution,\n", - " split_chunks_evenly=True,\n", - " cell_size=cell_size,\n", - " boundary_layers=pml_layers,\n", - " geometry=geometry,\n", - " k_point=k_point,\n", - " sources=sources,\n", - " symmetries=symmetries)\n", - "\n", - "n2f_obj = sim.add_near2far(fcen, df, nfreq, mp.Near2FarRegion(center=n2f_pt, size=mp.Vector3(y=sy)), nperiods=nperiods)\n", + "cell_size = mp.Vector3(sx, sy)\n", + "\n", + "sources = [\n", + " mp.Source(\n", + " mp.GaussianSource(fcen, fwidth=df),\n", + " component=mp.Ez,\n", + " center=src_pt,\n", + " size=mp.Vector3(y=sy),\n", + " )\n", + "]\n", + "\n", + "geometry = [\n", + " mp.Block(\n", + " material=glass,\n", + " size=mp.Vector3(dpml + dsub, mp.inf, mp.inf),\n", + " center=mp.Vector3(-0.5 * sx + 0.5 * (dpml + dsub)),\n", + " ),\n", + " mp.Block(\n", + " material=glass,\n", + " size=mp.Vector3(gh, gdc * gp, mp.inf),\n", + " center=mp.Vector3(-0.5 * sx + dpml + dsub + 0.5 * gh),\n", + " ),\n", + "]\n", + "\n", + "sim = mp.Simulation(\n", + " resolution=resolution,\n", + " split_chunks_evenly=True,\n", + " cell_size=cell_size,\n", + " boundary_layers=pml_layers,\n", + " geometry=geometry,\n", + " k_point=k_point,\n", + " sources=sources,\n", + " symmetries=symmetries,\n", + ")\n", + "\n", + "n2f_obj = sim.add_near2far(\n", + " fcen,\n", + " df,\n", + " nfreq,\n", + " mp.Near2FarRegion(center=n2f_pt, size=mp.Vector3(y=sy)),\n", + " nperiods=nperiods,\n", + ")\n", "\n", "sim.run(until_after_sources=mp.stop_when_fields_decayed(50, mp.Ez, n2f_pt, 1e-9))\n", "\n", - "ff_unitcell = sim.get_farfields(n2f_obj, ff_res, center=mp.Vector3(ff_distance,0.5*ff_length), size=mp.Vector3(y=ff_length))\n", + "ff_unitcell = sim.get_farfields(\n", + " n2f_obj,\n", + " ff_res,\n", + " center=mp.Vector3(ff_distance, 0.5 * ff_length),\n", + " size=mp.Vector3(y=ff_length),\n", + ")\n", "\n", "sim.reset_meep()\n", "\n", "### finite periodic grating with flat surface termination extending into PML\n", "\n", - "num_cells = 2*nperiods+1\n", - "sy = dpml+num_cells*gp+dpml\n", - "cell_size = mp.Vector3(sx,sy)\n", + "num_cells = 2 * nperiods + 1\n", + "sy = dpml + num_cells * gp + dpml\n", + "cell_size = mp.Vector3(sx, sy)\n", "\n", "pml_layers = [mp.PML(thickness=dpml)]\n", "\n", - "sources = [mp.Source(mp.GaussianSource(fcen, fwidth=df), component=mp.Ez, center=src_pt, size=mp.Vector3(y=sy-2*dpml))]\n", - "\n", - "geometry = [mp.Block(material=glass, size=mp.Vector3(dpml+dsub,mp.inf,mp.inf), center=mp.Vector3(-0.5*sx+0.5*(dpml+dsub)))]\n", + "sources = [\n", + " mp.Source(\n", + " mp.GaussianSource(fcen, fwidth=df),\n", + " component=mp.Ez,\n", + " center=src_pt,\n", + " size=mp.Vector3(y=sy - 2 * dpml),\n", + " )\n", + "]\n", + "\n", + "geometry = [\n", + " mp.Block(\n", + " material=glass,\n", + " size=mp.Vector3(dpml + dsub, mp.inf, mp.inf),\n", + " center=mp.Vector3(-0.5 * sx + 0.5 * (dpml + dsub)),\n", + " )\n", + "]\n", "\n", "for j in range(num_cells):\n", - " geometry.append(mp.Block(material=glass,\n", - " size=mp.Vector3(gh,gdc*gp,mp.inf),\n", - " center=mp.Vector3(-0.5*sx+dpml+dsub+0.5*gh,-0.5*sy+dpml+(j+0.5)*gp)))\n", - "\n", - "sim = mp.Simulation(resolution=resolution,\n", - " split_chunks_evenly=True, \n", - " cell_size=cell_size,\n", - " boundary_layers=pml_layers,\n", - " geometry=geometry,\n", - " k_point=k_point,\n", - " sources=sources,\n", - " symmetries=symmetries)\n", - "\n", - "n2f_obj = sim.add_near2far(fcen, df, nfreq, mp.Near2FarRegion(center=n2f_pt, size=mp.Vector3(y=sy-2*dpml)))\n", + " geometry.append(\n", + " mp.Block(\n", + " material=glass,\n", + " size=mp.Vector3(gh, gdc * gp, mp.inf),\n", + " center=mp.Vector3(\n", + " -0.5 * sx + dpml + dsub + 0.5 * gh, -0.5 * sy + dpml + (j + 0.5) * gp\n", + " ),\n", + " )\n", + " )\n", + "\n", + "sim = mp.Simulation(\n", + " resolution=resolution,\n", + " split_chunks_evenly=True,\n", + " cell_size=cell_size,\n", + " boundary_layers=pml_layers,\n", + " geometry=geometry,\n", + " k_point=k_point,\n", + " sources=sources,\n", + " symmetries=symmetries,\n", + ")\n", + "\n", + "n2f_obj = sim.add_near2far(\n", + " fcen, df, nfreq, mp.Near2FarRegion(center=n2f_pt, size=mp.Vector3(y=sy - 2 * dpml))\n", + ")\n", "\n", "sim.run(until_after_sources=mp.stop_when_fields_decayed(50, mp.Ez, n2f_pt, 1e-9))\n", "\n", - "ff_supercell = sim.get_farfields(n2f_obj, ff_res, center=mp.Vector3(ff_distance,0.5*ff_length), size=mp.Vector3(y=ff_length))\n", + "ff_supercell = sim.get_farfields(\n", + " n2f_obj,\n", + " ff_res,\n", + " center=mp.Vector3(ff_distance, 0.5 * ff_length),\n", + " size=mp.Vector3(y=ff_length),\n", + ")\n", "\n", - "norm_err = LA.norm(ff_unitcell['Ez']-ff_supercell['Ez'])/nperiods\n", - "print(\"error:, {}, {}\".format(nperiods,norm_err))" + "norm_err = LA.norm(ff_unitcell[\"Ez\"] - ff_supercell[\"Ez\"]) / nperiods\n", + "print(\"error:, {}, {}\".format(nperiods, norm_err))" ] }, { @@ -375,35 +442,35 @@ ], "source": [ "freqs = mp.get_near2far_freqs(n2f_obj)\n", - "wvl = np.divide(1,freqs)\n", - "ff_lengths = np.linspace(0,ff_length,ff_npts)\n", - "angles = [math.degrees(math.atan(f)) for f in ff_lengths/ff_distance]\n", + "wvl = np.divide(1, freqs)\n", + "ff_lengths = np.linspace(0, ff_length, ff_npts)\n", + "angles = [math.degrees(math.atan(f)) for f in ff_lengths / ff_distance]\n", "\n", "wvl_slice = 0.5\n", - "idx_slice = np.where(np.asarray(freqs) == 1/wvl_slice)[0][0]\n", + "idx_slice = np.where(np.asarray(freqs) == 1 / wvl_slice)[0][0]\n", "\n", - "rel_enh = np.absolute(ff_unitcell['Ez'])**2/np.absolute(ff_source['Ez'])**2\n", + "rel_enh = np.absolute(ff_unitcell[\"Ez\"]) ** 2 / np.absolute(ff_source[\"Ez\"]) ** 2\n", "\n", "plt.figure(dpi=150)\n", "\n", - "plt.subplot(1,2,1)\n", - "plt.pcolormesh(wvl,angles,rel_enh,cmap='Blues',shading='flat')\n", - "plt.axis([wvl_min,wvl_max,0,ff_angle])\n", + "plt.subplot(1, 2, 1)\n", + "plt.pcolormesh(wvl, angles, rel_enh, cmap=\"Blues\", shading=\"flat\")\n", + "plt.axis([wvl_min, wvl_max, 0, ff_angle])\n", "plt.xlabel(\"wavelength (μm)\")\n", "plt.ylabel(\"angle (degrees)\")\n", - "plt.grid(linewidth=0.5,linestyle='--')\n", - "plt.xticks([t for t in np.arange(wvl_min,wvl_max+0.1,0.1)])\n", - "plt.yticks([t for t in range(0,ff_angle+1,10)])\n", + "plt.grid(linewidth=0.5, linestyle=\"--\")\n", + "plt.xticks([t for t in np.arange(wvl_min, wvl_max + 0.1, 0.1)])\n", + "plt.yticks([t for t in range(0, ff_angle + 1, 10)])\n", "plt.title(\"far-field spectra\")\n", "\n", - "plt.subplot(1,2,2)\n", - "plt.plot(angles,rel_enh[:,idx_slice],'bo-')\n", - "plt.xlim(0,ff_angle)\n", + "plt.subplot(1, 2, 2)\n", + "plt.plot(angles, rel_enh[:, idx_slice], \"bo-\")\n", + "plt.xlim(0, ff_angle)\n", "plt.ylim(0)\n", - "plt.xticks([t for t in range(0,ff_angle+1,10)])\n", + "plt.xticks([t for t in range(0, ff_angle + 1, 10)])\n", "plt.xlabel(\"angle (degrees)\")\n", "plt.ylabel(\"relative enhancement\")\n", - "plt.grid(axis='x',linewidth=0.5,linestyle='--')\n", + "plt.grid(axis=\"x\", linewidth=0.5, linestyle=\"--\")\n", "plt.title(\"f.-f. spectra @ λ = {:.1} μm\".format(wvl_slice))\n", "\n", "plt.tight_layout(pad=0.5)\n", diff --git a/python/examples/binary_grating_oblique.ipynb b/python/examples/binary_grating_oblique.ipynb index 494b44cb5..8454e37f7 100644 --- a/python/examples/binary_grating_oblique.ipynb +++ b/python/examples/binary_grating_oblique.ipynb @@ -61,20 +61,20 @@ "metadata": {}, "outputs": [], "source": [ - "resolution = 50 # pixels/μm\n", + "resolution = 50 # pixels/μm\n", "\n", - "dpml = 1.0 # PML thickness\n", - "dsub = 3.0 # substrate thickness\n", - "dpad = 3.0 # length of padding between grating and PML\n", - "gp = 10.0 # grating period\n", - "gh = 0.5 # grating height\n", - "gdc = 0.5 # grating duty cycle\n", + "dpml = 1.0 # PML thickness\n", + "dsub = 3.0 # substrate thickness\n", + "dpad = 3.0 # length of padding between grating and PML\n", + "gp = 10.0 # grating period\n", + "gh = 0.5 # grating height\n", + "gdc = 0.5 # grating duty cycle\n", "\n", - "sx = dpml+dsub+gh+dpad+dpml\n", + "sx = dpml + dsub + gh + dpad + dpml\n", "sy = gp\n", "\n", - "cell_size = mp.Vector3(sx,sy,0)\n", - "pml_layers = [mp.PML(thickness=dpml,direction=mp.X)] " + "cell_size = mp.Vector3(sx, sy, 0)\n", + "pml_layers = [mp.PML(thickness=dpml, direction=mp.X)]" ] }, { @@ -93,34 +93,41 @@ "ng = 1.5\n", "glass = mp.Medium(index=ng)\n", "\n", - "wvl = 0.5 # center wavelength\n", - "fcen = 1/wvl # center frequency\n", - "df = 0.05*fcen # frequency width\n", + "wvl = 0.5 # center wavelength\n", + "fcen = 1 / wvl # center frequency\n", + "df = 0.05 * fcen # frequency width\n", "\n", "# rotation angle of incident planewave; counter clockwise (CCW) about Z axis, 0 degrees along +X axis\n", "theta_in = math.radians(10.7)\n", "\n", "# k (in source medium) with correct length (plane of incidence: XY)\n", - "k = mp.Vector3(fcen*ng).rotate(mp.Vector3(z=1), theta_in)\n", + "k = mp.Vector3(fcen * ng).rotate(mp.Vector3(z=1), theta_in)\n", "\n", "symmetries = []\n", "eig_parity = mp.ODD_Z\n", "if theta_in == 0:\n", - " k = mp.Vector3(0,0,0)\n", - " symmetries = [mp.Mirror(mp.Y)]\n", - " eig_parity += mp.EVEN_Y\n", + " k = mp.Vector3(0, 0, 0)\n", + " symmetries = [mp.Mirror(mp.Y)]\n", + " eig_parity += mp.EVEN_Y\n", "\n", - "def pw_amp(k,x0):\n", - " def _pw_amp(x):\n", - " return cmath.exp(1j*2*math.pi*k.dot(x+x0))\n", - " return _pw_amp\n", "\n", - "src_pt = mp.Vector3(-0.5*sx+dpml+0.3*dsub,0,0)\n", - "sources = [mp.Source(mp.GaussianSource(fcen,fwidth=df),\n", - " component=mp.Ez,\n", - " center=src_pt,\n", - " size=mp.Vector3(0,sy,0),\n", - " amp_func=pw_amp(k,src_pt))]" + "def pw_amp(k, x0):\n", + " def _pw_amp(x):\n", + " return cmath.exp(1j * 2 * math.pi * k.dot(x + x0))\n", + "\n", + " return _pw_amp\n", + "\n", + "\n", + "src_pt = mp.Vector3(-0.5 * sx + dpml + 0.3 * dsub, 0, 0)\n", + "sources = [\n", + " mp.Source(\n", + " mp.GaussianSource(fcen, fwidth=df),\n", + " component=mp.Ez,\n", + " center=src_pt,\n", + " size=mp.Vector3(0, sy, 0),\n", + " amp_func=pw_amp(k, src_pt),\n", + " )\n", + "]" ] }, { @@ -136,16 +143,20 @@ "metadata": {}, "outputs": [], "source": [ - "sim = mp.Simulation(resolution=resolution,\n", - " cell_size=cell_size,\n", - " boundary_layers=pml_layers,\n", - " k_point=k,\n", - " default_material=glass,\n", - " sources=sources,\n", - " symmetries=symmetries)\n", + "sim = mp.Simulation(\n", + " resolution=resolution,\n", + " cell_size=cell_size,\n", + " boundary_layers=pml_layers,\n", + " k_point=k,\n", + " default_material=glass,\n", + " sources=sources,\n", + " symmetries=symmetries,\n", + ")\n", "\n", - "refl_pt = mp.Vector3(-0.5*sx+dpml+0.5*dsub,0,0)\n", - "refl_flux = sim.add_flux(fcen, 0, 1, mp.FluxRegion(center=refl_pt, size=mp.Vector3(0,sy,0)))" + "refl_pt = mp.Vector3(-0.5 * sx + dpml + 0.5 * dsub, 0, 0)\n", + "refl_flux = sim.add_flux(\n", + " fcen, 0, 1, mp.FluxRegion(center=refl_pt, size=mp.Vector3(0, sy, 0))\n", + ")" ] }, { @@ -229,22 +240,38 @@ "source": [ "sim.reset_meep()\n", "\n", - "geometry = [mp.Block(material=glass, size=mp.Vector3(dpml+dsub,mp.inf,mp.inf), center=mp.Vector3(-0.5*sx+0.5*(dpml+dsub),0,0)),\n", - " mp.Block(material=glass, size=mp.Vector3(gh,gdc*gp,mp.inf), center=mp.Vector3(-0.5*sx+dpml+dsub+0.5*gh,0,0))]\n", + "geometry = [\n", + " mp.Block(\n", + " material=glass,\n", + " size=mp.Vector3(dpml + dsub, mp.inf, mp.inf),\n", + " center=mp.Vector3(-0.5 * sx + 0.5 * (dpml + dsub), 0, 0),\n", + " ),\n", + " mp.Block(\n", + " material=glass,\n", + " size=mp.Vector3(gh, gdc * gp, mp.inf),\n", + " center=mp.Vector3(-0.5 * sx + dpml + dsub + 0.5 * gh, 0, 0),\n", + " ),\n", + "]\n", "\n", - "sim = mp.Simulation(resolution=resolution,\n", - " cell_size=cell_size,\n", - " boundary_layers=pml_layers,\n", - " geometry=geometry,\n", - " k_point=k,\n", - " sources=sources,\n", - " symmetries=symmetries)\n", + "sim = mp.Simulation(\n", + " resolution=resolution,\n", + " cell_size=cell_size,\n", + " boundary_layers=pml_layers,\n", + " geometry=geometry,\n", + " k_point=k,\n", + " sources=sources,\n", + " symmetries=symmetries,\n", + ")\n", "\n", - "refl_flux = sim.add_flux(fcen, 0, 1, mp.FluxRegion(center=refl_pt, size=mp.Vector3(0,sy,0)))\n", - "sim.load_minus_flux_data(refl_flux,input_flux_data)\n", + "refl_flux = sim.add_flux(\n", + " fcen, 0, 1, mp.FluxRegion(center=refl_pt, size=mp.Vector3(0, sy, 0))\n", + ")\n", + "sim.load_minus_flux_data(refl_flux, input_flux_data)\n", "\n", - "tran_pt = mp.Vector3(0.5*sx-dpml-0.5*dpad,0,0)\n", - "tran_flux = sim.add_flux(fcen, 0, 1, mp.FluxRegion(center=tran_pt, size=mp.Vector3(0,sy,0)))" + "tran_pt = mp.Vector3(0.5 * sx - dpml - 0.5 * dpad, 0, 0)\n", + "tran_flux = sim.add_flux(\n", + " fcen, 0, 1, mp.FluxRegion(center=tran_pt, size=mp.Vector3(0, sy, 0))\n", + ")" ] }, { @@ -345,23 +372,31 @@ ], "source": [ "# Calculate the number of reflected orders\n", - "nm_r = np.floor((fcen*ng-k.y)*gp)-np.ceil((-fcen*ng-k.y)*gp) # number of reflected orders\n", + "nm_r = np.floor((fcen * ng - k.y) * gp) - np.ceil(\n", + " (-fcen * ng - k.y) * gp\n", + ") # number of reflected orders\n", "if theta_in == 0:\n", - " nm_r = nm_r/2 # since eig_parity removes degeneracy in y-direction\n", + " nm_r = nm_r / 2 # since eig_parity removes degeneracy in y-direction\n", "nm_r = int(nm_r)\n", "\n", "# Extract the coefficients for the reflected orders\n", - "res = sim.get_eigenmode_coefficients(refl_flux, range(1,nm_r+1), eig_parity=eig_parity)\n", + "res = sim.get_eigenmode_coefficients(\n", + " refl_flux, range(1, nm_r + 1), eig_parity=eig_parity\n", + ")\n", "r_coeffs = res.alpha\n", "\n", "# Calculate the number of transmitted orders\n", - "nm_t = np.floor((fcen-k.y)*gp)-np.ceil((-fcen-k.y)*gp) # number of transmitted orders\n", + "nm_t = np.floor((fcen - k.y) * gp) - np.ceil(\n", + " (-fcen - k.y) * gp\n", + ") # number of transmitted orders\n", "if theta_in == 0:\n", - " nm_t = nm_t/2 # since eig_parity removes degeneracy in y-direction\n", + " nm_t = nm_t / 2 # since eig_parity removes degeneracy in y-direction\n", "nm_t = int(nm_t)\n", "\n", "# Extract the coefficients for the transmitted orders\n", - "res = sim.get_eigenmode_coefficients(tran_flux, range(1,nm_t+1), eig_parity=eig_parity)\n", + "res = sim.get_eigenmode_coefficients(\n", + " tran_flux, range(1, nm_t + 1), eig_parity=eig_parity\n", + ")\n", "t_coeffs = res.alpha" ] }, @@ -391,20 +426,30 @@ } ], "source": [ - "r_angle = np.squeeze([math.degrees(np.sign(r_kdom.y)*math.acos(r_kdom.x/(ng*fcen))) for r_kdom in res.kdom])\n", - "Rmode = abs(r_coeffs[:,0,1])**2/input_flux[0]\n", + "r_angle = np.squeeze(\n", + " [\n", + " math.degrees(np.sign(r_kdom.y) * math.acos(r_kdom.x / (ng * fcen)))\n", + " for r_kdom in res.kdom\n", + " ]\n", + ")\n", + "Rmode = abs(r_coeffs[:, 0, 1]) ** 2 / input_flux[0]\n", "idx_r = np.argsort(r_angle)\n", "\n", - "t_angle = np.squeeze([math.degrees(np.sign(t_kdom.y)*math.acos(t_kdom.x/fcen)) for t_kdom in res.kdom])\n", - "Tmode = abs(t_coeffs[:,0,0])**2/input_flux[0]\n", + "t_angle = np.squeeze(\n", + " [\n", + " math.degrees(np.sign(t_kdom.y) * math.acos(t_kdom.x / fcen))\n", + " for t_kdom in res.kdom\n", + " ]\n", + ")\n", + "Tmode = abs(t_coeffs[:, 0, 0]) ** 2 / input_flux[0]\n", "idx_t = np.argsort(t_angle)\n", "\n", "plt.figure(dpi=150)\n", - "plt.plot(r_angle[idx_r],Rmode[idx_r], 'o-',color='blue',label='Reflection')\n", - "plt.plot(t_angle[idx_t],Tmode[idx_t], 'o-',color='red',label='Transmission')\n", + "plt.plot(r_angle[idx_r], Rmode[idx_r], \"o-\", color=\"blue\", label=\"Reflection\")\n", + "plt.plot(t_angle[idx_t], Tmode[idx_t], \"o-\", color=\"red\", label=\"Transmission\")\n", "plt.grid(True)\n", - "plt.xlabel('Diffraction Angle (degrees)')\n", - "plt.ylabel('Relative Power (au)')\n", + "plt.xlabel(\"Diffraction Angle (degrees)\")\n", + "plt.ylabel(\"Relative Power (au)\")\n", "plt.legend()\n", "plt.show()" ] @@ -431,12 +476,16 @@ } ], "source": [ - "print(\"mode-coeff:, {:.6f}, {:.6f}, {:.6f}\".format(np.sum(Rmode),np.sum(Tmode),np.sum(Rmode)+np.sum(Tmode)))\n", + "print(\n", + " \"mode-coeff:, {:.6f}, {:.6f}, {:.6f}\".format(\n", + " np.sum(Rmode), np.sum(Tmode), np.sum(Rmode) + np.sum(Tmode)\n", + " )\n", + ")\n", "r_flux = mp.get_fluxes(refl_flux)\n", "t_flux = mp.get_fluxes(tran_flux)\n", - "Rflux = -r_flux[0]/input_flux[0]\n", - "Tflux = t_flux[0]/input_flux[0]\n", - "print(\"poynting-flux:, {:.6f}, {:.6f}, {:.6f}\".format(Rflux,Tflux,Rflux+Tflux))" + "Rflux = -r_flux[0] / input_flux[0]\n", + "Tflux = t_flux[0] / input_flux[0]\n", + "print(\"poynting-flux:, {:.6f}, {:.6f}, {:.6f}\".format(Rflux, Tflux, Rflux + Tflux))" ] } ], diff --git a/python/examples/binary_grating_phasemap.ipynb b/python/examples/binary_grating_phasemap.ipynb index f160cb571..295e97635 100644 --- a/python/examples/binary_grating_phasemap.ipynb +++ b/python/examples/binary_grating_phasemap.ipynb @@ -756,85 +756,114 @@ "import numpy.matlib\n", "import matplotlib.pyplot as plt\n", "\n", - "resolution = 50 # pixels/μm\n", + "resolution = 50 # pixels/μm\n", "\n", - "dpml = 1.0 # PML thickness\n", - "dsub = 3.0 # substrate thickness\n", - "dpad = 3.0 # padding between grating and PML\n", + "dpml = 1.0 # PML thickness\n", + "dsub = 3.0 # substrate thickness\n", + "dpad = 3.0 # padding between grating and PML\n", "\n", - "wvl_min = 0.4 # min wavelength\n", - "wvl_max = 0.6 # max wavelength\n", - "fmin = 1/wvl_max # min frequency\n", - "fmax = 1/wvl_min # max frequency\n", - "fcen = 0.5*(fmin+fmax) # center frequency\n", - "df = fmax-fmin # frequency width\n", - "nfreq = 21 # number of frequency bins\n", + "wvl_min = 0.4 # min wavelength\n", + "wvl_max = 0.6 # max wavelength\n", + "fmin = 1 / wvl_max # min frequency\n", + "fmax = 1 / wvl_min # max frequency\n", + "fcen = 0.5 * (fmin + fmax) # center frequency\n", + "df = fmax - fmin # frequency width\n", + "nfreq = 21 # number of frequency bins\n", "\n", - "k_point = mp.Vector3(0,0,0)\n", + "k_point = mp.Vector3(0, 0, 0)\n", "\n", "glass = mp.Medium(index=1.5)\n", "\n", - "def grating(gp,gh,gdc,oddz):\n", - " sx = dpml+dsub+gh+dpad+dpml\n", - " sy = gp\n", "\n", - " cell_size = mp.Vector3(sx,sy,0)\n", - " pml_layers = [mp.PML(thickness=dpml,direction=mp.X)]\n", + "def grating(gp, gh, gdc, oddz):\n", + " sx = dpml + dsub + gh + dpad + dpml\n", + " sy = gp\n", "\n", - " src_pt = mp.Vector3(-0.5*sx+dpml+0.5*dsub,0,0)\n", - " sources = [mp.Source(mp.GaussianSource(fcen, fwidth=df), component=mp.Ez if oddz else mp.Hz, center=src_pt, size=mp.Vector3(0,sy,0))]\n", + " cell_size = mp.Vector3(sx, sy, 0)\n", + " pml_layers = [mp.PML(thickness=dpml, direction=mp.X)]\n", "\n", - " symmetries=[mp.Mirror(mp.Y, phase=+1 if oddz else -1)]\n", - " \n", - " sim = mp.Simulation(resolution=resolution,\n", - " cell_size=cell_size,\n", - " boundary_layers=pml_layers,\n", - " k_point=k_point,\n", - " default_material=glass,\n", - " sources=sources,\n", - " symmetries=symmetries)\n", + " src_pt = mp.Vector3(-0.5 * sx + dpml + 0.5 * dsub, 0, 0)\n", + " sources = [\n", + " mp.Source(\n", + " mp.GaussianSource(fcen, fwidth=df),\n", + " component=mp.Ez if oddz else mp.Hz,\n", + " center=src_pt,\n", + " size=mp.Vector3(0, sy, 0),\n", + " )\n", + " ]\n", "\n", - " mon_pt = mp.Vector3(0.5*sx-dpml-0.5*dpad,0,0)\n", - " flux_mon = sim.add_flux(fcen, df, nfreq, mp.FluxRegion(center=mon_pt, size=mp.Vector3(0,sy,0)))\n", + " symmetries = [mp.Mirror(mp.Y, phase=+1 if oddz else -1)]\n", "\n", - " sim.run(until_after_sources=100)\n", + " sim = mp.Simulation(\n", + " resolution=resolution,\n", + " cell_size=cell_size,\n", + " boundary_layers=pml_layers,\n", + " k_point=k_point,\n", + " default_material=glass,\n", + " sources=sources,\n", + " symmetries=symmetries,\n", + " )\n", "\n", - " input_flux = mp.get_fluxes(flux_mon)\n", + " mon_pt = mp.Vector3(0.5 * sx - dpml - 0.5 * dpad, 0, 0)\n", + " flux_mon = sim.add_flux(\n", + " fcen, df, nfreq, mp.FluxRegion(center=mon_pt, size=mp.Vector3(0, sy, 0))\n", + " )\n", "\n", - " sim.reset_meep()\n", + " sim.run(until_after_sources=100)\n", "\n", - " geometry = [mp.Block(material=glass, size=mp.Vector3(dpml+dsub,mp.inf,mp.inf), center=mp.Vector3(-0.5*sx+0.5*(dpml+dsub),0,0)),\n", - " mp.Block(material=glass, size=mp.Vector3(gh,gdc*gp,mp.inf), center=mp.Vector3(-0.5*sx+dpml+dsub+0.5*gh,0,0))]\n", + " input_flux = mp.get_fluxes(flux_mon)\n", "\n", - " sim = mp.Simulation(resolution=resolution,\n", - " cell_size=cell_size,\n", - " boundary_layers=pml_layers,\n", - " geometry=geometry,\n", - " k_point=k_point,\n", - " sources=sources,\n", - " symmetries=symmetries)\n", + " sim.reset_meep()\n", "\n", - " mode_mon = sim.add_flux(fcen, df, nfreq, mp.FluxRegion(center=mon_pt, size=mp.Vector3(0,sy,0)))\n", + " geometry = [\n", + " mp.Block(\n", + " material=glass,\n", + " size=mp.Vector3(dpml + dsub, mp.inf, mp.inf),\n", + " center=mp.Vector3(-0.5 * sx + 0.5 * (dpml + dsub), 0, 0),\n", + " ),\n", + " mp.Block(\n", + " material=glass,\n", + " size=mp.Vector3(gh, gdc * gp, mp.inf),\n", + " center=mp.Vector3(-0.5 * sx + dpml + dsub + 0.5 * gh, 0, 0),\n", + " ),\n", + " ]\n", "\n", - " sim.run(until_after_sources=300)\n", + " sim = mp.Simulation(\n", + " resolution=resolution,\n", + " cell_size=cell_size,\n", + " boundary_layers=pml_layers,\n", + " geometry=geometry,\n", + " k_point=k_point,\n", + " sources=sources,\n", + " symmetries=symmetries,\n", + " )\n", "\n", - " freqs = mp.get_eigenmode_freqs(mode_mon)\n", - " res = sim.get_eigenmode_coefficients(mode_mon, [1], eig_parity=mp.ODD_Z+mp.EVEN_Y if oddz else mp.EVEN_Z+mp.ODD_Y)\n", - " coeffs = res.alpha\n", + " mode_mon = sim.add_flux(\n", + " fcen, df, nfreq, mp.FluxRegion(center=mon_pt, size=mp.Vector3(0, sy, 0))\n", + " )\n", "\n", - " mode_wvl = [1/freqs[nf] for nf in range(nfreq)]\n", - " mode_tran = [abs(coeffs[0,nf,0])**2/input_flux[nf] for nf in range(nfreq)]\n", - " mode_phase = [np.angle(coeffs[0,nf,0]) for nf in range(nfreq)]\n", + " sim.run(until_after_sources=300)\n", + "\n", + " freqs = mp.get_eigenmode_freqs(mode_mon)\n", + " res = sim.get_eigenmode_coefficients(\n", + " mode_mon, [1], eig_parity=mp.ODD_Z + mp.EVEN_Y if oddz else mp.EVEN_Z + mp.ODD_Y\n", + " )\n", + " coeffs = res.alpha\n", + "\n", + " mode_wvl = [1 / freqs[nf] for nf in range(nfreq)]\n", + " mode_tran = [abs(coeffs[0, nf, 0]) ** 2 / input_flux[nf] for nf in range(nfreq)]\n", + " mode_phase = [np.angle(coeffs[0, nf, 0]) for nf in range(nfreq)]\n", + "\n", + " return mode_wvl, mode_tran, mode_phase\n", "\n", - " return mode_wvl, mode_tran, mode_phase\n", "\n", "gp = 0.35\n", - "gh = 0.6 \n", - "gdc = np.linspace(0.1,1.0,10)\n", - "mode_tran = np.empty((gdc.size,nfreq))\n", - "mode_phase = np.empty((gdc.size,nfreq))\n", + "gh = 0.6\n", + "gdc = np.linspace(0.1, 1.0, 10)\n", + "mode_tran = np.empty((gdc.size, nfreq))\n", + "mode_phase = np.empty((gdc.size, nfreq))\n", "for n in range(gdc.size):\n", - " mode_wvl, mode_tran[n,:], mode_phase[n,:] = grating(gp,gh,gdc[n],True)" + " mode_wvl, mode_tran[n, :], mode_phase[n, :] = grating(gp, gh, gdc[n], True)" ] }, { @@ -866,29 +895,45 @@ ], "source": [ "plt.figure(dpi=150)\n", - "plt.subplot(1,2,1)\n", - "plt.pcolormesh(mode_wvl, gdc, mode_tran, cmap='hot_r', shading='gouraud', vmin=0, vmax=mode_tran.max())\n", + "plt.subplot(1, 2, 1)\n", + "plt.pcolormesh(\n", + " mode_wvl,\n", + " gdc,\n", + " mode_tran,\n", + " cmap=\"hot_r\",\n", + " shading=\"gouraud\",\n", + " vmin=0,\n", + " vmax=mode_tran.max(),\n", + ")\n", "plt.axis([wvl_min, wvl_max, gdc[0], gdc[-1]])\n", "plt.xlabel(\"wavelength (μm)\")\n", - "plt.xticks([t for t in np.linspace(wvl_min,wvl_max,3)])\n", + "plt.xticks([t for t in np.linspace(wvl_min, wvl_max, 3)])\n", "plt.ylabel(\"grating duty cycle\")\n", - "plt.yticks([t for t in np.arange(gdc[0],gdc[-1]+0.1,0.1)])\n", + "plt.yticks([t for t in np.arange(gdc[0], gdc[-1] + 0.1, 0.1)])\n", "plt.title(\"transmittance\")\n", "cbar = plt.colorbar()\n", - "cbar.set_ticks([t for t in np.arange(0,1.2,0.2)])\n", - "cbar.set_ticklabels([\"{:.1f}\".format(t) for t in np.linspace(0,1,6)])\n", + "cbar.set_ticks([t for t in np.arange(0, 1.2, 0.2)])\n", + "cbar.set_ticklabels([\"{:.1f}\".format(t) for t in np.linspace(0, 1, 6)])\n", "\n", - "plt.subplot(1,2,2)\n", - "plt.pcolormesh(mode_wvl, gdc, mode_phase, cmap='RdBu', shading='gouraud', vmin=mode_phase.min(), vmax=mode_phase.max())\n", + "plt.subplot(1, 2, 2)\n", + "plt.pcolormesh(\n", + " mode_wvl,\n", + " gdc,\n", + " mode_phase,\n", + " cmap=\"RdBu\",\n", + " shading=\"gouraud\",\n", + " vmin=mode_phase.min(),\n", + " vmax=mode_phase.max(),\n", + ")\n", "plt.axis([wvl_min, wvl_max, gdc[0], gdc[-1]])\n", "plt.xlabel(\"wavelength (μm)\")\n", - "plt.xticks([t for t in np.linspace(wvl_min,wvl_max,3)])\n", + "plt.xticks([t for t in np.linspace(wvl_min, wvl_max, 3)])\n", "plt.ylabel(\"grating duty cycle\")\n", - "plt.yticks([t for t in np.arange(gdc[0],gdc[-1]+0.1,0.1)])\n", + "plt.yticks([t for t in np.arange(gdc[0], gdc[-1] + 0.1, 0.1)])\n", "plt.title(\"phase (radians)\")\n", "cbar = plt.colorbar()\n", - "cbar.set_ticks([t for t in range(-3,4)])\n", - "cbar.set_ticklabels([\"{:.1f}\".format(t) for t in range(-3,4)])\n", + "cbar.set_ticks([t for t in range(-3, 4)])\n", + "cbar.set_ticklabels([\"{:.1f}\".format(t) for t in range(-3, 4)])\n", "\n", "plt.subplots_adjust(wspace=0.5)" ] diff --git a/python/examples/cavity-farfield.ipynb b/python/examples/cavity-farfield.ipynb index 08ea67ee1..2314b9090 100644 --- a/python/examples/cavity-farfield.ipynb +++ b/python/examples/cavity-farfield.ipynb @@ -178,53 +178,74 @@ "import numpy as np\n", "import matplotlib.pyplot as plt\n", "\n", - "resolution = 20 # pixels/μm\n", + "resolution = 20 # pixels/μm\n", "\n", - "eps = 13 # dielectric constant of waveguide\n", - "w = 1.2 # width of waveguide\n", - "r = 0.36 # radius of holes\n", - "d = 1.4 # defect spacing (ordinary spacing = 1)\n", - "N = 3 # number of holes on either side of defect\n", + "eps = 13 # dielectric constant of waveguide\n", + "w = 1.2 # width of waveguide\n", + "r = 0.36 # radius of holes\n", + "d = 1.4 # defect spacing (ordinary spacing = 1)\n", + "N = 3 # number of holes on either side of defect\n", "\n", - "sy = 6 # size of cell in y direction (perpendicular to wvg.)\n", - "pad = 2 # padding between last hole and PML edge\n", - "dpml = 1 # PML thickness\n", - "sx = 2*(pad+dpml+N)+d-1 # size of cell in x direction\n", + "sy = 6 # size of cell in y direction (perpendicular to wvg.)\n", + "pad = 2 # padding between last hole and PML edge\n", + "dpml = 1 # PML thickness\n", + "sx = 2 * (pad + dpml + N) + d - 1 # size of cell in x direction\n", "\n", "cell = mp.Vector3(sx, sy, 0)\n", "pml_layers = mp.PML(dpml)\n", "\n", - "geometry = [mp.Block(center=mp.Vector3(),\n", - " size=mp.Vector3(mp.inf, w, mp.inf),\n", - " material=mp.Medium(epsilon=eps))]\n", + "geometry = [\n", + " mp.Block(\n", + " center=mp.Vector3(),\n", + " size=mp.Vector3(mp.inf, w, mp.inf),\n", + " material=mp.Medium(epsilon=eps),\n", + " )\n", + "]\n", "\n", "for i in range(N):\n", - " geometry.append(mp.Cylinder(r, center=mp.Vector3(0.5*d+i)))\n", - " geometry.append(mp.Cylinder(r, center=mp.Vector3(-0.5*d-i)))\n", + " geometry.append(mp.Cylinder(r, center=mp.Vector3(0.5 * d + i)))\n", + " geometry.append(mp.Cylinder(r, center=mp.Vector3(-0.5 * d - i)))\n", "\n", - "fcen = 0.25 # pulse center frequency\n", - "df = 0.2 # pulse width (in frequency)\n", + "fcen = 0.25 # pulse center frequency\n", + "df = 0.2 # pulse width (in frequency)\n", "\n", - "sources = mp.Source(src=mp.GaussianSource(fcen, fwidth=df), component=mp.Hz, center=mp.Vector3())\n", + "sources = mp.Source(\n", + " src=mp.GaussianSource(fcen, fwidth=df), component=mp.Hz, center=mp.Vector3()\n", + ")\n", "\n", - "symmetries = [mp.Mirror(mp.X, phase=-1),\n", - " mp.Mirror(mp.Y, phase=-1)]\n", + "symmetries = [mp.Mirror(mp.X, phase=-1), mp.Mirror(mp.Y, phase=-1)]\n", "\n", - "sim = mp.Simulation(cell_size=cell,\n", - " geometry=geometry,\n", - " sources=[sources],\n", - " symmetries=symmetries,\n", - " boundary_layers=[pml_layers],\n", - " resolution=resolution)\n", + "sim = mp.Simulation(\n", + " cell_size=cell,\n", + " geometry=geometry,\n", + " sources=[sources],\n", + " symmetries=symmetries,\n", + " boundary_layers=[pml_layers],\n", + " resolution=resolution,\n", + ")\n", "\n", "d1 = 0.2\n", "\n", - "nearfield = sim.add_near2far(fcen, 0, 1,\n", - " mp.Near2FarRegion(mp.Vector3(y=0.5*w+d1), size=mp.Vector3(sx-2*dpml)),\n", - " mp.Near2FarRegion(mp.Vector3(-0.5*sx+dpml,0.5*w+0.5*d1), size=mp.Vector3(y=d1), weight=-1.0),\n", - " mp.Near2FarRegion(mp.Vector3(0.5*sx-dpml,0.5*w+0.5*d1), size=mp.Vector3(y=d1)))\n", + "nearfield = sim.add_near2far(\n", + " fcen,\n", + " 0,\n", + " 1,\n", + " mp.Near2FarRegion(mp.Vector3(y=0.5 * w + d1), size=mp.Vector3(sx - 2 * dpml)),\n", + " mp.Near2FarRegion(\n", + " mp.Vector3(-0.5 * sx + dpml, 0.5 * w + 0.5 * d1),\n", + " size=mp.Vector3(y=d1),\n", + " weight=-1.0,\n", + " ),\n", + " mp.Near2FarRegion(\n", + " mp.Vector3(0.5 * sx - dpml, 0.5 * w + 0.5 * d1), size=mp.Vector3(y=d1)\n", + " ),\n", + ")\n", "\n", - "sim.run(until_after_sources=mp.stop_when_fields_decayed(50, mp.Hz, mp.Vector3(0.12,-0.37), 1e-8))" + "sim.run(\n", + " until_after_sources=mp.stop_when_fields_decayed(\n", + " 50, mp.Hz, mp.Vector3(0.12, -0.37), 1e-8\n", + " )\n", + ")" ] }, { @@ -259,11 +280,16 @@ "d2 = 20\n", "h = 4\n", "\n", - "ff = sim.get_farfields(nearfield, resolution, center=mp.Vector3(y=0.5*w+d2+0.5*h), size=mp.Vector3(sx-2*dpml,h))\n", + "ff = sim.get_farfields(\n", + " nearfield,\n", + " resolution,\n", + " center=mp.Vector3(y=0.5 * w + d2 + 0.5 * h),\n", + " size=mp.Vector3(sx - 2 * dpml, h),\n", + ")\n", "\n", "plt.figure(dpi=200)\n", - "plt.imshow(np.rot90(np.real(ff['Hz']),1),cmap='RdBu')\n", - "plt.axis('off')" + "plt.imshow(np.rot90(np.real(ff[\"Hz\"]), 1), cmap=\"RdBu\")\n", + "plt.axis(\"off\")" ] } ], diff --git a/python/examples/coupler.ipynb b/python/examples/coupler.ipynb index 8e4df35df..47de7645e 100644 --- a/python/examples/coupler.ipynb +++ b/python/examples/coupler.ipynb @@ -878,11 +878,11 @@ "import numpy\n", "import matplotlib.pyplot as plt\n", "\n", - "res = 25 # pixels/μm\n", - "three_d = False # 3d calculation?\n", - "d = 0.12 # branch separation\n", + "res = 25 # pixels/μm\n", + "three_d = False # 3d calculation?\n", + "d = 0.12 # branch separation\n", "\n", - "gdsII_file = 'coupler.gds'\n", + "gdsII_file = \"coupler.gds\"\n", "CELL_LAYER = 0\n", "PORT1_LAYER = 1\n", "PORT2_LAYER = 2\n", @@ -898,24 +898,28 @@ "t_air = 0.78\n", "\n", "dpml = 1\n", - "cell_thickness = dpml+t_oxide+t_Si+t_air+dpml\n", + "cell_thickness = dpml + t_oxide + t_Si + t_air + dpml\n", "\n", "oxide = mp.Medium(epsilon=2.25)\n", - "silicon=mp.Medium(epsilon=12)\n", + "silicon = mp.Medium(epsilon=12)\n", "\n", "lcen = 1.55\n", - "fcen = 1/lcen\n", - "df = 0.2*fcen\n", + "fcen = 1 / lcen\n", + "df = 0.2 * fcen\n", "\n", - "cell_zmax = 0.5*cell_thickness if three_d else 0\n", - "cell_zmin = -0.5*cell_thickness if three_d else 0\n", - "si_zmax = 0.5*t_Si if three_d else 10\n", - "si_zmin = -0.5*t_Si if three_d else -10\n", + "cell_zmax = 0.5 * cell_thickness if three_d else 0\n", + "cell_zmin = -0.5 * cell_thickness if three_d else 0\n", + "si_zmax = 0.5 * t_Si if three_d else 10\n", + "si_zmin = -0.5 * t_Si if three_d else -10\n", "\n", "# read cell size, volumes for source region and flux monitors,\n", "# and coupler geometry from GDSII file\n", - "upper_branch = mp.get_GDSII_prisms(silicon, gdsII_file, UPPER_BRANCH_LAYER, si_zmin, si_zmax)\n", - "lower_branch = mp.get_GDSII_prisms(silicon, gdsII_file, LOWER_BRANCH_LAYER, si_zmin, si_zmax)\n", + "upper_branch = mp.get_GDSII_prisms(\n", + " silicon, gdsII_file, UPPER_BRANCH_LAYER, si_zmin, si_zmax\n", + ")\n", + "lower_branch = mp.get_GDSII_prisms(\n", + " silicon, gdsII_file, LOWER_BRANCH_LAYER, si_zmin, si_zmax\n", + ")\n", "\n", "cell = mp.GDSII_vol(gdsII_file, CELL_LAYER, cell_zmin, cell_zmax)\n", "p1 = mp.GDSII_vol(gdsII_file, PORT1_LAYER, si_zmin, si_zmax)\n", @@ -926,14 +930,14 @@ "\n", "# displace upper and lower branches of coupler (as well as source and flux regions)\n", "if d != default_d:\n", - " delta_y = 0.5*(d-default_d)\n", + " delta_y = 0.5 * (d - default_d)\n", " delta = mp.Vector3(y=delta_y)\n", " p1.center += delta\n", " p2.center -= delta\n", " p3.center += delta\n", " p4.center -= delta\n", " src_vol.center += delta\n", - " cell.size += 2*delta\n", + " cell.size += 2 * delta\n", " for np in range(len(lower_branch)):\n", " lower_branch[np].center -= delta\n", " for nv in range(len(lower_branch[np].vertices)):\n", @@ -943,26 +947,32 @@ " for nv in range(len(upper_branch[np].vertices)):\n", " upper_branch[np].vertices[nv] += delta\n", "\n", - "geometry = upper_branch+lower_branch\n", + "geometry = upper_branch + lower_branch\n", "\n", "if three_d:\n", - " oxide_center = mp.Vector3(z=-0.5*t_oxide)\n", - " oxide_size = mp.Vector3(cell.size.x,cell.size.y,t_oxide)\n", + " oxide_center = mp.Vector3(z=-0.5 * t_oxide)\n", + " oxide_size = mp.Vector3(cell.size.x, cell.size.y, t_oxide)\n", " oxide_layer = [mp.Block(material=oxide, center=oxide_center, size=oxide_size)]\n", - " geometry = geometry+oxide_layer\n", + " geometry = geometry + oxide_layer\n", "\n", - "sources = [mp.EigenModeSource(src=mp.GaussianSource(fcen,fwidth=df),\n", - " size=src_vol.size,\n", - " center=src_vol.center,\n", - " eig_band=1,\n", - " eig_parity=mp.NO_PARITY if three_d else mp.EVEN_Y+mp.ODD_Z,\n", - " eig_match_freq=True)]\n", + "sources = [\n", + " mp.EigenModeSource(\n", + " src=mp.GaussianSource(fcen, fwidth=df),\n", + " size=src_vol.size,\n", + " center=src_vol.center,\n", + " eig_band=1,\n", + " eig_parity=mp.NO_PARITY if three_d else mp.EVEN_Y + mp.ODD_Z,\n", + " eig_match_freq=True,\n", + " )\n", + "]\n", "\n", - "sim = mp.Simulation(resolution=res,\n", - " cell_size=cell.size,\n", - " boundary_layers=[mp.PML(dpml)],\n", - " sources=sources,\n", - " geometry=geometry)\n", + "sim = mp.Simulation(\n", + " resolution=res,\n", + " cell_size=cell.size,\n", + " boundary_layers=[mp.PML(dpml)],\n", + " sources=sources,\n", + " geometry=geometry,\n", + ")\n", "\n", "mode1 = sim.add_mode_monitor(fcen, 0, 1, mp.ModeRegion(volume=p1))\n", "mode2 = sim.add_mode_monitor(fcen, 0, 1, mp.ModeRegion(volume=p2))\n", @@ -1007,17 +1017,25 @@ ], "source": [ "# S parameters\n", - "p1_coeff = sim.get_eigenmode_coefficients(mode1, [1], eig_parity=mp.NO_PARITY if three_d else mp.EVEN_Y+mp.ODD_Z).alpha[0,0,0]\n", - "p2_coeff = sim.get_eigenmode_coefficients(mode2, [1], eig_parity=mp.NO_PARITY if three_d else mp.EVEN_Y+mp.ODD_Z).alpha[0,0,1]\n", - "p3_coeff = sim.get_eigenmode_coefficients(mode3, [1], eig_parity=mp.NO_PARITY if three_d else mp.EVEN_Y+mp.ODD_Z).alpha[0,0,0]\n", - "p4_coeff = sim.get_eigenmode_coefficients(mode4, [1], eig_parity=mp.NO_PARITY if three_d else mp.EVEN_Y+mp.ODD_Z).alpha[0,0,0]\n", + "p1_coeff = sim.get_eigenmode_coefficients(\n", + " mode1, [1], eig_parity=mp.NO_PARITY if three_d else mp.EVEN_Y + mp.ODD_Z\n", + ").alpha[0, 0, 0]\n", + "p2_coeff = sim.get_eigenmode_coefficients(\n", + " mode2, [1], eig_parity=mp.NO_PARITY if three_d else mp.EVEN_Y + mp.ODD_Z\n", + ").alpha[0, 0, 1]\n", + "p3_coeff = sim.get_eigenmode_coefficients(\n", + " mode3, [1], eig_parity=mp.NO_PARITY if three_d else mp.EVEN_Y + mp.ODD_Z\n", + ").alpha[0, 0, 0]\n", + "p4_coeff = sim.get_eigenmode_coefficients(\n", + " mode4, [1], eig_parity=mp.NO_PARITY if three_d else mp.EVEN_Y + mp.ODD_Z\n", + ").alpha[0, 0, 0]\n", "\n", "# transmittance\n", - "p2_trans = abs(p2_coeff)**2/abs(p1_coeff)**2\n", - "p3_trans = abs(p3_coeff)**2/abs(p1_coeff)**2\n", - "p4_trans = abs(p4_coeff)**2/abs(p1_coeff)**2\n", + "p2_trans = abs(p2_coeff) ** 2 / abs(p1_coeff) ** 2\n", + "p3_trans = abs(p3_coeff) ** 2 / abs(p1_coeff) ** 2\n", + "p4_trans = abs(p4_coeff) ** 2 / abs(p1_coeff) ** 2\n", "\n", - "print(\"trans:, {:.2f}, {:.6f}, {:.6f}, {:.6f}\".format(d,p2_trans,p3_trans,p4_trans))" + "print(\"trans:, {:.2f}, {:.6f}, {:.6f}, {:.6f}\".format(d, p2_trans, p3_trans, p4_trans))" ] }, { @@ -1913,28 +1931,41 @@ "source": [ "sim.reset_meep()\n", "\n", - "sources = [mp.EigenModeSource(src=mp.ContinuousSource(fcen,fwidth=df),\n", - " size=src_vol.size,\n", - " center=src_vol.center,\n", - " eig_band=1,\n", - " eig_parity=mp.EVEN_Y+mp.ODD_Z,\n", - " eig_match_freq=True)]\n", + "sources = [\n", + " mp.EigenModeSource(\n", + " src=mp.ContinuousSource(fcen, fwidth=df),\n", + " size=src_vol.size,\n", + " center=src_vol.center,\n", + " eig_band=1,\n", + " eig_parity=mp.EVEN_Y + mp.ODD_Z,\n", + " eig_match_freq=True,\n", + " )\n", + "]\n", "\n", - "sim = mp.Simulation(resolution=res,\n", - " cell_size=cell.size,\n", - " boundary_layers=[mp.PML(dpml)],\n", - " sources=sources,\n", - " geometry=geometry)\n", + "sim = mp.Simulation(\n", + " resolution=res,\n", + " cell_size=cell.size,\n", + " boundary_layers=[mp.PML(dpml)],\n", + " sources=sources,\n", + " geometry=geometry,\n", + ")\n", "\n", - "sim.run(until=400) # arbitrary long run time to ensure that fields have reached steady state\n", + "sim.run(\n", + " until=400\n", + ") # arbitrary long run time to ensure that fields have reached steady state\n", "\n", "eps_data = sim.get_epsilon()\n", "ez_data = numpy.real(sim.get_efield_z())\n", "\n", "plt.figure(dpi=200)\n", - "plt.imshow(numpy.transpose(eps_data), interpolation='spline36', cmap='binary')\n", - "plt.imshow(numpy.flipud(numpy.transpose(ez_data)), interpolation='spline36', cmap='RdBu', alpha=0.9)\n", - "plt.axis('off')\n", + "plt.imshow(numpy.transpose(eps_data), interpolation=\"spline36\", cmap=\"binary\")\n", + "plt.imshow(\n", + " numpy.flipud(numpy.transpose(ez_data)),\n", + " interpolation=\"spline36\",\n", + " cmap=\"RdBu\",\n", + " alpha=0.9,\n", + ")\n", + "plt.axis(\"off\")\n", "plt.show()" ] }, diff --git a/python/examples/cylinder_cross_section.ipynb b/python/examples/cylinder_cross_section.ipynb index e0dad84e6..991295a92 100644 --- a/python/examples/cylinder_cross_section.ipynb +++ b/python/examples/cylinder_cross_section.ipynb @@ -115,47 +115,67 @@ "r = 0.7 # radius of cylinder\n", "h = 2.3 # height of cylinder\n", "\n", - "wvl_min = 2*np.pi*r/10\n", - "wvl_max = 2*np.pi*r/2\n", + "wvl_min = 2 * np.pi * r / 10\n", + "wvl_max = 2 * np.pi * r / 2\n", "\n", - "frq_min = 1/wvl_max\n", - "frq_max = 1/wvl_min\n", - "frq_cen = 0.5*(frq_min+frq_max)\n", - "dfrq = frq_max-frq_min\n", + "frq_min = 1 / wvl_max\n", + "frq_max = 1 / wvl_min\n", + "frq_cen = 0.5 * (frq_min + frq_max)\n", + "dfrq = frq_max - frq_min\n", "nfrq = 100\n", "\n", "## at least 8 pixels per smallest wavelength, i.e. np.floor(8/wvl_min)\n", "resolution = 25\n", "\n", - "dpml = 0.5*wvl_max\n", - "dair = 1.0*wvl_max\n", + "dpml = 0.5 * wvl_max\n", + "dair = 1.0 * wvl_max\n", "\n", "pml_layers = [mp.PML(thickness=dpml)]\n", "\n", - "sr = r+dair+dpml\n", - "sz = dpml+dair+h+dair+dpml\n", - "cell_size = mp.Vector3(sr,0,sz)\n", - "\n", - "sources = [mp.Source(mp.GaussianSource(frq_cen,fwidth=dfrq,is_integrated=True),\n", - " component=mp.Er,\n", - " center=mp.Vector3(0.5*sr,0,-0.5*sz+dpml),\n", - " size=mp.Vector3(sr)),\n", - " mp.Source(mp.GaussianSource(frq_cen,fwidth=dfrq,is_integrated=True),\n", - " component=mp.Ep,\n", - " center=mp.Vector3(0.5*sr,0,-0.5*sz+dpml),\n", - " size=mp.Vector3(sr),\n", - " amplitude=-1j)]\n", - "\n", - "sim = mp.Simulation(cell_size=cell_size,\n", - " boundary_layers=pml_layers,\n", - " resolution=resolution,\n", - " sources=sources,\n", - " dimensions=mp.CYLINDRICAL,\n", - " m=-1)\n", - "\n", - "box_z1 = sim.add_flux(frq_cen, dfrq, nfrq, mp.FluxRegion(center=mp.Vector3(0.5*r,0,-0.5*h),size=mp.Vector3(r)))\n", - "box_z2 = sim.add_flux(frq_cen, dfrq, nfrq, mp.FluxRegion(center=mp.Vector3(0.5*r,0,+0.5*h),size=mp.Vector3(r)))\n", - "box_r = sim.add_flux(frq_cen, dfrq, nfrq, mp.FluxRegion(center=mp.Vector3(r),size=mp.Vector3(z=h)))\n", + "sr = r + dair + dpml\n", + "sz = dpml + dair + h + dair + dpml\n", + "cell_size = mp.Vector3(sr, 0, sz)\n", + "\n", + "sources = [\n", + " mp.Source(\n", + " mp.GaussianSource(frq_cen, fwidth=dfrq, is_integrated=True),\n", + " component=mp.Er,\n", + " center=mp.Vector3(0.5 * sr, 0, -0.5 * sz + dpml),\n", + " size=mp.Vector3(sr),\n", + " ),\n", + " mp.Source(\n", + " mp.GaussianSource(frq_cen, fwidth=dfrq, is_integrated=True),\n", + " component=mp.Ep,\n", + " center=mp.Vector3(0.5 * sr, 0, -0.5 * sz + dpml),\n", + " size=mp.Vector3(sr),\n", + " amplitude=-1j,\n", + " ),\n", + "]\n", + "\n", + "sim = mp.Simulation(\n", + " cell_size=cell_size,\n", + " boundary_layers=pml_layers,\n", + " resolution=resolution,\n", + " sources=sources,\n", + " dimensions=mp.CYLINDRICAL,\n", + " m=-1,\n", + ")\n", + "\n", + "box_z1 = sim.add_flux(\n", + " frq_cen,\n", + " dfrq,\n", + " nfrq,\n", + " mp.FluxRegion(center=mp.Vector3(0.5 * r, 0, -0.5 * h), size=mp.Vector3(r)),\n", + ")\n", + "box_z2 = sim.add_flux(\n", + " frq_cen,\n", + " dfrq,\n", + " nfrq,\n", + " mp.FluxRegion(center=mp.Vector3(0.5 * r, 0, +0.5 * h), size=mp.Vector3(r)),\n", + ")\n", + "box_r = sim.add_flux(\n", + " frq_cen, dfrq, nfrq, mp.FluxRegion(center=mp.Vector3(r), size=mp.Vector3(z=h))\n", + ")\n", "\n", "sim.run(until_after_sources=10)\n", "\n", @@ -169,21 +189,39 @@ "sim.reset_meep()\n", "\n", "n_cyl = 2.0\n", - "geometry = [mp.Block(material=mp.Medium(index=n_cyl),\n", - " center=mp.Vector3(0.5*r),\n", - " size=mp.Vector3(r,0,h))]\n", - "\n", - "sim = mp.Simulation(cell_size=cell_size,\n", - " geometry=geometry,\n", - " boundary_layers=pml_layers,\n", - " resolution=resolution,\n", - " sources=sources,\n", - " dimensions=mp.CYLINDRICAL,\n", - " m=-1)\n", - "\n", - "box_z1 = sim.add_flux(frq_cen, dfrq, nfrq, mp.FluxRegion(center=mp.Vector3(0.5*r,0,-0.5*h),size=mp.Vector3(r)))\n", - "box_z2 = sim.add_flux(frq_cen, dfrq, nfrq, mp.FluxRegion(center=mp.Vector3(0.5*r,0,+0.5*h),size=mp.Vector3(r)))\n", - "box_r = sim.add_flux(frq_cen, dfrq, nfrq, mp.FluxRegion(center=mp.Vector3(r),size=mp.Vector3(z=h)))\n", + "geometry = [\n", + " mp.Block(\n", + " material=mp.Medium(index=n_cyl),\n", + " center=mp.Vector3(0.5 * r),\n", + " size=mp.Vector3(r, 0, h),\n", + " )\n", + "]\n", + "\n", + "sim = mp.Simulation(\n", + " cell_size=cell_size,\n", + " geometry=geometry,\n", + " boundary_layers=pml_layers,\n", + " resolution=resolution,\n", + " sources=sources,\n", + " dimensions=mp.CYLINDRICAL,\n", + " m=-1,\n", + ")\n", + "\n", + "box_z1 = sim.add_flux(\n", + " frq_cen,\n", + " dfrq,\n", + " nfrq,\n", + " mp.FluxRegion(center=mp.Vector3(0.5 * r, 0, -0.5 * h), size=mp.Vector3(r)),\n", + ")\n", + "box_z2 = sim.add_flux(\n", + " frq_cen,\n", + " dfrq,\n", + " nfrq,\n", + " mp.FluxRegion(center=mp.Vector3(0.5 * r, 0, +0.5 * h), size=mp.Vector3(r)),\n", + ")\n", + "box_r = sim.add_flux(\n", + " frq_cen, dfrq, nfrq, mp.FluxRegion(center=mp.Vector3(r), size=mp.Vector3(z=h))\n", + ")\n", "\n", "sim.load_minus_flux_data(box_z1, box_z1_data)\n", "sim.load_minus_flux_data(box_z2, box_z2_data)\n", @@ -195,16 +233,16 @@ "box_z2_flux = mp.get_fluxes(box_z2)\n", "box_r_flux = mp.get_fluxes(box_r)\n", "\n", - "scatt_flux = np.asarray(box_z1_flux)-np.asarray(box_z2_flux)-np.asarray(box_r_flux)\n", - "intensity = np.asarray(box_z1_flux0)/(np.pi*r**2)\n", - "scatt_cross_section = np.divide(-scatt_flux,intensity)\n", + "scatt_flux = np.asarray(box_z1_flux) - np.asarray(box_z2_flux) - np.asarray(box_r_flux)\n", + "intensity = np.asarray(box_z1_flux0) / (np.pi * r**2)\n", + "scatt_cross_section = np.divide(-scatt_flux, intensity)\n", "\n", "plt.figure(dpi=150)\n", - "plt.loglog(2*np.pi*r*np.asarray(freqs),scatt_cross_section,'bo-')\n", - "plt.grid(True,which=\"both\",ls=\"-\")\n", - "plt.xlabel('(cylinder circumference)/wavelength, 2πr/λ')\n", - "plt.ylabel('scattering cross section, σ')\n", - "plt.title('Scattering Cross Section of a Lossless Dielectric Cylinder')\n", + "plt.loglog(2 * np.pi * r * np.asarray(freqs), scatt_cross_section, \"bo-\")\n", + "plt.grid(True, which=\"both\", ls=\"-\")\n", + "plt.xlabel(\"(cylinder circumference)/wavelength, 2πr/λ\")\n", + "plt.ylabel(\"scattering cross section, σ\")\n", + "plt.title(\"Scattering Cross Section of a Lossless Dielectric Cylinder\")\n", "plt.tight_layout()\n", "plt.show()" ] diff --git a/python/examples/differential_cross_section.ipynb b/python/examples/differential_cross_section.ipynb index 12f091350..e26b07def 100644 --- a/python/examples/differential_cross_section.ipynb +++ b/python/examples/differential_cross_section.ipynb @@ -312,44 +312,72 @@ "\n", "frq_cen = 1.0\n", "\n", - "resolution = 20 # pixels/um\n", + "resolution = 20 # pixels/um\n", "\n", "dpml = 0.5\n", - "dair = 1.5 # at least 0.5/frq_cen padding between source and near-field monitor\n", + "dair = 1.5 # at least 0.5/frq_cen padding between source and near-field monitor\n", "\n", "pml_layers = [mp.PML(thickness=dpml)]\n", "\n", - "s = 2*(dpml+dair+r)\n", - "cell_size = mp.Vector3(s,s,s)\n", + "s = 2 * (dpml + dair + r)\n", + "cell_size = mp.Vector3(s, s, s)\n", "\n", "# circularly-polarized source with propagation axis along x\n", "# is_integrated=True necessary for any planewave source extending into PML\n", - "sources = [mp.Source(mp.GaussianSource(frq_cen,fwidth=0.2*frq_cen,is_integrated=True),\n", - " center=mp.Vector3(-0.5*s+dpml),\n", - " size=mp.Vector3(0,s,s),\n", - " component=mp.Ez),\n", - " mp.Source(mp.GaussianSource(frq_cen,fwidth=0.2*frq_cen,is_integrated=True),\n", - " center=mp.Vector3(-0.5*s+dpml),\n", - " size=mp.Vector3(0,s,s),\n", - " component=mp.Ey,\n", - " amplitude=1j)]\n", + "sources = [\n", + " mp.Source(\n", + " mp.GaussianSource(frq_cen, fwidth=0.2 * frq_cen, is_integrated=True),\n", + " center=mp.Vector3(-0.5 * s + dpml),\n", + " size=mp.Vector3(0, s, s),\n", + " component=mp.Ez,\n", + " ),\n", + " mp.Source(\n", + " mp.GaussianSource(frq_cen, fwidth=0.2 * frq_cen, is_integrated=True),\n", + " center=mp.Vector3(-0.5 * s + dpml),\n", + " size=mp.Vector3(0, s, s),\n", + " component=mp.Ey,\n", + " amplitude=1j,\n", + " ),\n", + "]\n", "\n", - "sim = mp.Simulation(resolution=resolution,\n", - " cell_size=cell_size,\n", - " boundary_layers=pml_layers,\n", - " sources=sources,\n", - " k_point=mp.Vector3())\n", + "sim = mp.Simulation(\n", + " resolution=resolution,\n", + " cell_size=cell_size,\n", + " boundary_layers=pml_layers,\n", + " sources=sources,\n", + " k_point=mp.Vector3(),\n", + ")\n", "\n", - "box_flux = sim.add_flux(frq_cen, 0, 1,\n", - " mp.FluxRegion(center=mp.Vector3(x=-2*r),size=mp.Vector3(0,4*r,4*r)))\n", + "box_flux = sim.add_flux(\n", + " frq_cen,\n", + " 0,\n", + " 1,\n", + " mp.FluxRegion(center=mp.Vector3(x=-2 * r), size=mp.Vector3(0, 4 * r, 4 * r)),\n", + ")\n", "\n", - "nearfield_box = sim.add_near2far(frq_cen, 0, 1,\n", - " mp.Near2FarRegion(center=mp.Vector3(x=-2*r),size=mp.Vector3(0,4*r,4*r),weight=+1),\n", - " mp.Near2FarRegion(center=mp.Vector3(x=+2*r),size=mp.Vector3(0,4*r,4*r),weight=-1),\n", - " mp.Near2FarRegion(center=mp.Vector3(y=-2*r),size=mp.Vector3(4*r,0,4*r),weight=+1),\n", - " mp.Near2FarRegion(center=mp.Vector3(y=+2*r),size=mp.Vector3(4*r,0,4*r),weight=-1),\n", - " mp.Near2FarRegion(center=mp.Vector3(z=-2*r),size=mp.Vector3(4*r,4*r,0),weight=+1),\n", - " mp.Near2FarRegion(center=mp.Vector3(z=+2*r),size=mp.Vector3(4*r,4*r,0),weight=-1))\n", + "nearfield_box = sim.add_near2far(\n", + " frq_cen,\n", + " 0,\n", + " 1,\n", + " mp.Near2FarRegion(\n", + " center=mp.Vector3(x=-2 * r), size=mp.Vector3(0, 4 * r, 4 * r), weight=+1\n", + " ),\n", + " mp.Near2FarRegion(\n", + " center=mp.Vector3(x=+2 * r), size=mp.Vector3(0, 4 * r, 4 * r), weight=-1\n", + " ),\n", + " mp.Near2FarRegion(\n", + " center=mp.Vector3(y=-2 * r), size=mp.Vector3(4 * r, 0, 4 * r), weight=+1\n", + " ),\n", + " mp.Near2FarRegion(\n", + " center=mp.Vector3(y=+2 * r), size=mp.Vector3(4 * r, 0, 4 * r), weight=-1\n", + " ),\n", + " mp.Near2FarRegion(\n", + " center=mp.Vector3(z=-2 * r), size=mp.Vector3(4 * r, 4 * r, 0), weight=+1\n", + " ),\n", + " mp.Near2FarRegion(\n", + " center=mp.Vector3(z=+2 * r), size=mp.Vector3(4 * r, 4 * r, 0), weight=-1\n", + " ),\n", + ")\n", "\n", "sim.run(until_after_sources=10)\n", "\n", @@ -359,54 +387,85 @@ "sim.reset_meep()\n", "\n", "n_sphere = 2.0\n", - "geometry = [mp.Sphere(material=mp.Medium(index=n_sphere),\n", - " center=mp.Vector3(),\n", - " radius=r)]\n", + "geometry = [\n", + " mp.Sphere(material=mp.Medium(index=n_sphere), center=mp.Vector3(), radius=r)\n", + "]\n", "\n", - "sim = mp.Simulation(resolution=resolution,\n", - " cell_size=cell_size,\n", - " boundary_layers=pml_layers,\n", - " sources=sources,\n", - " k_point=mp.Vector3(),\n", - " geometry=geometry)\n", + "sim = mp.Simulation(\n", + " resolution=resolution,\n", + " cell_size=cell_size,\n", + " boundary_layers=pml_layers,\n", + " sources=sources,\n", + " k_point=mp.Vector3(),\n", + " geometry=geometry,\n", + ")\n", "\n", - "nearfield_box = sim.add_near2far(frq_cen, 0, 1,\n", - " mp.Near2FarRegion(center=mp.Vector3(x=-2*r),size=mp.Vector3(0,4*r,4*r),weight=+1),\n", - " mp.Near2FarRegion(center=mp.Vector3(x=+2*r),size=mp.Vector3(0,4*r,4*r),weight=-1),\n", - " mp.Near2FarRegion(center=mp.Vector3(y=-2*r),size=mp.Vector3(4*r,0,4*r),weight=+1),\n", - " mp.Near2FarRegion(center=mp.Vector3(y=+2*r),size=mp.Vector3(4*r,0,4*r),weight=-1),\n", - " mp.Near2FarRegion(center=mp.Vector3(z=-2*r),size=mp.Vector3(4*r,4*r,0),weight=+1),\n", - " mp.Near2FarRegion(center=mp.Vector3(z=+2*r),size=mp.Vector3(4*r,4*r,0),weight=-1))\n", + "nearfield_box = sim.add_near2far(\n", + " frq_cen,\n", + " 0,\n", + " 1,\n", + " mp.Near2FarRegion(\n", + " center=mp.Vector3(x=-2 * r), size=mp.Vector3(0, 4 * r, 4 * r), weight=+1\n", + " ),\n", + " mp.Near2FarRegion(\n", + " center=mp.Vector3(x=+2 * r), size=mp.Vector3(0, 4 * r, 4 * r), weight=-1\n", + " ),\n", + " mp.Near2FarRegion(\n", + " center=mp.Vector3(y=-2 * r), size=mp.Vector3(4 * r, 0, 4 * r), weight=+1\n", + " ),\n", + " mp.Near2FarRegion(\n", + " center=mp.Vector3(y=+2 * r), size=mp.Vector3(4 * r, 0, 4 * r), weight=-1\n", + " ),\n", + " mp.Near2FarRegion(\n", + " center=mp.Vector3(z=-2 * r), size=mp.Vector3(4 * r, 4 * r, 0), weight=+1\n", + " ),\n", + " mp.Near2FarRegion(\n", + " center=mp.Vector3(z=+2 * r), size=mp.Vector3(4 * r, 4 * r, 0), weight=-1\n", + " ),\n", + ")\n", "\n", "sim.load_minus_near2far_data(nearfield_box, nearfield_box_data)\n", "\n", "sim.run(until_after_sources=100)\n", "\n", - "npts = 100 # number of points in [0,pi) range of polar angles to sample far fields along semi-circle\n", - "angles = np.pi/npts*np.arange(npts)\n", + "npts = 100 # number of points in [0,pi) range of polar angles to sample far fields along semi-circle\n", + "angles = np.pi / npts * np.arange(npts)\n", "\n", - "ff_r = 10000*r # radius of far-field semi-circle\n", + "ff_r = 10000 * r # radius of far-field semi-circle\n", "\n", - "E = np.zeros((npts,3),dtype=np.complex128)\n", - "H = np.zeros((npts,3),dtype=np.complex128)\n", + "E = np.zeros((npts, 3), dtype=np.complex128)\n", + "H = np.zeros((npts, 3), dtype=np.complex128)\n", "for n in range(npts):\n", - " ff = sim.get_farfield(nearfield_box, ff_r*mp.Vector3(np.cos(angles[n]),0,np.sin(angles[n])))\n", - " E[n,:] = [np.conj(ff[j]) for j in range(3)]\n", - " H[n,:] = [ff[j+3] for j in range(3)]\n", + " ff = sim.get_farfield(\n", + " nearfield_box, ff_r * mp.Vector3(np.cos(angles[n]), 0, np.sin(angles[n]))\n", + " )\n", + " E[n, :] = [np.conj(ff[j]) for j in range(3)]\n", + " H[n, :] = [ff[j + 3] for j in range(3)]\n", "\n", "# compute Poynting flux Pr in the radial direction. At large r,\n", "# all of the flux is radial so we can simply compute the magnitude of the Poynting vector.\n", - "Px = np.real(np.multiply(E[:,1],H[:,2])-np.multiply(E[:,2],H[:,1]))\n", - "Py = np.real(np.multiply(E[:,2],H[:,0])-np.multiply(E[:,0],H[:,2]))\n", - "Pz = np.real(np.multiply(E[:,0],H[:,1])-np.multiply(E[:,1],H[:,0]))\n", - "Pr = np.sqrt(np.square(Px)+np.square(Py)+np.square(Pz))\n", + "Px = np.real(np.multiply(E[:, 1], H[:, 2]) - np.multiply(E[:, 2], H[:, 1]))\n", + "Py = np.real(np.multiply(E[:, 2], H[:, 0]) - np.multiply(E[:, 0], H[:, 2]))\n", + "Pz = np.real(np.multiply(E[:, 0], H[:, 1]) - np.multiply(E[:, 1], H[:, 0]))\n", + "Pr = np.sqrt(np.square(Px) + np.square(Py) + np.square(Pz))\n", "\n", - "intensity = input_flux/(4*r)**2\n", + "intensity = input_flux / (4 * r) ** 2\n", "diff_cross_section = ff_r**2 * Pr / intensity\n", - "scatt_cross_section_meep = 2*np.pi * np.sum(diff_cross_section * np.sin(angles)) * np.pi/npts # trapezoidal rule integration\n", - "scatt_cross_section_theory = ps.MieQ(n_sphere,1000/frq_cen,2*r*1000,asDict=True,asCrossSection=True)['Csca']*1e-6 # units of um^2\n", + "scatt_cross_section_meep = (\n", + " 2 * np.pi * np.sum(diff_cross_section * np.sin(angles)) * np.pi / npts\n", + ") # trapezoidal rule integration\n", + "scatt_cross_section_theory = (\n", + " ps.MieQ(n_sphere, 1000 / frq_cen, 2 * r * 1000, asDict=True, asCrossSection=True)[\n", + " \"Csca\"\n", + " ]\n", + " * 1e-6\n", + ") # units of um^2\n", "\n", - "print(\"scatt:, {:.16f}, {:.16f}\".format(scatt_cross_section_meep,scatt_cross_section_theory))" + "print(\n", + " \"scatt:, {:.16f}, {:.16f}\".format(\n", + " scatt_cross_section_meep, scatt_cross_section_theory\n", + " )\n", + ")" ] }, { diff --git a/python/examples/finite_grating.ipynb b/python/examples/finite_grating.ipynb index e60714631..2f6600f25 100644 --- a/python/examples/finite_grating.ipynb +++ b/python/examples/finite_grating.ipynb @@ -138,21 +138,21 @@ "# False: plot the diffraction spectra based on a 1d cross section of the scattered fields\n", "field_profile = True\n", "\n", - "resolution = 50 # pixels/μm\n", + "resolution = 50 # pixels/μm\n", "\n", - "dpml = 1.0 # PML thickness\n", - "dsub = 2.0 # substrate thickness\n", - "dpad = 1.0 # flat-surface padding\n", - "gp = 1.0 # grating periodicity\n", - "gh = 0.5 # grating height\n", - "gdc = 0.5 # grating duty cycle\n", - "num_cells = 5 # number of grating unit cells\n", + "dpml = 1.0 # PML thickness\n", + "dsub = 2.0 # substrate thickness\n", + "dpad = 1.0 # flat-surface padding\n", + "gp = 1.0 # grating periodicity\n", + "gh = 0.5 # grating height\n", + "gdc = 0.5 # grating duty cycle\n", + "num_cells = 5 # number of grating unit cells\n", "\n", "# air region thickness adjacent to grating\n", "dair = 10 if field_profile else dpad\n", "\n", - "wvl = 0.5 # center wavelength\n", - "fcen = 1/wvl # center frequency\n", + "wvl = 0.5 # center wavelength\n", + "fcen = 1 / wvl # center frequency\n", "\n", "k_point = mp.Vector3()\n", "\n", @@ -160,32 +160,49 @@ "\n", "pml_layers = [mp.PML(thickness=dpml)]\n", "\n", - "symmetries=[mp.Mirror(mp.Y)]\n", - "\n", - "sx = dpml+dsub+gh+dair+dpml\n", - "sy = dpml+dpad+num_cells*gp+dpad+dpml\n", - "cell_size = mp.Vector3(sx,sy)\n", - "\n", - "src_pt = mp.Vector3(-0.5*sx+dpml+0.5*dsub)\n", - "sources = [mp.Source(mp.GaussianSource(fcen,fwidth=0.2*fcen),\n", - " component=mp.Ez,\n", - " center=src_pt,\n", - " size=mp.Vector3(y=sy))]\n", - "\n", - "geometry = [mp.Block(material=glass,\n", - " size=mp.Vector3(dpml+dsub,mp.inf,mp.inf),\n", - " center=mp.Vector3(-0.5*sx+0.5*(dpml+dsub)))]\n", - "\n", - "sim = mp.Simulation(resolution=resolution,\n", - " cell_size=cell_size,\n", - " boundary_layers=pml_layers,\n", - " geometry=geometry,\n", - " k_point=k_point,\n", - " sources=sources,\n", - " symmetries=symmetries)\n", - "\n", - "mon_pt = mp.Vector3(0.5*sx-dpml-0.5*dair)\n", - "near_fields = sim.add_dft_fields([mp.Ez], fcen, 0, 1, center=mon_pt, size=mp.Vector3(dair if field_profile else 0,sy-2*dpml))\n", + "symmetries = [mp.Mirror(mp.Y)]\n", + "\n", + "sx = dpml + dsub + gh + dair + dpml\n", + "sy = dpml + dpad + num_cells * gp + dpad + dpml\n", + "cell_size = mp.Vector3(sx, sy)\n", + "\n", + "src_pt = mp.Vector3(-0.5 * sx + dpml + 0.5 * dsub)\n", + "sources = [\n", + " mp.Source(\n", + " mp.GaussianSource(fcen, fwidth=0.2 * fcen),\n", + " component=mp.Ez,\n", + " center=src_pt,\n", + " size=mp.Vector3(y=sy),\n", + " )\n", + "]\n", + "\n", + "geometry = [\n", + " mp.Block(\n", + " material=glass,\n", + " size=mp.Vector3(dpml + dsub, mp.inf, mp.inf),\n", + " center=mp.Vector3(-0.5 * sx + 0.5 * (dpml + dsub)),\n", + " )\n", + "]\n", + "\n", + "sim = mp.Simulation(\n", + " resolution=resolution,\n", + " cell_size=cell_size,\n", + " boundary_layers=pml_layers,\n", + " geometry=geometry,\n", + " k_point=k_point,\n", + " sources=sources,\n", + " symmetries=symmetries,\n", + ")\n", + "\n", + "mon_pt = mp.Vector3(0.5 * sx - dpml - 0.5 * dair)\n", + "near_fields = sim.add_dft_fields(\n", + " [mp.Ez],\n", + " fcen,\n", + " 0,\n", + " 1,\n", + " center=mon_pt,\n", + " size=mp.Vector3(dair if field_profile else 0, sy - 2 * dpml),\n", + ")\n", "\n", "sim.run(until_after_sources=100)\n", "\n", @@ -194,19 +211,35 @@ "sim.reset_meep()\n", "\n", "for j in range(num_cells):\n", - " geometry.append(mp.Block(material=glass,\n", - " size=mp.Vector3(gh,gdc*gp,mp.inf),\n", - " center=mp.Vector3(-0.5*sx+dpml+dsub+0.5*gh,-0.5*sy+dpml+dpad+(j+0.5)*gp)))\n", - "\n", - "sim = mp.Simulation(resolution=resolution,\n", - " cell_size=cell_size,\n", - " boundary_layers=pml_layers,\n", - " geometry=geometry,\n", - " k_point=k_point,\n", - " sources=sources,\n", - " symmetries=symmetries)\n", - "\n", - "near_fields = sim.add_dft_fields([mp.Ez], fcen, 0, 1, center=mon_pt, size=mp.Vector3(dair if field_profile else 0,sy-2*dpml))\n", + " geometry.append(\n", + " mp.Block(\n", + " material=glass,\n", + " size=mp.Vector3(gh, gdc * gp, mp.inf),\n", + " center=mp.Vector3(\n", + " -0.5 * sx + dpml + dsub + 0.5 * gh,\n", + " -0.5 * sy + dpml + dpad + (j + 0.5) * gp,\n", + " ),\n", + " )\n", + " )\n", + "\n", + "sim = mp.Simulation(\n", + " resolution=resolution,\n", + " cell_size=cell_size,\n", + " boundary_layers=pml_layers,\n", + " geometry=geometry,\n", + " k_point=k_point,\n", + " sources=sources,\n", + " symmetries=symmetries,\n", + ")\n", + "\n", + "near_fields = sim.add_dft_fields(\n", + " [mp.Ez],\n", + " fcen,\n", + " 0,\n", + " 1,\n", + " center=mon_pt,\n", + " size=mp.Vector3(dair if field_profile else 0, sy - 2 * dpml),\n", + ")\n", "\n", "sim.run(until_after_sources=100)" ] @@ -232,39 +265,48 @@ "source": [ "grating_dft = sim.get_dft_array(near_fields, mp.Ez, 0)\n", "\n", - "scattered_field = grating_dft-flat_dft\n", - "scattered_amplitude = np.abs(scattered_field)**2\n", + "scattered_field = grating_dft - flat_dft\n", + "scattered_amplitude = np.abs(scattered_field) ** 2\n", "\n", - "[x,y,z,w] = sim.get_array_metadata(dft_cell=near_fields)\n", + "[x, y, z, w] = sim.get_array_metadata(dft_cell=near_fields)\n", "\n", "if field_profile:\n", " plt.figure(dpi=150)\n", - " plt.pcolormesh(x,y,np.rot90(scattered_amplitude),cmap='inferno',shading='gouraud',vmin=0,vmax=scattered_amplitude.max())\n", - " plt.gca().set_aspect('equal')\n", - " plt.xlabel('x (μm)')\n", - " plt.ylabel('y (μm)')\n", + " plt.pcolormesh(\n", + " x,\n", + " y,\n", + " np.rot90(scattered_amplitude),\n", + " cmap=\"inferno\",\n", + " shading=\"gouraud\",\n", + " vmin=0,\n", + " vmax=scattered_amplitude.max(),\n", + " )\n", + " plt.gca().set_aspect(\"equal\")\n", + " plt.xlabel(\"x (μm)\")\n", + " plt.ylabel(\"y (μm)\")\n", " # ensure that the height of the colobar matches that of the plot\n", " from mpl_toolkits.axes_grid1 import make_axes_locatable\n", + "\n", " divider = make_axes_locatable(plt.gca())\n", " cax = divider.append_axes(\"right\", size=\"5%\", pad=0.05)\n", " plt.colorbar(cax=cax)\n", " plt.tight_layout()\n", " plt.show()\n", "else:\n", - " ky = np.fft.fftshift(np.fft.fftfreq(len(scattered_field), 1/resolution))\n", + " ky = np.fft.fftshift(np.fft.fftfreq(len(scattered_field), 1 / resolution))\n", " FT_scattered_field = np.fft.fftshift(np.fft.fft(scattered_field))\n", " plt.figure(dpi=150)\n", " plt.subplots_adjust(hspace=0.3)\n", "\n", - " plt.subplot(2,1,1)\n", - " plt.plot(y,scattered_amplitude,'bo-')\n", + " plt.subplot(2, 1, 1)\n", + " plt.plot(y, scattered_amplitude, \"bo-\")\n", " plt.xlabel(\"y (μm)\")\n", " plt.ylabel(\"field amplitude\")\n", "\n", - " plt.subplot(2,1,2)\n", - " plt.plot(ky,np.abs(FT_scattered_field)**2,'ro-')\n", - " plt.gca().ticklabel_format(axis='y',style='sci',scilimits=(0,0))\n", - " plt.xlabel(r'wavevector k$_y$, 2π (μm)$^{-1}$')\n", + " plt.subplot(2, 1, 2)\n", + " plt.plot(ky, np.abs(FT_scattered_field) ** 2, \"ro-\")\n", + " plt.gca().ticklabel_format(axis=\"y\", style=\"sci\", scilimits=(0, 0))\n", + " plt.xlabel(r\"wavevector k$_y$, 2π (μm)$^{-1}$\")\n", " plt.ylabel(\"Fourier transform\")\n", " plt.gca().set_xlim([-3, 3])\n", "\n", diff --git a/python/examples/holey-wvg-bands.ipynb b/python/examples/holey-wvg-bands.ipynb index 8af8e0a94..9ed14d556 100644 --- a/python/examples/holey-wvg-bands.ipynb +++ b/python/examples/holey-wvg-bands.ipynb @@ -33,6 +33,7 @@ "import numpy as np\n", "from matplotlib import pyplot as plt\n", "from IPython.display import Video\n", + "\n", "%matplotlib notebook" ] }, @@ -50,21 +51,21 @@ "outputs": [], "source": [ "# Some parameters to describe the geometry:\n", - "eps = 13 # dielectric constant of waveguide\n", - "w = 1.2 # width of waveguide\n", - "r = 0.36 # radius of holes\n", + "eps = 13 # dielectric constant of waveguide\n", + "w = 1.2 # width of waveguide\n", + "r = 0.36 # radius of holes\n", "\n", "# The cell dimensions\n", - "sy = 12 # size of cell in y direction (perpendicular to wvg.)\n", - "dpml = 1 # PML thickness (y direction only!)\n", + "sy = 12 # size of cell in y direction (perpendicular to wvg.)\n", + "dpml = 1 # PML thickness (y direction only!)\n", "cell = mp.Vector3(1, sy)\n", "\n", "b = mp.Block(size=mp.Vector3(1e20, w, 1e20), material=mp.Medium(epsilon=eps))\n", "c = mp.Cylinder(radius=r)\n", "\n", - "geometry = [b,c]\n", + "geometry = [b, c]\n", "\n", - "resolution=20" + "resolution = 20" ] }, { @@ -99,10 +100,15 @@ "outputs": [], "source": [ "fcen = 0.25 # pulse center frequency\n", - "df = 1.5 # pulse freq. width: large df = short impulse\n", + "df = 1.5 # pulse freq. width: large df = short impulse\n", "\n", - "s = [mp.Source(src=mp.GaussianSource(fcen, fwidth=df), component=mp.Hz,\n", - " center=mp.Vector3(0.1234,0))]" + "s = [\n", + " mp.Source(\n", + " src=mp.GaussianSource(fcen, fwidth=df),\n", + " component=mp.Hz,\n", + " center=mp.Vector3(0.1234, 0),\n", + " )\n", + "]" ] }, { @@ -162,12 +168,14 @@ } ], "source": [ - "sim = mp.Simulation(cell_size=cell,\n", - " geometry=geometry,\n", - " boundary_layers=pml_layers,\n", - " sources=s,\n", - " symmetries=sym,\n", - " resolution=resolution)\n", + "sim = mp.Simulation(\n", + " cell_size=cell,\n", + " geometry=geometry,\n", + " boundary_layers=pml_layers,\n", + " sources=s,\n", + " symmetries=sym,\n", + " resolution=resolution,\n", + ")\n", "f = plt.figure(dpi=150)\n", "sim.plot2D(ax=f.gca())\n", "plt.show()" @@ -210,8 +218,10 @@ "kx = 0.4\n", "sim.k_point = mp.Vector3(kx)\n", "\n", - "sim.run(mp.after_sources(mp.Harminv(mp.Hz, mp.Vector3(0.1234), fcen, df)),\n", - " until_after_sources=300)" + "sim.run(\n", + " mp.after_sources(mp.Harminv(mp.Hz, mp.Vector3(0.1234), fcen, df)),\n", + " until_after_sources=300,\n", + ")" ] }, { @@ -263,18 +273,18 @@ ], "source": [ "kx = [k.x for k in kpts]\n", - "fig = plt.figure(dpi=100,figsize=(5,5))\n", + "fig = plt.figure(dpi=100, figsize=(5, 5))\n", "ax = plt.subplot(111)\n", "for i in range(len(all_freqs)):\n", " for ii in range(len(all_freqs[i])):\n", - " plt.scatter(kx[i],np.real(all_freqs[i][ii]),color='b')\n", + " plt.scatter(kx[i], np.real(all_freqs[i][ii]), color=\"b\")\n", "\n", - "ax.fill_between(kx, kx, 1.0, interpolate=True, color='gray', alpha = 0.3)\n", - "plt.xlim(0,0.5)\n", - "plt.ylim(0,1)\n", + "ax.fill_between(kx, kx, 1.0, interpolate=True, color=\"gray\", alpha=0.3)\n", + "plt.xlim(0, 0.5)\n", + "plt.ylim(0, 1)\n", "plt.grid(True)\n", - "plt.xlabel('$k_x(2\\pi)$')\n", - "plt.ylabel('$\\omega(2\\pi c)$')\n", + "plt.xlabel(\"$k_x(2\\pi)$\")\n", + "plt.ylabel(\"$\\omega(2\\pi c)$\")\n", "plt.tight_layout()\n", "plt.show()" ] @@ -314,19 +324,26 @@ "outputs": [], "source": [ "def run_sim(kx, omega, filename):\n", - " s = [mp.Source(src=mp.GaussianSource(omega, fwidth=0.01), component=mp.Hz,\n", - " center=mp.Vector3(0.1234,0))]\n", - " sim = mp.Simulation(cell_size=cell,\n", - " geometry=geometry,\n", - " boundary_layers=pml_layers,\n", - " sources=s,\n", - " symmetries=sym,\n", - " k_point = mp.Vector3(kx),\n", - " resolution=resolution)\n", + " s = [\n", + " mp.Source(\n", + " src=mp.GaussianSource(omega, fwidth=0.01),\n", + " component=mp.Hz,\n", + " center=mp.Vector3(0.1234, 0),\n", + " )\n", + " ]\n", + " sim = mp.Simulation(\n", + " cell_size=cell,\n", + " geometry=geometry,\n", + " boundary_layers=pml_layers,\n", + " sources=s,\n", + " symmetries=sym,\n", + " k_point=mp.Vector3(kx),\n", + " resolution=resolution,\n", + " )\n", " f = plt.figure(dpi=100)\n", - " animate = mp.Animate2D(sim,fields=mp.Hz,f=f,normalize=True,realtime=False)\n", - " sim.run(mp.at_every(5,animate),until_after_sources=1)\n", - " animate.to_mp4(10,filename)\n", + " animate = mp.Animate2D(sim, fields=mp.Hz, f=f, normalize=True, realtime=False)\n", + " sim.run(mp.at_every(5, animate), until_after_sources=1)\n", + " animate.to_mp4(10, filename)\n", " plt.close()" ] }, @@ -459,11 +476,13 @@ } ], "source": [ - "kx = [0.4,0.4,0.1,0.3,0.25]\n", - "omega = [0.1896,0.3175,0.4811,0.8838,0.2506]\n", - "filename = ['media/holey-wvg-bands-{}-{}.mp4'.format(k,om) for (k,om) in zip (kx,omega)]\n", - "for (k,om,fn) in zip(kx,omega,filename):\n", - " run_sim(*[k,om,fn])" + "kx = [0.4, 0.4, 0.1, 0.3, 0.25]\n", + "omega = [0.1896, 0.3175, 0.4811, 0.8838, 0.2506]\n", + "filename = [\n", + " \"media/holey-wvg-bands-{}-{}.mp4\".format(k, om) for (k, om) in zip(kx, omega)\n", + "]\n", + "for (k, om, fn) in zip(kx, omega, filename):\n", + " run_sim(*[k, om, fn])" ] }, { @@ -544,6 +563,7 @@ ], "source": [ "import IPython\n", + "\n", "for i in range(len(filename)):\n", " IPython.display.display(IPython.display.Video(filename[i]))" ] diff --git a/python/examples/holey-wvg-cavity.ipynb b/python/examples/holey-wvg-cavity.ipynb index 1e58e242b..393bb3187 100644 --- a/python/examples/holey-wvg-cavity.ipynb +++ b/python/examples/holey-wvg-cavity.ipynb @@ -34,6 +34,7 @@ "import numpy as np\n", "from matplotlib import pyplot as plt\n", "from IPython.display import Video\n", + "\n", "%matplotlib notebook" ] }, @@ -50,17 +51,17 @@ "metadata": {}, "outputs": [], "source": [ - "resolution = 20 # pixels/um\n", + "resolution = 20 # pixels/um\n", "\n", - "eps = 13 # dielectric constant of waveguide\n", - "w = 1.2 # width of waveguide\n", - "r = 0.36 # radius of holes\n", - "d = 1.4 # defect spacing (ordinary spacing = 1)\n", - "N = 3 # number of holes on either side of defect\n", + "eps = 13 # dielectric constant of waveguide\n", + "w = 1.2 # width of waveguide\n", + "r = 0.36 # radius of holes\n", + "d = 1.4 # defect spacing (ordinary spacing = 1)\n", + "N = 3 # number of holes on either side of defect\n", "\n", - "sy = 6 # size of cell in y direction (perpendicular to wvg.)\n", - "pad = 2 # padding between last hole and PML edge\n", - "dpml = 1 # PML thickness" + "sy = 6 # size of cell in y direction (perpendicular to wvg.)\n", + "pad = 2 # padding between last hole and PML edge\n", + "dpml = 1 # PML thickness" ] }, { @@ -76,7 +77,7 @@ "metadata": {}, "outputs": [], "source": [ - "sx = 2*(pad+dpml+N)+d-1 # size of cell in x direction" + "sx = 2 * (pad + dpml + N) + d - 1 # size of cell in x direction" ] }, { @@ -92,7 +93,7 @@ "metadata": {}, "outputs": [], "source": [ - "cell = mp.Vector3(sx,sy,0)" + "cell = mp.Vector3(sx, sy, 0)" ] }, { @@ -108,12 +109,12 @@ "metadata": {}, "outputs": [], "source": [ - "blk = mp.Block(size=mp.Vector3(mp.inf,w,mp.inf), material=mp.Medium(epsilon=eps))\n", + "blk = mp.Block(size=mp.Vector3(mp.inf, w, mp.inf), material=mp.Medium(epsilon=eps))\n", "geometry = [blk]\n", "\n", "for i in range(N):\n", - " geometry.append(mp.Cylinder(r, center=mp.Vector3(d/2+i)))\n", - " geometry.append(mp.Cylinder(r, center=mp.Vector3(-(d/2+i))))" + " geometry.append(mp.Cylinder(r, center=mp.Vector3(d / 2 + i)))\n", + " geometry.append(mp.Cylinder(r, center=mp.Vector3(-(d / 2 + i))))" ] }, { @@ -147,8 +148,8 @@ "metadata": {}, "outputs": [], "source": [ - "fcen = 0.25 # pulse center frequency\n", - "df = 0.2 # pulse frequency width" + "fcen = 0.25 # pulse center frequency\n", + "df = 0.2 # pulse frequency width" ] }, { @@ -164,10 +165,14 @@ "metadata": {}, "outputs": [], "source": [ - "src = [mp.Source(mp.GaussianSource(fcen, fwidth=df),\n", - " component=mp.Ey,\n", - " center=mp.Vector3(-0.5*sx+dpml),\n", - " size=mp.Vector3(0,w))]" + "src = [\n", + " mp.Source(\n", + " mp.GaussianSource(fcen, fwidth=df),\n", + " component=mp.Ey,\n", + " center=mp.Vector3(-0.5 * sx + dpml),\n", + " size=mp.Vector3(0, w),\n", + " )\n", + "]" ] }, { @@ -199,12 +204,14 @@ "metadata": {}, "outputs": [], "source": [ - "sim = mp.Simulation(cell_size=cell,\n", - " geometry=geometry,\n", - " boundary_layers=pml_layers,\n", - " sources=src,\n", - " symmetries=sym,\n", - " resolution=resolution)" + "sim = mp.Simulation(\n", + " cell_size=cell,\n", + " geometry=geometry,\n", + " boundary_layers=pml_layers,\n", + " sources=src,\n", + " symmetries=sym,\n", + " resolution=resolution,\n", + ")" ] }, { @@ -220,10 +227,11 @@ "metadata": {}, "outputs": [], "source": [ - "freg = mp.FluxRegion(center=mp.Vector3(0.5*sx-dpml-0.5),\n", - " size=mp.Vector3(0,2*w))\n", + "freg = mp.FluxRegion(\n", + " center=mp.Vector3(0.5 * sx - dpml - 0.5), size=mp.Vector3(0, 2 * w)\n", + ")\n", "\n", - "nfreq = 500 # number of frequencies at which to compute flux\n", + "nfreq = 500 # number of frequencies at which to compute flux\n", "\n", "# transmitted flux\n", "trans = sim.add_flux(fcen, df, nfreq, freg)" @@ -336,10 +344,14 @@ ], "source": [ "f = plt.figure(dpi=150)\n", - "animate = mp.Animate2D(sim,f=f,fields=mp.Hz,realtime=False,normalize=True)\n", + "animate = mp.Animate2D(sim, f=f, fields=mp.Hz, realtime=False, normalize=True)\n", "\n", - "sim.run(mp.during_sources(mp.at_every(0.4, animate)),\n", - " until_after_sources=mp.stop_when_fields_decayed(50, mp.Ey, mp.Vector3(0.5*sx-dpml-0.5), 1e-3))\n", + "sim.run(\n", + " mp.during_sources(mp.at_every(0.4, animate)),\n", + " until_after_sources=mp.stop_when_fields_decayed(\n", + " 50, mp.Ey, mp.Vector3(0.5 * sx - dpml - 0.5), 1e-3\n", + " ),\n", + ")\n", "plt.close()" ] }, @@ -372,8 +384,8 @@ } ], "source": [ - "filename = 'media/hole-wvg-cavity.mp4'\n", - "animate.to_mp4(10,filename)\n", + "filename = \"media/hole-wvg-cavity.mp4\"\n", + "animate.to_mp4(10, filename)\n", "Video(filename)" ] }, @@ -392,35 +404,46 @@ "metadata": {}, "outputs": [], "source": [ - "def sim_cavity(N=3,sy=6):\n", - " sx = 2*(pad+dpml+N)+d-1 # size of cell in x direction\n", - " cell = mp.Vector3(sx,sy,0)\n", - " blk = mp.Block(size=mp.Vector3(mp.inf,w,mp.inf), material=mp.Medium(epsilon=eps))\n", + "def sim_cavity(N=3, sy=6):\n", + " sx = 2 * (pad + dpml + N) + d - 1 # size of cell in x direction\n", + " cell = mp.Vector3(sx, sy, 0)\n", + " blk = mp.Block(size=mp.Vector3(mp.inf, w, mp.inf), material=mp.Medium(epsilon=eps))\n", " geometry = [blk]\n", "\n", " for i in range(N):\n", - " geometry.append(mp.Cylinder(r, center=mp.Vector3(d/2+i)))\n", - " geometry.append(mp.Cylinder(r, center=mp.Vector3(-(d/2+i))))\n", - " \n", - " src = [mp.Source(mp.GaussianSource(fcen, fwidth=df),\n", - " component=mp.Ey,\n", - " center=mp.Vector3(-0.5*sx+dpml),\n", - " size=mp.Vector3(0,w))]\n", - " \n", - " sim = mp.Simulation(cell_size=cell,\n", - " geometry=geometry,\n", - " boundary_layers=pml_layers,\n", - " sources=src,\n", - " symmetries=sym,\n", - " resolution=resolution)\n", - " \n", - " freg = mp.FluxRegion(center=mp.Vector3(0.5*sx-dpml-0.5),\n", - " size=mp.Vector3(0,2*w))\n", + " geometry.append(mp.Cylinder(r, center=mp.Vector3(d / 2 + i)))\n", + " geometry.append(mp.Cylinder(r, center=mp.Vector3(-(d / 2 + i))))\n", + "\n", + " src = [\n", + " mp.Source(\n", + " mp.GaussianSource(fcen, fwidth=df),\n", + " component=mp.Ey,\n", + " center=mp.Vector3(-0.5 * sx + dpml),\n", + " size=mp.Vector3(0, w),\n", + " )\n", + " ]\n", + "\n", + " sim = mp.Simulation(\n", + " cell_size=cell,\n", + " geometry=geometry,\n", + " boundary_layers=pml_layers,\n", + " sources=src,\n", + " symmetries=sym,\n", + " resolution=resolution,\n", + " )\n", + "\n", + " freg = mp.FluxRegion(\n", + " center=mp.Vector3(0.5 * sx - dpml - 0.5), size=mp.Vector3(0, 2 * w)\n", + " )\n", " nfreq = 500\n", " trans = sim.add_flux(fcen, df, nfreq, freg)\n", - " \n", - " sim.run(until_after_sources=mp.stop_when_fields_decayed(50, mp.Ey, mp.Vector3(0.5*sx-dpml-0.5), 1e-3))\n", - " \n", + "\n", + " sim.run(\n", + " until_after_sources=mp.stop_when_fields_decayed(\n", + " 50, mp.Ey, mp.Vector3(0.5 * sx - dpml - 0.5), 1e-3\n", + " )\n", + " )\n", + "\n", " freqs = mp.get_flux_freqs(trans)\n", " psd = mp.get_fluxes(trans)\n", "\n", @@ -502,8 +525,8 @@ } ], "source": [ - "freqs_wg, psd_wg = sim_cavity(N=0) # simple waveguide\n", - "freqs_cav, psd_cav = sim_cavity() # cavity" + "freqs_wg, psd_wg = sim_cavity(N=0) # simple waveguide\n", + "freqs_cav, psd_cav = sim_cavity() # cavity" ] }, { @@ -525,17 +548,17 @@ } ], "source": [ - "fig = plt.figure(figsize=(11,6),dpi=100)\n", + "fig = plt.figure(figsize=(11, 6), dpi=100)\n", "ax = fig.add_subplot(111)\n", - "plt.plot(freqs_cav,np.array(psd_cav)/np.array(psd_wg),'o-')\n", + "plt.plot(freqs_cav, np.array(psd_cav) / np.array(psd_wg), \"o-\")\n", "plt.grid(True)\n", - "plt.xlabel('Frequency')\n", - "plt.ylabel('Transmission')\n", + "plt.xlabel(\"Frequency\")\n", + "plt.ylabel(\"Transmission\")\n", "\n", "ax2 = fig.add_axes([0.52, 0.6, 0.2, 0.25])\n", - "plt.plot(freqs_cav,np.array(psd_cav)/np.array(psd_wg),'o-')\n", - "plt.xlim(0.23,0.24)\n", - "plt.ylim(0,0.8)\n", + "plt.plot(freqs_cav, np.array(psd_cav) / np.array(psd_wg), \"o-\")\n", + "plt.xlim(0.23, 0.24)\n", + "plt.ylim(0, 0.8)\n", "plt.grid(True)" ] }, @@ -567,27 +590,29 @@ "metadata": {}, "outputs": [], "source": [ - "def sim_cavity(N=3,sy=6,fcen=0.25,df=0.2):\n", - " sx = 2*(pad+dpml+N)+d-1 # size of cell in x direction\n", - " cell = mp.Vector3(sx,sy,0)\n", - " blk = mp.Block(size=mp.Vector3(mp.inf,w,mp.inf), material=mp.Medium(epsilon=eps))\n", + "def sim_cavity(N=3, sy=6, fcen=0.25, df=0.2):\n", + " sx = 2 * (pad + dpml + N) + d - 1 # size of cell in x direction\n", + " cell = mp.Vector3(sx, sy, 0)\n", + " blk = mp.Block(size=mp.Vector3(mp.inf, w, mp.inf), material=mp.Medium(epsilon=eps))\n", " geometry = [blk]\n", "\n", " for i in range(N):\n", - " geometry.append(mp.Cylinder(r, center=mp.Vector3(d/2+i)))\n", - " geometry.append(mp.Cylinder(r, center=mp.Vector3(-(d/2+i))))\n", - " \n", + " geometry.append(mp.Cylinder(r, center=mp.Vector3(d / 2 + i)))\n", + " geometry.append(mp.Cylinder(r, center=mp.Vector3(-(d / 2 + i))))\n", + "\n", " src = [mp.Source(mp.GaussianSource(fcen, fwidth=df), mp.Hz, mp.Vector3(0))]\n", - " \n", + "\n", " sym = [mp.Mirror(mp.Y, phase=-1), mp.Mirror(mp.X, phase=-1)]\n", - " \n", - " sim = mp.Simulation(cell_size=cell,\n", - " geometry=geometry,\n", - " boundary_layers=pml_layers,\n", - " sources=src,\n", - " symmetries=sym,\n", - " resolution=resolution)\n", - " \n", + "\n", + " sim = mp.Simulation(\n", + " cell_size=cell,\n", + " geometry=geometry,\n", + " boundary_layers=pml_layers,\n", + " sources=src,\n", + " symmetries=sym,\n", + " resolution=resolution,\n", + " )\n", + "\n", " return sim" ] }, @@ -676,13 +701,12 @@ ], "source": [ "h = mp.Harminv(mp.Hz, mp.Vector3(), fcen, df)\n", - "sim.run(mp.after_sources(h),\n", - " until_after_sources=400)\n", + "sim.run(mp.after_sources(h), until_after_sources=400)\n", "\n", "f = plt.figure(dpi=150)\n", - "animate = mp.Animate2D(sim,f=f,fields=mp.Hz,realtime=False,normalize=True)\n", + "animate = mp.Animate2D(sim, f=f, fields=mp.Hz, realtime=False, normalize=True)\n", "\n", - "sim.run(mp.at_every(1/fcen/20, animate), until=1/fcen)\n", + "sim.run(mp.at_every(1 / fcen / 20, animate), until=1 / fcen)\n", "plt.close()" ] }, @@ -715,8 +739,8 @@ } ], "source": [ - "filename = 'media/hole-wvg-cavity-res.mp4'\n", - "animate.to_mp4(10,filename)\n", + "filename = \"media/hole-wvg-cavity-res.mp4\"\n", + "animate.to_mp4(10, filename)\n", "Video(filename)" ] }, @@ -745,7 +769,7 @@ "Q = [m.Q for m in h.modes]\n", "\n", "for fiter, qiter in zip(f, Q):\n", - " print(f'Resonant frequency: {fiter}, Q: {qiter}') " + " print(f\"Resonant frequency: {fiter}, Q: {qiter}\")" ] }, { @@ -1072,14 +1096,13 @@ } ], "source": [ - "N_vec = np.arange(2,16,2)\n", + "N_vec = np.arange(2, 16, 2)\n", "f = []\n", "Q = []\n", "for N in N_vec:\n", " sim = sim_cavity(N=N)\n", " h = mp.Harminv(mp.Hz, mp.Vector3(), fcen, df)\n", - " sim.run(mp.after_sources(h),\n", - " until_after_sources=400)\n", + " sim.run(mp.after_sources(h), until_after_sources=400)\n", " f.append([m.freq for m in h.modes])\n", " Q.append([m.Q for m in h.modes])" ] @@ -1105,7 +1128,7 @@ ], "source": [ "for fiter, qiter in zip(f, Q):\n", - " print(f'Resonant frequency: {fiter}, Q: {qiter}') " + " print(f\"Resonant frequency: {fiter}, Q: {qiter}\")" ] }, { @@ -1141,10 +1164,10 @@ " Q_fund[i] = Q[i][int(idx[i])]\n", "\n", "plt.figure(dpi=150)\n", - "plt.semilogy(N_vec,Q_fund,'o-')\n", + "plt.semilogy(N_vec, Q_fund, \"o-\")\n", "plt.grid(True)\n", - "plt.xlabel('N (# of periods)')\n", - "plt.ylabel('Q')\n", + "plt.xlabel(\"N (# of periods)\")\n", + "plt.ylabel(\"Q\")\n", "plt.show()" ] }, @@ -1245,7 +1268,7 @@ } ], "source": [ - "sim = sim_cavity(N=16,sy=12,fcen=0.328227374843021,df=0.1)\n", + "sim = sim_cavity(N=16, sy=12, fcen=0.328227374843021, df=0.1)\n", "sim.run(until_after_sources=600)" ] }, @@ -1269,7 +1292,7 @@ ], "source": [ "f = plt.figure(dpi=150)\n", - "sim.plot2D(ax=f.gca(),fields=mp.Hz)\n", + "sim.plot2D(ax=f.gca(), fields=mp.Hz)\n", "plt.show()" ] }, diff --git a/python/examples/metal-cavity-ldos.ipynb b/python/examples/metal-cavity-ldos.ipynb index 6de91e4da..9f488cc65 100644 --- a/python/examples/metal-cavity-ldos.ipynb +++ b/python/examples/metal-cavity-ldos.ipynb @@ -34,37 +34,46 @@ "import numpy as np\n", "import matplotlib.pyplot as plt\n", "\n", + "\n", "def metal_cavity(w):\n", " resolution = 50\n", " sxy = 2\n", " dpml = 1\n", - " sxy = sxy+2*dpml\n", - " cell = mp.Vector3(sxy,sxy)\n", + " sxy = sxy + 2 * dpml\n", + " cell = mp.Vector3(sxy, sxy)\n", "\n", " pml_layers = [mp.PML(dpml)]\n", " a = 1\n", " t = 0.1\n", - " geometry = [mp.Block(mp.Vector3(a+2*t,a+2*t,mp.inf), material=mp.metal),\n", - " mp.Block(mp.Vector3(a,a,mp.inf), material=mp.air)]\n", - "\n", - " geometry.append(mp.Block(center=mp.Vector3(a/2),\n", - " size=mp.Vector3(2*t,w,mp.inf),\n", - " material=mp.air))\n", - "\n", - " fcen = math.sqrt(0.5)/a\n", + " geometry = [\n", + " mp.Block(mp.Vector3(a + 2 * t, a + 2 * t, mp.inf), material=mp.metal),\n", + " mp.Block(mp.Vector3(a, a, mp.inf), material=mp.air),\n", + " ]\n", + "\n", + " geometry.append(\n", + " mp.Block(\n", + " center=mp.Vector3(a / 2), size=mp.Vector3(2 * t, w, mp.inf), material=mp.air\n", + " )\n", + " )\n", + "\n", + " fcen = math.sqrt(0.5) / a\n", " df = 0.2\n", - " sources = [mp.Source(src=mp.GaussianSource(fcen,fwidth=df),\n", - " component=mp.Ez,\n", - " center=mp.Vector3())]\n", + " sources = [\n", + " mp.Source(\n", + " src=mp.GaussianSource(fcen, fwidth=df), component=mp.Ez, center=mp.Vector3()\n", + " )\n", + " ]\n", "\n", " symmetries = [mp.Mirror(mp.Y)]\n", "\n", - " sim = mp.Simulation(cell_size=cell,\n", - " geometry=geometry,\n", - " boundary_layers=pml_layers,\n", - " sources=sources,\n", - " symmetries=symmetries,\n", - " resolution=resolution)\n", + " sim = mp.Simulation(\n", + " cell_size=cell,\n", + " geometry=geometry,\n", + " boundary_layers=pml_layers,\n", + " sources=sources,\n", + " symmetries=symmetries,\n", + " resolution=resolution,\n", + " )\n", "\n", " h = mp.Harminv(mp.Ez, mp.Vector3(), fcen, df)\n", " sim.run(mp.after_sources(h), until_after_sources=500)\n", @@ -72,13 +81,13 @@ " m = h.modes[0]\n", " f = m.freq\n", " Q = m.Q\n", - " Vmode = 0.25*a*a\n", + " Vmode = 0.25 * a * a\n", " ldos_1 = Q / Vmode / (2 * math.pi * f * math.pi * 0.5)\n", - " \n", + "\n", " sim.reset_meep()\n", - " \n", - " T = 2*Q*(1/f)\n", - " sim.run(mp.dft_ldos(f,0,1), until_after_sources=T)\n", + "\n", + " T = 2 * Q * (1 / f)\n", + " sim.run(mp.dft_ldos(f, 0, 1), until_after_sources=T)\n", " ldos_2 = sim.ldos_data[0]\n", "\n", " return ldos_1, ldos_2" @@ -99,13 +108,13 @@ "metadata": {}, "outputs": [], "source": [ - "ws = np.arange(0.2,0.5,0.1)\n", + "ws = np.arange(0.2, 0.5, 0.1)\n", "ldos_1 = np.zeros(len(ws))\n", "ldos_2 = np.zeros(len(ws))\n", "\n", "for j in range(len(ws)):\n", " ldos_1[j], ldos_2[j] = metal_cavity(ws[j])\n", - " print(\"ldos:, {}, {}\".format(ldos_1[j],ldos_2[2]))" + " print(\"ldos:, {}, {}\".format(ldos_1[j], ldos_2[2]))" ] }, { @@ -115,10 +124,10 @@ "outputs": [], "source": [ "plt.figure(dpi=150)\n", - "plt.semilogy(1/ws,ldos_1,'bo-',label=\"2Q/(πωV)\")\n", - "plt.semilogy(1/ws,ldos_2,'rs-',label=\"LDOS\")\n", - "plt.xlabel('a/w')\n", - "plt.ylabel('2Q/(πωW) or LDOS')\n", + "plt.semilogy(1 / ws, ldos_1, \"bo-\", label=\"2Q/(πωV)\")\n", + "plt.semilogy(1 / ws, ldos_2, \"rs-\", label=\"LDOS\")\n", + "plt.xlabel(\"a/w\")\n", + "plt.ylabel(\"2Q/(πωW) or LDOS\")\n", "plt.show()" ] }, diff --git a/python/examples/metasurface_lens.ipynb b/python/examples/metasurface_lens.ipynb index a855f3b82..7fb38949a 100644 --- a/python/examples/metasurface_lens.ipynb +++ b/python/examples/metasurface_lens.ipynb @@ -26,114 +26,163 @@ "import numpy as np\n", "import matplotlib.pyplot as plt\n", "\n", - "resolution = 50 # pixels/μm\n", + "resolution = 50 # pixels/μm\n", "\n", - "dpml = 1.0 # PML thickness\n", - "dsub = 2.0 # substrate thickness\n", - "dpad = 2.0 # padding between grating and PML\n", + "dpml = 1.0 # PML thickness\n", + "dsub = 2.0 # substrate thickness\n", + "dpad = 2.0 # padding between grating and PML\n", "\n", - "lcen = 0.5 # center wavelength\n", - "fcen = 1/lcen # center frequency\n", - "df = 0.2*fcen # frequency width\n", + "lcen = 0.5 # center wavelength\n", + "fcen = 1 / lcen # center frequency\n", + "df = 0.2 * fcen # frequency width\n", "\n", - "focal_length = 200 # focal length of metalens\n", - "spot_length = 100 # far field line length\n", - "ff_res = 10 # far field resolution (points/μm)\n", + "focal_length = 200 # focal length of metalens\n", + "spot_length = 100 # far field line length\n", + "ff_res = 10 # far field resolution (points/μm)\n", "\n", - "k_point = mp.Vector3(0,0,0)\n", + "k_point = mp.Vector3(0, 0, 0)\n", "\n", "glass = mp.Medium(index=1.5)\n", "\n", - "pml_layers = [mp.PML(thickness=dpml,direction=mp.X)]\n", + "pml_layers = [mp.PML(thickness=dpml, direction=mp.X)]\n", "\n", - "symmetries=[mp.Mirror(mp.Y)]\n", + "symmetries = [mp.Mirror(mp.Y)]\n", "\n", - "def grating(gp,gh,gdc_list):\n", - " sx = dpml+dsub+gh+dpad+dpml\n", - " src_pt = mp.Vector3(-0.5*sx+dpml+0.5*dsub)\n", - " mon_pt = mp.Vector3(0.5*sx-dpml-0.5*dpad)\n", - " geometry = [mp.Block(material=glass,\n", - " size=mp.Vector3(dpml+dsub,mp.inf,mp.inf),\n", - " center=mp.Vector3(-0.5*sx+0.5*(dpml+dsub)))]\n", "\n", - " num_cells = len(gdc_list)\n", - " if num_cells == 1:\n", - " sy = gp\n", - " cell_size = mp.Vector3(sx,sy)\n", + "def grating(gp, gh, gdc_list):\n", + " sx = dpml + dsub + gh + dpad + dpml\n", + " src_pt = mp.Vector3(-0.5 * sx + dpml + 0.5 * dsub)\n", + " mon_pt = mp.Vector3(0.5 * sx - dpml - 0.5 * dpad)\n", + " geometry = [\n", + " mp.Block(\n", + " material=glass,\n", + " size=mp.Vector3(dpml + dsub, mp.inf, mp.inf),\n", + " center=mp.Vector3(-0.5 * sx + 0.5 * (dpml + dsub)),\n", + " )\n", + " ]\n", "\n", - " sources = [mp.Source(mp.GaussianSource(fcen, fwidth=df),\n", - " component=mp.Ez,\n", - " center=src_pt,\n", - " size=mp.Vector3(y=sy))]\n", + " num_cells = len(gdc_list)\n", + " if num_cells == 1:\n", + " sy = gp\n", + " cell_size = mp.Vector3(sx, sy)\n", "\n", - " sim = mp.Simulation(resolution=resolution,\n", - " cell_size=cell_size,\n", - " boundary_layers=pml_layers,\n", - " k_point=k_point,\n", - " default_material=glass,\n", - " sources=sources,\n", - " symmetries=symmetries)\n", + " sources = [\n", + " mp.Source(\n", + " mp.GaussianSource(fcen, fwidth=df),\n", + " component=mp.Ez,\n", + " center=src_pt,\n", + " size=mp.Vector3(y=sy),\n", + " )\n", + " ]\n", "\n", - " flux_obj = sim.add_flux(fcen, 0, 1, mp.FluxRegion(center=mon_pt, size=mp.Vector3(y=sy)))\n", + " sim = mp.Simulation(\n", + " resolution=resolution,\n", + " cell_size=cell_size,\n", + " boundary_layers=pml_layers,\n", + " k_point=k_point,\n", + " default_material=glass,\n", + " sources=sources,\n", + " symmetries=symmetries,\n", + " )\n", "\n", - " sim.run(until_after_sources=50)\n", - " \n", - " input_flux = mp.get_fluxes(flux_obj)\n", - " \n", - " sim.reset_meep()\n", + " flux_obj = sim.add_flux(\n", + " fcen, 0, 1, mp.FluxRegion(center=mon_pt, size=mp.Vector3(y=sy))\n", + " )\n", "\n", - " geometry.append(mp.Block(material=glass, size=mp.Vector3(gh,gdc_list[0]*gp,mp.inf), center=mp.Vector3(-0.5*sx+dpml+dsub+0.5*gh)))\n", + " sim.run(until_after_sources=50)\n", "\n", - " sim = mp.Simulation(resolution=resolution,\n", - " cell_size=cell_size,\n", - " boundary_layers=pml_layers,\n", - " geometry=geometry,\n", - " k_point=k_point,\n", - " sources=sources,\n", - " symmetries=symmetries)\n", + " input_flux = mp.get_fluxes(flux_obj)\n", "\n", - " flux_obj = sim.add_flux(fcen, 0, 1, mp.FluxRegion(center=mon_pt, size=mp.Vector3(y=sy)))\n", + " sim.reset_meep()\n", "\n", - " sim.run(until_after_sources=200)\n", - " \n", - " freqs = mp.get_eigenmode_freqs(flux_obj)\n", - " res = sim.get_eigenmode_coefficients(flux_obj, [1], eig_parity=mp.ODD_Z+mp.EVEN_Y)\n", - " coeffs = res.alpha\n", + " geometry.append(\n", + " mp.Block(\n", + " material=glass,\n", + " size=mp.Vector3(gh, gdc_list[0] * gp, mp.inf),\n", + " center=mp.Vector3(-0.5 * sx + dpml + dsub + 0.5 * gh),\n", + " )\n", + " )\n", "\n", - " mode_tran = abs(coeffs[0,0,0])**2/input_flux[0]\n", - " mode_phase = np.angle(coeffs[0,0,0])\n", - " if mode_phase > 0:\n", - " mode_phase -= 2*np.pi\n", - " \n", - " return mode_tran, mode_phase\n", - " \n", - " else: \n", - " sy = num_cells*gp\n", - " cell_size = mp.Vector3(sx,sy)\n", + " sim = mp.Simulation(\n", + " resolution=resolution,\n", + " cell_size=cell_size,\n", + " boundary_layers=pml_layers,\n", + " geometry=geometry,\n", + " k_point=k_point,\n", + " sources=sources,\n", + " symmetries=symmetries,\n", + " )\n", "\n", - " sources = [mp.Source(mp.GaussianSource(fcen, fwidth=df),\n", - " component=mp.Ez,\n", - " center=src_pt,\n", - " size=mp.Vector3(y=sy))]\n", + " flux_obj = sim.add_flux(\n", + " fcen, 0, 1, mp.FluxRegion(center=mon_pt, size=mp.Vector3(y=sy))\n", + " )\n", "\n", - " for j in range(num_cells):\n", - " geometry.append(mp.Block(material=glass,\n", - " size=mp.Vector3(gh,gdc_list[j]*gp,mp.inf),\n", - " center=mp.Vector3(-0.5*sx+dpml+dsub+0.5*gh,-0.5*sy+(j+0.5)*gp)))\n", + " sim.run(until_after_sources=200)\n", "\n", - " sim = mp.Simulation(resolution=resolution,\n", - " cell_size=cell_size,\n", - " boundary_layers=pml_layers,\n", - " geometry=geometry,\n", - " k_point=k_point,\n", - " sources=sources,\n", - " symmetries=symmetries)\n", + " freqs = mp.get_eigenmode_freqs(flux_obj)\n", + " res = sim.get_eigenmode_coefficients(\n", + " flux_obj, [1], eig_parity=mp.ODD_Z + mp.EVEN_Y\n", + " )\n", + " coeffs = res.alpha\n", "\n", - " n2f_obj = sim.add_near2far(fcen, 0, 1, mp.Near2FarRegion(center=mon_pt, size=mp.Vector3(y=sy)))\n", + " mode_tran = abs(coeffs[0, 0, 0]) ** 2 / input_flux[0]\n", + " mode_phase = np.angle(coeffs[0, 0, 0])\n", + " if mode_phase > 0:\n", + " mode_phase -= 2 * np.pi\n", "\n", - " sim.run(until_after_sources=100)\n", - " \n", - " return abs(sim.get_farfields(n2f_obj, ff_res, center=mp.Vector3(-0.5*sx+dpml+dsub+gh+focal_length), size=mp.Vector3(spot_length))['Ez'])**2" + " return mode_tran, mode_phase\n", + "\n", + " else:\n", + " sy = num_cells * gp\n", + " cell_size = mp.Vector3(sx, sy)\n", + "\n", + " sources = [\n", + " mp.Source(\n", + " mp.GaussianSource(fcen, fwidth=df),\n", + " component=mp.Ez,\n", + " center=src_pt,\n", + " size=mp.Vector3(y=sy),\n", + " )\n", + " ]\n", + "\n", + " for j in range(num_cells):\n", + " geometry.append(\n", + " mp.Block(\n", + " material=glass,\n", + " size=mp.Vector3(gh, gdc_list[j] * gp, mp.inf),\n", + " center=mp.Vector3(\n", + " -0.5 * sx + dpml + dsub + 0.5 * gh, -0.5 * sy + (j + 0.5) * gp\n", + " ),\n", + " )\n", + " )\n", + "\n", + " sim = mp.Simulation(\n", + " resolution=resolution,\n", + " cell_size=cell_size,\n", + " boundary_layers=pml_layers,\n", + " geometry=geometry,\n", + " k_point=k_point,\n", + " sources=sources,\n", + " symmetries=symmetries,\n", + " )\n", + "\n", + " n2f_obj = sim.add_near2far(\n", + " fcen, 0, 1, mp.Near2FarRegion(center=mon_pt, size=mp.Vector3(y=sy))\n", + " )\n", + "\n", + " sim.run(until_after_sources=100)\n", + "\n", + " return (\n", + " abs(\n", + " sim.get_farfields(\n", + " n2f_obj,\n", + " ff_res,\n", + " center=mp.Vector3(-0.5 * sx + dpml + dsub + gh + focal_length),\n", + " size=mp.Vector3(spot_length),\n", + " )[\"Ez\"]\n", + " )\n", + " ** 2\n", + " )" ] }, { @@ -1080,14 +1129,14 @@ } ], "source": [ - "gp = 0.3 # grating periodicity\n", - "gh = 1.8 # grating height\n", - "gdc = np.linspace(0.1,0.9,30) # grating duty cycle\n", + "gp = 0.3 # grating periodicity\n", + "gh = 1.8 # grating height\n", + "gdc = np.linspace(0.1, 0.9, 30) # grating duty cycle\n", "\n", "mode_tran = np.empty((gdc.size))\n", "mode_phase = np.empty((gdc.size))\n", "for n in range(gdc.size):\n", - " mode_tran[n], mode_phase[n] = grating(gp,gh,[gdc[n]])" + " mode_tran[n], mode_phase[n] = grating(gp, gh, [gdc[n]])" ] }, { @@ -1110,23 +1159,23 @@ ], "source": [ "plt.figure(dpi=200)\n", - "plt.subplot(1,2,1)\n", - "plt.plot(gdc, mode_tran, 'bo-')\n", - "plt.xlim(gdc[0],gdc[-1])\n", - "plt.xticks([t for t in np.linspace(0.1,0.9,5)])\n", + "plt.subplot(1, 2, 1)\n", + "plt.plot(gdc, mode_tran, \"bo-\")\n", + "plt.xlim(gdc[0], gdc[-1])\n", + "plt.xticks([t for t in np.linspace(0.1, 0.9, 5)])\n", "plt.xlabel(\"grating duty cycle\")\n", - "plt.ylim(0.96,1.00)\n", - "plt.yticks([t for t in np.linspace(0.96,1.00,5)])\n", + "plt.ylim(0.96, 1.00)\n", + "plt.yticks([t for t in np.linspace(0.96, 1.00, 5)])\n", "plt.title(\"transmittance\")\n", "\n", - "plt.subplot(1,2,2)\n", - "plt.plot(gdc, mode_phase, 'rs-')\n", + "plt.subplot(1, 2, 2)\n", + "plt.plot(gdc, mode_phase, \"rs-\")\n", "plt.grid(True)\n", - "plt.xlim(gdc[0],gdc[-1])\n", - "plt.xticks([t for t in np.linspace(0.1,0.9,5)])\n", + "plt.xlim(gdc[0], gdc[-1])\n", + "plt.xticks([t for t in np.linspace(0.1, 0.9, 5)])\n", "plt.xlabel(\"grating duty cycle\")\n", - "plt.ylim(-2*np.pi,0)\n", - "plt.yticks([t for t in np.linspace(-6,0,7)])\n", + "plt.ylim(-2 * np.pi, 0)\n", + "plt.yticks([t for t in np.linspace(-6, 0, 7)])\n", "plt.title(\"phase (radians)\")\n", "\n", "plt.tight_layout(pad=0.5)\n", @@ -1478,27 +1527,39 @@ } ], "source": [ - "gdc_new = np.linspace(0.16,0.65,500)\n", + "gdc_new = np.linspace(0.16, 0.65, 500)\n", "mode_phase_interp = np.interp(gdc_new, gdc, mode_phase)\n", - "print(\"phase-range:, {:.6f}\".format(mode_phase_interp.max()-mode_phase_interp.min()))\n", + "print(\"phase-range:, {:.6f}\".format(mode_phase_interp.max() - mode_phase_interp.min()))\n", "\n", "phase_tol = 1e-2\n", - "num_cells = [100,200,400]\n", - "ff_nc = np.empty((spot_length*ff_res,len(num_cells)))\n", + "num_cells = [100, 200, 400]\n", + "ff_nc = np.empty((spot_length * ff_res, len(num_cells)))\n", "\n", "for k in range(len(num_cells)):\n", - " gdc_list = []\n", - " for j in range(-num_cells[k],num_cells[k]+1):\n", - " phase_local = 2*np.pi/lcen * (focal_length-((j*gp)**2 + focal_length**2)**0.5) # local phase at the center of the j'th unit cell\n", - " phase_mod = phase_local % (-2*np.pi) # restrict phase to [-2*pi,0]\n", - " if phase_mod > mode_phase_interp.max():\n", - " phase_mod = mode_phase_interp.max()\n", - " if phase_mod < mode_phase_interp.min():\n", - " phase_mod = mode_phase_interp.min()\n", - " idx = np.transpose(np.nonzero(np.logical_and(mode_phase_interp > phase_mod-phase_tol, mode_phase_interp < phase_mod+phase_tol))).ravel()\n", - " gdc_list.append(gdc_new[idx[0]])\n", + " gdc_list = []\n", + " for j in range(-num_cells[k], num_cells[k] + 1):\n", + " phase_local = (\n", + " 2\n", + " * np.pi\n", + " / lcen\n", + " * (focal_length - ((j * gp) ** 2 + focal_length**2) ** 0.5)\n", + " ) # local phase at the center of the j'th unit cell\n", + " phase_mod = phase_local % (-2 * np.pi) # restrict phase to [-2*pi,0]\n", + " if phase_mod > mode_phase_interp.max():\n", + " phase_mod = mode_phase_interp.max()\n", + " if phase_mod < mode_phase_interp.min():\n", + " phase_mod = mode_phase_interp.min()\n", + " idx = np.transpose(\n", + " np.nonzero(\n", + " np.logical_and(\n", + " mode_phase_interp > phase_mod - phase_tol,\n", + " mode_phase_interp < phase_mod + phase_tol,\n", + " )\n", + " )\n", + " ).ravel()\n", + " gdc_list.append(gdc_new[idx[0]])\n", "\n", - " ff_nc[:,k] = grating(gp,gh,gdc_list)" + " ff_nc[:, k] = grating(gp, gh, gdc_list)" ] }, { @@ -1531,15 +1592,25 @@ } ], "source": [ - "x = np.linspace(focal_length-0.5*spot_length,focal_length+0.5*spot_length,ff_res*spot_length)\n", + "x = np.linspace(\n", + " focal_length - 0.5 * spot_length,\n", + " focal_length + 0.5 * spot_length,\n", + " ff_res * spot_length,\n", + ")\n", "plt.figure(dpi=200)\n", - "plt.semilogy(x,abs(ff_nc[:,0])**2,'bo-',label='num_cells = {}'.format(2*num_cells[0]+1))\n", - "plt.semilogy(x,abs(ff_nc[:,1])**2,'ro-',label='num_cells = {}'.format(2*num_cells[1]+1))\n", - "plt.semilogy(x,abs(ff_nc[:,2])**2,'go-',label='num_cells = {}'.format(2*num_cells[2]+1))\n", - "plt.xlabel('x coordinate (μm)')\n", - "plt.ylabel(r'energy density of far-field electric fields, |E$_z$|$^2$')\n", - "plt.title('focusing properties of a binary-grating metasurface lens')\n", - "plt.legend(loc='upper right')\n", + "plt.semilogy(\n", + " x, abs(ff_nc[:, 0]) ** 2, \"bo-\", label=\"num_cells = {}\".format(2 * num_cells[0] + 1)\n", + ")\n", + "plt.semilogy(\n", + " x, abs(ff_nc[:, 1]) ** 2, \"ro-\", label=\"num_cells = {}\".format(2 * num_cells[1] + 1)\n", + ")\n", + "plt.semilogy(\n", + " x, abs(ff_nc[:, 2]) ** 2, \"go-\", label=\"num_cells = {}\".format(2 * num_cells[2] + 1)\n", + ")\n", + "plt.xlabel(\"x coordinate (μm)\")\n", + "plt.ylabel(r\"energy density of far-field electric fields, |E$_z$|$^2$\")\n", + "plt.title(\"focusing properties of a binary-grating metasurface lens\")\n", + "plt.legend(loc=\"upper right\")\n", "plt.tight_layout()\n", "plt.show()" ] diff --git a/python/examples/mie_scattering.ipynb b/python/examples/mie_scattering.ipynb index d6b2790a2..65050ed7a 100644 --- a/python/examples/mie_scattering.ipynb +++ b/python/examples/mie_scattering.ipynb @@ -24,48 +24,83 @@ "\n", "r = 1.0 # radius of sphere\n", "\n", - "wvl_min = 2*np.pi*r/10\n", - "wvl_max = 2*np.pi*r/2\n", + "wvl_min = 2 * np.pi * r / 10\n", + "wvl_max = 2 * np.pi * r / 2\n", "\n", - "frq_min = 1/wvl_max\n", - "frq_max = 1/wvl_min\n", - "frq_cen = 0.5*(frq_min+frq_max)\n", - "dfrq = frq_max-frq_min\n", + "frq_min = 1 / wvl_max\n", + "frq_max = 1 / wvl_min\n", + "frq_cen = 0.5 * (frq_min + frq_max)\n", + "dfrq = frq_max - frq_min\n", "nfrq = 100\n", "\n", "## at least 8 pixels per smallest wavelength, i.e. np.floor(8/wvl_min)\n", "resolution = 25\n", "\n", - "dpml = 0.5*wvl_max\n", - "dair = 0.5*wvl_max\n", + "dpml = 0.5 * wvl_max\n", + "dair = 0.5 * wvl_max\n", "\n", "pml_layers = [mp.PML(thickness=dpml)]\n", "\n", - "symmetries = [mp.Mirror(mp.Y),\n", - " mp.Mirror(mp.Z,phase=-1)]\n", + "symmetries = [mp.Mirror(mp.Y), mp.Mirror(mp.Z, phase=-1)]\n", "\n", - "s = 2*(dpml+dair+r)\n", - "cell_size = mp.Vector3(s,s,s)\n", + "s = 2 * (dpml + dair + r)\n", + "cell_size = mp.Vector3(s, s, s)\n", "\n", "# is_integrated=True necessary for any planewave source extending into PML\n", - "sources = [mp.Source(mp.GaussianSource(frq_cen,fwidth=dfrq,is_integrated=True),\n", - " center=mp.Vector3(-0.5*s+dpml),\n", - " size=mp.Vector3(0,s,s),\n", - " component=mp.Ez)]\n", - "\n", - "sim = mp.Simulation(resolution=resolution,\n", - " cell_size=cell_size,\n", - " boundary_layers=pml_layers,\n", - " sources=sources,\n", - " k_point=mp.Vector3(),\n", - " symmetries=symmetries)\n", - "\n", - "box_x1 = sim.add_flux(frq_cen, dfrq, nfrq, mp.FluxRegion(center=mp.Vector3(x=-r),size=mp.Vector3(0,2*r,2*r)))\n", - "box_x2 = sim.add_flux(frq_cen, dfrq, nfrq, mp.FluxRegion(center=mp.Vector3(x=+r),size=mp.Vector3(0,2*r,2*r)))\n", - "box_y1 = sim.add_flux(frq_cen, dfrq, nfrq, mp.FluxRegion(center=mp.Vector3(y=-r),size=mp.Vector3(2*r,0,2*r)))\n", - "box_y2 = sim.add_flux(frq_cen, dfrq, nfrq, mp.FluxRegion(center=mp.Vector3(y=+r),size=mp.Vector3(2*r,0,2*r)))\n", - "box_z1 = sim.add_flux(frq_cen, dfrq, nfrq, mp.FluxRegion(center=mp.Vector3(z=-r),size=mp.Vector3(2*r,2*r,0)))\n", - "box_z2 = sim.add_flux(frq_cen, dfrq, nfrq, mp.FluxRegion(center=mp.Vector3(z=+r),size=mp.Vector3(2*r,2*r,0)))\n", + "sources = [\n", + " mp.Source(\n", + " mp.GaussianSource(frq_cen, fwidth=dfrq, is_integrated=True),\n", + " center=mp.Vector3(-0.5 * s + dpml),\n", + " size=mp.Vector3(0, s, s),\n", + " component=mp.Ez,\n", + " )\n", + "]\n", + "\n", + "sim = mp.Simulation(\n", + " resolution=resolution,\n", + " cell_size=cell_size,\n", + " boundary_layers=pml_layers,\n", + " sources=sources,\n", + " k_point=mp.Vector3(),\n", + " symmetries=symmetries,\n", + ")\n", + "\n", + "box_x1 = sim.add_flux(\n", + " frq_cen,\n", + " dfrq,\n", + " nfrq,\n", + " mp.FluxRegion(center=mp.Vector3(x=-r), size=mp.Vector3(0, 2 * r, 2 * r)),\n", + ")\n", + "box_x2 = sim.add_flux(\n", + " frq_cen,\n", + " dfrq,\n", + " nfrq,\n", + " mp.FluxRegion(center=mp.Vector3(x=+r), size=mp.Vector3(0, 2 * r, 2 * r)),\n", + ")\n", + "box_y1 = sim.add_flux(\n", + " frq_cen,\n", + " dfrq,\n", + " nfrq,\n", + " mp.FluxRegion(center=mp.Vector3(y=-r), size=mp.Vector3(2 * r, 0, 2 * r)),\n", + ")\n", + "box_y2 = sim.add_flux(\n", + " frq_cen,\n", + " dfrq,\n", + " nfrq,\n", + " mp.FluxRegion(center=mp.Vector3(y=+r), size=mp.Vector3(2 * r, 0, 2 * r)),\n", + ")\n", + "box_z1 = sim.add_flux(\n", + " frq_cen,\n", + " dfrq,\n", + " nfrq,\n", + " mp.FluxRegion(center=mp.Vector3(z=-r), size=mp.Vector3(2 * r, 2 * r, 0)),\n", + ")\n", + "box_z2 = sim.add_flux(\n", + " frq_cen,\n", + " dfrq,\n", + " nfrq,\n", + " mp.FluxRegion(center=mp.Vector3(z=+r), size=mp.Vector3(2 * r, 2 * r, 0)),\n", + ")\n", "\n", "sim.run(until_after_sources=10)\n", "\n", @@ -82,24 +117,56 @@ "sim.reset_meep()\n", "\n", "n_sphere = 2.0\n", - "geometry = [mp.Sphere(material=mp.Medium(index=n_sphere),\n", - " center=mp.Vector3(),\n", - " radius=r)]\n", - "\n", - "sim = mp.Simulation(resolution=resolution,\n", - " cell_size=cell_size,\n", - " boundary_layers=pml_layers,\n", - " sources=sources,\n", - " k_point=mp.Vector3(),\n", - " symmetries=symmetries,\n", - " geometry=geometry)\n", - "\n", - "box_x1 = sim.add_flux(frq_cen, dfrq, nfrq, mp.FluxRegion(center=mp.Vector3(x=-r),size=mp.Vector3(0,2*r,2*r)))\n", - "box_x2 = sim.add_flux(frq_cen, dfrq, nfrq, mp.FluxRegion(center=mp.Vector3(x=+r),size=mp.Vector3(0,2*r,2*r)))\n", - "box_y1 = sim.add_flux(frq_cen, dfrq, nfrq, mp.FluxRegion(center=mp.Vector3(y=-r),size=mp.Vector3(2*r,0,2*r)))\n", - "box_y2 = sim.add_flux(frq_cen, dfrq, nfrq, mp.FluxRegion(center=mp.Vector3(y=+r),size=mp.Vector3(2*r,0,2*r)))\n", - "box_z1 = sim.add_flux(frq_cen, dfrq, nfrq, mp.FluxRegion(center=mp.Vector3(z=-r),size=mp.Vector3(2*r,2*r,0)))\n", - "box_z2 = sim.add_flux(frq_cen, dfrq, nfrq, mp.FluxRegion(center=mp.Vector3(z=+r),size=mp.Vector3(2*r,2*r,0)))\n", + "geometry = [\n", + " mp.Sphere(material=mp.Medium(index=n_sphere), center=mp.Vector3(), radius=r)\n", + "]\n", + "\n", + "sim = mp.Simulation(\n", + " resolution=resolution,\n", + " cell_size=cell_size,\n", + " boundary_layers=pml_layers,\n", + " sources=sources,\n", + " k_point=mp.Vector3(),\n", + " symmetries=symmetries,\n", + " geometry=geometry,\n", + ")\n", + "\n", + "box_x1 = sim.add_flux(\n", + " frq_cen,\n", + " dfrq,\n", + " nfrq,\n", + " mp.FluxRegion(center=mp.Vector3(x=-r), size=mp.Vector3(0, 2 * r, 2 * r)),\n", + ")\n", + "box_x2 = sim.add_flux(\n", + " frq_cen,\n", + " dfrq,\n", + " nfrq,\n", + " mp.FluxRegion(center=mp.Vector3(x=+r), size=mp.Vector3(0, 2 * r, 2 * r)),\n", + ")\n", + "box_y1 = sim.add_flux(\n", + " frq_cen,\n", + " dfrq,\n", + " nfrq,\n", + " mp.FluxRegion(center=mp.Vector3(y=-r), size=mp.Vector3(2 * r, 0, 2 * r)),\n", + ")\n", + "box_y2 = sim.add_flux(\n", + " frq_cen,\n", + " dfrq,\n", + " nfrq,\n", + " mp.FluxRegion(center=mp.Vector3(y=+r), size=mp.Vector3(2 * r, 0, 2 * r)),\n", + ")\n", + "box_z1 = sim.add_flux(\n", + " frq_cen,\n", + " dfrq,\n", + " nfrq,\n", + " mp.FluxRegion(center=mp.Vector3(z=-r), size=mp.Vector3(2 * r, 2 * r, 0)),\n", + ")\n", + "box_z2 = sim.add_flux(\n", + " frq_cen,\n", + " dfrq,\n", + " nfrq,\n", + " mp.FluxRegion(center=mp.Vector3(z=+r), size=mp.Vector3(2 * r, 2 * r, 0)),\n", + ")\n", "\n", "sim.load_minus_flux_data(box_x1, box_x1_data)\n", "sim.load_minus_flux_data(box_x2, box_x2_data)\n", @@ -117,11 +184,20 @@ "box_z1_flux = mp.get_fluxes(box_z1)\n", "box_z2_flux = mp.get_fluxes(box_z2)\n", "\n", - "scatt_flux = np.asarray(box_x1_flux)-np.asarray(box_x2_flux)+np.asarray(box_y1_flux)-np.asarray(box_y2_flux)+np.asarray(box_z1_flux)-np.asarray(box_z2_flux)\n", - "intensity = np.asarray(box_x1_flux0)/(2*r)**2\n", - "scatt_cross_section = np.divide(scatt_flux,intensity)\n", - "scatt_eff_meep = scatt_cross_section*-1/(np.pi*r**2)\n", - "scatt_eff_theory = [ps.MieQ(n_sphere,1000/f,2*r*1000,asDict=True)['Qsca'] for f in freqs]" + "scatt_flux = (\n", + " np.asarray(box_x1_flux)\n", + " - np.asarray(box_x2_flux)\n", + " + np.asarray(box_y1_flux)\n", + " - np.asarray(box_y2_flux)\n", + " + np.asarray(box_z1_flux)\n", + " - np.asarray(box_z2_flux)\n", + ")\n", + "intensity = np.asarray(box_x1_flux0) / (2 * r) ** 2\n", + "scatt_cross_section = np.divide(scatt_flux, intensity)\n", + "scatt_eff_meep = scatt_cross_section * -1 / (np.pi * r**2)\n", + "scatt_eff_theory = [\n", + " ps.MieQ(n_sphere, 1000 / f, 2 * r * 1000, asDict=True)[\"Qsca\"] for f in freqs\n", + "]" ] }, { @@ -140,13 +216,13 @@ "outputs": [], "source": [ "plt.figure(dpi=150)\n", - "plt.loglog(2*np.pi*r*np.asarray(freqs),scatt_eff_meep,'bo-',label='Meep')\n", - "plt.loglog(2*np.pi*r*np.asarray(freqs),scatt_eff_theory,'ro-',label='theory')\n", - "plt.grid(True,which=\"both\",ls=\"-\")\n", - "plt.xlabel('(sphere circumference)/wavelength, 2πr/λ')\n", - "plt.ylabel('scattering efficiency, σ/πr$^{2}$')\n", - "plt.legend(loc='upper right')\n", - "plt.title('Mie Scattering of a Lossless Dielectric Sphere')\n", + "plt.loglog(2 * np.pi * r * np.asarray(freqs), scatt_eff_meep, \"bo-\", label=\"Meep\")\n", + "plt.loglog(2 * np.pi * r * np.asarray(freqs), scatt_eff_theory, \"ro-\", label=\"theory\")\n", + "plt.grid(True, which=\"both\", ls=\"-\")\n", + "plt.xlabel(\"(sphere circumference)/wavelength, 2πr/λ\")\n", + "plt.ylabel(\"scattering efficiency, σ/πr$^{2}$\")\n", + "plt.legend(loc=\"upper right\")\n", + "plt.title(\"Mie Scattering of a Lossless Dielectric Sphere\")\n", "plt.tight_layout()\n", "plt.show()" ] diff --git a/python/examples/mode-decomposition.ipynb b/python/examples/mode-decomposition.ipynb index 3c97872ea..ee0a2f252 100644 --- a/python/examples/mode-decomposition.ipynb +++ b/python/examples/mode-decomposition.ipynb @@ -396,28 +396,27 @@ "import meep as mp\n", "import matplotlib.pyplot as plt\n", "\n", - "resolution = 25 # pixels/μm\n", + "resolution = 25 # pixels/μm\n", "\n", - "w1 = 1.0 # width of waveguide 1\n", - "w2 = 2.0 # width of waveguide 2\n", - "Lw = 10.0 # length of waveguides 1 and 2\n", + "w1 = 1.0 # width of waveguide 1\n", + "w2 = 2.0 # width of waveguide 2\n", + "Lw = 10.0 # length of waveguides 1 and 2\n", "\n", "# lengths of waveguide taper\n", "Lts = [2**m for m in range(4)]\n", "\n", - "dair = 3.0 # length of air region\n", - "dpml_x = 6.0 # length of PML in x direction\n", - "dpml_y = 2.0 # length of PML in y direction\n", + "dair = 3.0 # length of air region\n", + "dpml_x = 6.0 # length of PML in x direction\n", + "dpml_y = 2.0 # length of PML in y direction\n", "\n", - "sy = dpml_y+dair+w2+dair+dpml_y\n", + "sy = dpml_y + dair + w2 + dair + dpml_y\n", "\n", "Si = mp.Medium(epsilon=12.0)\n", "\n", - "boundary_layers = [mp.PML(dpml_x,direction=mp.X),\n", - " mp.PML(dpml_y,direction=mp.Y)]\n", + "boundary_layers = [mp.PML(dpml_x, direction=mp.X), mp.PML(dpml_y, direction=mp.Y)]\n", "\n", - "lcen = 6.67 # mode wavelength\n", - "fcen = 1/lcen # mode frequency\n", + "lcen = 6.67 # mode wavelength\n", + "fcen = 1 / lcen # mode frequency\n", "\n", "symmetries = [mp.Mirror(mp.Y)]\n", "\n", @@ -425,35 +424,45 @@ "R_flux = []\n", "\n", "for Lt in Lts:\n", - " sx = dpml_x+Lw+Lt+Lw+dpml_x\n", - " cell_size = mp.Vector3(sx,sy,0)\n", + " sx = dpml_x + Lw + Lt + Lw + dpml_x\n", + " cell_size = mp.Vector3(sx, sy, 0)\n", "\n", - " src_pt = mp.Vector3(-0.5*sx+dpml_x+0.2*Lw)\n", - " sources = [mp.EigenModeSource(src=mp.GaussianSource(fcen,fwidth=0.2*fcen),\n", - " center=src_pt,\n", - " size=mp.Vector3(y=sy-2*dpml_y),\n", - " eig_match_freq=True,\n", - " eig_parity=mp.ODD_Z+mp.EVEN_Y)]\n", + " src_pt = mp.Vector3(-0.5 * sx + dpml_x + 0.2 * Lw)\n", + " sources = [\n", + " mp.EigenModeSource(\n", + " src=mp.GaussianSource(fcen, fwidth=0.2 * fcen),\n", + " center=src_pt,\n", + " size=mp.Vector3(y=sy - 2 * dpml_y),\n", + " eig_match_freq=True,\n", + " eig_parity=mp.ODD_Z + mp.EVEN_Y,\n", + " )\n", + " ]\n", "\n", " # straight waveguide\n", - " vertices = [mp.Vector3(-0.5*sx-1,0.5*w1),\n", - " mp.Vector3(0.5*sx+1,0.5*w1),\n", - " mp.Vector3(0.5*sx+1,-0.5*w1),\n", - " mp.Vector3(-0.5*sx-1,-0.5*w1)]\n", + " vertices = [\n", + " mp.Vector3(-0.5 * sx - 1, 0.5 * w1),\n", + " mp.Vector3(0.5 * sx + 1, 0.5 * w1),\n", + " mp.Vector3(0.5 * sx + 1, -0.5 * w1),\n", + " mp.Vector3(-0.5 * sx - 1, -0.5 * w1),\n", + " ]\n", "\n", - " sim = mp.Simulation(resolution=resolution,\n", - " cell_size=cell_size,\n", - " boundary_layers=boundary_layers,\n", - " geometry=[mp.Prism(vertices,height=mp.inf,material=Si)],\n", - " sources=sources,\n", - " symmetries=symmetries)\n", + " sim = mp.Simulation(\n", + " resolution=resolution,\n", + " cell_size=cell_size,\n", + " boundary_layers=boundary_layers,\n", + " geometry=[mp.Prism(vertices, height=mp.inf, material=Si)],\n", + " sources=sources,\n", + " symmetries=symmetries,\n", + " )\n", "\n", - " mon_pt = mp.Vector3(-0.5*sx+dpml_x+0.7*Lw)\n", - " flux = sim.add_flux(fcen,0,1,mp.FluxRegion(center=mon_pt,size=mp.Vector3(y=sy-2*dpml_y)))\n", + " mon_pt = mp.Vector3(-0.5 * sx + dpml_x + 0.7 * Lw)\n", + " flux = sim.add_flux(\n", + " fcen, 0, 1, mp.FluxRegion(center=mon_pt, size=mp.Vector3(y=sy - 2 * dpml_y))\n", + " )\n", "\n", - " sim.run(until_after_sources=mp.stop_when_fields_decayed(50,mp.Ez,mon_pt,1e-9))\n", + " sim.run(until_after_sources=mp.stop_when_fields_decayed(50, mp.Ez, mon_pt, 1e-9))\n", "\n", - " res = sim.get_eigenmode_coefficients(flux,[1],eig_parity=mp.ODD_Z+mp.EVEN_Y)\n", + " res = sim.get_eigenmode_coefficients(flux, [1], eig_parity=mp.ODD_Z + mp.EVEN_Y)\n", " incident_coeffs = res.alpha\n", " incident_flux = mp.get_fluxes(flux)\n", " incident_flux_data = sim.get_flux_data(flux)\n", @@ -461,34 +470,42 @@ " sim.reset_meep()\n", "\n", " # linear taper\n", - " vertices = [mp.Vector3(-0.5*sx-1,0.5*w1),\n", - " mp.Vector3(-0.5*Lt,0.5*w1),\n", - " mp.Vector3(0.5*Lt,0.5*w2),\n", - " mp.Vector3(0.5*sx+1,0.5*w2),\n", - " mp.Vector3(0.5*sx+1,-0.5*w2),\n", - " mp.Vector3(0.5*Lt,-0.5*w2),\n", - " mp.Vector3(-0.5*Lt,-0.5*w1),\n", - " mp.Vector3(-0.5*sx-1,-0.5*w1)]\n", + " vertices = [\n", + " mp.Vector3(-0.5 * sx - 1, 0.5 * w1),\n", + " mp.Vector3(-0.5 * Lt, 0.5 * w1),\n", + " mp.Vector3(0.5 * Lt, 0.5 * w2),\n", + " mp.Vector3(0.5 * sx + 1, 0.5 * w2),\n", + " mp.Vector3(0.5 * sx + 1, -0.5 * w2),\n", + " mp.Vector3(0.5 * Lt, -0.5 * w2),\n", + " mp.Vector3(-0.5 * Lt, -0.5 * w1),\n", + " mp.Vector3(-0.5 * sx - 1, -0.5 * w1),\n", + " ]\n", "\n", - " sim = mp.Simulation(resolution=resolution,\n", - " cell_size=cell_size,\n", - " boundary_layers=boundary_layers,\n", - " geometry=[mp.Prism(vertices,height=mp.inf,material=Si)],\n", - " sources=sources,\n", - " symmetries=symmetries)\n", + " sim = mp.Simulation(\n", + " resolution=resolution,\n", + " cell_size=cell_size,\n", + " boundary_layers=boundary_layers,\n", + " geometry=[mp.Prism(vertices, height=mp.inf, material=Si)],\n", + " sources=sources,\n", + " symmetries=symmetries,\n", + " )\n", "\n", - " flux = sim.add_flux(fcen,0,1,mp.FluxRegion(center=mon_pt,size=mp.Vector3(y=sy-2*dpml_y)))\n", - " sim.load_minus_flux_data(flux,incident_flux_data)\n", + " flux = sim.add_flux(\n", + " fcen, 0, 1, mp.FluxRegion(center=mon_pt, size=mp.Vector3(y=sy - 2 * dpml_y))\n", + " )\n", + " sim.load_minus_flux_data(flux, incident_flux_data)\n", "\n", - " sim.run(until_after_sources=mp.stop_when_fields_decayed(50,mp.Ez,mon_pt,1e-9))\n", + " sim.run(until_after_sources=mp.stop_when_fields_decayed(50, mp.Ez, mon_pt, 1e-9))\n", "\n", - " res2 = sim.get_eigenmode_coefficients(flux,[1],eig_parity=mp.ODD_Z+mp.EVEN_Y)\n", + " res2 = sim.get_eigenmode_coefficients(flux, [1], eig_parity=mp.ODD_Z + mp.EVEN_Y)\n", " taper_coeffs = res2.alpha\n", " taper_flux = mp.get_fluxes(flux)\n", "\n", - " R_coeffs.append(abs(taper_coeffs[0,0,1])**2/abs(incident_coeffs[0,0,0])**2)\n", - " R_flux.append(-taper_flux[0]/incident_flux[0])\n", - " print(\"refl:, {}, {:.8f}, {:.8f}\".format(Lt,R_coeffs[-1],R_flux[-1]))" + " R_coeffs.append(\n", + " abs(taper_coeffs[0, 0, 1]) ** 2 / abs(incident_coeffs[0, 0, 0]) ** 2\n", + " )\n", + " R_flux.append(-taper_flux[0] / incident_flux[0])\n", + " print(\"refl:, {}, {:.8f}, {:.8f}\".format(Lt, R_coeffs[-1], R_flux[-1]))" ] }, { @@ -518,12 +535,14 @@ ], "source": [ "plt.figure(dpi=200)\n", - "plt.loglog(Lts,R_coeffs,'bo-',label='mode decomposition')\n", - "plt.loglog(Lts,R_flux,'ro-',label='Poynting flux')\n", - "plt.loglog(Lts,[0.005/Lt**2 for Lt in Lts],'k-',label=r'quadratic reference (1/Lt$^2$)')\n", - "plt.legend(loc='upper right')\n", - "plt.xlabel('taper length Lt (μm)')\n", - "plt.ylabel('reflectance')\n", + "plt.loglog(Lts, R_coeffs, \"bo-\", label=\"mode decomposition\")\n", + "plt.loglog(Lts, R_flux, \"ro-\", label=\"Poynting flux\")\n", + "plt.loglog(\n", + " Lts, [0.005 / Lt**2 for Lt in Lts], \"k-\", label=r\"quadratic reference (1/Lt$^2$)\"\n", + ")\n", + "plt.legend(loc=\"upper right\")\n", + "plt.xlabel(\"taper length Lt (μm)\")\n", + "plt.ylabel(\"reflectance\")\n", "plt.show()" ] }, diff --git a/python/examples/oblique-planewave.ipynb b/python/examples/oblique-planewave.ipynb index 75efcdad6..4083cccc3 100644 --- a/python/examples/oblique-planewave.ipynb +++ b/python/examples/oblique-planewave.ipynb @@ -53,40 +53,46 @@ "metadata": {}, "outputs": [], "source": [ - "def run_sim(rot_angle = 0):\n", + "def run_sim(rot_angle=0):\n", "\n", - " resolution = 50 # pixels/μm\n", + " resolution = 50 # pixels/μm\n", "\n", - " cell_size = mp.Vector3(14,10,0)\n", + " cell_size = mp.Vector3(14, 10, 0)\n", "\n", - " pml_layers = [mp.PML(thickness=2,direction=mp.X)]\n", + " pml_layers = [mp.PML(thickness=2, direction=mp.X)]\n", "\n", - " fsrc = 1.0 # frequency of planewave (wavelength = 1/fsrc)\n", + " fsrc = 1.0 # frequency of planewave (wavelength = 1/fsrc)\n", "\n", - " n = 1.5 # refractive index of homogeneous material\n", + " n = 1.5 # refractive index of homogeneous material\n", " default_material = mp.Medium(index=n)\n", "\n", - " k_point = mp.Vector3(fsrc*n).rotate(mp.Vector3(z=1), rot_angle)\n", + " k_point = mp.Vector3(fsrc * n).rotate(mp.Vector3(z=1), rot_angle)\n", "\n", - " sources = [mp.EigenModeSource(src=mp.ContinuousSource(fsrc),\n", - " center=mp.Vector3(),\n", - " size=mp.Vector3(y=10),\n", - " direction=mp.AUTOMATIC if rot_angle == 0 else mp.NO_DIRECTION,\n", - " eig_kpoint=k_point,\n", - " eig_band=1,\n", - " eig_parity=mp.EVEN_Y+mp.ODD_Z if rot_angle == 0 else mp.ODD_Z,\n", - " eig_match_freq=True)]\n", + " sources = [\n", + " mp.EigenModeSource(\n", + " src=mp.ContinuousSource(fsrc),\n", + " center=mp.Vector3(),\n", + " size=mp.Vector3(y=10),\n", + " direction=mp.AUTOMATIC if rot_angle == 0 else mp.NO_DIRECTION,\n", + " eig_kpoint=k_point,\n", + " eig_band=1,\n", + " eig_parity=mp.EVEN_Y + mp.ODD_Z if rot_angle == 0 else mp.ODD_Z,\n", + " eig_match_freq=True,\n", + " )\n", + " ]\n", "\n", - " sim = mp.Simulation(cell_size=cell_size,\n", - " resolution=resolution,\n", - " boundary_layers=pml_layers,\n", - " sources=sources,\n", - " k_point=k_point,\n", - " default_material=default_material,\n", - " symmetries=[mp.Mirror(mp.Y)] if rot_angle == 0 else [])\n", + " sim = mp.Simulation(\n", + " cell_size=cell_size,\n", + " resolution=resolution,\n", + " boundary_layers=pml_layers,\n", + " sources=sources,\n", + " k_point=k_point,\n", + " default_material=default_material,\n", + " symmetries=[mp.Mirror(mp.Y)] if rot_angle == 0 else [],\n", + " )\n", "\n", " sim.run(until=100)\n", - " \n", + "\n", " plt.figure(dpi=100)\n", " sim.plot2D(fields=mp.Ez)\n", " plt.show()" @@ -219,7 +225,7 @@ } ], "source": [ - "for rot_angle in np.radians([0,20,40]):\n", + "for rot_angle in np.radians([0, 20, 40]):\n", " run_sim(rot_angle)" ] }, diff --git a/python/examples/oblique-source.ipynb b/python/examples/oblique-source.ipynb index 96dec7d27..af62389a5 100644 --- a/python/examples/oblique-source.ipynb +++ b/python/examples/oblique-source.ipynb @@ -62,33 +62,43 @@ "metadata": {}, "outputs": [], "source": [ - "resolution = 20 # pixels/μm\n", + "resolution = 20 # pixels/μm\n", "\n", - "cell_size = mp.Vector3(14,14)\n", + "cell_size = mp.Vector3(14, 14)\n", "\n", "pml_layers = [mp.PML(thickness=2)]\n", "\n", "# rotation angle (in degrees) of waveguide, counter clockwise (CCW) around z-axis\n", "rot_angle = np.radians(20)\n", "\n", - "geometry = [mp.Block(center=mp.Vector3(),\n", - " size=mp.Vector3(mp.inf,1,mp.inf),\n", - " e1 = mp.Vector3(1).rotate(mp.Vector3(z=1), rot_angle),\n", - " e2 = mp.Vector3(y=1).rotate(mp.Vector3(z=1), rot_angle),\n", - " material=mp.Medium(epsilon=12))]\n", + "geometry = [\n", + " mp.Block(\n", + " center=mp.Vector3(),\n", + " size=mp.Vector3(mp.inf, 1, mp.inf),\n", + " e1=mp.Vector3(1).rotate(mp.Vector3(z=1), rot_angle),\n", + " e2=mp.Vector3(y=1).rotate(mp.Vector3(z=1), rot_angle),\n", + " material=mp.Medium(epsilon=12),\n", + " )\n", + "]\n", "\n", - "fsrc = 0.15 # frequency of eigenmode or constant-amplitude source\n", + "fsrc = 0.15 # frequency of eigenmode or constant-amplitude source\n", "\n", - "sources = [mp.Source(src=mp.GaussianSource(fsrc,fwidth=0.2*fsrc),\n", - " center=mp.Vector3(),\n", - " size=mp.Vector3(y=2),\n", - " component=mp.Ez)]\n", + "sources = [\n", + " mp.Source(\n", + " src=mp.GaussianSource(fsrc, fwidth=0.2 * fsrc),\n", + " center=mp.Vector3(),\n", + " size=mp.Vector3(y=2),\n", + " component=mp.Ez,\n", + " )\n", + "]\n", "\n", - "sim = mp.Simulation(cell_size=cell_size,\n", - " resolution=resolution,\n", - " boundary_layers=pml_layers,\n", - " sources=sources,\n", - " geometry=geometry)" + "sim = mp.Simulation(\n", + " cell_size=cell_size,\n", + " resolution=resolution,\n", + " boundary_layers=pml_layers,\n", + " sources=sources,\n", + " geometry=geometry,\n", + ")" ] }, { @@ -160,8 +170,8 @@ ], "source": [ "f = plt.figure(dpi=100)\n", - "animate = mp.Animate2D(sim,mp.Ez,f=f,normalize=True)\n", - "sim.run(mp.at_every(1,animate),until_after_sources=50)\n", + "animate = mp.Animate2D(sim, mp.Ez, f=f, normalize=True)\n", + "sim.run(mp.at_every(1, animate), until_after_sources=50)\n", "plt.close()" ] }, @@ -201,8 +211,8 @@ } ], "source": [ - "filename = 'media/oblique-source-normal.mp4'\n", - "animate.to_mp4(10,filename)\n", + "filename = \"media/oblique-source-normal.mp4\"\n", + "animate.to_mp4(10, filename)\n", "Video(filename)" ] }, @@ -223,26 +233,34 @@ "metadata": {}, "outputs": [], "source": [ - "kx = 0.4 # initial guess for wavevector in x-direction of eigenmode\n", - "kpoint = mp.Vector3(kx).rotate(mp.Vector3(z=1), rot_angle) # Rotate the vector by the specified amount\n", + "kx = 0.4 # initial guess for wavevector in x-direction of eigenmode\n", + "kpoint = mp.Vector3(kx).rotate(\n", + " mp.Vector3(z=1), rot_angle\n", + ") # Rotate the vector by the specified amount\n", "\n", - "bnum = 1 # band number of eigenmode\n", + "bnum = 1 # band number of eigenmode\n", "\n", - "sources = [mp.EigenModeSource(src=mp.GaussianSource(fsrc,fwidth=0.2*fsrc),\n", - " center=mp.Vector3(),\n", - " size=mp.Vector3(y=14),\n", - " direction=mp.NO_DIRECTION,\n", - " eig_kpoint=kpoint,\n", - " eig_band=bnum,\n", - " eig_parity=mp.EVEN_Y+mp.ODD_Z if rot_angle == 0 else mp.ODD_Z,\n", - " eig_match_freq=True)]\n", + "sources = [\n", + " mp.EigenModeSource(\n", + " src=mp.GaussianSource(fsrc, fwidth=0.2 * fsrc),\n", + " center=mp.Vector3(),\n", + " size=mp.Vector3(y=14),\n", + " direction=mp.NO_DIRECTION,\n", + " eig_kpoint=kpoint,\n", + " eig_band=bnum,\n", + " eig_parity=mp.EVEN_Y + mp.ODD_Z if rot_angle == 0 else mp.ODD_Z,\n", + " eig_match_freq=True,\n", + " )\n", + "]\n", "\n", - "sim = mp.Simulation(cell_size=cell_size,\n", - " resolution=resolution,\n", - " boundary_layers=pml_layers,\n", - " sources=sources,\n", - " geometry=geometry,\n", - " symmetries=[mp.Mirror(mp.Y)] if rot_angle == 0 else [])" + "sim = mp.Simulation(\n", + " cell_size=cell_size,\n", + " resolution=resolution,\n", + " boundary_layers=pml_layers,\n", + " sources=sources,\n", + " geometry=geometry,\n", + " symmetries=[mp.Mirror(mp.Y)] if rot_angle == 0 else [],\n", + ")" ] }, { @@ -280,8 +298,8 @@ ], "source": [ "f = plt.figure(dpi=100)\n", - "animate = mp.Animate2D(sim,mp.Ez,f=f,normalize=True)\n", - "sim.run(mp.at_every(1,animate),until_after_sources=50)\n", + "animate = mp.Animate2D(sim, mp.Ez, f=f, normalize=True)\n", + "sim.run(mp.at_every(1, animate), until_after_sources=50)\n", "plt.close()" ] }, @@ -314,8 +332,8 @@ } ], "source": [ - "filename = 'media/oblique-source-eig.mp4'\n", - "animate.to_mp4(10,filename)\n", + "filename = \"media/oblique-source-eig.mp4\"\n", + "animate.to_mp4(10, filename)\n", "Video(filename)" ] }, @@ -427,40 +445,57 @@ ], "source": [ "for rot_angle in np.radians([0, 20, 40]):\n", - " \n", - " resolution = 20\n", "\n", - " geometry = [mp.Block(center=mp.Vector3(),\n", - " size=mp.Vector3(mp.inf,1,mp.inf),\n", - " e1=mp.Vector3(1).rotate(mp.Vector3(z=1), rot_angle),\n", - " e2=mp.Vector3(y=1).rotate(mp.Vector3(z=1), rot_angle),\n", - " material=mp.Medium(epsilon=12))]\n", + " resolution = 20\n", "\n", - " sources = [mp.EigenModeSource(src=mp.GaussianSource(fsrc,fwidth=0.2*fsrc),\n", - " center=mp.Vector3(),\n", - " size=mp.Vector3(y=14),\n", - " direction=mp.NO_DIRECTION,\n", - " eig_kpoint=kpoint,\n", - " eig_band=bnum,\n", - " eig_parity=mp.ODD_Z,\n", - " eig_match_freq=True)]\n", + " geometry = [\n", + " mp.Block(\n", + " center=mp.Vector3(),\n", + " size=mp.Vector3(mp.inf, 1, mp.inf),\n", + " e1=mp.Vector3(1).rotate(mp.Vector3(z=1), rot_angle),\n", + " e2=mp.Vector3(y=1).rotate(mp.Vector3(z=1), rot_angle),\n", + " material=mp.Medium(epsilon=12),\n", + " )\n", + " ]\n", "\n", - " sim = mp.Simulation(cell_size=cell_size,\n", - " resolution=resolution,\n", - " boundary_layers=pml_layers,\n", - " sources=sources,\n", - " geometry=geometry)\n", + " sources = [\n", + " mp.EigenModeSource(\n", + " src=mp.GaussianSource(fsrc, fwidth=0.2 * fsrc),\n", + " center=mp.Vector3(),\n", + " size=mp.Vector3(y=14),\n", + " direction=mp.NO_DIRECTION,\n", + " eig_kpoint=kpoint,\n", + " eig_band=bnum,\n", + " eig_parity=mp.ODD_Z,\n", + " eig_match_freq=True,\n", + " )\n", + " ]\n", "\n", + " sim = mp.Simulation(\n", + " cell_size=cell_size,\n", + " resolution=resolution,\n", + " boundary_layers=pml_layers,\n", + " sources=sources,\n", + " geometry=geometry,\n", + " )\n", "\n", - " tran = sim.add_flux(fsrc, 0, 1, mp.FluxRegion(center=mp.Vector3(x=5), size=mp.Vector3(y=14)))\n", + " tran = sim.add_flux(\n", + " fsrc, 0, 1, mp.FluxRegion(center=mp.Vector3(x=5), size=mp.Vector3(y=14))\n", + " )\n", " sim.run(until_after_sources=50)\n", - " res = sim.get_eigenmode_coefficients(tran,\n", - " [1],\n", - " eig_parity=mp.EVEN_Y+mp.ODD_Z if rot_angle == 0 else mp.ODD_Z,\n", - " direction=mp.NO_DIRECTION,\n", - " kpoint_func=lambda f,n: kpoint)\n", - " print(\"flux:, {:.6f}, {:.6f}\".format(mp.get_fluxes(tran)[0],abs(res.alpha[0,0,0])**2))\n", - " \n", + " res = sim.get_eigenmode_coefficients(\n", + " tran,\n", + " [1],\n", + " eig_parity=mp.EVEN_Y + mp.ODD_Z if rot_angle == 0 else mp.ODD_Z,\n", + " direction=mp.NO_DIRECTION,\n", + " kpoint_func=lambda f, n: kpoint,\n", + " )\n", + " print(\n", + " \"flux:, {:.6f}, {:.6f}\".format(\n", + " mp.get_fluxes(tran)[0], abs(res.alpha[0, 0, 0]) ** 2\n", + " )\n", + " )\n", + "\n", " sim.plot2D(fields=mp.Ez)\n", " plt.show()" ] diff --git a/python/examples/parallel-wvgs-force.ipynb b/python/examples/parallel-wvgs-force.ipynb index 32e9eb0d8..db2954e22 100644 --- a/python/examples/parallel-wvgs-force.ipynb +++ b/python/examples/parallel-wvgs-force.ipynb @@ -33,7 +33,7 @@ "import numpy as np\n", "import matplotlib.pyplot as plt\n", "\n", - "resolution = 40 # pixels/μm\n", + "resolution = 40 # pixels/μm\n", "\n", "Si = mp.Medium(index=3.45)\n", "\n", @@ -42,67 +42,89 @@ "\n", "sx = 5\n", "sy = 3\n", - "cell = mp.Vector3(sx+2*dpml,sy+2*dpml,0)\n", + "cell = mp.Vector3(sx + 2 * dpml, sy + 2 * dpml, 0)\n", "\n", - "a = 1.0 # waveguide width/height\n", + "a = 1.0 # waveguide width/height\n", "\n", "k_point = mp.Vector3(z=0.5)\n", "\n", - "def parallel_waveguide(s,xodd):\n", - " geometry = [mp.Block(center=mp.Vector3(-0.5*(s+a)),\n", - " size=mp.Vector3(a,a,mp.inf),\n", - " material=Si),\n", - " mp.Block(center=mp.Vector3(0.5*(s+a)),\n", - " size=mp.Vector3(a,a,mp.inf),\n", - " material=Si)]\n", "\n", - " symmetries = [mp.Mirror(mp.X, phase=-1 if xodd else 1),\n", - " mp.Mirror(mp.Y, phase=-1)]\n", + "def parallel_waveguide(s, xodd):\n", + " geometry = [\n", + " mp.Block(\n", + " center=mp.Vector3(-0.5 * (s + a)),\n", + " size=mp.Vector3(a, a, mp.inf),\n", + " material=Si,\n", + " ),\n", + " mp.Block(\n", + " center=mp.Vector3(0.5 * (s + a)), size=mp.Vector3(a, a, mp.inf), material=Si\n", + " ),\n", + " ]\n", + "\n", + " symmetries = [mp.Mirror(mp.X, phase=-1 if xodd else 1), mp.Mirror(mp.Y, phase=-1)]\n", + "\n", + " sim = mp.Simulation(\n", + " resolution=resolution,\n", + " cell_size=cell,\n", + " geometry=geometry,\n", + " boundary_layers=pml_layers,\n", + " symmetries=symmetries,\n", + " k_point=k_point,\n", + " )\n", "\n", - " sim = mp.Simulation(resolution=resolution,\n", - " cell_size=cell,\n", - " geometry=geometry,\n", - " boundary_layers=pml_layers,\n", - " symmetries=symmetries,\n", - " k_point=k_point)\n", - " \n", " sim.init_sim()\n", - " EigenmodeData = sim.get_eigenmode(0.22,\n", - " mp.Z,\n", - " mp.Volume(center=mp.Vector3(), size=mp.Vector3(sx,sy)),\n", - " 2 if xodd else 1,\n", - " k_point,\n", - " match_frequency=False,\n", - " parity=mp.ODD_Y)\n", + " EigenmodeData = sim.get_eigenmode(\n", + " 0.22,\n", + " mp.Z,\n", + " mp.Volume(center=mp.Vector3(), size=mp.Vector3(sx, sy)),\n", + " 2 if xodd else 1,\n", + " k_point,\n", + " match_frequency=False,\n", + " parity=mp.ODD_Y,\n", + " )\n", "\n", " fcen = EigenmodeData.freq\n", " print(\"freq:, {}, {}, {}\".format(\"xodd\" if xodd else \"xeven\", s, fcen))\n", "\n", " sim.reset_meep()\n", "\n", - " eig_sources = [mp.EigenModeSource(src=mp.GaussianSource(fcen, fwidth=0.1*fcen),\n", - " size=mp.Vector3(sx,sy),\n", - " center=mp.Vector3(),\n", - " eig_band=2 if xodd else 1,\n", - " eig_kpoint=k_point,\n", - " eig_match_freq=False,\n", - " eig_parity=mp.ODD_Y)]\n", + " eig_sources = [\n", + " mp.EigenModeSource(\n", + " src=mp.GaussianSource(fcen, fwidth=0.1 * fcen),\n", + " size=mp.Vector3(sx, sy),\n", + " center=mp.Vector3(),\n", + " eig_band=2 if xodd else 1,\n", + " eig_kpoint=k_point,\n", + " eig_match_freq=False,\n", + " eig_parity=mp.ODD_Y,\n", + " )\n", + " ]\n", "\n", " sim.change_sources(eig_sources)\n", "\n", - " flux_reg = mp.FluxRegion(direction=mp.Z, center=mp.Vector3(), size=mp.Vector3(sx,sy))\n", + " flux_reg = mp.FluxRegion(\n", + " direction=mp.Z, center=mp.Vector3(), size=mp.Vector3(sx, sy)\n", + " )\n", " wvg_flux = sim.add_flux(fcen, 0, 1, flux_reg)\n", "\n", - " force_reg1 = mp.ForceRegion(mp.Vector3(0.49*s), direction=mp.X, weight=1, size=mp.Vector3(y=sy))\n", - " force_reg2 = mp.ForceRegion(mp.Vector3(0.5*s+1.01*a), direction=mp.X, weight=-1, size=mp.Vector3(y=sy))\n", + " force_reg1 = mp.ForceRegion(\n", + " mp.Vector3(0.49 * s), direction=mp.X, weight=1, size=mp.Vector3(y=sy)\n", + " )\n", + " force_reg2 = mp.ForceRegion(\n", + " mp.Vector3(0.5 * s + 1.01 * a), direction=mp.X, weight=-1, size=mp.Vector3(y=sy)\n", + " )\n", " wvg_force = sim.add_force(fcen, 0, 1, force_reg1, force_reg2)\n", "\n", " sim.run(until_after_sources=1500)\n", "\n", " flux = mp.get_fluxes(wvg_flux)[0]\n", " force = mp.get_forces(wvg_force)[0]\n", - " print(\"data:, {}, {}, {}, {}, {}\".format(\"xodd\" if xodd else \"xeven\", s, flux, force, -force/flux))\n", - " \n", + " print(\n", + " \"data:, {}, {}, {}, {}, {}\".format(\n", + " \"xodd\" if xodd else \"xeven\", s, flux, force, -force / flux\n", + " )\n", + " )\n", + "\n", " sim.reset_meep()\n", " return flux, force" ] @@ -2319,15 +2341,15 @@ } ], "source": [ - "s = np.arange(0.1,1.1,0.1)\n", + "s = np.arange(0.1, 1.1, 0.1)\n", "fluxes_odd = np.zeros(s.size)\n", "forces_odd = np.zeros(s.size)\n", "fluxes_even = np.zeros(s.size)\n", "forces_even = np.zeros(s.size)\n", "\n", "for k in range(len(s)):\n", - " fluxes_odd[k], forces_odd[k] = parallel_waveguide(s[k],True)\n", - " fluxes_even[k], forces_even[k] = parallel_waveguide(s[k],False)" + " fluxes_odd[k], forces_odd[k] = parallel_waveguide(s[k], True)\n", + " fluxes_even[k], forces_even[k] = parallel_waveguide(s[k], False)" ] }, { @@ -2350,12 +2372,12 @@ ], "source": [ "plt.figure(dpi=150)\n", - "plt.plot(s,-forces_odd/fluxes_odd,'rs',label='anti-symmetric')\n", - "plt.plot(s,-forces_even/fluxes_even,'bo',label='symmetric')\n", + "plt.plot(s, -forces_odd / fluxes_odd, \"rs\", label=\"anti-symmetric\")\n", + "plt.plot(s, -forces_even / fluxes_even, \"bo\", label=\"symmetric\")\n", "plt.grid(True)\n", - "plt.xlabel('waveguide separation s/a')\n", - "plt.ylabel('optical force (F/L)(ac/P)')\n", - "plt.legend(loc='upper right')\n", + "plt.xlabel(\"waveguide separation s/a\")\n", + "plt.ylabel(\"optical force (F/L)(ac/P)\")\n", + "plt.legend(loc=\"upper right\")\n", "plt.show()" ] }, @@ -3185,7 +3207,7 @@ "Si = mp.Medium(index=3.45)\n", "\n", "syz = 10\n", - "geometry_lattice = mp.Lattice(size=mp.Vector3(0,syz,syz))\n", + "geometry_lattice = mp.Lattice(size=mp.Vector3(0, syz, syz))\n", "\n", "k_points = [mp.Vector3(0.5)]\n", "\n", @@ -3194,20 +3216,29 @@ "\n", "a = 1.0 # waveguide width\n", "\n", - "def parallel_waveguide(s,yodd):\n", - " geometry = [mp.Block(center=mp.Vector3(0,-0.5*(s+a),0),\n", - " size=mp.Vector3(mp.inf,a,a),\n", - " material=Si),\n", - " mp.Block(center=mp.Vector3(0,0.5*(s+a),0),\n", - " size=mp.Vector3(mp.inf,a,a),\n", - " material=Si)]\n", "\n", - " ms = mpb.ModeSolver(resolution=resolution,\n", - " k_points=k_points,\n", - " geometry_lattice=geometry_lattice,\n", - " geometry=geometry,\n", - " num_bands=num_bands,\n", - " tolerance=tolerance)\n", + "def parallel_waveguide(s, yodd):\n", + " geometry = [\n", + " mp.Block(\n", + " center=mp.Vector3(0, -0.5 * (s + a), 0),\n", + " size=mp.Vector3(mp.inf, a, a),\n", + " material=Si,\n", + " ),\n", + " mp.Block(\n", + " center=mp.Vector3(0, 0.5 * (s + a), 0),\n", + " size=mp.Vector3(mp.inf, a, a),\n", + " material=Si,\n", + " ),\n", + " ]\n", + "\n", + " ms = mpb.ModeSolver(\n", + " resolution=resolution,\n", + " k_points=k_points,\n", + " geometry_lattice=geometry_lattice,\n", + " geometry=geometry,\n", + " num_bands=num_bands,\n", + " tolerance=tolerance,\n", + " )\n", "\n", " if yodd:\n", " ms.run_yodd_zodd()\n", @@ -3215,11 +3246,12 @@ " ms.run_yeven_zodd()\n", "\n", " f = ms.get_freqs()[0]\n", - " vg = ms.compute_group_velocity_component(mp.Vector3(1,0,0))[0]\n", + " vg = ms.compute_group_velocity_component(mp.Vector3(1, 0, 0))[0]\n", + "\n", + " return f, vg\n", "\n", - " return f,vg\n", "\n", - "ss = np.arange(0.05,1.15,0.1)\n", + "ss = np.arange(0.05, 1.15, 0.1)\n", "\n", "f_odd = np.zeros(len(ss))\n", "vg_odd = np.zeros(len(ss))\n", @@ -3227,19 +3259,21 @@ "vg_even = np.zeros(len(ss))\n", "\n", "for j in range(len(ss)):\n", - " f_odd[j], vg_odd[j] = parallel_waveguide(ss[j],True)\n", - " f_even[j], vg_even[j] = parallel_waveguide(ss[j],False)\n", + " f_odd[j], vg_odd[j] = parallel_waveguide(ss[j], True)\n", + " f_even[j], vg_even[j] = parallel_waveguide(ss[j], False)\n", + "\n", + "ds = ss[1] - ss[0]\n", + "\n", "\n", - "ds = ss[1]-ss[0]\n", + "def compute_force(f, vg):\n", + " f_avg = 0.5 * (f[:-1] + f[1:])\n", + " df = f[1:] - f[:-1]\n", + " vg_avg = 0.5 * (vg[:-1] + vg[1:])\n", + " return -1 / f_avg * df / ds * 1 / vg_avg\n", "\n", - "def compute_force(f,vg):\n", - " f_avg = 0.5*(f[:-1]+f[1:])\n", - " df = f[1:]-f[:-1]\n", - " vg_avg = 0.5*(vg[:-1]+vg[1:])\n", - " return -1/f_avg * df/ds * 1/vg_avg\n", "\n", - "force_odd = compute_force(f_odd,vg_odd)\n", - "force_even = compute_force(f_even,vg_even)" + "force_odd = compute_force(f_odd, vg_odd)\n", + "force_even = compute_force(f_even, vg_even)" ] }, { @@ -3262,13 +3296,13 @@ ], "source": [ "plt.figure(dpi=200)\n", - "plt.plot(ss[:-1],force_odd,'b-',label='anti-symmetric')\n", - "plt.plot(ss[:-1],force_even,'r-',label='symmetric')\n", + "plt.plot(ss[:-1], force_odd, \"b-\", label=\"anti-symmetric\")\n", + "plt.plot(ss[:-1], force_even, \"r-\", label=\"symmetric\")\n", "plt.xlabel(\"waveguide separation s/a\")\n", "plt.ylabel(\"optical force (F/L)(ac/P)\")\n", - "plt.legend(loc='upper right')\n", - "plt.xticks(np.arange(0,1.2,0.2))\n", - "plt.yticks(np.arange(-1.5,1.0,0.5))\n", + "plt.legend(loc=\"upper right\")\n", + "plt.xticks(np.arange(0, 1.2, 0.2))\n", + "plt.yticks(np.arange(-1.5, 1.0, 0.5))\n", "plt.show()" ] } diff --git a/python/examples/perturbation_theory.ipynb b/python/examples/perturbation_theory.ipynb index e4cfa98b4..c78cb2cb9 100644 --- a/python/examples/perturbation_theory.ipynb +++ b/python/examples/perturbation_theory.ipynb @@ -169,53 +169,62 @@ "import meep as mp\n", "import numpy as np\n", "\n", - "resolution = 100 # pixels/um\n", + "resolution = 100 # pixels/um\n", "\n", - "perpendicular = False # perpendicular (Hz) or parallel (Ez) source?\n", + "perpendicular = False # perpendicular (Hz) or parallel (Ez) source?\n", "\n", "if perpendicular:\n", " src_cmpt = mp.Hz\n", - " fcen = 0.21 # pulse center frequency\n", + " fcen = 0.21 # pulse center frequency\n", "else:\n", " src_cmpt = mp.Ez\n", - " fcen = 0.17 # pulse center frequency\n", + " fcen = 0.17 # pulse center frequency\n", "\n", - "n = 3.4 # index of waveguide\n", - "w = 1 # ring width\n", - "r = 1 # inner radius of ring\n", - "pad = 4 # padding between waveguide and edge of PML\n", - "dpml = 2 # thickness of PML\n", - "m = 5 # angular dependence\n", + "n = 3.4 # index of waveguide\n", + "w = 1 # ring width\n", + "r = 1 # inner radius of ring\n", + "pad = 4 # padding between waveguide and edge of PML\n", + "dpml = 2 # thickness of PML\n", + "m = 5 # angular dependence\n", "\n", "pml_layers = [mp.PML(dpml)]\n", "\n", - "sr = r + w + pad + dpml # radial size (cell is from 0 to sr)\n", - "dimensions = mp.CYLINDRICAL # coordinate system is (r,phi,z) instead of (x,y,z)\n", + "sr = r + w + pad + dpml # radial size (cell is from 0 to sr)\n", + "dimensions = mp.CYLINDRICAL # coordinate system is (r,phi,z) instead of (x,y,z)\n", "cell = mp.Vector3(sr)\n", "\n", - "geometry = [mp.Block(center=mp.Vector3(r + (w / 2)),\n", - " size=mp.Vector3(w, mp.inf, mp.inf),\n", - " material=mp.Medium(index=n))]\n", + "geometry = [\n", + " mp.Block(\n", + " center=mp.Vector3(r + (w / 2)),\n", + " size=mp.Vector3(w, mp.inf, mp.inf),\n", + " material=mp.Medium(index=n),\n", + " )\n", + "]\n", "\n", "# find resonant frequency of unperturbed geometry using broadband source\n", "\n", - "df = 0.2*fcen # pulse width (in frequency)\n", - "\n", - "sources = [mp.Source(mp.GaussianSource(fcen,fwidth=df),\n", - " component=src_cmpt,\n", - " center=mp.Vector3(r+0.1))]\n", - "\n", - "sim = mp.Simulation(cell_size=cell,\n", - " geometry=geometry,\n", - " boundary_layers=pml_layers,\n", - " resolution=resolution,\n", - " sources=sources,\n", - " dimensions=dimensions,\n", - " m=m)\n", - "\n", - "h = mp.Harminv(src_cmpt, mp.Vector3(r+0.1), fcen, df)\n", - "sim.run(mp.after_sources(h),\n", - " until_after_sources=100)\n", + "df = 0.2 * fcen # pulse width (in frequency)\n", + "\n", + "sources = [\n", + " mp.Source(\n", + " mp.GaussianSource(fcen, fwidth=df),\n", + " component=src_cmpt,\n", + " center=mp.Vector3(r + 0.1),\n", + " )\n", + "]\n", + "\n", + "sim = mp.Simulation(\n", + " cell_size=cell,\n", + " geometry=geometry,\n", + " boundary_layers=pml_layers,\n", + " resolution=resolution,\n", + " sources=sources,\n", + " dimensions=dimensions,\n", + " m=m,\n", + ")\n", + "\n", + "h = mp.Harminv(src_cmpt, mp.Vector3(r + 0.1), fcen, df)\n", + "sim.run(mp.after_sources(h), until_after_sources=100)\n", "\n", "frq_unperturbed = h.modes[0].freq\n", "\n", @@ -224,35 +233,69 @@ "# unperturbed geometry with narrowband source centered at resonant frequency\n", "\n", "fcen = frq_unperturbed\n", - "df = 0.05*fcen\n", - "\n", - "sources = [mp.Source(mp.GaussianSource(fcen,fwidth=df),\n", - " component=src_cmpt,\n", - " center=mp.Vector3(r+0.1))]\n", - "\n", - "sim = mp.Simulation(cell_size=cell,\n", - " geometry=geometry,\n", - " boundary_layers=pml_layers,\n", - " resolution=resolution,\n", - " sources=sources,\n", - " dimensions=dimensions,\n", - " m=m)\n", + "df = 0.05 * fcen\n", + "\n", + "sources = [\n", + " mp.Source(\n", + " mp.GaussianSource(fcen, fwidth=df),\n", + " component=src_cmpt,\n", + " center=mp.Vector3(r + 0.1),\n", + " )\n", + "]\n", + "\n", + "sim = mp.Simulation(\n", + " cell_size=cell,\n", + " geometry=geometry,\n", + " boundary_layers=pml_layers,\n", + " resolution=resolution,\n", + " sources=sources,\n", + " dimensions=dimensions,\n", + " m=m,\n", + ")\n", "\n", "sim.run(until_after_sources=100)\n", "\n", "deps = 1 - n**2\n", - "deps_inv = 1 - 1/n**2\n", + "deps_inv = 1 - 1 / n**2\n", "\n", "if perpendicular:\n", - " para_integral = deps*2*np.pi*(r*abs(sim.get_field_point(mp.Ep, mp.Vector3(r)))**2 - (r+w)*abs(sim.get_field_point(mp.Ep, mp.Vector3(r+w)))**2)\n", - " perp_integral = deps_inv*2*np.pi*(-r*abs(sim.get_field_point(mp.Dr, mp.Vector3(r)))**2 + (r+w)*abs(sim.get_field_point(mp.Dr, mp.Vector3(r+w)))**2)\n", + " para_integral = (\n", + " deps\n", + " * 2\n", + " * np.pi\n", + " * (\n", + " r * abs(sim.get_field_point(mp.Ep, mp.Vector3(r))) ** 2\n", + " - (r + w) * abs(sim.get_field_point(mp.Ep, mp.Vector3(r + w))) ** 2\n", + " )\n", + " )\n", + " perp_integral = (\n", + " deps_inv\n", + " * 2\n", + " * np.pi\n", + " * (\n", + " -r * abs(sim.get_field_point(mp.Dr, mp.Vector3(r))) ** 2\n", + " + (r + w) * abs(sim.get_field_point(mp.Dr, mp.Vector3(r + w))) ** 2\n", + " )\n", + " )\n", " numerator_integral = para_integral + perp_integral\n", "else:\n", - " numerator_integral = deps*2*np.pi*(r*abs(sim.get_field_point(mp.Ez, mp.Vector3(r)))**2 - (r+w)*abs(sim.get_field_point(mp.Ez, mp.Vector3(r+w)))**2)\n", - "\n", - "denominator_integral = sim.electric_energy_in_box(center=mp.Vector3(0.5*sr), size=mp.Vector3(sr))\n", - "\n", - "perturb_theory_dw_dR = -frq_unperturbed * numerator_integral / (4 * denominator_integral)\n", + " numerator_integral = (\n", + " deps\n", + " * 2\n", + " * np.pi\n", + " * (\n", + " r * abs(sim.get_field_point(mp.Ez, mp.Vector3(r))) ** 2\n", + " - (r + w) * abs(sim.get_field_point(mp.Ez, mp.Vector3(r + w))) ** 2\n", + " )\n", + " )\n", + "\n", + "denominator_integral = sim.electric_energy_in_box(\n", + " center=mp.Vector3(0.5 * sr), size=mp.Vector3(sr)\n", + ")\n", + "\n", + "perturb_theory_dw_dR = (\n", + " -frq_unperturbed * numerator_integral / (4 * denominator_integral)\n", + ")\n", "\n", "sim.reset_meep()\n", "\n", @@ -260,31 +303,44 @@ "\n", "dr = 0.01\n", "\n", - "sources = [mp.Source(mp.GaussianSource(fcen,fwidth=df),\n", - " component=src_cmpt,\n", - " center=mp.Vector3(r + dr + 0.1))]\n", - "\n", - "geometry = [mp.Block(center=mp.Vector3(r + dr + (w / 2)),\n", - " size=mp.Vector3(w, mp.inf, mp.inf),\n", - " material=mp.Medium(index=n))]\n", - "\n", - "sim = mp.Simulation(cell_size=cell,\n", - " geometry=geometry,\n", - " boundary_layers=pml_layers,\n", - " resolution=resolution,\n", - " sources=sources,\n", - " dimensions=dimensions,\n", - " m=m)\n", - "\n", - "h = mp.Harminv(src_cmpt, mp.Vector3(r+dr+0.1), fcen, df)\n", - "sim.run(mp.after_sources(h),\n", - " until_after_sources=100)\n", + "sources = [\n", + " mp.Source(\n", + " mp.GaussianSource(fcen, fwidth=df),\n", + " component=src_cmpt,\n", + " center=mp.Vector3(r + dr + 0.1),\n", + " )\n", + "]\n", + "\n", + "geometry = [\n", + " mp.Block(\n", + " center=mp.Vector3(r + dr + (w / 2)),\n", + " size=mp.Vector3(w, mp.inf, mp.inf),\n", + " material=mp.Medium(index=n),\n", + " )\n", + "]\n", + "\n", + "sim = mp.Simulation(\n", + " cell_size=cell,\n", + " geometry=geometry,\n", + " boundary_layers=pml_layers,\n", + " resolution=resolution,\n", + " sources=sources,\n", + " dimensions=dimensions,\n", + " m=m,\n", + ")\n", + "\n", + "h = mp.Harminv(src_cmpt, mp.Vector3(r + dr + 0.1), fcen, df)\n", + "sim.run(mp.after_sources(h), until_after_sources=100)\n", "\n", "frq_perturbed = h.modes[0].freq\n", "\n", "finite_diff_dw_dR = (frq_perturbed - frq_unperturbed) / dr\n", "\n", - "print(\"dwdR:, {} (pert. theory), {} (finite diff.)\".format(perturb_theory_dw_dR,finite_diff_dw_dR))" + "print(\n", + " \"dwdR:, {} (pert. theory), {} (finite diff.)\".format(\n", + " perturb_theory_dw_dR, finite_diff_dw_dR\n", + " )\n", + ")" ] }, { diff --git a/python/examples/polarization_grating.ipynb b/python/examples/polarization_grating.ipynb index c7e49ba03..65165d5c6 100644 --- a/python/examples/polarization_grating.ipynb +++ b/python/examples/polarization_grating.ipynb @@ -28,63 +28,102 @@ "import numpy as np\n", "import matplotlib.pyplot as plt\n", "\n", - "resolution = 30 # pixels/μm\n", + "resolution = 30 # pixels/μm\n", "\n", - "dpml = 1.0 # PML thickness\n", - "dsub = 1.0 # substrate thickness\n", - "dpad = 1.0 # padding thickness\n", + "dpml = 1.0 # PML thickness\n", + "dsub = 1.0 # substrate thickness\n", + "dpad = 1.0 # padding thickness\n", "\n", - "k_point = mp.Vector3(0,0,0)\n", + "k_point = mp.Vector3(0, 0, 0)\n", "\n", - "pml_layers = [mp.PML(thickness=dpml,direction=mp.X)]\n", + "pml_layers = [mp.PML(thickness=dpml, direction=mp.X)]\n", "\n", "n_0 = 1.55\n", "delta_n = 0.159\n", - "epsilon_diag = mp.Matrix(mp.Vector3(n_0**2,0,0),mp.Vector3(0,n_0**2,0),mp.Vector3(0,0,(n_0+delta_n)**2))\n", + "epsilon_diag = mp.Matrix(\n", + " mp.Vector3(n_0**2, 0, 0),\n", + " mp.Vector3(0, n_0**2, 0),\n", + " mp.Vector3(0, 0, (n_0 + delta_n) ** 2),\n", + ")\n", "\n", - "wvl = 0.54 # center wavelength\n", - "fcen = 1/wvl # center frequency\n", + "wvl = 0.54 # center wavelength\n", + "fcen = 1 / wvl # center frequency\n", "\n", - "def pol_grating(d,ph,gp,nmode):\n", - " sx = dpml+dsub+d+d+dpad+dpml\n", + "\n", + "def pol_grating(d, ph, gp, nmode):\n", + " sx = dpml + dsub + d + d + dpad + dpml\n", " sy = gp\n", "\n", - " cell_size = mp.Vector3(sx,sy,0)\n", + " cell_size = mp.Vector3(sx, sy, 0)\n", "\n", " # twist angle of nematic director; from equation 1b\n", " def phi(p):\n", - " xx = p.x-(-0.5*sx+dpml+dsub)\n", + " xx = p.x - (-0.5 * sx + dpml + dsub)\n", " if (xx >= 0) and (xx <= d):\n", - " return math.pi*p.y/gp + ph*xx/d\n", + " return math.pi * p.y / gp + ph * xx / d\n", " else:\n", - " return math.pi*p.y/gp - ph*xx/d + 2*ph\n", + " return math.pi * p.y / gp - ph * xx / d + 2 * ph\n", "\n", " # return the anisotropic permittivity tensor for a uniaxial, twisted nematic liquid crystal\n", " def lc_mat(p):\n", " # rotation matrix for rotation around x axis\n", - " Rx = mp.Matrix(mp.Vector3(1,0,0),mp.Vector3(0,math.cos(phi(p)),math.sin(phi(p))),mp.Vector3(0,-math.sin(phi(p)),math.cos(phi(p))))\n", + " Rx = mp.Matrix(\n", + " mp.Vector3(1, 0, 0),\n", + " mp.Vector3(0, math.cos(phi(p)), math.sin(phi(p))),\n", + " mp.Vector3(0, -math.sin(phi(p)), math.cos(phi(p))),\n", + " )\n", " lc_epsilon = Rx * epsilon_diag * Rx.transpose()\n", - " lc_epsilon_diag = mp.Vector3(lc_epsilon[0].x,lc_epsilon[1].y,lc_epsilon[2].z)\n", - " lc_epsilon_offdiag = mp.Vector3(lc_epsilon[1].x,lc_epsilon[2].x,lc_epsilon[2].y)\n", - " return mp.Medium(epsilon_diag=lc_epsilon_diag,epsilon_offdiag=lc_epsilon_offdiag)\n", + " lc_epsilon_diag = mp.Vector3(lc_epsilon[0].x, lc_epsilon[1].y, lc_epsilon[2].z)\n", + " lc_epsilon_offdiag = mp.Vector3(\n", + " lc_epsilon[1].x, lc_epsilon[2].x, lc_epsilon[2].y\n", + " )\n", + " return mp.Medium(\n", + " epsilon_diag=lc_epsilon_diag, epsilon_offdiag=lc_epsilon_offdiag\n", + " )\n", "\n", - " geometry = [mp.Block(center=mp.Vector3(-0.5*sx+0.5*(dpml+dsub)),size=mp.Vector3(dpml+dsub,mp.inf,mp.inf),material=mp.Medium(index=n_0)),\n", - " mp.Block(center=mp.Vector3(-0.5*sx+dpml+dsub+d),size=mp.Vector3(2*d,mp.inf,mp.inf),material=lc_mat)]\n", + " geometry = [\n", + " mp.Block(\n", + " center=mp.Vector3(-0.5 * sx + 0.5 * (dpml + dsub)),\n", + " size=mp.Vector3(dpml + dsub, mp.inf, mp.inf),\n", + " material=mp.Medium(index=n_0),\n", + " ),\n", + " mp.Block(\n", + " center=mp.Vector3(-0.5 * sx + dpml + dsub + d),\n", + " size=mp.Vector3(2 * d, mp.inf, mp.inf),\n", + " material=lc_mat,\n", + " ),\n", + " ]\n", "\n", " # linear-polarized planewave pulse source\n", - " src_pt = mp.Vector3(-0.5*sx+dpml+0.3*dsub,0,0)\n", - " sources = [mp.Source(mp.GaussianSource(fcen,fwidth=0.05*fcen), component=mp.Ez, center=src_pt, size=mp.Vector3(0,sy,0)),\n", - " mp.Source(mp.GaussianSource(fcen,fwidth=0.05*fcen), component=mp.Ey, center=src_pt, size=mp.Vector3(0,sy,0))]\n", + " src_pt = mp.Vector3(-0.5 * sx + dpml + 0.3 * dsub, 0, 0)\n", + " sources = [\n", + " mp.Source(\n", + " mp.GaussianSource(fcen, fwidth=0.05 * fcen),\n", + " component=mp.Ez,\n", + " center=src_pt,\n", + " size=mp.Vector3(0, sy, 0),\n", + " ),\n", + " mp.Source(\n", + " mp.GaussianSource(fcen, fwidth=0.05 * fcen),\n", + " component=mp.Ey,\n", + " center=src_pt,\n", + " size=mp.Vector3(0, sy, 0),\n", + " ),\n", + " ]\n", "\n", - " sim = mp.Simulation(resolution=resolution,\n", - " cell_size=cell_size,\n", - " boundary_layers=pml_layers,\n", - " k_point=k_point,\n", - " sources=sources,\n", - " default_material=mp.Medium(index=n_0))\n", + " sim = mp.Simulation(\n", + " resolution=resolution,\n", + " cell_size=cell_size,\n", + " boundary_layers=pml_layers,\n", + " k_point=k_point,\n", + " sources=sources,\n", + " default_material=mp.Medium(index=n_0),\n", + " )\n", "\n", - " tran_pt = mp.Vector3(0.5*sx-dpml-0.5*dpad,0,0)\n", - " tran_flux = sim.add_flux(fcen, 0, 1, mp.FluxRegion(center=tran_pt, size=mp.Vector3(0,sy,0)))\n", + " tran_pt = mp.Vector3(0.5 * sx - dpml - 0.5 * dpad, 0, 0)\n", + " tran_flux = sim.add_flux(\n", + " fcen, 0, 1, mp.FluxRegion(center=tran_pt, size=mp.Vector3(0, sy, 0))\n", + " )\n", "\n", " sim.run(until_after_sources=100)\n", "\n", @@ -92,22 +131,30 @@ "\n", " sim.reset_meep()\n", "\n", - " sim = mp.Simulation(resolution=resolution,\n", - " cell_size=cell_size,\n", - " boundary_layers=pml_layers,\n", - " k_point=k_point,\n", - " sources=sources,\n", - " geometry=geometry)\n", + " sim = mp.Simulation(\n", + " resolution=resolution,\n", + " cell_size=cell_size,\n", + " boundary_layers=pml_layers,\n", + " k_point=k_point,\n", + " sources=sources,\n", + " geometry=geometry,\n", + " )\n", "\n", - " tran_flux = sim.add_flux(fcen, 0, 1, mp.FluxRegion(center=tran_pt, size=mp.Vector3(0,sy,0)))\n", + " tran_flux = sim.add_flux(\n", + " fcen, 0, 1, mp.FluxRegion(center=tran_pt, size=mp.Vector3(0, sy, 0))\n", + " )\n", "\n", " sim.run(until_after_sources=300)\n", "\n", - " res1 = sim.get_eigenmode_coefficients(tran_flux, range(1,nmode+1), eig_parity=mp.ODD_Z+mp.EVEN_Y)\n", - " res2 = sim.get_eigenmode_coefficients(tran_flux, range(1,nmode+1), eig_parity=mp.EVEN_Z+mp.ODD_Y)\n", - " angles = [math.degrees(math.acos(kdom.x/fcen)) for kdom in res1.kdom]\n", + " res1 = sim.get_eigenmode_coefficients(\n", + " tran_flux, range(1, nmode + 1), eig_parity=mp.ODD_Z + mp.EVEN_Y\n", + " )\n", + " res2 = sim.get_eigenmode_coefficients(\n", + " tran_flux, range(1, nmode + 1), eig_parity=mp.EVEN_Z + mp.ODD_Y\n", + " )\n", + " angles = [math.degrees(math.acos(kdom.x / fcen)) for kdom in res1.kdom]\n", "\n", - " return input_flux[0], angles, res1.alpha[:,0,0], res2.alpha[:,0,0];" + " return input_flux[0], angles, res1.alpha[:, 0, 0], res2.alpha[:, 0, 0];" ] }, { @@ -3144,11 +3191,11 @@ } ], "source": [ - "ph_uniaxial = 0 # chiral layer twist angle for uniaxial grating\n", - "ph_twisted = 70 # chiral layer twist angle for bilayer grating\n", - "gp = 6.5 # grating period\n", - "nmode = 5 # number of mode coefficients to compute\n", - "dd = np.arange(0.2,3.5,0.2) # chiral layer thickness\n", + "ph_uniaxial = 0 # chiral layer twist angle for uniaxial grating\n", + "ph_twisted = 70 # chiral layer twist angle for bilayer grating\n", + "gp = 6.5 # grating period\n", + "nmode = 5 # number of mode coefficients to compute\n", + "dd = np.arange(0.2, 3.5, 0.2) # chiral layer thickness\n", "\n", "m0_uniaxial = np.zeros(dd.size)\n", "m1_uniaxial = np.zeros(dd.size)\n", @@ -3159,18 +3206,22 @@ "ang_twisted = np.zeros(dd.size)\n", "\n", "for k in range(len(dd)):\n", - " input_flux, angles, coeffs1, coeffs2 = pol_grating(0.5*dd[k],math.radians(ph_uniaxial),gp,nmode)\n", - " tran = (abs(coeffs1)**2+abs(coeffs2)**2)/input_flux\n", + " input_flux, angles, coeffs1, coeffs2 = pol_grating(\n", + " 0.5 * dd[k], math.radians(ph_uniaxial), gp, nmode\n", + " )\n", + " tran = (abs(coeffs1) ** 2 + abs(coeffs2) ** 2) / input_flux\n", " for m in range(nmode):\n", - " print(\"tran (uniaxial):, {}, {:.2f}, {:.5f}\".format(m,angles[m],tran[m]))\n", + " print(\"tran (uniaxial):, {}, {:.2f}, {:.5f}\".format(m, angles[m], tran[m]))\n", " m0_uniaxial[k] = tran[0]\n", " m1_uniaxial[k] = tran[1]\n", " ang_uniaxial[k] = angles[1]\n", "\n", - " input_flux, angles, coeffs1, coeffs2 = pol_grating(dd[k],math.radians(ph_twisted),gp,nmode)\n", - " tran = (abs(coeffs1)**2+abs(coeffs2)**2)/input_flux\n", + " input_flux, angles, coeffs1, coeffs2 = pol_grating(\n", + " dd[k], math.radians(ph_twisted), gp, nmode\n", + " )\n", + " tran = (abs(coeffs1) ** 2 + abs(coeffs2) ** 2) / input_flux\n", " for m in range(nmode):\n", - " print(\"tran (twisted):, {}, {:.2f}, {:.5f}\".format(m,angles[m],tran[m]))\n", + " print(\"tran (twisted):, {}, {:.2f}, {:.5f}\".format(m, angles[m], tran[m]))\n", " m0_twisted[k] = tran[0]\n", " m1_twisted[k] = tran[1]\n", " ang_twisted[k] = angles[1]" @@ -3190,13 +3241,13 @@ "outputs": [], "source": [ "cos_angles = [math.cos(math.radians(t)) for t in ang_uniaxial]\n", - "tran = m0_uniaxial+2*m1_uniaxial\n", - "eff_m0 = m0_uniaxial/tran\n", - "eff_m1 = (2*m1_uniaxial/tran)/cos_angles\n", + "tran = m0_uniaxial + 2 * m1_uniaxial\n", + "eff_m0 = m0_uniaxial / tran\n", + "eff_m1 = (2 * m1_uniaxial / tran) / cos_angles\n", "\n", - "phase = delta_n*dd/wvl\n", - "eff_m0_analytic = [math.cos(math.pi*p)**2 for p in phase]\n", - "eff_m1_analytic = [math.sin(math.pi*p)**2 for p in phase]" + "phase = delta_n * dd / wvl\n", + "eff_m0_analytic = [math.cos(math.pi * p) ** 2 for p in phase]\n", + "eff_m1_analytic = [math.sin(math.pi * p) ** 2 for p in phase]" ] }, { @@ -3219,31 +3270,31 @@ ], "source": [ "plt.figure(dpi=150)\n", - "plt.subplot(1,2,1)\n", - "plt.plot(phase,eff_m0,'bo-',clip_on=False,label='0th order (meep)')\n", - "plt.plot(phase,eff_m0_analytic,'b--',clip_on=False,label='0th order (analytic)')\n", - "plt.plot(phase,eff_m1,'ro-',clip_on=False,label='±1 orders (meep)')\n", - "plt.plot(phase,eff_m1_analytic,'r--',clip_on=False,label='±1 orders (analytic)')\n", + "plt.subplot(1, 2, 1)\n", + "plt.plot(phase, eff_m0, \"bo-\", clip_on=False, label=\"0th order (meep)\")\n", + "plt.plot(phase, eff_m0_analytic, \"b--\", clip_on=False, label=\"0th order (analytic)\")\n", + "plt.plot(phase, eff_m1, \"ro-\", clip_on=False, label=\"±1 orders (meep)\")\n", + "plt.plot(phase, eff_m1_analytic, \"r--\", clip_on=False, label=\"±1 orders (analytic)\")\n", "plt.axis([0, 1.0, 0, 1])\n", - "plt.xticks([t for t in np.arange(0,1.2,0.2)])\n", + "plt.xticks([t for t in np.arange(0, 1.2, 0.2)])\n", "plt.xlabel(\"phase delay Δnd/λ\")\n", "plt.ylabel(\"diffraction efficiency @ λ = 0.54 μm\")\n", - "plt.legend(loc='center')\n", + "plt.legend(loc=\"center\")\n", "plt.title(\"homogeneous uniaxial grating\")\n", "\n", "cos_angles = [math.cos(math.radians(t)) for t in ang_twisted]\n", - "tran = m0_twisted+2*m1_twisted\n", - "eff_m0 = m0_twisted/tran\n", - "eff_m1 = (2*m1_twisted/tran)/cos_angles\n", + "tran = m0_twisted + 2 * m1_twisted\n", + "eff_m0 = m0_twisted / tran\n", + "eff_m1 = (2 * m1_twisted / tran) / cos_angles\n", "\n", - "plt.subplot(1,2,2)\n", - "plt.plot(phase,eff_m0,'bo-',clip_on=False,label='0th order (meep)')\n", - "plt.plot(phase,eff_m1,'ro-',clip_on=False,label='±1 orders (meep)')\n", + "plt.subplot(1, 2, 2)\n", + "plt.plot(phase, eff_m0, \"bo-\", clip_on=False, label=\"0th order (meep)\")\n", + "plt.plot(phase, eff_m1, \"ro-\", clip_on=False, label=\"±1 orders (meep)\")\n", "plt.axis([0, 1.0, 0, 1])\n", - "plt.xticks([t for t in np.arange(0,1.2,0.2)])\n", + "plt.xticks([t for t in np.arange(0, 1.2, 0.2)])\n", "plt.xlabel(\"phase delay Δnd/λ\")\n", "plt.ylabel(\"diffraction efficiency @ λ = 0.54 μm\")\n", - "plt.legend(loc='center')\n", + "plt.legend(loc=\"center\")\n", "plt.title(\"bilayer twisted-nematic grating\")\n", "\n", "plt.tight_layout()\n", diff --git a/python/examples/refl-angular.ipynb b/python/examples/refl-angular.ipynb index b0dd4e27a..ae5c0b948 100644 --- a/python/examples/refl-angular.ipynb +++ b/python/examples/refl-angular.ipynb @@ -32,47 +32,60 @@ "import numpy.matlib\n", "import matplotlib.pyplot as plt\n", "\n", - "resolution = 50 # pixels/um\n", + "resolution = 50 # pixels/um\n", "\n", - "dpml = 1.0 # PML thickness\n", - "sz = 10 + 2*dpml\n", + "dpml = 1.0 # PML thickness\n", + "sz = 10 + 2 * dpml\n", "cell_size = mp.Vector3(z=sz)\n", "pml_layers = [mp.PML(dpml)]\n", "\n", - "wvl_min = 0.4 # min wavelength\n", - "wvl_max = 0.8 # max wavelength\n", - "fmin = 1/wvl_max # min frequency\n", - "fmax = 1/wvl_min # max frequency\n", - "fcen = 0.5*(fmin+fmax) # center frequency\n", - "df = fmax-fmin # frequency width\n", - "nfreq = 50 # number of frequency bins\n", + "wvl_min = 0.4 # min wavelength\n", + "wvl_max = 0.8 # max wavelength\n", + "fmin = 1 / wvl_max # min frequency\n", + "fmax = 1 / wvl_min # max frequency\n", + "fcen = 0.5 * (fmin + fmax) # center frequency\n", + "df = fmax - fmin # frequency width\n", + "nfreq = 50 # number of frequency bins\n", "\n", - "def planar_reflectance(theta): \n", + "\n", + "def planar_reflectance(theta):\n", " # rotation angle (in degrees) of source: CCW around Y axis, 0 degrees along +Z axis\n", " theta_r = math.radians(theta)\n", "\n", " # plane of incidence is XZ; rotate counter clockwise (CCW) about y-axis\n", " k = mp.Vector3(z=fmin).rotate(mp.Vector3(y=1), theta_r)\n", - " \n", + "\n", " # if normal incidence, force number of dimensions to be 1\n", " if theta_r == 0:\n", " dimensions = 1\n", " else:\n", " dimensions = 3\n", - " \n", - " sources = [mp.Source(mp.GaussianSource(fcen,fwidth=df), component=mp.Ex, center=mp.Vector3(z=-0.5*sz+dpml))]\n", "\n", - " sim = mp.Simulation(cell_size=cell_size,\n", - " boundary_layers=pml_layers,\n", - " sources=sources,\n", - " k_point=k,\n", - " dimensions=dimensions,\n", - " resolution=resolution)\n", + " sources = [\n", + " mp.Source(\n", + " mp.GaussianSource(fcen, fwidth=df),\n", + " component=mp.Ex,\n", + " center=mp.Vector3(z=-0.5 * sz + dpml),\n", + " )\n", + " ]\n", + "\n", + " sim = mp.Simulation(\n", + " cell_size=cell_size,\n", + " boundary_layers=pml_layers,\n", + " sources=sources,\n", + " k_point=k,\n", + " dimensions=dimensions,\n", + " resolution=resolution,\n", + " )\n", "\n", - " refl_fr = mp.FluxRegion(center=mp.Vector3(z=-0.25*sz))\n", + " refl_fr = mp.FluxRegion(center=mp.Vector3(z=-0.25 * sz))\n", " refl = sim.add_flux(fcen, df, nfreq, refl_fr)\n", - " \n", - " sim.run(until_after_sources=mp.stop_when_fields_decayed(50, mp.Ex, mp.Vector3(z=-0.5*sz+dpml), 1e-9))\n", + "\n", + " sim.run(\n", + " until_after_sources=mp.stop_when_fields_decayed(\n", + " 50, mp.Ex, mp.Vector3(z=-0.5 * sz + dpml), 1e-9\n", + " )\n", + " )\n", "\n", " empty_flux = mp.get_fluxes(refl)\n", " empty_data = sim.get_flux_data(refl)\n", @@ -80,20 +93,32 @@ " sim.reset_meep()\n", "\n", " # add a block with n=3.5 for the air-dielectric interface\n", - " geometry = [mp.Block(mp.Vector3(mp.inf,mp.inf,0.5*sz), center=mp.Vector3(z=0.25*sz), material=mp.Medium(index=3.5))]\n", + " geometry = [\n", + " mp.Block(\n", + " mp.Vector3(mp.inf, mp.inf, 0.5 * sz),\n", + " center=mp.Vector3(z=0.25 * sz),\n", + " material=mp.Medium(index=3.5),\n", + " )\n", + " ]\n", "\n", - " sim = mp.Simulation(cell_size=cell_size,\n", - " geometry=geometry,\n", - " boundary_layers=pml_layers,\n", - " sources=sources,\n", - " k_point=k,\n", - " dimensions=dimensions,\n", - " resolution=resolution)\n", + " sim = mp.Simulation(\n", + " cell_size=cell_size,\n", + " geometry=geometry,\n", + " boundary_layers=pml_layers,\n", + " sources=sources,\n", + " k_point=k,\n", + " dimensions=dimensions,\n", + " resolution=resolution,\n", + " )\n", "\n", " refl = sim.add_flux(fcen, df, nfreq, refl_fr)\n", " sim.load_minus_flux_data(refl, empty_data)\n", "\n", - " sim.run(until_after_sources=mp.stop_when_fields_decayed(50, mp.Ex, mp.Vector3(z=-0.5*sz+dpml), 1e-9))\n", + " sim.run(\n", + " until_after_sources=mp.stop_when_fields_decayed(\n", + " 50, mp.Ex, mp.Vector3(z=-0.5 * sz + dpml), 1e-9\n", + " )\n", + " )\n", "\n", " refl_flux = mp.get_fluxes(refl)\n", " freqs = mp.get_flux_freqs(refl)\n", @@ -102,12 +127,12 @@ " theta_out = np.empty(nfreq)\n", " R = np.empty(nfreq)\n", " for i in range(nfreq):\n", - " wvls[i] = 1/freqs[i]\n", - " theta_out[i] = math.degrees(math.asin(k.x/freqs[i]))\n", - " R[i] = -refl_flux[i]/empty_flux[i]\n", - " print(\"refl:, {}, {}, {}, {}\".format(k.x,wvls[i],theta_out[i],R[i]))\n", - " \n", - " return k.x*np.ones(nfreq), wvls, theta_out, R " + " wvls[i] = 1 / freqs[i]\n", + " theta_out[i] = math.degrees(math.asin(k.x / freqs[i]))\n", + " R[i] = -refl_flux[i] / empty_flux[i]\n", + " print(\"refl:, {}, {}, {}, {}\".format(k.x, wvls[i], theta_out[i], R[i]))\n", + "\n", + " return k.x * np.ones(nfreq), wvls, theta_out, R" ] }, { @@ -1472,17 +1497,17 @@ } ], "source": [ - "theta_in = np.arange(0,85,5)\n", + "theta_in = np.arange(0, 85, 5)\n", "wvl = np.empty(nfreq)\n", - "kxs = np.empty((nfreq,theta_in.size))\n", - "thetas = np.empty((nfreq,theta_in.size))\n", - "Rmeep = np.empty((nfreq,theta_in.size))\n", + "kxs = np.empty((nfreq, theta_in.size))\n", + "thetas = np.empty((nfreq, theta_in.size))\n", + "Rmeep = np.empty((nfreq, theta_in.size))\n", "\n", "for j in range(theta_in.size):\n", - " kxs[:,j], wvl, thetas[:,j], Rmeep[:,j] = planar_reflectance(theta_in[j])\n", + " kxs[:, j], wvl, thetas[:, j], Rmeep[:, j] = planar_reflectance(theta_in[j])\n", "\n", "# create a 2d matrix for the wavelength by repeating the column vector for each angle\n", - "wvls = np.transpose(np.matlib.repmat(wvl,theta_in.size,1))" + "wvls = np.transpose(np.matlib.repmat(wvl, theta_in.size, 1))" ] }, { @@ -1516,15 +1541,17 @@ ], "source": [ "plt.figure(dpi=200)\n", - "plt.pcolormesh(kxs, wvls, Rmeep, cmap='inferno', shading='gouraud', vmin=0, vmax=Rmeep.max())\n", - "plt.axis([kxs[0,0], kxs[0,-1], wvl_min, wvl_max])\n", - "plt.yticks([t for t in np.linspace(0.4,0.8,5)])\n", + "plt.pcolormesh(\n", + " kxs, wvls, Rmeep, cmap=\"inferno\", shading=\"gouraud\", vmin=0, vmax=Rmeep.max()\n", + ")\n", + "plt.axis([kxs[0, 0], kxs[0, -1], wvl_min, wvl_max])\n", + "plt.yticks([t for t in np.linspace(0.4, 0.8, 5)])\n", "plt.xlabel(r\"Bloch-periodic wavevector (k$_x$/2π)\")\n", "plt.ylabel(\"wavelength (μm)\")\n", "plt.title(\"reflectance (meep)\")\n", "cbar = plt.colorbar()\n", - "cbar.set_ticks([t for t in np.linspace(0,0.4,5)])\n", - "cbar.set_ticklabels([\"{:.1f}\".format(t) for t in np.linspace(0,0.4,5)])" + "cbar.set_ticks([t for t in np.linspace(0, 0.4, 5)])\n", + "cbar.set_ticklabels([\"{:.1f}\".format(t) for t in np.linspace(0, 0.4, 5)])" ] }, { @@ -1547,16 +1574,18 @@ ], "source": [ "plt.figure(dpi=200)\n", - "plt.pcolormesh(thetas, wvls, Rmeep, cmap='inferno', shading='gouraud', vmin=0, vmax=Rmeep.max())\n", + "plt.pcolormesh(\n", + " thetas, wvls, Rmeep, cmap=\"inferno\", shading=\"gouraud\", vmin=0, vmax=Rmeep.max()\n", + ")\n", "plt.axis([thetas.min(), thetas.max(), wvl_min, wvl_max])\n", - "plt.xticks([t for t in range(0,100,20)])\n", - "plt.yticks([t for t in np.linspace(0.4,0.8,5)])\n", + "plt.xticks([t for t in range(0, 100, 20)])\n", + "plt.yticks([t for t in np.linspace(0.4, 0.8, 5)])\n", "plt.xlabel(\"angle of incident planewave (degrees)\")\n", "plt.ylabel(\"wavelength (μm)\")\n", "plt.title(\"reflectance (meep)\")\n", "cbar = plt.colorbar()\n", - "cbar.set_ticks([t for t in np.linspace(0,0.4,5)])\n", - "cbar.set_ticklabels([\"{:.1f}\".format(t) for t in np.linspace(0,0.4,5)])" + "cbar.set_ticks([t for t in np.linspace(0, 0.4, 5)])\n", + "cbar.set_ticklabels([\"{:.1f}\".format(t) for t in np.linspace(0, 0.4, 5)])" ] }, { @@ -1578,33 +1607,47 @@ } ], "source": [ - "n1=1\n", - "n2=3.5\n", + "n1 = 1\n", + "n2 = 3.5\n", "\n", "# compute angle of refracted planewave in medium n2\n", "# for incident planewave in medium n1 at angle theta_in\n", - "theta_out = lambda theta_in: math.asin(n1*math.sin(theta_in)/n2)\n", + "theta_out = lambda theta_in: math.asin(n1 * math.sin(theta_in) / n2)\n", "\n", "# compute Fresnel reflectance for P-polarization in medium n2\n", "# for incident planewave in medium n1 at angle theta_in\n", - "Rfresnel = lambda theta_in: math.fabs((n1*math.cos(theta_out(theta_in))-n2*math.cos(theta_in))/(n1*math.cos(theta_out(theta_in))+n2*math.cos(theta_in)))**2\n", + "Rfresnel = (\n", + " lambda theta_in: math.fabs(\n", + " (n1 * math.cos(theta_out(theta_in)) - n2 * math.cos(theta_in))\n", + " / (n1 * math.cos(theta_out(theta_in)) + n2 * math.cos(theta_in))\n", + " )\n", + " ** 2\n", + ")\n", "\n", "Ranalytic = np.empty((nfreq, theta_in.size))\n", "for m in range(wvl.size):\n", " for n in range(theta_in.size):\n", - " Ranalytic[m,n] = Rfresnel(math.radians(thetas[m,n]))\n", + " Ranalytic[m, n] = Rfresnel(math.radians(thetas[m, n]))\n", "\n", "plt.figure(dpi=200)\n", - "plt.pcolormesh(thetas, wvls, Ranalytic, cmap='inferno', shading='gouraud', vmin=0, vmax=Ranalytic.max())\n", + "plt.pcolormesh(\n", + " thetas,\n", + " wvls,\n", + " Ranalytic,\n", + " cmap=\"inferno\",\n", + " shading=\"gouraud\",\n", + " vmin=0,\n", + " vmax=Ranalytic.max(),\n", + ")\n", "plt.axis([thetas.min(), thetas.max(), wvl_min, wvl_max])\n", - "plt.xticks([t for t in range(0,100,20)])\n", - "plt.yticks([t for t in np.linspace(0.4,0.8,5)])\n", + "plt.xticks([t for t in range(0, 100, 20)])\n", + "plt.yticks([t for t in np.linspace(0.4, 0.8, 5)])\n", "plt.xlabel(\"angle of incident planewave (degrees)\")\n", "plt.ylabel(\"wavelength (μm)\")\n", "plt.title(\"reflectance (analytic)\")\n", "cbar = plt.colorbar()\n", - "cbar.set_ticks([t for t in np.linspace(0,0.4,5)])\n", - "cbar.set_ticklabels([\"{:.1f}\".format(t) for t in np.linspace(0,0.4,5)])" + "cbar.set_ticks([t for t in np.linspace(0, 0.4, 5)])\n", + "cbar.set_ticklabels([\"{:.1f}\".format(t) for t in np.linspace(0, 0.4, 5)])" ] } ], diff --git a/python/examples/refl-quartz.ipynb b/python/examples/refl-quartz.ipynb index fcf26bf51..e11604456 100644 --- a/python/examples/refl-quartz.ipynb +++ b/python/examples/refl-quartz.ipynb @@ -68,27 +68,35 @@ "resolution = 200 # pixels/μm\n", "\n", "dpml = 1.0\n", - "sz = 10+2*dpml\n", + "sz = 10 + 2 * dpml\n", "cell_size = mp.Vector3(z=sz)\n", "pml_layers = [mp.PML(dpml)]\n", "\n", "wvl_min = 0.4\n", "wvl_max = 0.8\n", - "fmin = 1/wvl_max\n", - "fmax = 1/wvl_min\n", - "fcen = 0.5*(fmax+fmin)\n", - "df = fmax-fmin\n", + "fmin = 1 / wvl_max\n", + "fmax = 1 / wvl_min\n", + "fcen = 0.5 * (fmax + fmin)\n", + "df = fmax - fmin\n", "nfreq = 50\n", "\n", - "sources = [mp.Source(mp.GaussianSource(fcen,fwidth=df), component=mp.Ex, center=mp.Vector3(z=-0.5*sz+dpml))]\n", - "\n", - "sim = mp.Simulation(cell_size=cell_size,\n", - " boundary_layers=pml_layers,\n", - " sources=sources,\n", - " dimensions=1,\n", - " resolution=resolution)\n", - "\n", - "refl_fr = mp.FluxRegion(center=mp.Vector3(z=-0.25*sz))\n", + "sources = [\n", + " mp.Source(\n", + " mp.GaussianSource(fcen, fwidth=df),\n", + " component=mp.Ex,\n", + " center=mp.Vector3(z=-0.5 * sz + dpml),\n", + " )\n", + "]\n", + "\n", + "sim = mp.Simulation(\n", + " cell_size=cell_size,\n", + " boundary_layers=pml_layers,\n", + " sources=sources,\n", + " dimensions=1,\n", + " resolution=resolution,\n", + ")\n", + "\n", + "refl_fr = mp.FluxRegion(center=mp.Vector3(z=-0.25 * sz))\n", "refl = sim.add_flux(fcen, df, nfreq, refl_fr)\n", "\n", "sim.run(until_after_sources=mp.stop_when_fields_decayed(50, mp.Ex, mp.Vector3(), 1e-9))\n", @@ -97,14 +105,22 @@ "empty_data = sim.get_flux_data(refl)\n", "sim.reset_meep()\n", "\n", - "geometry = [mp.Block(mp.Vector3(mp.inf,mp.inf,0.5*sz), center=mp.Vector3(z=0.25*sz), material=fused_quartz)]\n", - "\n", - "sim = mp.Simulation(cell_size=cell_size,\n", - " boundary_layers=pml_layers,\n", - " geometry=geometry,\n", - " sources=sources,\n", - " dimensions=1,\n", - " resolution=resolution)\n", + "geometry = [\n", + " mp.Block(\n", + " mp.Vector3(mp.inf, mp.inf, 0.5 * sz),\n", + " center=mp.Vector3(z=0.25 * sz),\n", + " material=fused_quartz,\n", + " )\n", + "]\n", + "\n", + "sim = mp.Simulation(\n", + " cell_size=cell_size,\n", + " boundary_layers=pml_layers,\n", + " geometry=geometry,\n", + " sources=sources,\n", + " dimensions=1,\n", + " resolution=resolution,\n", + ")\n", "\n", "refl = sim.add_flux(fcen, df, nfreq, refl_fr)\n", "sim.load_minus_flux_data(refl, empty_data)\n", @@ -112,7 +128,7 @@ "sim.run(until_after_sources=mp.stop_when_fields_decayed(50, mp.Ex, mp.Vector3(), 1e-9))\n", "\n", "refl_flux = mp.get_fluxes(refl)\n", - "R_meep = -1*np.divide(refl_flux,empty_flux)" + "R_meep = -1 * np.divide(refl_flux, empty_flux)" ] }, { @@ -142,20 +158,27 @@ ], "source": [ "freqs = mp.get_flux_freqs(refl)\n", - "wvls = np.divide(1,freqs)\n", - "\n", - "eps_quartz = lambda l: 1+0.6961663*math.pow(l,2)/(pow(l,2)-pow(0.0684043,2))+0.4079426*pow(l,2)/(pow(l,2)-pow(0.1162414,2))+0.8974794*pow(l,2)/(pow(l,2)-pow(9.896161,2))\n", - "R_fresnel = lambda l: math.pow(math.fabs(1-math.sqrt(eps_quartz(l)))/(1+math.sqrt(eps_quartz(l))),2)\n", + "wvls = np.divide(1, freqs)\n", + "\n", + "eps_quartz = (\n", + " lambda l: 1\n", + " + 0.6961663 * math.pow(l, 2) / (pow(l, 2) - pow(0.0684043, 2))\n", + " + 0.4079426 * pow(l, 2) / (pow(l, 2) - pow(0.1162414, 2))\n", + " + 0.8974794 * pow(l, 2) / (pow(l, 2) - pow(9.896161, 2))\n", + ")\n", + "R_fresnel = lambda l: math.pow(\n", + " math.fabs(1 - math.sqrt(eps_quartz(l))) / (1 + math.sqrt(eps_quartz(l))), 2\n", + ")\n", "R_analytic = [R_fresnel(i) for i in wvls]\n", "\n", "plt.figure()\n", - "plt.plot(wvls,R_meep,'bo-',label='meep')\n", - "plt.plot(wvls,R_analytic,'rs-',label='analytic')\n", + "plt.plot(wvls, R_meep, \"bo-\", label=\"meep\")\n", + "plt.plot(wvls, R_analytic, \"rs-\", label=\"analytic\")\n", "plt.xlabel(\"wavelength (μm)\")\n", "plt.ylabel(\"reflectance\")\n", "plt.axis([0.4, 0.8, 0.0340, 0.0365])\n", - "plt.xticks([t for t in np.arange(0.4,0.9,0.1)])\n", - "plt.legend(loc='upper right')\n", + "plt.xticks([t for t in np.arange(0.4, 0.9, 0.1)])\n", + "plt.legend(loc=\"upper right\")\n", "plt.show()" ] } diff --git a/python/examples/ring.ipynb b/python/examples/ring.ipynb index 18b1fd4e7..e4a8090bf 100644 --- a/python/examples/ring.ipynb +++ b/python/examples/ring.ipynb @@ -32,16 +32,17 @@ "source": [ "import meep as mp\n", "import matplotlib.pyplot as plt\n", + "\n", "%matplotlib inline\n", "import numpy as np\n", "from IPython.display import Video\n", "\n", - "n = 3.4 # index of waveguide\n", - "w = 1 # width of waveguide\n", - "r = 1 # inner radius of ring\n", - "pad = 4 # padding between waveguide and edge of PML\n", - "dpml = 2 # thickness of PML\n", - "sxy = 2*(r+w+pad+dpml) # cell size" + "n = 3.4 # index of waveguide\n", + "w = 1 # width of waveguide\n", + "r = 1 # inner radius of ring\n", + "pad = 4 # padding between waveguide and edge of PML\n", + "dpml = 2 # thickness of PML\n", + "sxy = 2 * (r + w + pad + dpml) # cell size" ] }, { @@ -57,7 +58,7 @@ "metadata": {}, "outputs": [], "source": [ - "c1 = mp.Cylinder(radius=r+w, material=mp.Medium(index=n))\n", + "c1 = mp.Cylinder(radius=r + w, material=mp.Medium(index=n))\n", "c2 = mp.Cylinder(radius=r)" ] }, @@ -76,9 +77,9 @@ "metadata": {}, "outputs": [], "source": [ - "fcen = 0.15 # pulse center frequency\n", - "df = 0.1 # pulse frequency width\n", - "src = mp.Source(mp.GaussianSource(fcen, fwidth=df), mp.Ez, mp.Vector3(r+0.1))" + "fcen = 0.15 # pulse center frequency\n", + "df = 0.1 # pulse frequency width\n", + "src = mp.Source(mp.GaussianSource(fcen, fwidth=df), mp.Ez, mp.Vector3(r + 0.1))" ] }, { @@ -119,11 +120,13 @@ } ], "source": [ - "sim = mp.Simulation(cell_size=mp.Vector3(sxy, sxy),\n", - " geometry=[c1, c2],\n", - " sources=[src],\n", - " resolution=10, \n", - " boundary_layers=[mp.PML(dpml)])\n", + "sim = mp.Simulation(\n", + " cell_size=mp.Vector3(sxy, sxy),\n", + " geometry=[c1, c2],\n", + " sources=[src],\n", + " resolution=10,\n", + " boundary_layers=[mp.PML(dpml)],\n", + ")\n", "plt.figure(dpi=150)\n", "sim.plot2D()\n", "plt.show()" @@ -155,9 +158,11 @@ } ], "source": [ - "sim.run(mp.at_beginning(mp.output_epsilon),\n", - " mp.after_sources(mp.Harminv(mp.Ez, mp.Vector3(r+0.1), fcen, df)),\n", - " until_after_sources=300)" + "sim.run(\n", + " mp.at_beginning(mp.output_epsilon),\n", + " mp.after_sources(mp.Harminv(mp.Ez, mp.Vector3(r + 0.1), fcen, df)),\n", + " until_after_sources=300,\n", + ")" ] }, { @@ -228,24 +233,26 @@ ], "source": [ "sim.reset_meep()\n", - "fcen=0.118\n", + "fcen = 0.118\n", "df = 0.1\n", - "sim.sources = [mp.Source(mp.GaussianSource(fcen, fwidth=df), mp.Ez, mp.Vector3(r+0.1))]\n", + "sim.sources = [\n", + " mp.Source(mp.GaussianSource(fcen, fwidth=df), mp.Ez, mp.Vector3(r + 0.1))\n", + "]\n", "\n", "# Start the simulation and get into steady state\n", - "sim.run(until=600) \n", + "sim.run(until=600)\n", "\n", "# Prepare the animator and record the steady state response\n", "f = plt.figure(dpi=150)\n", "Animate = mp.Animate2D(sim, fields=mp.Ez, f=f, realtime=False, normalize=True)\n", - "sim.run(mp.at_every(0.5,Animate),until=25)\n", + "sim.run(mp.at_every(0.5, Animate), until=25)\n", "\n", "# Close the animator's working frame\n", "plt.close()\n", "\n", "# Process the animation and view it\n", "filename = \"media/ring_simple.mp4\"\n", - "Animate.to_mp4(5,filename)\n", + "Animate.to_mp4(5, filename)\n", "Video(filename)" ] }, @@ -295,25 +302,27 @@ ], "source": [ "sim.reset_meep()\n", - "fcen=0.147\n", + "fcen = 0.147\n", "df = 0.1\n", - "sim.sources = [mp.Source(mp.GaussianSource(fcen, fwidth=df), mp.Ez, mp.Vector3(r+0.1))]\n", + "sim.sources = [\n", + " mp.Source(mp.GaussianSource(fcen, fwidth=df), mp.Ez, mp.Vector3(r + 0.1))\n", + "]\n", "sim.init_sim()\n", "\n", "# Start the simulation and get into steady state\n", - "sim.run(until=500) \n", + "sim.run(until=500)\n", "\n", "# Prepare the animator and record the steady state response\n", "f = plt.figure(dpi=150)\n", "Animate = mp.Animate2D(sim, fields=mp.Ez, f=f, realtime=False, normalize=True)\n", - "sim.run(mp.at_every(0.5,Animate),until=25)\n", + "sim.run(mp.at_every(0.5, Animate), until=25)\n", "\n", "# Close the animator's working frame\n", "plt.close()\n", "\n", "# Process the animation and view it\n", "filename = \"media/ring_mid.mp4\"\n", - "Animate.to_mp4(5,filename)\n", + "Animate.to_mp4(5, filename)\n", "Video(filename)" ] }, @@ -363,24 +372,26 @@ ], "source": [ "sim.reset_meep()\n", - "fcen=0.175\n", + "fcen = 0.175\n", "df = 0.1\n", - "sim.sources = [mp.Source(mp.GaussianSource(fcen, fwidth=df), mp.Ez, mp.Vector3(r+0.1))]\n", + "sim.sources = [\n", + " mp.Source(mp.GaussianSource(fcen, fwidth=df), mp.Ez, mp.Vector3(r + 0.1))\n", + "]\n", "\n", "# Start the simulation and get into steady state\n", - "sim.run(until=500) \n", + "sim.run(until=500)\n", "\n", "# Prepare the animator and record the steady state response\n", "f = plt.figure(dpi=150)\n", "Animate = mp.Animate2D(sim, fields=mp.Ez, f=f, realtime=False, normalize=True)\n", - "sim.run(mp.at_every(0.5,Animate),until=25)\n", + "sim.run(mp.at_every(0.5, Animate), until=25)\n", "\n", "# Close the animator's working frame\n", "plt.close()\n", "\n", "# Process the animation and view it\n", "filename = \"media/ring_large.mp4\"\n", - "Animate.to_mp4(5,filename)\n", + "Animate.to_mp4(5, filename)\n", "Video(filename)" ] } diff --git a/python/examples/solve-cw.ipynb b/python/examples/solve-cw.ipynb index dc1799b6b..a6823a4ab 100644 --- a/python/examples/solve-cw.ipynb +++ b/python/examples/solve-cw.ipynb @@ -89,36 +89,41 @@ "pad = 4\n", "dpml = 2\n", "\n", - "sxy = 2*(r+w+pad+dpml)\n", - "cell_size = mp.Vector3(sxy,sxy)\n", + "sxy = 2 * (r + w + pad + dpml)\n", + "cell_size = mp.Vector3(sxy, sxy)\n", "\n", "pml_layers = [mp.PML(dpml)]\n", "\n", - "nonpml_vol = mp.Volume(mp.Vector3(), size=mp.Vector3(sxy-2*dpml,sxy-2*dpml))\n", + "nonpml_vol = mp.Volume(mp.Vector3(), size=mp.Vector3(sxy - 2 * dpml, sxy - 2 * dpml))\n", "\n", - "geometry = [mp.Cylinder(radius=r+w, material=mp.Medium(index=n)),\n", - " mp.Cylinder(radius=r)]\n", + "geometry = [\n", + " mp.Cylinder(radius=r + w, material=mp.Medium(index=n)),\n", + " mp.Cylinder(radius=r),\n", + "]\n", "\n", "fcen = 0.118\n", "\n", - "src = [mp.Source(mp.ContinuousSource(fcen),\n", - " component=mp.Ez,\n", - " center=mp.Vector3(r+0.1)),\n", - " mp.Source(mp.ContinuousSource(fcen),\n", - " component=mp.Ez,\n", - " center=mp.Vector3(-(r+0.1)),\n", - " amplitude=-1)]\n", + "src = [\n", + " mp.Source(mp.ContinuousSource(fcen), component=mp.Ez, center=mp.Vector3(r + 0.1)),\n", + " mp.Source(\n", + " mp.ContinuousSource(fcen),\n", + " component=mp.Ez,\n", + " center=mp.Vector3(-(r + 0.1)),\n", + " amplitude=-1,\n", + " ),\n", + "]\n", "\n", - "symmetries = [mp.Mirror(mp.X,phase=-1),\n", - " mp.Mirror(mp.Y,phase=+1)]\n", + "symmetries = [mp.Mirror(mp.X, phase=-1), mp.Mirror(mp.Y, phase=+1)]\n", "\n", - "sim = mp.Simulation(cell_size=cell_size,\n", - " geometry=geometry,\n", - " sources=src,\n", - " resolution=10,\n", - " force_complex_fields=True,\n", - " symmetries=symmetries,\n", - " boundary_layers=pml_layers)\n", + "sim = mp.Simulation(\n", + " cell_size=cell_size,\n", + " geometry=geometry,\n", + " sources=src,\n", + " resolution=10,\n", + " force_complex_fields=True,\n", + " symmetries=symmetries,\n", + " boundary_layers=pml_layers,\n", + ")\n", "f = plt.figure(dpi=120)\n", "sim.plot2D(ax=f.gca())\n", "plt.show()" @@ -138,13 +143,13 @@ "outputs": [], "source": [ "num_tols = 5\n", - "tols = np.power(10, np.arange(-8.0,-8.0-num_tols,-1.0))\n", - "ez_dat = np.zeros((122,122,num_tols), dtype=np.complex_)\n", + "tols = np.power(10, np.arange(-8.0, -8.0 - num_tols, -1.0))\n", + "ez_dat = np.zeros((122, 122, num_tols), dtype=np.complex_)\n", "\n", "for i in range(num_tols):\n", " sim.init_sim()\n", " sim.solve_cw(tols[i], 10000, 10)\n", - " ez_dat[:,:,i] = sim.get_array(vol=nonpml_vol, component=mp.Ez)" + " ez_dat[:, :, i] = sim.get_array(vol=nonpml_vol, component=mp.Ez)" ] }, { @@ -173,14 +178,14 @@ } ], "source": [ - "err_dat = np.zeros(num_tols-1)\n", - "for i in range(num_tols-1):\n", - " err_dat[i] = LA.norm(ez_dat[:,:,i]-ez_dat[:,:,num_tols-1])\n", + "err_dat = np.zeros(num_tols - 1)\n", + "for i in range(num_tols - 1):\n", + " err_dat[i] = LA.norm(ez_dat[:, :, i] - ez_dat[:, :, num_tols - 1])\n", "\n", "plt.figure(dpi=150)\n", - "plt.loglog(tols[:num_tols-1], err_dat, 'bo-');\n", - "plt.xlabel(\"frequency-domain solver tolerance\");\n", - "plt.ylabel(\"L2 norm of error in fields\");\n", + "plt.loglog(tols[: num_tols - 1], err_dat, \"bo-\")\n", + "plt.xlabel(\"frequency-domain solver tolerance\")\n", + "plt.ylabel(\"L2 norm of error in fields\")\n", "plt.show()" ] }, @@ -211,18 +216,22 @@ ], "source": [ "eps_data = sim.get_array(vol=nonpml_vol, component=mp.Dielectric)\n", - "ez_data = np.real(ez_dat[:,:,num_tols-1])\n", + "ez_data = np.real(ez_dat[:, :, num_tols - 1])\n", "\n", "plt.figure()\n", - "plt.imshow(eps_data.transpose(), interpolation='spline36', cmap='binary')\n", - "plt.imshow(ez_data.transpose(), interpolation='spline36', cmap='RdBu', alpha=0.9)\n", - "plt.axis('off')\n", + "plt.imshow(eps_data.transpose(), interpolation=\"spline36\", cmap=\"binary\")\n", + "plt.imshow(ez_data.transpose(), interpolation=\"spline36\", cmap=\"RdBu\", alpha=0.9)\n", + "plt.axis(\"off\")\n", "plt.show()\n", "\n", "if np.all(np.diff(err_dat) < 0):\n", - " print(\"PASSED solve_cw test: error in the fields is decreasing with increasing resolution\")\n", + " print(\n", + " \"PASSED solve_cw test: error in the fields is decreasing with increasing resolution\"\n", + " )\n", "else:\n", - " print(\"FAILED solve_cw test: error in the fields is NOT decreasing with increasing resolution\")" + " print(\n", + " \"FAILED solve_cw test: error in the fields is NOT decreasing with increasing resolution\"\n", + " )" ] }, { @@ -244,20 +253,26 @@ "sim.reset_meep()\n", "\n", "df = 0.08\n", - "src = [mp.Source(mp.GaussianSource(fcen,fwidth=df),\n", - " component=mp.Ez,\n", - " center=mp.Vector3(r+0.1)),\n", - " mp.Source(mp.GaussianSource(fcen,fwidth=df),\n", - " component=mp.Ez,\n", - " center=mp.Vector3(-(r+0.1)),\n", - " amplitude=-1)]\n", + "src = [\n", + " mp.Source(\n", + " mp.GaussianSource(fcen, fwidth=df), component=mp.Ez, center=mp.Vector3(r + 0.1)\n", + " ),\n", + " mp.Source(\n", + " mp.GaussianSource(fcen, fwidth=df),\n", + " component=mp.Ez,\n", + " center=mp.Vector3(-(r + 0.1)),\n", + " amplitude=-1,\n", + " ),\n", + "]\n", "\n", - "sim = mp.Simulation(cell_size=mp.Vector3(sxy,sxy),\n", - " geometry=geometry,\n", - " sources=src,\n", - " resolution=10,\n", - " symmetries=symmetries,\n", - " boundary_layers=pml_layers)\n", + "sim = mp.Simulation(\n", + " cell_size=mp.Vector3(sxy, sxy),\n", + " geometry=geometry,\n", + " sources=src,\n", + " resolution=10,\n", + " symmetries=symmetries,\n", + " boundary_layers=pml_layers,\n", + ")\n", "\n", "dft_obj = sim.add_dft_fields([mp.Ez], fcen, 0, 1, where=nonpml_vol)\n", "\n", @@ -287,9 +302,9 @@ "ez_data = np.real(sim.get_dft_array(dft_obj, mp.Ez, 0))\n", "\n", "plt.figure()\n", - "plt.imshow(eps_data.transpose(), interpolation='spline36', cmap='binary')\n", - "plt.imshow(ez_data.transpose(), interpolation='spline36', cmap='RdBu', alpha=0.9)\n", - "plt.axis('off')\n", + "plt.imshow(eps_data.transpose(), interpolation=\"spline36\", cmap=\"binary\")\n", + "plt.imshow(ez_data.transpose(), interpolation=\"spline36\", cmap=\"RdBu\", alpha=0.9)\n", + "plt.axis(\"off\")\n", "plt.show()" ] } diff --git a/python/examples/stochastic_emitter.ipynb b/python/examples/stochastic_emitter.ipynb index 59f33cec8..a18bf3022 100644 --- a/python/examples/stochastic_emitter.ipynb +++ b/python/examples/stochastic_emitter.ipynb @@ -28,13 +28,27 @@ "import numpy as np\n", "\n", "import argparse\n", + "\n", "parser = argparse.ArgumentParser()\n", - "parser.add_argument('-res', type=int, default=50, help='resolution (pixels/um)')\n", - "parser.add_argument('-nr', type=int, default=20, help='number of random trials (method 1)')\n", - "parser.add_argument('-nd', type=int, default=10, help='number of dipoles')\n", - "parser.add_argument('-nf', type=int, default=500, help='number of frequencies')\n", - "parser.add_argument('-textured', action='store_true', default=False, help='flat (default) or textured surface')\n", - "parser.add_argument('-method', type=int, choices=[1,2], default=1, help='type of method: (1) random dipoles with nr trials or (2) single dipole with 1 run per dipole')\n", + "parser.add_argument(\"-res\", type=int, default=50, help=\"resolution (pixels/um)\")\n", + "parser.add_argument(\n", + " \"-nr\", type=int, default=20, help=\"number of random trials (method 1)\"\n", + ")\n", + "parser.add_argument(\"-nd\", type=int, default=10, help=\"number of dipoles\")\n", + "parser.add_argument(\"-nf\", type=int, default=500, help=\"number of frequencies\")\n", + "parser.add_argument(\n", + " \"-textured\",\n", + " action=\"store_true\",\n", + " default=False,\n", + " help=\"flat (default) or textured surface\",\n", + ")\n", + "parser.add_argument(\n", + " \"-method\",\n", + " type=int,\n", + " choices=[1, 2],\n", + " default=1,\n", + " help=\"type of method: (1) random dipoles with nr trials or (2) single dipole with 1 run per dipole\",\n", + ")\n", "args = parser.parse_args()\n", "\n", "resolution = args.res\n", @@ -47,56 +61,81 @@ "dAg = 0.5\n", "\n", "sx = 1.1\n", - "sy = dpml+dair+hrod+dsub+dAg\n", + "sy = dpml + dair + hrod + dsub + dAg\n", "\n", - "cell_size = mp.Vector3(sx,sy)\n", + "cell_size = mp.Vector3(sx, sy)\n", "\n", - "pml_layers = [mp.PML(direction=mp.Y,\n", - " thickness=dpml,\n", - " side=mp.High)]\n", + "pml_layers = [mp.PML(direction=mp.Y, thickness=dpml, side=mp.High)]\n", "\n", "fcen = 1.0\n", "df = 0.2\n", "nfreq = args.nf\n", "ndipole = args.nd\n", "ntrial = args.nr\n", - "run_time = 2*nfreq/df\n", - "\n", - "geometry = [mp.Block(material=mp.Medium(index=3.45),\n", - " center=mp.Vector3(0,0.5*sy-dpml-dair-hrod-0.5*dsub),\n", - " size=mp.Vector3(mp.inf,dsub,mp.inf)),\n", - " mp.Block(material=Ag,\n", - " center=mp.Vector3(0,-0.5*sy+0.5*dAg),\n", - " size=mp.Vector3(mp.inf,dAg,mp.inf))]\n", + "run_time = 2 * nfreq / df\n", + "\n", + "geometry = [\n", + " mp.Block(\n", + " material=mp.Medium(index=3.45),\n", + " center=mp.Vector3(0, 0.5 * sy - dpml - dair - hrod - 0.5 * dsub),\n", + " size=mp.Vector3(mp.inf, dsub, mp.inf),\n", + " ),\n", + " mp.Block(\n", + " material=Ag,\n", + " center=mp.Vector3(0, -0.5 * sy + 0.5 * dAg),\n", + " size=mp.Vector3(mp.inf, dAg, mp.inf),\n", + " ),\n", + "]\n", "\n", "if args.textured:\n", - " geometry.append(mp.Block(material=mp.Medium(index=3.45),\n", - " center=mp.Vector3(0,0.5*sy-dpml-dair-0.5*hrod),\n", - " size=mp.Vector3(wrod,hrod,mp.inf)))\n", + " geometry.append(\n", + " mp.Block(\n", + " material=mp.Medium(index=3.45),\n", + " center=mp.Vector3(0, 0.5 * sy - dpml - dair - 0.5 * hrod),\n", + " size=mp.Vector3(wrod, hrod, mp.inf),\n", + " )\n", + " )\n", "\n", - "def compute_flux(m=1,n=0):\n", + "\n", + "def compute_flux(m=1, n=0):\n", " if m == 1:\n", " sources = []\n", " for n in range(ndipole):\n", - " sources.append(mp.Source(mp.CustomSource(src_func=lambda t: np.random.randn()),\n", - " component=mp.Ez,\n", - " center=mp.Vector3(sx*(-0.5+n/ndipole),-0.5*sy+dAg+0.5*dsub)))\n", + " sources.append(\n", + " mp.Source(\n", + " mp.CustomSource(src_func=lambda t: np.random.randn()),\n", + " component=mp.Ez,\n", + " center=mp.Vector3(\n", + " sx * (-0.5 + n / ndipole), -0.5 * sy + dAg + 0.5 * dsub\n", + " ),\n", + " )\n", + " )\n", " else:\n", - " sources = [mp.Source(mp.GaussianSource(fcen,fwidth=df),\n", - " component=mp.Ez,\n", - " center=mp.Vector3(sx*(-0.5+n/ndipole),-0.5*sy+dAg+0.5*dsub))]\n", - "\n", - " sim = mp.Simulation(cell_size=cell_size,\n", - " resolution=resolution,\n", - " k_point=mp.Vector3(),\n", - " boundary_layers=pml_layers,\n", - " geometry=geometry,\n", - " sources=sources)\n", - "\n", - " flux_mon = sim.add_flux(fcen,\n", - " df,\n", - " nfreq,\n", - " mp.FluxRegion(center=mp.Vector3(0,0.5*sy-dpml),size=mp.Vector3(sx)))\n", + " sources = [\n", + " mp.Source(\n", + " mp.GaussianSource(fcen, fwidth=df),\n", + " component=mp.Ez,\n", + " center=mp.Vector3(\n", + " sx * (-0.5 + n / ndipole), -0.5 * sy + dAg + 0.5 * dsub\n", + " ),\n", + " )\n", + " ]\n", + "\n", + " sim = mp.Simulation(\n", + " cell_size=cell_size,\n", + " resolution=resolution,\n", + " k_point=mp.Vector3(),\n", + " boundary_layers=pml_layers,\n", + " geometry=geometry,\n", + " sources=sources,\n", + " )\n", + "\n", + " flux_mon = sim.add_flux(\n", + " fcen,\n", + " df,\n", + " nfreq,\n", + " mp.FluxRegion(center=mp.Vector3(0, 0.5 * sy - dpml), size=mp.Vector3(sx)),\n", + " )\n", "\n", " sim.run(until=run_time)\n", "\n", @@ -105,19 +144,29 @@ "\n", " return freqs, flux\n", "\n", + "\n", "if args.method == 1:\n", - " fluxes = np.zeros((nfreq,ntrial))\n", + " fluxes = np.zeros((nfreq, ntrial))\n", " for t in range(ntrial):\n", - " freqs, fluxes[:,t] = compute_flux(m=1)\n", + " freqs, fluxes[:, t] = compute_flux(m=1)\n", "else:\n", - " fluxes = np.zeros((nfreq,ndipole))\n", + " fluxes = np.zeros((nfreq, ndipole))\n", " for d in range(ndipole):\n", - " freqs, fluxes[:,d] = compute_flux(m=2,n=d)\n", + " freqs, fluxes[:, d] = compute_flux(m=2, n=d)\n", "\n", "\n", "if mp.am_master():\n", - " with open('method{}_{}_res{}_nfreq{}_ndipole{}.npz'.format(args.method,\"textured\" if args.textured else \"flat\",resolution,nfreq,ndipole),'wb') as f:\n", - " np.savez(f,freqs=freqs,fluxes=fluxes)" + " with open(\n", + " \"method{}_{}_res{}_nfreq{}_ndipole{}.npz\".format(\n", + " args.method,\n", + " \"textured\" if args.textured else \"flat\",\n", + " resolution,\n", + " nfreq,\n", + " ndipole,\n", + " ),\n", + " \"wb\",\n", + " ) as f:\n", + " np.savez(f, freqs=freqs, fluxes=fluxes)" ] }, { @@ -155,24 +204,24 @@ "import numpy as np\n", "import matplotlib.pyplot as plt\n", "\n", - "method1_f0 = np.load('method1_flat_res50_nfreq500_ndipole10.npz')\n", - "method1_f1 = np.load('method1_textured_res50_nfreq500_ndipole10.npz')\n", + "method1_f0 = np.load(\"method1_flat_res50_nfreq500_ndipole10.npz\")\n", + "method1_f1 = np.load(\"method1_textured_res50_nfreq500_ndipole10.npz\")\n", "\n", - "method1_freqs = method1_f0['freqs']\n", - "method1_f0_mean = np.mean(method1_f0['fluxes'],axis=1)\n", - "method1_f1_mean = np.mean(method1_f1['fluxes'],axis=1)\n", + "method1_freqs = method1_f0[\"freqs\"]\n", + "method1_f0_mean = np.mean(method1_f0[\"fluxes\"], axis=1)\n", + "method1_f1_mean = np.mean(method1_f1[\"fluxes\"], axis=1)\n", "\n", - "method2_f0 = np.load('method2_flat_res50_nfreq500_ndipole10.npz')\n", - "method2_f1 = np.load('method2_textured_res50_nfreq500_ndipole10.npz')\n", + "method2_f0 = np.load(\"method2_flat_res50_nfreq500_ndipole10.npz\")\n", + "method2_f1 = np.load(\"method2_textured_res50_nfreq500_ndipole10.npz\")\n", "\n", - "method2_freqs = method2_f0['freqs']\n", - "method2_f0_mean = np.mean(method2_f0['fluxes'],axis=1)\n", - "method2_f1_mean = np.mean(method2_f1['fluxes'],axis=1)\n", + "method2_freqs = method2_f0[\"freqs\"]\n", + "method2_f0_mean = np.mean(method2_f0[\"fluxes\"], axis=1)\n", + "method2_f1_mean = np.mean(method2_f1[\"fluxes\"], axis=1)\n", "\n", - "plt.semilogy(method1_freqs,method1_f1_mean/method1_f0_mean,'b-',label='Method 1')\n", - "plt.semilogy(method2_freqs,method2_f1_mean/method2_f0_mean,'r-',label='Method 2')\n", - "plt.xlabel('frequency')\n", - "plt.ylabel('normalized flux')\n", + "plt.semilogy(method1_freqs, method1_f1_mean / method1_f0_mean, \"b-\", label=\"Method 1\")\n", + "plt.semilogy(method2_freqs, method2_f1_mean / method2_f0_mean, \"r-\", label=\"Method 2\")\n", + "plt.xlabel(\"frequency\")\n", + "plt.ylabel(\"normalized flux\")\n", "plt.legend()\n", "plt.show()" ] diff --git a/python/examples/straight-waveguide.ipynb b/python/examples/straight-waveguide.ipynb index 91d703bf3..53de3462b 100644 --- a/python/examples/straight-waveguide.ipynb +++ b/python/examples/straight-waveguide.ipynb @@ -44,7 +44,7 @@ "metadata": {}, "outputs": [], "source": [ - "cell = mp.Vector3(16,8,0)" + "cell = mp.Vector3(16, 8, 0)" ] }, { @@ -68,9 +68,13 @@ "metadata": {}, "outputs": [], "source": [ - "geometry = [mp.Block(mp.Vector3(mp.inf,1,mp.inf),\n", - " center=mp.Vector3(),\n", - " material=mp.Medium(epsilon=12))]" + "geometry = [\n", + " mp.Block(\n", + " mp.Vector3(mp.inf, 1, mp.inf),\n", + " center=mp.Vector3(),\n", + " material=mp.Medium(epsilon=12),\n", + " )\n", + "]" ] }, { @@ -94,9 +98,11 @@ "metadata": {}, "outputs": [], "source": [ - "sources = [mp.Source(mp.ContinuousSource(frequency=0.15),\n", - " component=mp.Ez,\n", - " center=mp.Vector3(-7,0))]" + "sources = [\n", + " mp.Source(\n", + " mp.ContinuousSource(frequency=0.15), component=mp.Ez, center=mp.Vector3(-7, 0)\n", + " )\n", + "]" ] }, { @@ -176,11 +182,13 @@ "metadata": {}, "outputs": [], "source": [ - "sim = mp.Simulation(cell_size=cell,\n", - " boundary_layers=pml_layers,\n", - " geometry=geometry,\n", - " sources=sources,\n", - " resolution=resolution)" + "sim = mp.Simulation(\n", + " cell_size=cell,\n", + " boundary_layers=pml_layers,\n", + " geometry=geometry,\n", + " sources=sources,\n", + " resolution=resolution,\n", + ")" ] }, { @@ -224,6 +232,7 @@ ], "source": [ "from matplotlib import pyplot as plt\n", + "\n", "%matplotlib inline\n", "plt.figure(dpi=100)\n", "sim.plot2D()\n", @@ -357,7 +366,7 @@ } ], "source": [ - "sim.run(mp.at_every(1,Animate),until=100)\n", + "sim.run(mp.at_every(1, Animate), until=100)\n", "plt.close()" ] }, @@ -383,7 +392,7 @@ ], "source": [ "filename = \"media/straight_waveguide.mp4\"\n", - "Animate.to_mp4(10,filename)" + "Animate.to_mp4(10, filename)" ] }, { @@ -416,6 +425,7 @@ ], "source": [ "from IPython.display import Video\n", + "\n", "Video(filename)" ] }, diff --git a/python/examples/zone_plate.ipynb b/python/examples/zone_plate.ipynb index e97e055e6..5796367a2 100644 --- a/python/examples/zone_plate.ipynb +++ b/python/examples/zone_plate.ipynb @@ -30,85 +30,139 @@ "import math\n", "import matplotlib.pyplot as plt\n", "\n", - "resolution = 25 # pixels/μm\n", + "resolution = 25 # pixels/μm\n", "\n", - "dpml = 1.0 # PML thickness\n", - "dsub = 2.0 # substrate thickness\n", - "dpad = 2.0 # padding betweeen zone plate and PML\n", - "zh = 0.5 # zone-plate height\n", - "zN = 25 # number of zones (odd zones: π phase shift, even zones: none)\n", - "focal_length = 200 # focal length of zone plate\n", - "spot_length = 100 # far-field line length\n", - "ff_res = 10 # far-field resolution\n", + "dpml = 1.0 # PML thickness\n", + "dsub = 2.0 # substrate thickness\n", + "dpad = 2.0 # padding betweeen zone plate and PML\n", + "zh = 0.5 # zone-plate height\n", + "zN = 25 # number of zones (odd zones: π phase shift, even zones: none)\n", + "focal_length = 200 # focal length of zone plate\n", + "spot_length = 100 # far-field line length\n", + "ff_res = 10 # far-field resolution\n", "\n", "pml_layers = [mp.PML(thickness=dpml)]\n", "\n", "wvl_cen = 0.5\n", - "frq_cen = 1/wvl_cen\n", - "dfrq = 0.2*frq_cen\n", + "frq_cen = 1 / wvl_cen\n", + "dfrq = 0.2 * frq_cen\n", "\n", "## radii of zones\n", "## ref: eq. 7 of http://zoneplate.lbl.gov/theory\n", - "r = [math.sqrt(n*wvl_cen*(focal_length+n*wvl_cen/4)) for n in range(1,zN+1)]\n", - "\n", - "sr = r[-1]+dpad+dpml\n", - "sz = dpml+dsub+zh+dpad+dpml\n", - "cell_size = mp.Vector3(sr,0,sz)\n", - "\n", - "sources = [mp.Source(mp.GaussianSource(frq_cen,fwidth=dfrq,is_integrated=True),\n", - " component=mp.Er,\n", - " center=mp.Vector3(0.5*sr,0,-0.5*sz+dpml),\n", - " size=mp.Vector3(sr)),\n", - " mp.Source(mp.GaussianSource(frq_cen,fwidth=dfrq,is_integrated=True),\n", - " component=mp.Ep,\n", - " center=mp.Vector3(0.5*sr,0,-0.5*sz+dpml),\n", - " size=mp.Vector3(sr),\n", - " amplitude=-1j)]\n", + "r = [\n", + " math.sqrt(n * wvl_cen * (focal_length + n * wvl_cen / 4)) for n in range(1, zN + 1)\n", + "]\n", + "\n", + "sr = r[-1] + dpad + dpml\n", + "sz = dpml + dsub + zh + dpad + dpml\n", + "cell_size = mp.Vector3(sr, 0, sz)\n", + "\n", + "sources = [\n", + " mp.Source(\n", + " mp.GaussianSource(frq_cen, fwidth=dfrq, is_integrated=True),\n", + " component=mp.Er,\n", + " center=mp.Vector3(0.5 * sr, 0, -0.5 * sz + dpml),\n", + " size=mp.Vector3(sr),\n", + " ),\n", + " mp.Source(\n", + " mp.GaussianSource(frq_cen, fwidth=dfrq, is_integrated=True),\n", + " component=mp.Ep,\n", + " center=mp.Vector3(0.5 * sr, 0, -0.5 * sz + dpml),\n", + " size=mp.Vector3(sr),\n", + " amplitude=-1j,\n", + " ),\n", + "]\n", "\n", "glass = mp.Medium(index=1.5)\n", "\n", - "geometry = [mp.Block(material=glass,\n", - " size=mp.Vector3(sr,0,dpml+dsub),\n", - " center=mp.Vector3(0.5*sr,0,-0.5*sz+0.5*(dpml+dsub)))]\n", - "\n", - "for n in range(zN-1,-1,-1):\n", - " geometry.append(mp.Block(material=glass if n % 2 == 0 else mp.vacuum,\n", - " size=mp.Vector3(r[n],0,zh),\n", - " center=mp.Vector3(0.5*r[n],0,-0.5*sz+dpml+dsub+0.5*zh)))\n", - " \n", - "sim = mp.Simulation(cell_size=cell_size,\n", - " boundary_layers=pml_layers,\n", - " resolution=resolution,\n", - " sources=sources,\n", - " geometry=geometry,\n", - " dimensions=mp.CYLINDRICAL,\n", - " m=-1)\n", + "geometry = [\n", + " mp.Block(\n", + " material=glass,\n", + " size=mp.Vector3(sr, 0, dpml + dsub),\n", + " center=mp.Vector3(0.5 * sr, 0, -0.5 * sz + 0.5 * (dpml + dsub)),\n", + " )\n", + "]\n", + "\n", + "for n in range(zN - 1, -1, -1):\n", + " geometry.append(\n", + " mp.Block(\n", + " material=glass if n % 2 == 0 else mp.vacuum,\n", + " size=mp.Vector3(r[n], 0, zh),\n", + " center=mp.Vector3(0.5 * r[n], 0, -0.5 * sz + dpml + dsub + 0.5 * zh),\n", + " )\n", + " )\n", + "\n", + "sim = mp.Simulation(\n", + " cell_size=cell_size,\n", + " boundary_layers=pml_layers,\n", + " resolution=resolution,\n", + " sources=sources,\n", + " geometry=geometry,\n", + " dimensions=mp.CYLINDRICAL,\n", + " m=-1,\n", + ")\n", "\n", "## near-field monitor\n", - "n2f_obj = sim.add_near2far(frq_cen, 0, 1, mp.Near2FarRegion(center=mp.Vector3(0.5*(sr-dpml),0,0.5*sz-dpml),size=mp.Vector3(sr-dpml)))\n", + "n2f_obj = sim.add_near2far(\n", + " frq_cen,\n", + " 0,\n", + " 1,\n", + " mp.Near2FarRegion(\n", + " center=mp.Vector3(0.5 * (sr - dpml), 0, 0.5 * sz - dpml),\n", + " size=mp.Vector3(sr - dpml),\n", + " ),\n", + ")\n", "\n", "sim.run(until_after_sources=100)\n", "\n", - "ff_r = sim.get_farfields(n2f_obj, ff_res, center=mp.Vector3(0.5*(sr-dpml),0,-0.5*sz+dpml+dsub+zh+focal_length),size=mp.Vector3(sr-dpml))\n", - "ff_z = sim.get_farfields(n2f_obj, ff_res, center=mp.Vector3(z=-0.5*sz+dpml+dsub+zh+focal_length),size=mp.Vector3(z=spot_length))\n", - "\n", - "E2_r = np.absolute(ff_r['Ex'])**2+np.absolute(ff_r['Ey'])**2+np.absolute(ff_r['Ez'])**2\n", - "E2_z = np.absolute(ff_z['Ex'])**2+np.absolute(ff_z['Ey'])**2+np.absolute(ff_z['Ez'])**2\n", + "ff_r = sim.get_farfields(\n", + " n2f_obj,\n", + " ff_res,\n", + " center=mp.Vector3(\n", + " 0.5 * (sr - dpml), 0, -0.5 * sz + dpml + dsub + zh + focal_length\n", + " ),\n", + " size=mp.Vector3(sr - dpml),\n", + ")\n", + "ff_z = sim.get_farfields(\n", + " n2f_obj,\n", + " ff_res,\n", + " center=mp.Vector3(z=-0.5 * sz + dpml + dsub + zh + focal_length),\n", + " size=mp.Vector3(z=spot_length),\n", + ")\n", + "\n", + "E2_r = (\n", + " np.absolute(ff_r[\"Ex\"]) ** 2\n", + " + np.absolute(ff_r[\"Ey\"]) ** 2\n", + " + np.absolute(ff_r[\"Ez\"]) ** 2\n", + ")\n", + "E2_z = (\n", + " np.absolute(ff_z[\"Ex\"]) ** 2\n", + " + np.absolute(ff_z[\"Ey\"]) ** 2\n", + " + np.absolute(ff_z[\"Ez\"]) ** 2\n", + ")\n", "\n", "plt.figure(dpi=200)\n", - "plt.subplot(1,2,1)\n", - "plt.semilogy(np.linspace(0,sr-dpml,len(E2_r)),E2_r,'bo-')\n", - "plt.xlim(-2,20)\n", - "plt.xticks([t for t in np.arange(0,25,5)])\n", - "plt.grid(True,axis=\"y\",which=\"both\",ls=\"-\")\n", - "plt.xlabel(r'$r$ coordinate (μm)')\n", - "plt.ylabel(r'energy density of far fields, |E|$^2$')\n", - "plt.subplot(1,2,2)\n", - "plt.semilogy(np.linspace(focal_length-0.5*spot_length,focal_length+0.5*spot_length,len(E2_z)),E2_z,'bo-')\n", - "plt.grid(True,axis=\"y\",which=\"both\",ls=\"-\")\n", - "plt.xlabel(r'$z$ coordinate (μm)')\n", - "plt.ylabel(r'energy density of far fields, |E|$^2$')\n", - "plt.suptitle(r\"binary-phase zone plate with focal length $z$ = {} μm\".format(focal_length))\n", + "plt.subplot(1, 2, 1)\n", + "plt.semilogy(np.linspace(0, sr - dpml, len(E2_r)), E2_r, \"bo-\")\n", + "plt.xlim(-2, 20)\n", + "plt.xticks([t for t in np.arange(0, 25, 5)])\n", + "plt.grid(True, axis=\"y\", which=\"both\", ls=\"-\")\n", + "plt.xlabel(r\"$r$ coordinate (μm)\")\n", + "plt.ylabel(r\"energy density of far fields, |E|$^2$\")\n", + "plt.subplot(1, 2, 2)\n", + "plt.semilogy(\n", + " np.linspace(\n", + " focal_length - 0.5 * spot_length, focal_length + 0.5 * spot_length, len(E2_z)\n", + " ),\n", + " E2_z,\n", + " \"bo-\",\n", + ")\n", + "plt.grid(True, axis=\"y\", which=\"both\", ls=\"-\")\n", + "plt.xlabel(r\"$z$ coordinate (μm)\")\n", + "plt.ylabel(r\"energy density of far fields, |E|$^2$\")\n", + "plt.suptitle(\n", + " r\"binary-phase zone plate with focal length $z$ = {} μm\".format(focal_length)\n", + ")\n", "plt.tight_layout()\n", "plt.savefig(\"zone_plate_farfields.png\")" ]