maxwelllink.measurements.meep_linear module

Meep cavity linear spectroscopy: two FDTD runs per measurement.

class maxwelllink.measurements.meep_linear.MeepCavityMeasurement[source]

Bases: DummyMeasurement

Shared two-run machinery of every Meep cavity measurement.

Each measurement excites the system with one broadband Gaussian pulse and performs two simulations that differ only in the structure:

  1. reference(): the normalization run on the "reference_geometry" of the cavity setup (no molecules, no extra_geometry);

  2. signal_run(): the full cavity, plus molecules and extra_geometry.

Subclasses fetch and validate their setup dict in _cavity_setup and implement the three DummyMeasurement steps on top of the helpers here.

__init__(cavity, omega_min, omega_max, units='cm-1', nfreq=200, molecules=None, hub=None, extra_geometry=(), decay_by=1.0e-5, steps=None, max_time=1.0e4, min_time=0.0, source_amplitude=None, **meep_kwargs)[source]

Initialize a two-run Meep measurement of an FDTD cavity.

Parameters:
  • cavity (DummyCavity subclass) – The cavity to probe; it must provide the setup dict that _cavity_setup fetches (optical_setup() or emission_setup()).

  • 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”.

  • nfreq (int, default: 200) – Number of frequency points of the spectrum.

  • molecules (sequence of mxl.Molecule or None, optional) – Molecules from place_molecule, included in the signal run only (as in make_simulation).

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

  • extra_geometry (sequence, optional) – Geometry appended to the signal run only, e.g. the region from place_region or a nanoparticle.

  • decay_by (float, default: 1e-5) – Stop each run once the monitored fields have decayed to this fraction of their peak.

  • steps (int or None, optional) – Run each simulation for a fixed number of FDTD time steps instead of the decay criterion.

  • max_time (float, default: 1e4) – Hard cap (Meep time units after the pulse) on the decay-based stopping, with a warning when it triggers; raise it for very high-Q cavities.

  • min_time (float, default: 0.0) – Minimum Meep time to keep running after the pulse. A record of length T resolves quality factors only up to about frequency * T, so raise this when a resonance comes out suspiciously broad.

  • source_amplitude (float or None, optional) – Overall Gaussian-source amplitude. None uses the cavity setup’s source_amplitude or 1.0 when the setup omits it. Per-component amplitudes in source_components are relative phase/polarization factors multiplied by this value.

  • **meep_kwargs – Extra keyword arguments forwarded to both simulations (e.g. m=).

decay_check_dt = 50
postprocess(reference, signals)

Combine the reference and the raw signals into observable arrays.

Notes

This method must be overridden by subclasses. Implementations end with return self._assemble_result(omega_cminv, **observables).

Parameters:
  • reference (object) – The return value of reference().

  • signals (object) – The return value of signal_run().

reference()

Return the excitation baseline of the measurement.

Depending on the EM solver, this is computed analytically (e.g. the Fourier transform of a known laser pulse) or by a molecule-free reference simulation (e.g. the FDTD normalization run).

Notes

This method must be overridden by subclasses.

run()

Run the measurement: the reference first, then the signal run, then the combination. Subclasses may pass state between the steps via attributes (e.g. fields recorded in the reference run).

Notes

This method should not be overridden by subclasses.

Returns:

The frequency axes plus the observables of the measurement.

Return type:

dict

signal_run()

Excite the full system and return the raw response signals.

Notes

This method must be overridden by subclasses.

class maxwelllink.measurements.meep_linear.MeepPurcellSpectroscopy[source]

Bases: MeepCavityMeasurement

Purcell-factor spectroscopy of an FDTD cavity (two Meep runs).

A point dipole drives the full cavity in one run and the homogeneous reference structure of emission_setup() in the other (the classical-emitter method), and the observables are ratios of the two runs:

  • purcell : total decay-rate enhancement, LDOS(cavity) / LDOS(reference);

  • purcell_radiative : far-field enhancement, the power crossing the "radiated" surface over the total power the reference dipole emits;

  • radiative_efficiency : their ratio, the fraction of the emitted power that reaches the far field.

Examples

>>> from maxwelllink.cavity import NPoM
>>> spectrum = NPoM().purcell(500.0, 900.0, units="nm")
>>> spectrum["wavelength_nm"], spectrum["purcell"]
__init__(cavity, omega_min, omega_max, units='cm-1', offset_nm=(0.0, 0.0, 0.0), component=None, **kwargs)[source]

Initialize the Purcell measurement of an FDTD cavity.

Parameters:
  • cavity (DummyCavity subclass) – The cavity to probe; it must implement emission_setup().

  • 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 cavity 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.

decay_check_dt = 10.0
postprocess(reference, signals)[source]

Combine the two runs into the Purcell observables.

Every spectrum is a ratio of the two runs, so all prefactors cancel.

reference()[source]

Normalization run: drive the same dipole in the homogeneous reference structure.

