GF_Mie

Generalized Mie dyadic Green’s function for concentric spherical dielectrics.

This module is the spherical analogue of GF_Sommerfeld.py in the MQED-QD project. Instead of evaluating Sommerfeld integrals for a planar stack, it expands the electromagnetic Green tensor in normalized vector spherical functions and uses Mie coefficients to enforce boundary conditions at one or two spherical interfaces.

Implemented geometries

sphere

Region 0 is the exterior background and region 1 is a homogeneous sphere. The source dipole is assumed to be in region 0, matching the MATLAB generalized-Mie implementation.

coreshell

Region 0 is exterior, region 1 is shell, region 2 is core. The exterior scattered Green tensor is implemented for exterior sources. For finite spherical-shell cavities, source and observer points in the core use inner reflection coefficients from both shell interfaces. Shell observations and cross-region transmission are not implemented.

simplecavity

Region 0 is the exterior medium and region 1 is a spherical cavity. The source dipole is assumed to be in the cavity.

Coordinate convention

The sphere/cavity is centered at the origin. Public Green-tensor methods accept Cartesian source and observer positions in meters and return 3x3 Cartesian Green tensors. Internally, the Mie expansion is evaluated in the spherical basis at the observer and then rotated back to Cartesian coordinates.

The code follows the notation of the uploaded MATLAB implementation:

  • alpha and beta are exterior TM/TE reflection coefficients.

  • delta and gamma are interior TM/TE transmission coefficients.

  • p/q and r/s are source expansion coefficients for exterior and cavity sources respectively.

The returned tensor has the same normalization as the existing Sommerfeld code: E = k^2 G p / eps0 in SI conventions. For convenience, field_for_dipole returns G @ dipole_direction or G @ dipole_moment depending on what you pass in.

class mqed.Dyadic_GF.GF_Mie.AngularFunctions(ntau: numpy.ndarray, npi: numpy.ndarray, np_func: numpy.ndarray, m: numpy.ndarray, mask: numpy.ndarray, order: Literal['normal', 'reversed'])[source]

Normalized angular functions used by the vector spherical functions.

__delattr__(name)

Implement delattr(self, name).

__eq__(other)

Return self==value.

__init__(ntau: numpy.ndarray, npi: numpy.ndarray, np_func: numpy.ndarray, m: numpy.ndarray, mask: numpy.ndarray, order: Literal['normal', 'reversed']) None
__repr__()

Return repr(self).

__setattr__(name, value)

Implement setattr(self, name, value).

class mqed.Dyadic_GF.GF_Mie.MieCoefficients(alpha: numpy.ndarray, beta: numpy.ndarray, gamma: numpy.ndarray | None = None, delta: numpy.ndarray | None = None)[source]

Mie coefficients for a spherical boundary problem.

__delattr__(name)

Implement delattr(self, name).

__eq__(other)

Return self==value.

__init__(alpha: numpy.ndarray, beta: numpy.ndarray, gamma: numpy.ndarray | None = None, delta: numpy.ndarray | None = None) None
__repr__()

Return repr(self).

__setattr__(name, value)

Implement setattr(self, name, value).

class mqed.Dyadic_GF.GF_Mie.MieGreenFunction(refractive_indices: Sequence[complex], radii_m: Sequence[float] | float, omega: float, nmax: int, geometry: Literal['sphere', 'coreshell', 'simplecavity'] = 'sphere', strict_regions: bool = True)[source]

Dyadic Green tensor for spherical Mie geometries.

Parameters:
  • refractive_indices – Relative refractive indices by region. Use [n0, n1] for sphere or simplecavity and [n0, n1, n2] for coreshell.

  • radii_m – Spherical boundary radii in meters. For sphere and simplecavity give one radius. For coreshell give [outer_radius, core_radius].

  • omega – Angular frequency in rad/s.

  • nmax – Highest multipole order in the Mie sum.

  • geometry"sphere", "coreshell", or "simplecavity".

  • strict_regions – If true, invalid source-region placements raise an error. If false, the calculation proceeds but the result is not guaranteed to match the derivation.

__init__(refractive_indices: Sequence[complex], radii_m: Sequence[float] | float, omega: float, nmax: int, geometry: Literal['sphere', 'coreshell', 'simplecavity'] = 'sphere', strict_regions: bool = True)[source]
_direct_medium_index(source_region: int, observer_region: int) int | None[source]

Return medium index for the direct homogeneous term, or None.

static _sum_mie_field(vsf: VectorSphericalFunctions, coeff_M: numpy.ndarray, coeff_N: numpy.ndarray) numpy.ndarray[source]

Sum TE/M and TM/N contributions to one spherical-basis vector.

calculate_components(observer_position_m: Sequence[float], source_position_m: Sequence[float]) MieResult[source]

Return total, homogeneous, and structure tensors for one point pair.

calculate_total_Green_function(observer_position_m: Sequence[float], source_position_m: Sequence[float]) numpy.ndarray[source]

Return the total 3x3 Cartesian Green tensor.

calculate_total_Green_functions_for_points(observer_positions_m: numpy.ndarray, source_position_m: Sequence[float]) numpy.ndarray[source]

