spectral_density

Spectral Density from the Dyadic Green’s Function

Computes the generalized spectral density tensor \(J_{\alpha\beta}(\omega)\) from dyadic Green’s function data stored in HDF5 files.

Physics Background

In macroscopic QED, the interaction between quantum emitters and the electromagnetic environment is fully characterised by the dyadic Green’s function \(\mathbf{G}(\mathbf{r}_\alpha, \mathbf{r}_\beta, \omega)\). The generalized spectral density is defined as:

\[J_{\alpha\beta}(\omega) = \frac{\omega^{2}}{\pi\,\hbar\,\varepsilon_0\,c^{2}}\; \boldsymbol{\mu}_\alpha \cdot \operatorname{Im}\!\left[ \mathbf{G}(\mathbf{r}_\alpha,\,\mathbf{r}_\beta,\,\omega) \right] \cdot \boldsymbol{\mu}_\beta\]

where \(\alpha, \beta\) label molecular emitters at positions \(\mathbf{r}_\alpha, \mathbf{r}_\beta\) with transition dipole moments \(\boldsymbol{\mu}_\alpha, \boldsymbol{\mu}_\beta\).

Physical interpretation

  • Self-term \(J_{\alpha\alpha}(\omega)\): Encodes the local photonic density of states projected onto the emitter’s dipole orientation. Proportional to the Purcell-enhanced spontaneous emission rate:

    \[\Gamma_{\alpha\alpha}(\omega) = 2\pi\, J_{\alpha\alpha}(\omega)\]
  • Cross-term \(J_{\alpha\beta}(\omega)\) with \(\alpha \neq \beta\): Encodes the environment-mediated dissipative coupling between emitters \(\alpha\) and \(\beta\). Related to the Lindblad dissipation matrix element:

    \[\Gamma_{\alpha\beta}(\omega) = 2\pi\, J_{\alpha\beta}(\omega)\]

Connection to the Markov approximation

The Lindblad master equation used in mqed.Lindblad evaluates \(J_{\alpha\beta}\) at the single emitter frequency \(\omega_M\):

\[\Gamma_{\alpha\beta} = \frac{2\,\omega_M^{2}}{\hbar\,\varepsilon_0\,c^{2}}\; \boldsymbol{\mu}_\alpha \cdot \operatorname{Im}\!\left[ \mathbf{G}(\mathbf{r}_\alpha,\,\mathbf{r}_\beta,\,\omega_M) \right] \cdot \boldsymbol{\mu}_\beta\]

This is valid when \(J_{\alpha\beta}(\omega)\) varies slowly near \(\omega_M\). Computing the full spectral density allows one to:

  1. Verify the Markov approximation — check that \(J_{\alpha\beta}(\omega)\) is smooth near \(\omega_M\).

  2. Compute the Casimir–Polder (Lamb) shift via the principal-value integral:

    \[\Lambda_\alpha^{\mathrm{Sc}} = \mathcal{P}\!\int_0^\infty \!\mathrm{d}\omega\; J_{\alpha\alpha}^{\mathrm{Sc}}(\omega)\, \left( \frac{1}{\omega + \omega_M} - \frac{1}{\omega - \omega_M} \right)\]
  3. Serve as input for non-Markovian methods (HEOM, TEDOPA, etc.) that require the full bath spectral function.

Data layouts

This module supports four Green’s function storage layouts:

  • Separation-indexed (gf_layout='separation'): \(G(K, 3, 3)\) per energy, indexed by donor–acceptor separation \(R_x\). Output shape: (K, M) where K = number of separations and M = number of energies.

  • Pair-indexed (gf_layout='pair'): \(G(N, N, 3, 3)\) per energy, for all emitter pairs. Output shape: (N, N, M) where N = number of emitters.

  • Projected circulant ring (gf_layout='ring_circulant'): A projected scalar row G(M, N) whose cyclic shifts reconstruct the emitter-pair coupling matrix. Output shape: (N, N, M).

  • Scan-indexed (gf_layout='scan'): \(G(P, 3, 3)\) per energy, for one fixed source and explicit observer positions. Output shape: (P, M) where P = number of observer points.

mqed.analysis.spectral_density._resolve_orientations(cfg)[source]

Resolve donor/acceptor dipole orientations from config.

Follows the same convention as FE.py — supports ‘magic’ angle and explicit theta/phi in degrees.

mqed.analysis.spectral_density._save_spectral_density_h5(filepath: Path, data: dict) None[source]

Save spectral density results to HDF5.

Handles numpy arrays as datasets and scalars/strings as attributes. Follows the same HDF5 conventions as mqed.utils.dgf_data.save_gf_h5().

mqed.analysis.spectral_density.compute_and_save_spectral_density(cfg) None

