maxwelllink.cavity.npom module

A plasmonic nanoparticle-on-mirror (NPoM) cavity built from the Meep materials library: a gold nanosphere held a nanometer above a gold film.

class maxwelllink.cavity.npom.NPoM[source]

Bases: DummyCavity

A gold nanosphere above a gold mirror, separated by a molecular spacer.

The geometry convention follows Chikkaraddy et al., Nature 535, 127 (2016), doi:10.1038/nature17974.

The gap center on the symmetry axis is the hotspot, and the allowed region is the spacer disk underneath the particle.

The gap plasmon is a rotationally symmetric mode polarized along z, so a cylindrical m = 0 run reproduces the full 3D physics at 2D cost.

The paper’s dark-field scattering spectrum comes from linear_spectrum and its classical-emitter Purcell spectrum from purcell. Both need a cell sized for the reddest measured wavelength; see the padding_nm and pml_nm parameters of __init__.

Examples

>>> from maxwelllink.cavity import NPoM
>>> cav = NPoM(resolution=5000.0)
>>> spectrum = cav.linear_spectrum(500.0, 900.0, units="nm", min_time=30.0)
>>> lam, scattering = spectrum["wavelength_nm"], spectrum["scattering"]
>>> enhancement = cav.purcell(500.0, 900.0, units="nm", min_time=30.0)
>>> purcell_factor = enhancement["purcell"]
__init__(radius_nm=RADIUS_NM, gap_nm=GAP_NM, spacer_index=SPACER_INDEX, film_nm=FILM_NM, omega_ref=REPORTED['gap_mode_nm'], units='nm', material=None, dimensions=CYLINDRICAL, resolution=None, pml_nm=None, padding_nm=None)[source]

Initialize the parameters of a gold nanoparticle-on-mirror cavity.

Parameters:
  • radius_nm (float, default: 20.0) – Radius (nm) of the gold nanosphere (40 nm diameter).

  • gap_nm (float, default: 1.0) – Thickness (nm) of the spacer between the particle and the mirror.

  • spacer_index (float, default: 1.4) – Refractive index of the spacer layer, which extends laterally across the whole cell as in the paper.

  • film_nm (float, default: 70.0) – Thickness (nm) of the gold mirror.

  • omega_ref (float, default: 660.0) – Reference frequency (or wavelength) in units, i.e. roughly where the gap plasmon is expected. It sets no length of the structure, only the default grid, padding, and boundary thickness.

  • units (str, default: "nm") – Units of omega_ref: “cm-1”, “eV”, “au”, “nm”, or “um”.

  • material (mp.Medium or None, optional) – Material of the particle and the mirror. Default: gold (meep.materials.Au).

  • dimensions (int, default: mxl.CYLINDRICAL) – mxl.CYLINDRICAL for the (r, z) half plane, where the cavity sets m = 0 (the sector holding the gap mode), or 3 for full 3D.

  • resolution (float or None, optional) – Meep resolution. Default: six pixels across the gap, and at least 20 pixels per reference wavelength in the spacer.

  • pml_nm (float or None, optional) – Boundary thickness in nm. Default: a quarter of the reference wavelength, sized for a far-field probe at omega_ref; a redder window needs more (see Notes).

  • padding_nm (float or None, optional) – Free space (nm) between the particle and the boundary layers. Default: 0.15 reference wavelengths, sized for a far-field probe at omega_ref; a redder window needs more (see Notes).

Notes

The default cell is not good enough for linear spectrum and purcell measurements over a wide wavelength range, especially for cylindrical cells.

### TOY MODEL RUNNING IN LOCAL MACHINES: 20-radius nm and 1 nm gap particle, 500-800 nm measurement window: NPoM(padding_nm=150.0, pml_nm=250.0), resolution 1000.

### PRACTICAL CALCULATIONS FOR NATURE 2016 PAPER: 20-radius nm and 1 nm gap particle, 500-800 nm measurement window: - Linear scattering spectrum: NPoM(padding_nm=300.0, pml_nm=300.0), resolution 4000. - Purcell factor: NPoM(padding_nm=500.0, pml_nm=700.0), resolution 4000.

For converged spectra, size the cell from the reddest wavelength lam_max of the window to be measured:

padding_nm >= 0.75 * lam_max - radius_nm pml_nm >= 0.9 * lam_max

Half of it is enough when linear_spectrum is only used for the resonance position and linewidth, while the full value is needed for purcell and for the long-wavelength tail of the scattering spectrum.

