Phonons¶
Phonon mode data and modulated-polarisation helpers. Docstrings are the source of truth, rendered with mkdocstrings (numpydoc style).
photonics_helper.phonon ¶
Phonon module — multi-mode Raman-active phonon modeling.
Provides PhononMode dataclass and PhononResponse class for combining multiple Raman-active phonon modes into a unified response function.
PHONON_MATERIALS
module-attribute
¶
PHONON_MATERIALS: dict[str, list[PhononMode]] = {'LiNbO3': [PhononMode(Wavenumber(254, '1/cm'), Wavenumber(14, '1/cm'), 'A₁', 1.0, note='Barker & Loudon (1967)'), PhononMode(Wavenumber(162, '1/cm'), Wavenumber(8, '1/cm'), 'A₁', 0.8, note='Ridah et al. (1997)'), PhononMode(Wavenumber(701, '1/cm'), Wavenumber(6, '1/cm'), 'A₁', 0.6, note='Barker & Loudon (1967)'), PhononMode(Wavenumber(637, '1/cm'), Wavenumber(5, '1/cm'), 'E', 0.7, note='Ridah et al. (1997)'), PhononMode(Wavenumber(576, '1/cm'), Wavenumber(4, '1/cm'), 'E', 0.5, note='Barker & Loudon (1967)'), PhononMode(Wavenumber(277, '1/cm'), Wavenumber(10, '1/cm'), 'E', 0.4, note='Ridah et al. (1997)'), PhononMode(Wavenumber(819, '1/cm'), Wavenumber(3, '1/cm'), 'E', 0.3, note='Barker & Loudon (1967)')], 'LiTaO3': [PhononMode(Wavenumber(255, '1/cm'), Wavenumber(12, '1/cm'), 'A₁', 1.0, note='Raptis (1988)'), PhononMode(Wavenumber(143, '1/cm'), Wavenumber(6, '1/cm'), 'A₁', 0.7, note='Margueron et al. (2012)'), PhononMode(Wavenumber(740, '1/cm'), Wavenumber(5, '1/cm'), 'A₁', 0.5, note='Raptis (1988)'), PhononMode(Wavenumber(690, '1/cm'), Wavenumber(4, '1/cm'), 'E', 0.6, note='Raptis (1988)'), PhononMode(Wavenumber(327, '1/cm'), Wavenumber(8, '1/cm'), 'E', 0.4, note='Margueron et al. (2012)')], 'BaTiO3': [PhononMode(Wavenumber(258, '1/cm'), Wavenumber(5, '1/cm'), 'A₁', 1.0, note='Scalabrin et al. (1977)'), PhononMode(Wavenumber(181, '1/cm'), Wavenumber(3, '1/cm'), 'A₁', 0.8, note='Chaves et al. (1974)'), PhononMode(Wavenumber(142, '1/cm'), Wavenumber(2, '1/cm'), 'A₁', 0.6, note='Scalabrin et al. (1977)'), PhononMode(Wavenumber(520, '1/cm'), Wavenumber(45, '1/cm'), 'A₁', 0.9, note='Scalabrin et al. (1977)'), PhononMode(Wavenumber(306, '1/cm'), Wavenumber(4, '1/cm'), 'E', 0.7, note='Chaves et al. (1974)'), PhononMode(Wavenumber(280, '1/cm'), Wavenumber(3, '1/cm'), 'E', 0.5, note='Scalabrin et al. (1977)'), PhononMode(Wavenumber(720, '1/cm'), Wavenumber(6, '1/cm'), 'E', 0.4, note='Chaves et al. (1974)'), PhononMode(Wavenumber(890, '1/cm'), Wavenumber(8, '1/cm'), 'B₁', 0.3, note='Scalabrin et al. (1977)')], 'YAG': [PhononMode(Wavenumber(784, '1/cm'), Wavenumber(8, '1/cm'), 'T₂g', 1.0, note='Hurrell et al. (1968)'), PhononMode(Wavenumber(360, '1/cm'), Wavenumber(5, '1/cm'), 'E_g', 0.6, note='Hurrell et al. (1968)'), PhononMode(Wavenumber(260, '1/cm'), Wavenumber(4, '1/cm'), 'E_g', 0.5, note='Hurrell et al. (1968)'), PhononMode(Wavenumber(1230, '1/cm'), Wavenumber(6, '1/cm'), 'T₂g', 0.7, note='Lamaignere et al. (2020)'), PhononMode(Wavenumber(1500, '1/cm'), Wavenumber(10, '1/cm'), 'A₁g', 0.4, note='Hurrell et al. (1968)')], 'Al2O3': [PhononMode(Wavenumber(418, '1/cm'), Wavenumber(5, '1/cm'), 'E_g', 1.0, note='Watson et al. (1981)'), PhononMode(Wavenumber(378, '1/cm'), Wavenumber(4, '1/cm'), 'E_g', 0.8, note='Major et al. (2004)'), PhononMode(Wavenumber(636, '1/cm'), Wavenumber(6, '1/cm'), 'A₁g', 0.6, note='Watson et al. (1981)'), PhononMode(Wavenumber(750, '1/cm'), Wavenumber(8, '1/cm'), 'E_g', 0.5, note='Watson et al. (1981)'), PhononMode(Wavenumber(1150, '1/cm'), Wavenumber(10, '1/cm'), 'A₁g', 0.4, note='Major et al. (2004)')], 'KTP': [PhononMode(Wavenumber(270, '1/cm'), Wavenumber(20, '1/cm'), 'A', 1.0, note='Neufeld et al. (2023) — dominant'), PhononMode(Wavenumber(500, '1/cm'), Wavenumber(15, '1/cm'), 'A', 0.8, note='Neufeld et al. (2023)'), PhononMode(Wavenumber(620, '1/cm'), Wavenumber(12, '1/cm'), 'B', 0.7, note='Neufeld et al. (2023)'), PhononMode(Wavenumber(750, '1/cm'), Wavenumber(10, '1/cm'), 'A', 0.6, note='Neufeld et al. (2023)'), PhononMode(Wavenumber(890, '1/cm'), Wavenumber(8, '1/cm'), 'B', 0.5, note='Neufeld et al. (2023)')], 'GaN': [PhononMode(Wavenumber(568, '1/cm'), Wavenumber(4, '1/cm'), 'E₂(high)', 1.0, note='Zeng et al. (2020)'), PhononMode(Wavenumber(144, '1/cm'), Wavenumber(3, '1/cm'), 'A₁(LO)', 0.6, note='Zeng et al. (2020)'), PhononMode(Wavenumber(532, '1/cm'), Wavenumber(5, '1/cm'), 'E₁(LO)', 0.5, note='Almeida et al. (2019)'), PhononMode(Wavenumber(736, '1/cm'), Wavenumber(6, '1/cm'), 'A₁(LO)', 0.4, note='Zeng et al. (2020)')], 'AlN': [PhononMode(Wavenumber(658, '1/cm'), Wavenumber(1, '1/cm'), 'E₂(high)', 1.0, note='Jung & Tang (2016)'), PhononMode(Wavenumber(615, '1/cm'), Wavenumber(2, '1/cm'), 'E₁(LO)', 0.7, note='Pandit et al. (2007)'), PhononMode(Wavenumber(895, '1/cm'), Wavenumber(3, '1/cm'), 'A₁(LO)', 0.5, note='Jung & Tang (2016)'), PhononMode(Wavenumber(330, '1/cm'), Wavenumber(2, '1/cm'), 'A₁(TO)', 0.4, note='Pandit et al. (2007)')], 'SiC_4H': [PhononMode(Wavenumber(777, '1/cm'), Wavenumber(5, '1/cm'), 'E₂(TO)', 1.0, note='Feldman et al. (1968)'), PhononMode(Wavenumber(983, '1/cm'), Wavenumber(8, '1/cm'), 'A₁(LO)', 0.6, note='Li et al. (2023)'), PhononMode(Wavenumber(750, '1/cm'), Wavenumber(4, '1/cm'), 'A₁(TO)', 0.5, note='Feldman et al. (1968)'), PhononMode(Wavenumber(250, '1/cm'), Wavenumber(3, '1/cm'), 'Folded TA', 0.3, note='Feldman et al. (1968)')], 'YLF': [PhononMode(Wavenumber(262, '1/cm'), Wavenumber(5, '1/cm'), 'B_g', 1.0, note='Miller et al. (1970)'), PhononMode(Wavenumber(170, '1/cm'), Wavenumber(4, '1/cm'), 'A_g', 0.7, note='Salaun et al. (1997)'), PhononMode(Wavenumber(380, '1/cm'), Wavenumber(6, '1/cm'), 'E_g', 0.6, note='Miller et al. (1970)'), PhononMode(Wavenumber(520, '1/cm'), Wavenumber(8, '1/cm'), 'B_g', 0.5, note='Miller et al. (1970)'), PhononMode(Wavenumber(640, '1/cm'), Wavenumber(5, '1/cm'), 'E_g', 0.4, note='Salaun et al. (1997)')]}
PhononMode ¶
A single Raman-active phonon mode.
Attributes:
| Name | Type | Description |
|---|---|---|
shift_cm |
Wavenumber
|
Raman shift (e.g. |
linewidth_cm |
Wavenumber
|
Full width at half maximum (e.g. |
symmetry |
str or None
|
Symmetry label (e.g. "A₁g", "E_g", "A₁(TO)"). |
relative_strength |
float
|
Relative Raman cross-section (default 1.0). |
lo_phonon_cm |
Wavenumber or None
|
LO phonon frequency (if different from Raman shift). |
to_phonon_cm |
Wavenumber or None
|
TO phonon frequency. |
note |
str or None
|
Annotation or source reference. |
PhononResponse ¶
Multi-mode Raman response function.
Combines multiple PhononMode instances into a unified response by summing individual mode responses weighted by their relative strengths.
Each mode produces a Lorentzian lineshape in frequency domain: L(ω) = (γ/2) / [(ω - ω₀)² + (γ/2)²] where ω₀ is the mode shift and γ is the linewidth.
The time-domain response is the inverse FFT of the frequency-domain response.
Attributes:
| Name | Type | Description |
|---|---|---|
modes |
list[PhononMode]
|
List of phonon modes. |
fR |
float
|
Total Raman fraction. If None, computed as sum of relative strengths. |
from_material
classmethod
¶
from_material(name: str, db: 'object | None' = None) -> 'PhononResponse'
Build a response for a material, database-first.
Resolution order:
RamanDatabase.get_phonon_modes(name)— the shipped database, the same interface used for n/k data.- The canonical :data:
PHONON_MATERIALStable (offline / empty DB).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
material name (e.g. ``"LiNbO3"``).
|
|
required |
db
|
optional existing ``RamanDatabase`` instance to reuse.
|
|
None
|
Raises:
| Type | Description |
|---|---|
KeyError
|
If neither the database nor the canonical table has modes for the material; the message lists the available material names. |
h_R ¶
h_R(t: NDArray) -> NDArray
Causal, unit-integral delayed Raman response h_R(t).
A superposition of damped oscillators, one per phonon mode::
h_R(t) = Z^-1 * sum_i w_i * exp(-t/tau_i) * sin(omega_i t) * theta(t)
where omega_i is the mode's angular frequency from its Raman shift,
gamma_i its angular-frequency FWHM from its linewidth
(tau_i = 2/gamma_i, the damped-oscillator / Lorentzian relation
delta_omega = 2/tau), w_i its relative strength, and Z is
chosen so that integral_0^inf h_R(t) dt = 1. This is the
multi-vibrational-mode form used with the standard GNLSE delayed
response R(t) = (1 - f_R) delta(t) + f_R h_R(t).
References
Agrawal, Nonlinear Fiber Optics, 5th ed., Sec. 2.3.2 (normalization
integral h_R dt = 1); Hollenbeck & Cantrell, J. Opt. Soc. Am. B
19, 2886 (2002) (multi-vibrational-mode Raman response); Stolen,
Tomlinson, Haus & Gordon, J. Opt. Soc. Am. B 6, 1159 (1989).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
t
|
NDArray
|
Time array in seconds. |
required |
Returns:
| Type | Description |
|---|---|
NDArray
|
|
frequency_domain ¶
frequency_domain(w_cm: WavenumberArray | NDArray) -> NDArray
Frequency-domain response: sum of Lorentzian mode lineshapes.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
w_cm
|
WavenumberArray | NDArray
|
Frequency axis in cm⁻¹ (a :class: |
required |
Returns:
| Type | Description |
|---|---|
NDArray — Total response (sum of weighted Lorentzians).
|
|
time_domain ¶
time_domain(t: NDArray) -> NDArray
Time-domain response via inverse FFT of frequency-domain response.
The time-domain response is the inverse FFT of the frequency-domain response, representing the delayed Raman response in the time domain.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
t
|
NDArray
|
Time array in seconds. |
required |
Returns:
| Type | Description |
|---|---|
NDArray — Time-domain response (sum of damped oscillations).
|
|
plot_modes ¶
plot_modes(backend: Literal['matplotlib', 'plotly'] = 'matplotlib')
Bar chart of all phonon modes.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
backend
|
'matplotlib' or 'plotly'
|
|
'matplotlib'
|
Returns:
| Type | Description |
|---|---|
fig or None — Plot figure, or None if no modes.
|
|
plot_spectrum ¶
plot_spectrum(shift_range_cm: float = 200, n_points: int = 1000, backend: Literal['matplotlib', 'plotly'] = 'matplotlib')
Overlay of all Lorentzian mode lineshapes.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
shift_range_cm
|
float
|
Range around 0 to plot (cm⁻¹). |
200
|
n_points
|
int
|
Number of points. |
1000
|
backend
|
'matplotlib' or 'plotly'
|
|
'matplotlib'
|
Returns:
| Type | Description |
|---|---|
fig or None — Plot figure, or None if no modes.
|
|
demo ¶
demo()
Self-check: verify basic functionality.
Returns:
| Type | Description |
|---|---|
dict — Test results with pass/fail status.
|
|