Compute the generalized spectral density and save to HDF5.

This is the Hydra CLI entry point. Configuration is loaded from configs/analysis/spectral_density.yaml.

mqed.analysis.spectral_density.compute_spectral_density_pair(G_imag: numpy.ndarray, energy_eV: numpy.ndarray, p_orientations: numpy.ndarray, mu_debye: float = 1.0) numpy.ndarray[source]

Compute spectral density for pair-indexed Green’s function data.

For each energy slice \(\omega_m\) and emitter pair \((\alpha, \beta)\), evaluates:

\[J_{\alpha\beta}(\omega_m) = \frac{|\mu|^{2}\,\omega_m^{2}} {\pi\,\hbar\,\varepsilon_0\,c^{2}}\; \hat{\boldsymbol{\mu}}_\alpha \cdot \operatorname{Im}\!\bigl[ \mathbf{G}(\mathbf{r}_\alpha,\,\mathbf{r}_\beta,\,\omega_m) \bigr] \cdot \hat{\boldsymbol{\mu}}_\beta\]

where \(\hat{\boldsymbol{\mu}}_\alpha\) is the dipole orientation of emitter \(\alpha\) and all emitters share the same magnitude \(|\mu|\).

Parameters:
  • G_imag – Imaginary part of the Green’s function, shape (M, N, N, 3, 5). M = number of energies, N = number of emitters.

  • energy_eV – Energy grid in eV, shape (M,).

  • p_orientations – Dipole orientation unit vectors for each emitter, shape (N, 3). For the stationary case where all emitters share the same orientation, broadcast a single (3,) vector.

  • mu_debye – Dipole moment magnitude in Debye (same for all emitters).

Returns:

Spectral density array, shape (N, N, M), in units of eV.

J[alpha, beta, m] is \(J_{\alpha\beta}(\omega_m)\).

Return type:

J

mqed.analysis.spectral_density.compute_spectral_density_ring_circulant(projected_imag_row: numpy.ndarray, energy_eV: numpy.ndarray, mu_debye: float = 1.0) numpy.ndarray[source]

Compute J(N,N,M) from an already projected circulant Green row.

mqed.analysis.spectral_density.compute_spectral_density_scan(G_imag: numpy.ndarray, energy_eV: numpy.ndarray, p_source: numpy.ndarray, p_observer: numpy.ndarray, mu_source_debye: float = 1.0, mu_observer_debye: float = 1.0) numpy.ndarray[source]

Compute spectral density for fixed-source scan Green’s function data.

Parameters:
  • G_imag – Imaginary part of the Green’s function, shape (M, P, 3, 3). M = number of energies, P = number of observer positions.

  • energy_eV – Energy grid in eV, shape (M,).

  • p_source – Source/donor dipole orientation unit vector, shape (3,).

  • p_observer – Observer/acceptor dipole orientation unit vector, shape (3,).

  • mu_source_debye – Source/donor dipole moment magnitude in Debye.

  • mu_observer_debye – Observer/acceptor dipole moment magnitude in Debye.

Returns:

Spectral density array, shape (P, M), in units of eV.

mqed.analysis.spectral_density.compute_spectral_density_separation(G_imag: numpy.ndarray, energy_eV: numpy.ndarray, p_donor: numpy.ndarray, p_acceptor: numpy.ndarray, mu_D_debye: float = 1.0, mu_A_debye: float = 1.0) numpy.ndarray[source]

Compute spectral density for separation-indexed Green’s function data.

For each energy slice \(\omega_m\) and separation index k, evaluates:

\[J_k(\omega_m) = \frac{|\mu_D|\,|\mu_A|\,\omega_m^{2}} {\pi\,\hbar\,\varepsilon_0\,c^{2}}\; \hat{\boldsymbol{\mu}}_A \cdot \operatorname{Im}\!\bigl[ \mathbf{G}_k(\omega_m) \bigr] \cdot \hat{\boldsymbol{\mu}}_D\]

where the dipole moment vectors are \(\boldsymbol{\mu} = |\mu|\,\hat{\boldsymbol{\mu}}\), and the returned quantity has units of eV (energy).

Parameters:
  • G_imag – Imaginary part of the Green’s function, shape (M, K, 3, 3). M = number of energies, K = number of separations.

  • energy_eV – Energy grid in eV, shape (M,).

  • p_donor – Donor dipole orientation unit vector, shape (3,).

  • p_acceptor – Acceptor dipole orientation unit vector, shape (3,).

  • mu_D_debye – Donor dipole moment magnitude in Debye.

  • mu_A_debye – Acceptor dipole moment magnitude in Debye.

Returns:

Spectral density array, shape (K, M), in units of eV.

J[k, m] is \(J_k(\omega_m)\).

Return type:

J