Skip to content

materials.absorbers.layered

Declarative layer stacks and the transfer-matrix absorber solver.

An absorber is declared as a list of layers ordered from the sound-incidence side towards the termination and solved at one angle, in the same time convention as the element models of porous, with the forward wave carried by (so a passive medium has ):

  • Transfer-matrix multilayer prediction: each fluid layer contributes with the in-depth wavenumber from Snell’s law and (Cox & D’Antonio Eqs. (2.29)-(2.32); Bies Eq. (D.83); equivalent to the layer-recursion of Bies Eq. (D.95) and Mechel Sect. D.4). Thin resonant sheets (perforated plate, microperforated plate, limp membrane) enter as series transfer impedances . The stack is closed by a rigid wall, by free air or by an arbitrary termination impedance, giving the surface impedance, the oblique reflection factor and . This same layer transfer matrix underlies the critically-coupled perfect-absorber designs of Jiménez, Groby, Pagneux & Romero-García (2017, Applied Sciences 7(6), 618, doi:10.3390/app7060618) and, for a rigidly-backed high-porosity layer, Jiménez, Romero-García & Groby (2018, Acta Acustica united with Acustica 104(3), 396-409, doi:10.3813/AAA.919183), where the critical-coupling condition on the surface impedance yields total single-frequency absorption.

  • Random incidence: the random-incidence (Paris) integral follows Mechel Sect. D.5 Eqs. (9)-(10), with the closed form for locally reacting surfaces implemented in statistical_absorption (its maximum over passive impedances is the published 0.951).

The elements a stack is built from live elsewhere: the equivalent fluid a PorousLayer carries and the sheet impedances the plate and membrane layers evaluate come from porous, and the three Biot waves a PoroelasticLayer carries come from biot.

Auto-generated from the source docstrings by scripts/generate_api_docs.py (make api-docs). Do not edit by hand.

AirLayer(thickness: float)

A plain air gap of thickness metres inside the stack.

diffuse_field_absorption(
frequency: ArrayLike,
layers: list[Layer] | tuple[Layer, ...],
*,
angle_limit: float = 1.5707963267948966,
quadrature_points: int = 64,
termination: str | complex | ArrayLike = 'rigid',
speed_of_sound: float = 343.0,
air_density: float = 1.205,
viscosity: float = 1.84e-05,
) -> DiffuseFieldAbsorptionResult

Random-incidence absorption by the Paris integral (Mechel Sect. D.5).

(Mechel 2e Sect. D.5 Eq. (9)), evaluated with fixed-order Gauss-Legendre quadrature over the bulk-reacting of layered_absorber (Sect. D.6 notes the bulk integral generally must be evaluated numerically). Some references truncate the integral at 75-87 degrees instead of 90 (Sect. D.5); set angle_limit accordingly.

Parameters

NameDescription
frequencyFrequency vector f, in hertz.
layersLayer stack, as in layered_absorber.
angle_limitUpper integration angle theta_lim, in radians (0 < theta_lim <= pi/2; default pi/2).
quadrature_pointsGauss-Legendre order (default 64).
terminationAs in layered_absorber.
speed_of_soundSpeed of sound c in air, in m/s.
air_densityAir density rho, in kg/m3.
viscosityDynamic viscosity of air, in Pa s.

Returns: A DiffuseFieldAbsorptionResult.

DiffuseFieldAbsorptionResult(
frequency: Real,
absorption: Real,
angle_limit: float,
)

Random-incidence (Paris-integral) absorption of a layered absorber.

absorption is from Mechel 2e Sect. D.5 Eq. (9): the plane-wave weighted by and normalised by .

DiffuseFieldAbsorptionResult.plot(
ax: Axes | None = None,
*,
language: str = 'en',
**kwargs: Any,
) -> Axes

Plot the random-incidence absorption spectrum .

Requires matplotlib (pip install phonometry[plot]); returns the Axes.

layered_absorber(
frequency: ArrayLike,
layers: list[Layer] | tuple[Layer, ...],
*,
angle: float = 0.0,
termination: str | complex | ArrayLike = 'rigid',
speed_of_sound: float = 343.0,
air_density: float = 1.205,
viscosity: float = 1.84e-05,
) -> LayeredAbsorberResult

Transfer-matrix prediction of a layered absorber at one angle.

The layers list is ordered from the sound-incidence side towards the termination. Fluid layers (AirLayer, PorousLayer) contribute the oblique chain matrix of Cox & D’Antonio 3e Eq. (2.29) (equivalently the impedance recursion of Bies 5e Eq. (D.95) and the scheme of Mechel 2e Sect. D.4); sheet layers (PerforatedPlateLayer, MicroperforatedPlateLayer, MembraneLayer) enter as locally reacting series impedances; a PoroelasticLayer carries the three Biot waves of its elastic frame and switches the whole stack to the six-variable global-matrix assembly of Allard & Atalla 2e Sect. 11.5, with the coupling matrices of Sect. 11.4. The chain is closed by a rigid wall (termination="rigid"), by radiation into free air behind (termination="free", ) or by an arbitrary complex impedance. The reflection factor is and (Mechel 2e Sect. D.3 Eq. (2)).