Vectorized convenience wrapper over observer positions.

electric_field_si(observer_position_m: Sequence[float], source_position_m: Sequence[float], dipole_moment_Cm: Sequence[complex], medium_region_for_prefactor: int | None = None) numpy.ndarray[source]

Return the SI electric field generated by a point dipole moment.

This helper applies E = k^2 G p / eps0 using the direct medium index when available. For transmitted-only cases, pass medium_region_for_prefactor explicitly if you want a different convention.

expected_source_region() int[source]

Default source region implemented by the uploaded MATLAB theory/code.

field_for_dipole(observer_position_m: Sequence[float], source_position_m: Sequence[float], dipole_vector_cart: Sequence[complex]) numpy.ndarray[source]

Return G(observer, source) @ dipole_vector.

mie_coefficients() MieCoefficients[source]

Return and cache the Mie coefficients for the active frequency.

projected_green(observer_position_m: Sequence[float], source_position_m: Sequence[float], observer_orientation_cart: Sequence[complex], source_orientation_cart: Sequence[complex]) complex[source]

Return e_A · G(r_A,r_D) · e_D for oriented dipoles.

projected_im_green_at_source(source_position_m: Sequence[float], orientation_cart: Sequence[complex]) float[source]

Return Im[e · G(r,r) · e] with the homogeneous regular term included.

purcell_factor(source_position_m: Sequence[float], orientation_cart: Sequence[complex], reference_k: float | None = None) float[source]

Return the orientation-resolved Purcell factor.

The default reference uses k0 to match the uploaded MATLAB code, whose examples place the coincident source in a vacuum-like region. Pass reference_k=abs(n_region*k0) if a different homogeneous reference is desired.

region_of(position_m: Sequence[float]) int[source]

Return the concentric-region index of a Cartesian position.

source_coefficients(source_position_m: Sequence[float], source_orientation_cart: Sequence[complex], kind: Literal['green', 'dipole'] = 'green') SourceCoefficients[source]

Expansion coefficients of an electric point dipole.

kind='green' gives the coefficient normalization used to assemble the Green tensor. kind='dipole' gives the MATLAB Gaussian-unit electric-field prefactor.

structure_component(observer_position_m: Sequence[float], source_position_m: Sequence[float]) numpy.ndarray[source]

Return the 3x3 Cartesian structure Green tensor.

The tensor is assembled column-by-column by exciting x-, y-, and z-oriented unit dipoles.

structure_field_for_orientation(observer_position_m: Sequence[float], source_position_m: Sequence[float], source_orientation_cart: Sequence[complex]) numpy.ndarray[source]

Return the structure-induced G_sc @ orientation vector in Cartesian components.

For exterior points this is the scattered field; for points across the boundary it is the transmitted Green-tensor contribution.

vacuum_component(observer_position_m: Sequence[float], source_position_m: Sequence[float], refractive_index: complex | None = None) numpy.ndarray[source]

Homogeneous-space dyadic Green tensor.

\[G_0 = \frac{e^{ikR}}{4\pi R k^2} \left[k^2(I-\hat R\hat R)+(3\hat R\hat R-I)/R^2 + i k (I-3\hat R\hat R)/R\right].\]

The coincident-point value returns the regular imaginary part i k/(6π) I.

class mqed.Dyadic_GF.GF_Mie.MieResult(total: numpy.ndarray, vacuum: numpy.ndarray, structure: numpy.ndarray, observer_region: int, source_region: int)[source]

Container returned by high-level field helpers.

__delattr__(name)

Implement delattr(self, name).

__eq__(other)

Return self==value.

__init__(total: numpy.ndarray, vacuum: numpy.ndarray, structure: numpy.ndarray, observer_region: int, source_region: int) None
__repr__()

Return repr(self).

__setattr__(name, value)

Implement setattr(self, name, value).

class mqed.Dyadic_GF.GF_Mie.RadialFunctions(z: numpy.ndarray, riccati: numpy.ndarray, d_riccati: numpy.ndarray, d_riccati_over_z: numpy.ndarray, kind: Literal['bessel', 'hankel1'])[source]

Radial Bessel/Hankel data for all multipoles n=1..nmax.

z

Spherical Bessel/Hankel function j_n(z) or h_n^(1)(z).

Type:

numpy.ndarray

riccati

Riccati-Bessel/Hankel function z*j_n(z) or z*h_n^(1)(z).

Type:

numpy.ndarray

d_riccati

Derivative of riccati with respect to its argument.

Type:

numpy.ndarray

d_riccati_over_z

d_riccati / z. The small-argument Bessel limit is handled explicitly for n=1.

Type:

numpy.ndarray

kind

"bessel" for regular waves or "hankel1" for outgoing waves.

Type:

Literal[‘bessel’, ‘hankel1’]

__delattr__(name)

Implement delattr(self, name).

__eq__(other)

Return self==value.

__init__(z: numpy.ndarray, riccati: numpy.ndarray, d_riccati: numpy.ndarray, d_riccati_over_z: numpy.ndarray, kind: Literal['bessel', 'hankel1']) None
__repr__()