With a cell that is too small, the scattering resonance comes out redshifted and too broad, and the total Purcell factor rises with wavelength instead of decaying.

property allowed_bounds_nm

Per-axis allowed bounds in nm, e.g. {"x": (-704.5, 704.5)}.

emission_setup(offset_nm=(0.0, 0.0, 0.0), component=None)[source]

Local-dipole (Purcell) probe of the NPoM: a z-polarized dipole at the gap hotspot (the classical-emitter method of Chikkaraddy et al.).

The reference is the homogeneous spacer medium with its own closed collection box (the mirror is absent there, so an open-bottomed box would leak the downward radiation).

Same keys as DummyCavity.emission_setup.

Parameters:
  • offset_nm (sequence of three floats, default: (0, 0, 0)) – Displacement (nm) of the dipole from the gap hotspot.

  • component (Meep field component or None, optional) – Dipole orientation. Default: mp.Ez, along the gap field.

estimate_driver_count(region)[source]

Estimate how many socket molecules (drivers) the gap disk of place_region needs, equal to the number of FDTD grid points inside it.

The disk is a rectangle of the (r, z) half plane in cylindrical cells, and a cylinder in 3D.

Parameters:

region (mp.Cylinder) – The region returned by place_region.

Returns:

The estimated number of drivers (grid points inside the region).

Return type:

int

linear_spectrum(omega_min, omega_max, units='cm-1', **kwargs)

Compute the far-field linear spectrum of the cavity: the probe declared by optical_setup().

This gives transmission/reflection/absorption for mirror cavities and scattering/absorption/extinction for plasmonic nanocavities.

For the local-dipole (Purcell) observables, use purcell instead.

Parameters:
  • omega_min (float) – Frequency window in units.

  • omega_max (float) – Frequency window in units.

  • units (str, default: "cm-1") – Units of the window: “cm-1”, “eV”, “au”, “nm”, or “um”.

  • **kwargs – Forwarded to MeepCavityMeasurement: molecules, hub, extra_geometry, nfreq, decay_by, steps, max_time, min_time, source_amplitude, and extra Meep keyword arguments.

Returns:

Dictionary with arrays omega_cminv, wavelength_nm, frequency_meep, and the observables of the declared probe.

Return type:

dict

make_simulation(molecules=None, hub=None, sources=None, extra_geometry=(), **meep_kwargs)

Build the mxl.MeepSimulation for this cavity.

  • Pass hub and molecules for molecule-level coupling via sockets;

  • Pass hub and extra_geometry for grid-level coupling via sockets;

  • Pass molecules alone for molecule-level coupling via embedded drivers (with driver and driver_kwargs in the molecules);

  • Pass nothing at all for a pure Meep simulation.

Parameters:
  • molecules (sequence of mxl.Molecule or None, optional) – Molecules to include in the simulation.

  • hub (SocketHub or None, optional) – Socket hub shared by socket-mode molecules.

  • sources (sequence or None, optional) – Additional native Meep sources (laser excitation etc.).

  • extra_geometry (sequence, optional) – Geometry appended after the cavity structure, e.g. the region from place_region.

  • **meep_kwargs – Extra keyword arguments forwarded to the simulation; they override the cavity defaults on conflicts.

meep_to_nm(value_meep)

Convert a length from Meep units to nanometers.

nm_to_meep(value_nm)

Convert a length from nanometers to Meep units.

optical_setup()[source]

Far-field probe of the NPoM: the dark-field-type scattering measurement of Chikkaraddy et al., Nature 535, 127 (2016).

A grazing sheet of vertical current drives the gap mode. The reference run (the film and spacer, without the particle) records the incident fields subtracted at the collection surface.

All observables are normalized by the incident intensity at the hotspot. Same keys as DummyCavity.optical_setup.

place_molecule(hub=None, driver=None, offset_nm=(0.0, 0.0, 0.0), size_nm=None, sigma_nm=None, hotspot=None, **molecule_kwargs)

Create an mxl.Molecule inside the cavity (molecule-level coupling).

The molecule sits at the cavity hotspot by default and can be shifted with offset_nm.

Its center, size, sigma, and dimensions are chosen consistently with the cavity grid, so the returned molecule can be passed directly to make_simulation.

Use place_region instead for grid-level coupling.

Notes

This method should not be overridden by subclasses.