Zs, R and alpha are evaluated with the numerically robust admittance recursion (algebraically identical to the chain product but immune to the overflow of the raw matrix entries for extremely attenuating layers); the raw chain matrix is still returned in transfer_matrix and may overflow in such extreme cases.

Parameters

NameDescription
frequencyFrequency vector f, in hertz.
layersLayer stack from the incidence side to the termination.
anglePolar angle of incidence theta, in radians (; grazing incidence is excluded).
termination"rigid" (default), "free", or a non-zero complex impedance (scalar or per-frequency array), in Pa s/m.
speed_of_soundSpeed of sound c in air, in m/s.
air_densityAir density rho, in kg/m3.
viscosityDynamic viscosity of air, in Pa s (sheet layers).

Returns: A LayeredAbsorberResult.

LayeredAbsorberResult(
frequency: Real,
angle: float,
surface_impedance: Complex,
normalized_impedance: Complex,
reflection: Complex,
absorption: Real,
transfer_matrix: Complex,
layers: tuple[Layer, ...] | None = None,
)

Oblique-incidence prediction of a layered absorber.

All arrays share the shape of frequency. surface_impedance is the specific impedance at the front face (may be inf for a lossless-sheet stack over a rigid wall), reflection the complex plane-wave reflection factor , absorption the coefficient and transfer_matrix the total chain matrix with shape (2, 2, len(frequency)) (unimodular: every layer is reciprocal).

layers retains the layer sequence the stack was solved with (front layer first) so plot_geometry can draw the cross-section; it is appended after the original fields and defaults to None for hand-built results.

LayeredAbsorberResult.plot(
ax: Axes | None = None,
*,
language: str = 'en',
**kwargs: Any,
) -> Axes

Plot the absorption spectrum with overlaid.

Requires matplotlib (pip install phonometry[plot]); returns the Axes.

LayeredAbsorberResult.plot_geometry(
ax: Axes | None = None,
*,
language: str = 'en',
**kwargs: Any,
) -> Axes

Draw the solved stack cross-section to scale (dimensioned).

Requires matplotlib (pip install phonometry[plot]); returns the Axes.

Raises

ExceptionWhen
ValueErrorIf the result does not retain its layers.
MembraneLayer(surface_density: float, resistance: float = 0.0)

A limp impervious membrane (see membrane_impedance).

MicroperforatedPlateLayer(
thickness: float,
hole_radius: float,
open_area: float,
end_correction: float = 0.85,
)

A microperforated plate (see microperforated_plate_impedance).

PerforatedPlateLayer(
thickness: float,
hole_radius: float,
open_area: float,
end_correction: float | None = None,
)

A rigid perforated plate (see perforated_plate_impedance).

PoroelasticLayer(
thickness: float,
medium: PorousMediumResult,
porosity: float,
tortuosity: float,
frame_density: float,
shear_modulus: complex,
poisson_ratio: float = 0.0,
)

A porous layer whose frame is elastic (full Biot theory).

Where PorousLayer collapses the material into a single wave in an equivalent fluid, this layer carries the three Biot waves of Allard & Atalla 2e chapter 6 - two compressional and one shear - so the frame can resonate. It is the only layer type that reproduces the quarter-wavelength frame resonance of frame_quarter_wave_resonance, and the only one for which an air gap behind the layer, a bonded backing or an oblique angle change the frame motion rather than only the pore fluid.

medium is the rigid-frame equivalent fluid of the pores (normally a johnson_champoux_allard result on the solver’s frequency vector): the frame inertia is added by the Biot model itself, so a limp-corrected medium would count it twice. The remaining fields describe the frame.

Adding one of these to a stack switches layered_absorber to the global-matrix assembly of Allard & Atalla Sect. 11.5. Two adjacent poroelastic layers are coupled as bonded frames (their Eq. (11.67)); a sheet layer next to a poroelastic layer is coupled as a free, mechanically decoupled screen (air on both sides, their Sect. 11.3.6).

PorousLayer(thickness: float, medium: PorousMediumResult)

A porous layer of thickness metres described by medium.

medium is a PorousMediumResult (from delany_bazley, miki, johnson_champoux_allard, or built directly from measured Zc/k data) evaluated on the same frequency vector that is passed to layered_absorber.

statistical_absorption(
normalized_impedance: ArrayLike,
*,
angle_limit: float = 1.5707963267948966,
) -> Real

Closed-form Paris integral for a locally reacting plane.

With the normalised surface admittance (Mechel 2e Sect. D.5 Eq. (10)):

reducing for to Eq. (4) and, for real admittance, to the printed special case. The maximum over passive impedances is 0.951 (the published bound for locally reacting absorbers, Sect. D.5).

Parameters

NameDescription
normalized_impedanceNormalised surface impedance (complex scalar or array), with .
angle_limitUpper integration angle theta_lim, in radians (0 < theta_lim <= pi/2; default pi/2).

Returns: Statistical absorption coefficient alpha_dif.