Return repr(self).

__setattr__(name, value)

Implement setattr(self, name, value).

class mqed.Dyadic_GF.GF_Mie.SourceCoefficients(p: numpy.ndarray | None = None, q: numpy.ndarray | None = None, r: numpy.ndarray | None = None, s: numpy.ndarray | None = None)[source]

Expansion coefficients of an electric point-dipole source.

__delattr__(name)

Implement delattr(self, name).

__eq__(other)

Return self==value.

__init__(p: numpy.ndarray | None = None, q: numpy.ndarray | None = None, r: numpy.ndarray | None = None, s: numpy.ndarray | None = None) None
__repr__()

Return repr(self).

__setattr__(name, value)

Implement setattr(self, name, value).

class mqed.Dyadic_GF.GF_Mie.VectorSphericalFunctions(M: numpy.ndarray, N: numpy.ndarray)[source]

Vector spherical functions in the local spherical basis.

Arrays have shape (nmax, 2*nmax + 1, 3). The last index is the spherical component (r, theta, phi).

__delattr__(name)

Implement delattr(self, name).

__eq__(other)

Return self==value.

__init__(M: numpy.ndarray, N: numpy.ndarray) None
__repr__()

Return repr(self).

__setattr__(name, value)

Implement setattr(self, name, value).

mqed.Dyadic_GF.GF_Mie.azimuthal_table(nmax: int, phi: float, order: Literal['normal', 'reversed']) numpy.ndarray[source]

Return the normalized azimuthal factors (2π)^-1/2 exp(i m phi).

mqed.Dyadic_GF.GF_Mie.cartesian_to_spherical(position: Sequence[float]) numpy.ndarray[source]

Convert a Cartesian position to (r, theta, phi).

theta is the polar angle measured from +z and phi is the azimuthal angle returned by atan2(y, x). At the origin, both angles are set to 0.

mqed.Dyadic_GF.GF_Mie.dlog_riccati(z: complex, nmax: int) tuple[numpy.ndarray, numpy.ndarray][source]

Logarithmic derivatives D1=psi'/psi and D3=xi'/xi.

This is a direct Python translation of the recurrence used in the uploaded MATLAB Dlog function. It is used for the core/shell and simple-cavity formulas, where direct ratios can be poorly conditioned.

mqed.Dyadic_GF.GF_Mie.mie_coreshell(refractive_indices: Sequence[complex], k0_radii: Sequence[float], nmax: int) MieCoefficients[source]

Mie coefficients for a core/shell sphere.

Parameters:
  • refractive_indices[n_exterior, n_shell, n_core].

  • k0_radii[k0 * outer_radius, k0 * core_radius].

alpha and beta are exterior-source scattering coefficients. gamma and delta are finite-shell inner-cavity reflection coefficients for a source and observer both in the core.

mqed.Dyadic_GF.GF_Mie.mie_simple_cavity(refractive_indices: Sequence[complex], k0_radius: float, nmax: int) MieCoefficients[source]

Mie coefficients for a spherical cavity embedded in an exterior medium.

mqed.Dyadic_GF.GF_Mie.mie_single(refractive_indices: Sequence[complex], k0_radius: float, nmax: int) MieCoefficients[source]

Mie coefficients for one homogeneous sphere.

mqed.Dyadic_GF.GF_Mie.normalized_tau_pi_p(nmax: int, theta: float, order: Literal['normal', 'reversed'] = 'normal') AngularFunctions[source]

Compute normalized tau_nm, pi_nm, and P_nm tables.

This follows the uploaded MATLAB function NormTauPiP: it obtains the angular functions from Wigner-d matrix elements instead of directly differentiating associated Legendre polynomials, which is more stable at high multipole order.

mqed.Dyadic_GF.GF_Mie.spherical_radial_functions(z_arg: complex, nmax: int, kind: Literal['bessel', 'hankel1']) RadialFunctions[source]

Return radial functions for all orders n=1..nmax.

mqed.Dyadic_GF.GF_Mie.vector_cartesian_to_spherical(vector: Sequence[complex], theta: float, phi: float) numpy.ndarray[source]

Convert vector components from Cartesian to the local spherical basis.

mqed.Dyadic_GF.GF_Mie.vector_spherical_functions(kr: complex, nmax: int, radial: RadialFunctions, angular: AngularFunctions, emphi: numpy.ndarray) VectorSphericalFunctions[source]

Generate normalized vector spherical functions M_nm and N_nm.

The implementation mirrors MATLAB VectSphFunc. The output components are in the local spherical basis at the evaluation point.

mqed.Dyadic_GF.GF_Mie.vector_spherical_to_cartesian(vector: Sequence[complex], theta: float, phi: float) numpy.ndarray[source]

Convert vector components from the local spherical basis to Cartesian.

mqed.Dyadic_GF.GF_Mie.wigner_d(j: int, theta: float) numpy.ndarray[source]

Return the Wigner small-d matrix d^j(theta).

A light rounding is used only for cache keys; the error is well below the numerical tolerance of the Mie sums.