Records what the dipole emits (LDOS) and radiates through the closed reference_surface (= everything it emits, the reference being lossless).

run()

Run the measurement: the reference first, then the signal run, then the combination. Subclasses may pass state between the steps via attributes (e.g. fields recorded in the reference run).

Notes

This method should not be overridden by subclasses.

Returns:

The frequency axes plus the observables of the measurement.

Return type:

dict

signal_run()[source]

Cavity run: drive the full cavity (plus molecules and extra_geometry).

Records the emitted power together with the power crossing each detector surface.

class maxwelllink.measurements.meep_linear.MeepReflectionSpectroscopy[source]

Bases: MeepCavityMeasurement

Reflection spectroscopy of an opaque FDTD cavity (two Meep runs).

The reference run records the incident spectrum. The signal run subtracts those incident fields at the same monitor and records the reflected power. For an opaque, mirror-backed structure, the unreflected fraction is the absorbed power, so this measurement returns absorption = 1 - reflection.

__init__(cavity, omega_min, omega_max, units='cm-1', nfreq=200, molecules=None, hub=None, extra_geometry=(), decay_by=1.0e-5, steps=None, max_time=1.0e4, min_time=0.0, source_amplitude=None, **meep_kwargs)

Initialize a two-run Meep measurement of an FDTD cavity.

Parameters:
  • cavity (DummyCavity subclass) – The cavity to probe; it must provide the setup dict that _cavity_setup fetches (optical_setup() or emission_setup()).

  • 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”.

  • nfreq (int, default: 200) – Number of frequency points of the spectrum.

  • molecules (sequence of mxl.Molecule or None, optional) – Molecules from place_molecule, included in the signal run only (as in make_simulation).

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

  • extra_geometry (sequence, optional) – Geometry appended to the signal run only, e.g. the region from place_region or a nanoparticle.

  • decay_by (float, default: 1e-5) – Stop each run once the monitored fields have decayed to this fraction of their peak.

  • steps (int or None, optional) – Run each simulation for a fixed number of FDTD time steps instead of the decay criterion.

  • max_time (float, default: 1e4) – Hard cap (Meep time units after the pulse) on the decay-based stopping, with a warning when it triggers; raise it for very high-Q cavities.

  • min_time (float, default: 0.0) – Minimum Meep time to keep running after the pulse. A record of length T resolves quality factors only up to about frequency * T, so raise this when a resonance comes out suspiciously broad.

  • source_amplitude (float or None, optional) – Overall Gaussian-source amplitude. None uses the cavity setup’s source_amplitude or 1.0 when the setup omits it. Per-component amplitudes in source_components are relative phase/polarization factors multiplied by this value.

  • **meep_kwargs – Extra keyword arguments forwarded to both simulations (e.g. m=).

decay_check_dt = 50
postprocess(reference, signals)[source]

Return the R and A = 1 - R spectra of an opaque structure.

reference()[source]

Record the incident flux and fields in the reference structure.

run()

Run the measurement: the reference first, then the signal run, then the combination. Subclasses may pass state between the steps via attributes (e.g. fields recorded in the reference run).

Notes

This method should not be overridden by subclasses.

Returns:

The frequency axes plus the observables of the measurement.

Return type:

dict

signal_run()[source]

Record only the reflected flux from the full structure.

class maxwelllink.measurements.meep_linear.MeepScatteringSpectroscopy[source]

Bases: MeepCavityMeasurement

Scattering spectroscopy of a localized scatterer (two Meep runs).

The reference run excites the structure without the scatterer and records the incident fields at the collection surface.

The signal run subtracts them, so the surface records scattered power only (the dark-field-type probe of Chikkaraddy et al., Nature 535, 127 (2016)).

All observables are divided by the incident intensity at the cavity.

Examples

>>> from maxwelllink.cavity import NPoM
>>> spectrum = NPoM().linear_spectrum(500.0, 900.0, units="nm")
>>> spectrum["wavelength_nm"], spectrum["scattering"]
__init__(cavity, omega_min, omega_max, units='cm-1', nfreq=200, molecules=None, hub=None, extra_geometry=(), decay_by=1.0e-5, steps=None, max_time=1.0e4, min_time=0.0, source_amplitude=None, **meep_kwargs)

Initialize a two-run Meep measurement of an FDTD cavity.

