### Optimisation output example Source: https://uos-integrated-nanophotonics-group.github.io/MieDiff/auto_gallery/ex_06_optimisation.html Example output showing the optimal core and shell parameters. ```text -------------------------------------------------- optimum: r_core = 56.9nm r_shell = 101.8nm n_core = 4.44+0.10j n_shell = 2.44+0.10j ``` -------------------------------- ### Setup for Mie coefficient gradient demo Source: https://uos-integrated-nanophotonics-group.github.io/MieDiff/auto_gallery/ex_05_autodiff.html Defines the particle configuration (radii, refractive indices, wavelength) and enables gradient tracking on the shell radius. This setup is used by the subsequent gradient examples. ```python # - some radii and ref.index particle config for this demo wl0 = [500.0] # nm k0 = 2 * torch.pi / torch.as_tensor(wl0) n_c = torch.as_tensor(3.0) n_s = torch.as_tensor(4.0) r_c = torch.as_tensor(110.0) # nm r_s = torch.as_tensor(130.0) # nm r_s.requires_grad = True # which Mie order to evaluate (Note: supports vectorization) n_max = 2 ``` -------------------------------- ### Setup optimization parameters Source: https://uos-integrated-nanophotonics-group.github.io/MieDiff/_downloads/9ec4249233fc3807cf0d1998b5be463a/ex_08_multi_scattering_autodiff.ipynb Initialize the target focal point and the geometry parameters (positions, core radii, shell thicknesses) with gradient tracking enabled. ```python # optimization target z_focus = -6000 r_target = torch.as_tensor([[0, 0, z_focus]], device=OptConfig.device) # initialize geometry: uniform grid # Note: it's required to specify the device before setting `require_grad`` z0_metasurface = 0 D_area = 7000 N_particles = 10 # construct grid of N x N particles geo_pos_init = tg.tools.geometry.coordinate_map_2d_square( D_area / 2, N_particles, z0_metasurface ) geo_pos_init = geo_pos_init["r_probe"][:, :2] # optimize x,y coordinates geo_pos = geo_pos_init.clone().detach().to(OptConfig.device) geo_pos.requires_grad = True rc_init = torch.zeros(len(geo_pos_init), device=OptConfig.device) geo_rc = rc_init.clone().detach() geo_rc.requires_grad = True rs_init = torch.zeros(len(geo_pos_init), device=OptConfig.device) geo_rs = rs_init.clone().detach() geo_rs.requires_grad = True # init the optimizer with the target parameters optimizer = OptConfig.optimizer([geo_pos, geo_rc, geo_rs], lr=OptConfig.lr) ``` -------------------------------- ### Output: smallest size parameter Source: https://uos-integrated-nanophotonics-group.github.io/MieDiff/auto_gallery/ex_03_large_particles_stability.html Printed output from the setup code showing the smallest size parameter value. ```text smallest size parameter of the simulations: 116.41 ``` -------------------------------- ### Optimization Output Log Source: https://uos-integrated-nanophotonics-group.github.io/MieDiff/auto_gallery/ex_06_optimisation.html Example output showing the loss and parameter values across iterations. ```text --- iter 0: loss=5.47, best=0.74 r_core, r_shell = 69.0nm, 105.3nm n_core, n_shell = 3.83+0.06j, 1.94+0.05j --- iter 1: loss=4.11, best=0.75 r_core, r_shell = 54.3nm, 98.3nm n_core, n_shell = 4.31+0.08j, 2.50+0.06j --- iter 2: loss=3.55, best=0.67 r_core, r_shell = 61.5nm, 108.1nm n_core, n_shell = 4.09+0.07j, 2.42+0.07j --- iter 3: loss=3.31, best=0.34 r_core, r_shell = 60.2nm, 105.2nm n_core, n_shell = 4.08+0.07j, 2.33+0.07j --- iter 4: loss=3.03, best=0.58 r_core, r_shell = 72.9nm, 112.8nm n_core, n_shell = 3.95+0.07j, 1.92+0.07j --- iter 5: loss=2.79, best=0.34 r_core, r_shell = 71.7nm, 110.3nm n_core, n_shell = 3.93+0.08j, 1.84+0.07j --- iter 6: loss=2.58, best=0.31 r_core, r_shell = 57.5nm, 100.3nm n_core, n_shell = 4.35+0.09j, 2.39+0.07j --- iter 7: loss=2.41, best=0.26 r_core, r_shell = 61.3nm, 106.0nm n_core, n_shell = 4.14+0.08j, 2.22+0.08j --- iter 8: loss=2.29, best=0.27 r_core, r_shell = 62.5nm, 108.1nm n_core, n_shell = 4.17+0.08j, 2.24+0.09j --- iter 9: loss=2.18, best=0.41 r_core, r_shell = 63.4nm, 109.5nm n_core, n_shell = 4.19+0.09j, 2.24+0.09j --- iter 10: loss=2.06, best=0.41 r_core, r_shell = 69.9nm, 110.7nm n_core, n_shell = 3.70+0.10j, 2.07+0.08j --- iter 11: loss=1.98, best=0.35 r_core, r_shell = 63.6nm, 109.4nm n_core, n_shell = 4.20+0.09j, 2.20+0.09j --- iter 12: loss=1.92, best=0.24 r_core, r_shell = 63.1nm, 108.4nm n_core, n_shell = 4.21+0.09j, 2.16+0.09j --- iter 13: loss=1.85, best=0.20 r_core, r_shell = 60.6nm, 102.8nm n_core, n_shell = 4.38+0.09j, 2.26+0.08j --- iter 14: loss=1.76, best=0.30 r_core, r_shell = 62.0nm, 106.2nm n_core, n_shell = 4.21+0.09j, 2.10+0.09j --- iter 15: loss=1.69, best=0.31 r_core, r_shell = 56.8nm, 98.8nm n_core, n_shell = 4.18+0.09j, 2.66+0.09j --- iter 16: loss=1.66, best=0.25 r_core, r_shell = 56.9nm, 107.4nm n_core, n_shell = 4.26+0.09j, 2.36+0.08j --- iter 17: loss=1.63, best=0.26 ``` -------------------------------- ### Install pyMieDiff via pip Source: https://uos-integrated-nanophotonics-group.github.io/MieDiff/_sources/index.md Use the pip package manager to install the library. ```bash $ pip install pymiediff ``` -------------------------------- ### Initialize a multilayer Particle Source: https://uos-integrated-nanophotonics-group.github.io/MieDiff/generated/pymiediff.Particle.__init__.html Example showing the creation of a spherical particle with two layers using the preferred multilayer input format. ```python >>> import pymiediff as pmd >>> p = pmd.Particle(r_layers=[50, 80], eps_layers=[2.25, 4.0], mat_env=1.0) ``` -------------------------------- ### Setup 4-layer sphere parameters Source: https://uos-integrated-nanophotonics-group.github.io/MieDiff/auto_gallery/ex_03_large_particles_stability.html Defines wavelength range, environment refractive index, layer radii, refractive indices, permittivities, and truncation order. Prints the smallest size parameter of the simulations. ```python wl0 = torch.linspace(1095.0, 1100.0, 180, dtype=torch.float64) # nm k0 = 2 * torch.pi / wl0 n_env = 1.0 # outer radii of each layer (nm), from core to shell r_layers = torch.tensor([135.0, 365.0, 395.0, 5630.0], dtype=torch.float64) # refractive indices of the layers (constant over wavelength for this demo) n_layers = torch.tensor( [2.1 + 0.15j, 1.75 + 0.00j, 0.45 + 5.06j, 3.62 + 0.0j], dtype=torch.complex128, ) eps_layers = n_layers**2 # truncation order (None for auto) n_max = None # get smallest size parameter of the configs x_l = 2 * torch.pi * n_layers[-1].abs() * r_layers[-1] / wl0.max() print(f"smallest size parameter of the simulations: {x_l:.2f}") ``` -------------------------------- ### Setup optimization target spectrum Source: https://uos-integrated-nanophotonics-group.github.io/MieDiff/_downloads/2c2e13f70a8f15c2f567d53db9f1955f/ex_06_optimisation.ipynb Defines the wavelength range and a Gaussian target spectrum centered at 600nm for the optimization process. ```python # - define the range of wavelengths to be incuded in optimisation. N_wl = 21 wl0 = torch.linspace(400, 800, N_wl) k0 = 2 * torch.pi / wl0 # - for this example we target a gaussian like spectra centered at 600.0nm def gaussian(x, mu, sig): return ( 1.0 / (np.sqrt(2.0 * np.pi) * sig) * np.exp(-np.power((x - mu) / sig, 2.0) / 2) ) target = gaussian(wl0.numpy(), 600.0, 60.0) * 700 + 0.5 target_tensor = torch.tensor(target) # - we can plot the target spectra plt.figure() plt.plot(wl0, target, label="Target spetra.") plt.xlabel("$\lambda$ (nm)") plt.legend() # plt.savefig("ex_04a.svg", dpi=300) plt.show() ``` -------------------------------- ### Example usage of interp1d Source: https://uos-integrated-nanophotonics-group.github.io/MieDiff/generated/generated/pymiediff.helper.helper.interp1d.html Demonstrates how to use interp1d to interpolate a value between two sample points. ```python >>> import torch >>> interp1d(torch.tensor([0.5]), torch.tensor([0.0, 1.0]), torch.tensor([0.0, 2.0])) tensor([1.]) ``` -------------------------------- ### Setup test case parameters Source: https://uos-integrated-nanophotonics-group.github.io/MieDiff/_downloads/eaf1089427df783f9fa9bdb6e44bd007/ex_10_benchmark.ipynb Defines the physical parameters for the Mie scattering test case, including wavelength range, core/shell radii, and refractive indices. ```python # - config N_wl = 256 wl0 = torch.linspace(500, 1500, N_wl) k0 = 2 * torch.pi / wl0 r_core = 200.0 r_shell = 420.0 n_core = 0.5 + 5.1j n_shell = 4.5 # caution: metal-like shells can become unstable mat_core = pmd.materials.MatConstant(n_core**2) mat_shell = pmd.materials.MatConstant(n_shell**2) n_env = 1.0 ``` -------------------------------- ### Import required libraries Source: https://uos-integrated-nanophotonics-group.github.io/MieDiff/_downloads/5b4a0d7c1c7e83e79ffe99259c959c68/ex_04_multilayer_nearfields.ipynb Imports necessary libraries for numerical computation, plotting, and Mie theory. Requires scattnlay to be installed. ```python import time import numpy as np import matplotlib.pyplot as plt from matplotlib.patches import Circle import torch import pymiediff as pmd try: from scattnlay import fieldnlay except ImportError as exc: raise ImportError( "This example requires `scattnlay`. Install via `pip install scattnlay`." ) from exc ``` -------------------------------- ### Setup 4-layer sphere and wavelength Source: https://uos-integrated-nanophotonics-group.github.io/MieDiff/auto_gallery/ex_04_multilayer_nearfields.html Defines the physical parameters of the 4-layer sphere and calculates the truncation order n_max. ```python wl0 = torch.as_tensor([700.0], dtype=torch.float64) # nm k0 = 2 * torch.pi / wl0 n_env = 1.2 # outer radii of each layer (nm) r_layers = torch.tensor([45.0, 75.0, 85.0, 125.0], dtype=torch.float64) # refractive indices in each layer n_layers = torch.tensor( [0.45 + 7.55j, 5.5 + 0.1j, 0.45 + 7.55j, 2.1 + 0.0j], dtype=torch.complex128 ) eps_layers = n_layers**2 # resolve truncation using pymiediff internal criterion mie = pmd.multishell.mie_coefficients( k0=k0, r_layers=r_layers, eps_layers=eps_layers, eps_env=n_env**2, n_max=None, ) n_max_use = int(mie["n_max"]) print("Using n_max =", n_max_use) ``` ```text Using n_max = 22 ``` -------------------------------- ### Setup 4-layer sphere configuration Source: https://uos-integrated-nanophotonics-group.github.io/MieDiff/_downloads/6083c716d142e13d2a864769891ebaae/ex_03_large_particles_stability.ipynb Defines the wavelength range, refractive indices, and layer radii for a 4-layer sphere simulation. ```python wl0 = torch.linspace(1095.0, 1100.0, 180, dtype=torch.float64) # nm k0 = 2 * torch.pi / wl0 n_env = 1.0 # outer radii of each layer (nm), from core to shell r_layers = torch.tensor([135.0, 365.0, 395.0, 5630.0], dtype=torch.float64) # refractive indices of the layers (constant over wavelength for this demo) n_layers = torch.tensor( [2.1 + 0.15j, 1.75 + 0.00j, 0.45 + 5.06j, 3.62 + 0.0j], dtype=torch.complex128, ) eps_layers = n_layers**2 # truncation order (None for auto) n_max = None # get smallest size parameter of the configs x_l = 2 * torch.pi * n_layers[-1].abs() * r_layers[-1] / wl0.max() print(f"smallest size parameter of the simulations: {x_l:.2f}") ``` -------------------------------- ### Training output log Source: https://uos-integrated-nanophotonics-group.github.io/MieDiff/auto_gallery/ex_09_tandem.html Example output generated during the initial phase of the training loop, showing the progress of the loss function over iterations. ```text ------------------------------- LR=0.0001, batch_size=32 ------------------------------- Epoch 1, time=0.00s 0%| | 0/777 [00:00>> import torch >>> from pymiediff.helper.helper import get_truncution_criteroin_wiscombe >>> get_truncution_criteroin_wiscombe(torch.tensor([3.0])) 10 ``` ``` -------------------------------- ### MaterialBase.__init__(device='cpu') Source: https://uos-integrated-nanophotonics-group.github.io/MieDiff/generated/generated/pymiediff.materials.MaterialBase.__init__.html Constructor for the MaterialBase class. Initializes the material base with a device specification, defaulting to 'cpu'. ```APIDOC ## MaterialBase.__init__(device='cpu') ### Description Initializes a new instance of the MaterialBase class. ### Method Constructor ### Signature MaterialBase.__init__(device: device = 'cpu') ### Parameters - **device** (device) - Optional - The device on which the material base is initialized. Defaults to 'cpu'. ### Returns None ``` -------------------------------- ### Initialize StructAutodiffMieEffPola3D Source: https://uos-integrated-nanophotonics-group.github.io/MieDiff/generated/generated/pymiediff.helper.tg.html Demonstrates the typical usage of importing the module and initializing an auto-differentiable point polarizability structure from a pymiediff particle. ```python import pymiediff as pmd from pymiediff.helper.tg import StructAutodiffMieEffPola3D # define a core‑shell particle particle = pmd.Particle(…) # create an auto‑diff point polarizability structure struct = StructAutodiffMieEffPola3D(particle, wavelengths=torch.linspace(500, 800, 5)) ``` -------------------------------- ### Setting up physical parameters Source: https://uos-integrated-nanophotonics-group.github.io/MieDiff/_downloads/86084b1138505bc09748112a5f2dd053/ex_02_simple_optimisation.ipynb Defines the wavelength, wavenumber, and refractive indices for the particle and environment. ```python wl0 = torch.tensor([700.0]) # nm k0 = 2 * torch.pi / wl0 n_p = 3.5 n_env = 1.0 ``` -------------------------------- ### Initialize Random Parameters Source: https://uos-integrated-nanophotonics-group.github.io/MieDiff/_downloads/2c2e13f70a8f15c2f567d53db9f1955f/ex_06_optimisation.ipynb Sets up random guesses for core radius, shell thickness, and material parameters, enabling gradient tracking for optimisation. ```python # number of random guesses to make. num_guesses = 100 # 2 size parameters (radius of core and thickness of shell) # 4 material parameters: real and imag parts of constant ref. indices r_opt_arr = torch.normal(0, 1, (2, num_guesses)) n_opt_arr = torch.normal(0, 1, (4, num_guesses)) r_opt_arr.requires_grad = True n_opt_arr.requires_grad = True ``` -------------------------------- ### Import dependencies for pymiediff and scattnlay Source: https://uos-integrated-nanophotonics-group.github.io/MieDiff/auto_gallery/ex_03_large_particles_stability.html Imports numpy, matplotlib, torch, and pymiediff. Optionally imports scattnlay, raising an ImportError with installation instructions if unavailable. ```python import numpy as np import matplotlib.pyplot as plt import torch import pymiediff as pmd try: from scattnlay import scattnlay except ImportError as exc: raise ImportError( "This example requires `scattnlay`. Install via `pip install scattnlay`." ) from exc ``` -------------------------------- ### Import required libraries Source: https://uos-integrated-nanophotonics-group.github.io/MieDiff/_downloads/6083c716d142e13d2a864769891ebaae/ex_03_large_particles_stability.ipynb Imports necessary libraries including numpy, matplotlib, torch, and pymiediff. It also attempts to import scattnlay, raising an ImportError if it is not installed. ```python import numpy as np import matplotlib.pyplot as plt import torch import pymiediff as pmd try: from scattnlay import scattnlay except ImportError as exc: raise ImportError( "This example requires `scattnlay`. Install via `pip install scattnlay`." ) from exc ``` -------------------------------- ### setup_plane_waves_configs(n_angles, inc_planes=['xz', 'xy']) Source: https://uos-integrated-nanophotonics-group.github.io/MieDiff/generated/generated/pymiediff.helper.tg.setup_plane_waves_configs.html Creates illumination configuration dictionaries for plane waves. This function accepts the number of in-plane incidence angles and a list of incidence planes, and returns a list of dictionaries with keys 'angle', 'inc_plane', and 'polarization'. ```APIDOC ## setup_plane_waves_configs(n_angles, inc_planes=['xz', 'xy']) ### Description Creates illumination configuration dictionaries for plane waves. ### Parameters - **n_angles** (int) - Required - Number of in-plane incidence angles. - **inc_planes** (list of str, default=['xz', 'xy']) - Optional - Incidence planes. ### Returns - **list of dict** - Illumination definitions with keys `angle`, `inc_plane`, and `polarization`. ``` -------------------------------- ### Import required libraries Source: https://uos-integrated-nanophotonics-group.github.io/MieDiff/_downloads/eaf1089427df783f9fa9bdb6e44bd007/ex_10_benchmark.ipynb Imports necessary libraries for benchmarking, including pymiediff, treams, PyMieSim, and others. It raises an ImportError if the required external Mie tools are not installed. ```python import time import numpy as np import matplotlib.pyplot as plt import torch import pymiediff as pmd # other Mie tools try: import pymiecs as pmc import treams from TypedUnit import ureg from PyMieSim.experiment.scatterer import CoreShell from PyMieSim.experiment.source import Gaussian from PyMieSim.experiment import Setup from scattnlay import scattnlay except ImportError as exc: raise ImportError( "This example requires `treams`, `scattnlay`, `PyMieSim` and `pymiecs`" ) from exc ``` -------------------------------- ### Create and run GPM multi-particle simulation Source: https://uos-integrated-nanophotonics-group.github.io/MieDiff/auto_gallery/ex_07_multi_scattering.html Sets up a configuration of 5 particles on a circle with radius 700 nm, runs the GPM simulation, and retrieves the nearfield at a specified wavelength and probe positions. ```python # create simple multi-particle configuration: 5 particles on a circle pos_multi = tg.tools.geometry.coordinate_map_1d_circular(r=700, n_phi=5)["r_probe"] sim_multi = tg.simulation.Simulation( structures=[structMieGPM_gpm.copy(pos_multi)], environment=env, illumination_fields=e_inc_list, wavelengths=wl0, ) sim_multi.run() nf_sim_multi = sim_multi.get_nearfield(wl0[idx_wl], r_probe=r_probe) ``` -------------------------------- ### Configure Multi-Particle Simulation Source: https://uos-integrated-nanophotonics-group.github.io/MieDiff/_downloads/6e6c30464aef4050396f4b5156b1cc87/ex_07_multi_scattering.ipynb Sets up a configuration with 5 particles arranged on a circle and runs the simulation. ```python # create simple multi-particle configuration: 5 particles on a circle pos_multi = tg.tools.geometry.coordinate_map_1d_circular(r=700, n_phi=5)["r_probe"] sim_multi = tg.simulation.Simulation( structures=[structMieGPM_gpm.copy(pos_multi)], environment=env, illumination_fields=e_inc_list, wavelengths=wl0, ) sim_multi.run() nf_sim_multi = sim_multi.get_nearfield(wl0[idx_wl], r_probe=r_probe) ``` -------------------------------- ### StructAutodiffMieEffPola3D.__init__(_mie_particle_, _wavelengths_, _n_env=None_, _backend=None_, _r0=None_, _quadrupol_tol=0.15_, _verbose=True_) Source: https://uos-integrated-nanophotonics-group.github.io/MieDiff/generated/generated/pymiediff.helper.tg.StructAutodiffMieEffPola3D.__init__.html Builds a dipolar 3D effective-polarizability structure for a Mie particle. It evaluates the polarizability at the given wavelengths and initializes the structure in-place. ```APIDOC ## StructAutodiffMieEffPola3D.__init__ ### Description Builds a dipolar 3D effective-polarizability structure for a Mie particle. It evaluates the polarizability at the given wavelengths and initializes the structure in-place. ### Method Constructor ### Signature StructAutodiffMieEffPola3D.__init__(_mie_particle_, _wavelengths_, _n_env=None_, _backend=None_, _r0=None_, _quadrupol_tol=0.15_, _verbose=True_) ### Parameters - **mie_particle** (`pymiediff.Particle`) - Required - The Mie particle to build a GPM model for. - **wavelengths** (`torch.Tensor`) - Required - Wavelengths (in nm) at which the polarizability is evaluated. - **n_env** (`float`, optional) - Optional - Refractive index of the surrounding medium. If not provided, use the environment defined in the particle. - **backend** (optional) - Optional - Backend specification (not detailed in source). - **r0** (`torch.Tensor`, optional) - Optional - Position of the point polarizability (x, y, z). If `None`, the origin `[0, 0, 0]` is used. - **quadrupol_tol** (`float`, optional) - Optional - Tolerance for the ratio of residual quadrupole terms relative to the dipole term. Wavelengths where the quadrupole contribution exceeds this ratio raise a warning (default is `0.15`). - **verbose** (`bool`, default `True`) - Optional - Print progress information during GPM extraction. ### Returns Initializes the structure in-place. Return type: None. ### Raises - **ValueError** - If the supplied parameters are inconsistent or insufficient for the Mie calculation. ### Notes - The electric and magnetic dipole Mie coefficients are converted to volume-scaled polarizabilities following García-Etxarri et al., Opt. Express 19, 4815 (2011). - The torch device for all output tensors is the `mie_particle` device. ``` -------------------------------- ### Run TorchGDM simulation and compare extinction Source: https://uos-integrated-nanophotonics-group.github.io/MieDiff/_downloads/6e6c30464aef4050396f4b5156b1cc87/ex_07_multi_scattering.ipynb Sets up a plane wave illumination, runs the TorchGDM simulation, and compares the resulting extinction cross-section with PyMieDiff calculations. ```python # - illumination: normal incidence linear pol. plane wave e_inc_list = [tg.env.freespace_3d.PlaneWave(e0p=1, e0s=0, inc_angle=0)] env = tg.env.freespace_3d.EnvHomogeneous3D(env_material=n_env**2) sim_single = tg.simulation.Simulation( structures=[structMieGPM_gpm], environment=env, illumination_fields=e_inc_list, wavelengths=wl0, ) sim_single.run() # extinction cross section comparison cs_mie = particle.get_cross_sections(k0=k0) cs = sim_single.get_spectra_crosssections() print("") print("Evaluated wavelengths (nm):") print(f" {wl0}") print("PyMieDiff extinction cross section (nm^2):") print(f" {cs_mie["cs_ext"]}") print("TorchGDM extinction cross section (nm^2):") print(f" {cs["ecs"][:,0]}") print(f"rel. errors:") print(f" {[cs_mie["cs_ext"][i] / cs["ecs"][i] for i in range(len(wl0))]}") ``` -------------------------------- ### Enable GPU Support Source: https://uos-integrated-nanophotonics-group.github.io/MieDiff/_sources/index.md Initialize the particle class with a device argument to enable GPU acceleration. ```python p = pmd.Particle( r_layers=[50.0, 80.0], # nm mat_layers=[mat_core, mat_shell], device="cuda", ) ``` -------------------------------- ### Calculate efficiencies with PyMieDiff Source: https://uos-integrated-nanophotonics-group.github.io/MieDiff/_downloads/eaf1089427df783f9fa9bdb6e44bd007/ex_10_benchmark.ipynb Demonstrates setting up a particle and performing both single and batched cross-section calculations. ```python # - setup the particle p = pmd.Particle( mat_env=n_env, r_core=r_core, mat_core=mat_core, r_shell=r_shell, mat_shell=mat_shell, ) # - PyMieDiff Mie coefficients t0 = time.time() cs_pmd = p.get_cross_sections(k0) t_pymiediff = time.time() - t0 # - batched evaluation N_batch = 128 r_c_many = torch.linspace(r_core, r_core + 50, N_batch) r_s_many = torch.linspace(r_shell, r_shell + 50, N_batch) eps_c_many = n_core**2 + torch.linspace(0, 1, N_batch).unsqueeze(0).broadcast_to( N_wl, N_batch ) eps_s_many = n_shell**2 + torch.linspace(0, 1, N_batch).unsqueeze(0).broadcast_to( N_wl, N_batch ) # particle-first spectra layout: (N_part, N_layers, N_k0) eps_c_many = eps_c_many.T eps_s_many = eps_s_many.T t0 = time.time() res_mie = pmd.multishell.cross_sections( k0, r_layers=torch.stack([r_c_many, r_s_many], dim=1), eps_layers=torch.stack([eps_c_many, eps_s_many], dim=1), eps_env=n_env**2, ) t_pymiediff_batch = (time.time() - t0) / (N_batch) ``` -------------------------------- ### Execute training schedule Source: https://uos-integrated-nanophotonics-group.github.io/MieDiff/_downloads/2cdeb7fff4097cace4d20f687014c618/ex_09_tandem.ipynb Runs the training process using a predefined list of configurations for batch size, learning rate, and epochs. ```python model = FullyConnected().to(device) confs = [ dict(bs=32, lr=1e-4, n_ep=5), dict(bs=64, lr=1e-4, n_ep=5), dict(bs=128, lr=1e-4, n_ep=6), dict(bs=256, lr=1e-5, n_ep=6), ] t_start = time.time() for conf in confs: learning_rate = conf["lr"] batch_size = conf["bs"] epochs = conf["n_ep"] print("-------------------------------") print(f"LR={learning_rate}, batch_size={batch_size}") print("-------------------------------") loss_fn = nn.MSELoss() optimizer = torch.optim.AdamW(model.parameters(), lr=learning_rate) train_dataloader = torch.utils.data.DataLoader(q_sca_target, batch_size=batch_size) for t in range(epochs): print(f"Epoch {t+1}, time={time.time()-t_start:.2f}s") train_loop(train_dataloader, model, loss_fn, optimizer) print("Done!") ``` -------------------------------- ### Setting up the particle configuration Source: https://uos-integrated-nanophotonics-group.github.io/MieDiff/_downloads/3a51d2d2729ddf885de305cb8a33e582/ex_05_autodiff.ipynb Configures particle dimensions and materials, setting requires_grad=True for parameters where gradients are needed. ```python # - config wl0 = torch.linspace(500, 1000, 50) wl0.requires_grad = True k0 = 2 * torch.pi / wl0 r_core = torch.as_tensor(70.0) r_core.requires_grad = True r_shell = 100.0 mat_core = pmd.materials.MatDatabase("Si") mat_shell = pmd.materials.MatDatabase("Ge") n_env = 1.0 # - setup the particle p = pmd.Particle( mat_env=n_env, r_core=r_core, mat_core=mat_core, r_shell=r_shell, mat_shell=mat_shell, ) print(p) ``` -------------------------------- ### Importing required libraries Source: https://uos-integrated-nanophotonics-group.github.io/MieDiff/_downloads/3a51d2d2729ddf885de305cb8a33e582/ex_05_autodiff.ipynb Initial imports for plotting, PyTorch, and pymiediff. ```python import matplotlib.pyplot as plt import torch import pymiediff as pmd ``` -------------------------------- ### MaterialBase.__init__ Source: https://uos-integrated-nanophotonics-group.github.io/MieDiff/generated/generated/pymiediff.materials.MaterialBase.html Constructor for the MaterialBase class. Initializes the material permittivity base class with a specified device. ```APIDOC ## MaterialBase.__init__ ### Description Constructor for the MaterialBase class. Initializes the material permittivity base class with a specified device. ### Method Constructor ### Signature `__init__(_device: device = 'cpu')` ### Parameters - **_device** (device) - Optional - The device on which to place tensors. Default is 'cpu'. ### Returns None ``` -------------------------------- ### MatDatabase.__init__() Source: https://uos-integrated-nanophotonics-group.github.io/MieDiff/generated/generated/pymiediff.materials.MatDatabase.html Constructor for MatDatabase. Initializes the object with a name, optional YAML file, device, and optional initial lookup wavelengths. ```APIDOC ## MatDatabase.__init__() ### Description Initializes a MatDatabase instance for dispersion from a database entry or a YAML file. ### Method Constructor ### Signature MatDatabase(name='', yaml_file=None, device='cpu', init_lookup_wavelengths=None) ### Parameters - **name** (str, optional) - Name of database entry. Defaults to "". - **yaml_file** (str, optional) - Path to optional YAML file with material data to load. If given, file is loaded and no database entry will be used, even if the name matches. Defaults to None. - **device** (torch.device, optional) - Device to use. Defaults to "cpu". - **init_lookup_wavelengths** (torch.Tensor, optional) - Optional list of wavelengths to generate an initial lookup table. Defaults to None. ### Raises - **ValueError** - Unknown material or unknown dispersion model type. ``` -------------------------------- ### Importing required libraries Source: https://uos-integrated-nanophotonics-group.github.io/MieDiff/_downloads/86084b1138505bc09748112a5f2dd053/ex_02_simple_optimisation.ipynb Imports the necessary torch and pymiediff modules for the optimization process. ```python import torch import pymiediff as pmd ```