Parameters:
  • hub (SocketHub or None, optional) – Socket hub for socket-mode molecules, exclusive with driver.

  • driver (str or None, optional) – Embedded driver name for non-socket molecules (e.g. "tls"), exclusive with hub.

  • offset_nm (sequence of three floats, default: (0, 0, 0)) – Displacement (nm) from the hotspot; only components along active axes may be nonzero. Cylindrical molecule coupling supports only an on-axis molecule, so only (0, 0, dz) is accepted there.

  • size_nm (float or None, optional) – Extent of the molecular polarization region along every active axis. Default: ten times sigma.

  • sigma_nm (float or None, optional) – Width of the regularized polarization kernel. Default: two grid points, which keeps the kernel resolvable at any resolution.

  • hotspot (str or None, optional) – Name of an entry in self.hotspots to place the molecule at, for cavities with several field maxima. Default: hotspot_center.

  • **molecule_kwargs – Forwarded verbatim to mxl.Molecule (e.g. driver_kwargs, rescaling_factor, polarization_type). For the anisotropic polarization type, construct mxl.Molecule directly instead (it needs a three-component sigma).

Return type:

maxwelllink.Molecule

place_region(epsilon=None, hub=None, offset_nm=(0.0, 0.0, 0.0), width_nm=None, rescaling_factor=1.0, **susceptibility_kwargs)[source]

Create a disk of molecular medium inside the gap (grid-level coupling).

The disk fills the spacer thickness and is centered at the hotspot plus offset_nm.

Pass it to make_simulation via extra_geometry=[region].

Parameters:
  • epsilon (float or None, optional) – Background permittivity of the molecular medium. Default: that of the spacer the disk replaces (spacer_index ** 2).

  • hub (SusceptibilitySocketHub or None, optional) – Socket hub of the grid-level route.

  • offset_nm (sequence of three floats, default: (0, 0, 0)) – Displacement (nm) of the disk center from the hotspot.

  • width_nm (float or None, optional) – Diameter (nm) of the disk. Default: twice the lateral radius sqrt(radius * gap) of the gap mode.

  • rescaling_factor (float, default: 1.0) – Rescaling factor of mp.MXLSocketSusceptibility.

  • **susceptibility_kwargs – Forwarded to mp.MXLSocketSusceptibility (e.g. real_field_only, timeout).

Return type:

mp.Cylinder

plot(ax=None, **kwargs)

Visualize the cavity structure and its optical setup.

Parameters:
  • ax (matplotlib Axes or None, optional) – Axes to draw into. A new figure is created when None.

  • **kwargs – Forwarded to mp.Simulation.plot2D in 2D and 3D.

Returns:

The axes containing the plot.

Return type:

matplotlib Axes

purcell(omega_min, omega_max, units='cm-1', offset_nm=(0.0, 0.0, 0.0), component=None, **kwargs)

Compute the Purcell spectrum of the cavity.

A point dipole at the hotspot drives the cavity in one run and the homogeneous reference structure of emission_setup() in another, and every observable is the ratio of the two runs.

Parameters:
  • omega_min (float) – Frequency window in units.

  • omega_max (float) – Frequency window in units.

  • units (str, default: "cm-1") – Units of the window: “cm-1”, “eV”, “au”, “nm”, or “um”.

  • offset_nm (sequence of three floats, default: (0, 0, 0)) – Displacement (nm) of the dipole from the hotspot.

  • component (Meep field component or None, optional) – Dipole orientation (e.g. mp.Er). Default: the orientation chosen by the cavity (mp.Ez).

  • **kwargs – Forwarded to MeepCavityMeasurement: molecules, hub, extra_geometry, nfreq, decay_by, steps, max_time, min_time, and extra Meep keyword arguments.

Returns:

Dictionary with arrays omega_cminv, wavelength_nm, frequency_meep, and the Purcell observables: purcell (total decay-rate enhancement), purcell_radiative (far-field enhancement), radiative_efficiency (their ratio), plus the raw LDOS and flux arrays.

Return type:

dict

sim_kwargs(extra_geometry=())

Return the generated Meep ingredients as a plain dict, for users who prefer to assemble mp.Simulation(**kwargs) themselves.

Parameters:

extra_geometry (sequence, optional) – Geometry appended after the cavity structure.

Returns:

Keyword arguments for mp.Simulation: cell_size, geometry, boundary_layers, resolution, and k_point when the cavity is periodic.

Return type:

dict

summary()

Return a human-readable description of the generated setup (MPI Safe).