Parameters:
  • cavity (DummyCavity subclass) – The cavity to probe; it must provide the setup dict that _cavity_setup fetches (optical_setup() or emission_setup()).

  • 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”.

  • nfreq (int, default: 200) – Number of frequency points of the spectrum.

  • molecules (sequence of mxl.Molecule or None, optional) – Molecules from place_molecule, included in the signal run only (as in make_simulation).

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

  • extra_geometry (sequence, optional) – Geometry appended to the signal run only, e.g. the region from place_region or a nanoparticle.

  • decay_by (float, default: 1e-5) – Stop each run once the monitored fields have decayed to this fraction of their peak.

  • steps (int or None, optional) – Run each simulation for a fixed number of FDTD time steps instead of the decay criterion.

  • max_time (float, default: 1e4) – Hard cap (Meep time units after the pulse) on the decay-based stopping, with a warning when it triggers; raise it for very high-Q cavities.

  • min_time (float, default: 0.0) – Minimum Meep time to keep running after the pulse. A record of length T resolves quality factors only up to about frequency * T, so raise this when a resonance comes out suspiciously broad.

  • source_amplitude (float or None, optional) – Overall Gaussian-source amplitude. None uses the cavity setup’s source_amplitude or 1.0 when the setup omits it. Per-component amplitudes in source_components are relative phase/polarization factors multiplied by this value.

  • **meep_kwargs – Extra keyword arguments forwarded to both simulations (e.g. m=).

decay_check_dt = 10.0
postprocess(reference, signals)[source]

Combine the two runs into the scattering, absorption, and extinction spectra, all divided by the incident intensity at the hotspot, plus the field-enhancement spectrum enhancement = |E|^2 / |E_inc|^2 at the hotspot (the sharpest signature of a high-Q resonance).

reference()[source]

Normalization run: excite the structure without the scatterer.

Records the incident spectrum |E_inc|^2 at the hotspot, the incident fields at the collection surface (stashed for the signal run), and the net flux through the closed box.

run()

Run the measurement: the reference first, then the signal run, then the combination. Subclasses may pass state between the steps via attributes (e.g. fields recorded in the reference run).

Notes

This method should not be overridden by subclasses.

Returns:

The frequency axes plus the observables of the measurement.

Return type:

dict

signal_run()[source]

Scattering run: excite the full structure.

The stored incident fields are subtracted at the collection surface (scattered power only); the closed box keeps the total fields (for the absorbed power). The total intensity |E|^2 at the hotspot is recorded for the field-enhancement spectrum.

class maxwelllink.measurements.meep_linear.MeepTransmissionSpectroscopy[source]

Bases: MeepCavityMeasurement

Transmission/reflection spectroscopy of an FDTD cavity (two Meep runs).

A plane-wave pulse crosses the structure; the reference run records the incident spectrum, and the signal run records what is transmitted and reflected by the full cavity.

Examples

>>> from maxwelllink.measurements import MeepTransmissionSpectroscopy
>>> measurement = MeepTransmissionSpectroscopy(cavity, 2000.0, 2650.0, units="cm-1")
>>> spectrum = measurement.run()
__init__(cavity, omega_min, omega_max, units='cm-1', nfreq=200, molecules=None, hub=None, extra_geometry=(), decay_by=1.0e-5, steps=None, max_time=1.0e4, min_time=0.0, source_amplitude=None, **meep_kwargs)

Initialize a two-run Meep measurement of an FDTD cavity.

Parameters:
  • cavity (DummyCavity subclass) – The cavity to probe; it must provide the setup dict that _cavity_setup fetches (optical_setup() or emission_setup()).

  • 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”.

  • nfreq (int, default: 200) – Number of frequency points of the spectrum.

  • molecules (sequence of mxl.Molecule or None, optional) – Molecules from place_molecule, included in the signal run only (as in make_simulation).

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

  • extra_geometry (sequence, optional) – Geometry appended to the signal run only, e.g. the region from place_region or a nanoparticle.

  • decay_by (float, default: 1e-5) – Stop each run once the monitored fields have decayed to this fraction of their peak.

  • steps (int or None, optional) – Run each simulation for a fixed number of FDTD time steps instead of the decay criterion.

  • max_time (float, default: 1e4) – Hard cap (Meep time units after the pulse) on the decay-based stopping, with a warning when it triggers; raise it for very high-Q cavities.

  • min_time (float, default: 0.0) – Minimum Meep time to keep running after the pulse. A record of length T resolves quality factors only up to about frequency * T, so raise this when a resonance comes out suspiciously broad.

  • source_amplitude (float or None, optional) – Overall Gaussian-source amplitude. None uses the cavity setup’s source_amplitude or 1.0 when the setup omits it. Per-component amplitudes in source_components are relative phase/polarization factors multiplied by this value.

  • **meep_kwargs – Extra keyword arguments forwarded to both simulations (e.g. m=).

decay_check_dt = 50
postprocess(reference, signals)[source]

Divide the fluxes into the T, R, and A = 1 - T - R spectra.

reference()[source]

Normalization run: excite the reference structure (no molecules, no extra_geometry) and record the incident spectrum.

The incident fields at the reflection detector are stashed for the signal run.

run()

Run the measurement: the reference first, then the signal run, then the combination. Subclasses may pass state between the steps via attributes (e.g. fields recorded in the reference run).

Notes

This method should not be overridden by subclasses.

Returns:

The frequency axes plus the observables of the measurement.

Return type:

dict

signal_run()[source]

Scattering run: excite the full cavity (plus molecules and extra_geometry).

The incident wave is subtracted at the reflection detector, so it records only what returns.