Ir al contenido

noise_control.silencers

La referencia de la API se publica en inglés en los dos idiomas: se genera a partir de los docstrings del código, que son su texto original.

Reactive silencers by the four-pole (transmission-matrix) method.

A reactive silencer controls noise by reflecting it back to the source with impedance discontinuities — sudden area changes and side branches — rather than by dissipating it in absorptive material. The one-dimensional plane-wave theory represents each acoustic element by a 2x2 transfer (four-pole) matrix relating the sound pressure p and volume velocity S u at its two ends, and a compound silencer is the ordered matrix product of its elements (Bies, Hansen & Howard, Engineering Noise Control 5th ed., §8.8-8.9; Munjal, Acoustics of Ducts and Mufflers).

Transfer matrix (Bies Eq. (8.133)), state vector [p, S u] with the characteristic acoustic impedance . The plane-wave element for a straight duct of length L and area S is (Bies Eq. (8.143), no flow)

and a side branch of acoustic impedance Z_b is the shunt element (Bies Eq. (8.144))

Transmission loss from the compound matrix T (Munjal, Acoustics of Ducts and Mufflers 2nd ed., Eq. (3.27), no flow; reduces to Bies Eq. (8.148) for equal inlet/outlet areas):

with and . A zero-length element between unequal areas then reproduces the classic sudden-expansion result with , and the TL is the same from either side, as reciprocity of a passive two-port requires. Bies Eq. (8.141) prints this formula with impedance ratios on T11 and T22 ( and ) instead of the overall prefactor; as printed it fails the sudden-expansion limit (see docs/ERRATA.md). TL is the intrinsic attenuation for an anechoic termination. The insertion loss for a source of internal impedance Z_s radiating into a termination impedance Z_r is the extra attenuation of inserting the silencer in place of a direct connection,

which is 0 when the silencer reduces to a through connection () and, for equal inlet/outlet areas, equals the transmission loss for the anechoic reference (with unequal areas the direct connection contains the same area jump, so its mismatch loss cancels from the insertion loss but not from the transmission loss).

Simple expansion chamber. A chamber of area S_exp and length L between pipes of area S_duct has the closed-form transmission loss (Bies Eq. (8.111)) with area ratio

peaking at when and dropping to 0 at (no dissipation). The four-pole product reproduces this exactly, and the machinery extends to side-branch (Helmholtz, quarter-wave) and extended-tube resonators that the closed form cannot cover.

Layouts of your own. Anything the four named devices do not cover is built by cascading elements directly. SilencerChain does that through the same duct_matrix, shunt_matrix and cascade calls while keeping the arguments each element was given, which is what lets a hand-built chain be drawn (SilencerChain.plot_geometry) and not only computed. The drawing shows the ducts to scale and marks the branch points, because that is the whole of what the elements declare: a duct element is handed a length and an area, a shunt element only an impedance.

Validity. All of this is one-dimensional: it holds while the duct and the chamber carry plane waves only, that is below the first higher-order-mode cut-on frequency of the widest cross section (phonometry.noise_control.duct_modes). Every result reports that frequency as ReactiveSilencerResult.plane_wave_limit and raises a PlaneWaveWarning when the analysis grid reaches past it: the numbers are still returned, but above cut-on they describe the plane-wave mode alone and a measurement will show the rest.

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

cascade(*matrices: _Complex) -> _Complex

Cascade element four-pole matrices from inlet to outlet.

The compound matrix is the ordered product T1 @ T2 @ ... @ Tn (the state at the inlet equals the compound matrix times the state at the outlet), broadcast over the frequency axis.

Parameters

NameDescription
matricesOne or more (n_freq, 2, 2) arrays sharing n_freq.

Returns: The compound (n_freq, 2, 2) array.

duct_matrix(
frequencies: ArrayLike,
length: float,
area: float,
*,
speed_of_sound: float = 343.0,
density: float = 1.206,
) -> _Complex

Four-pole matrix of a straight duct (Bies Eq. (8.143), no flow).

Parameters

NameDescription
frequenciesFrequencies f, Hz (1-D array).
lengthDuct length L, m.
areaCross-sectional area S, m2.
speed_of_soundSpeed of sound c, m/s.
densityAir density rho, kg/m3.

Returns: A (n_freq, 2, 2) complex transfer-matrix array.

expansion_chamber(
frequencies: ArrayLike,
length: float,
chamber_area: float,
pipe_area: float,
*,
speed_of_sound: float = 343.0,
density: float = 1.206,
source_impedance: ArrayLike | None = None,
radiation_impedance: ArrayLike | None = None,
) -> ReactiveSilencerResult

Simple expansion-chamber silencer (Bies Eq. (8.111) / four-pole).

Parameters

NameDescription
frequenciesFrequencies f, Hz (1-D array).
lengthChamber length L, m.
chamber_areaChamber cross-sectional area S_exp, m2.
pipe_areaInlet/outlet pipe area S_duct, m2.
speed_of_soundSpeed of sound c, m/s.
densityAir density rho, kg/m3.
source_impedanceOptional source impedance Z_s for the insertion loss, Pa s/m3.
radiation_impedanceOptional radiation impedance Z_r for the insertion loss, Pa s/m3.

Returns: A ReactiveSilencerResult (its transmission_loss equals the closed form ).

extended_tube_chamber(
frequencies: ArrayLike,
length: float,
chamber_area: float,
pipe_area: float,
*,
inlet_extension: float = 0.0,
outlet_extension: float = 0.0,
speed_of_sound: float = 343.0,
density: float = 1.206,
source_impedance: ArrayLike | None = None,
radiation_impedance: ArrayLike | None = None,
) -> ReactiveSilencerResult

Extended-inlet/outlet expansion chamber (Bies §8.9.7).

The inlet and outlet pipes extend a distance into the chamber, forming annular quarter-wave side branches (of area and lengths equal to the extensions, Bies Eq. (8.156)) at the two junctions. Tuning the extensions (classically and ) places quarter-wave peaks that fill the troughs of the plain expansion chamber. With both extensions 0 the result reduces exactly to expansion_chamber.

The junction where each extended pipe ends is where its three ducts meet, so the straight chamber element cascaded between the two side branches is the length left over, (Bies Figure 8.19(a) and Example 8.2, where ), and not the full chamber length. When the two extensions meet () the straight element vanishes and the two annular branches shunt the same plane, which is the well-defined limit of the cascade; extensions that would overlap are rejected.

Parameters

NameDescription
frequenciesFrequencies f, Hz (1-D array).
lengthOverall chamber length L, m, extensions included.
chamber_areaChamber cross-sectional area S_exp, m2.
pipe_areaInlet/outlet pipe area S_duct, m2.
inlet_extensionInlet pipe extension into the chamber L_a, m.
outlet_extensionOutlet pipe extension into the chamber L_b, m.
speed_of_soundSpeed of sound c, m/s.
densityAir density rho, kg/m3.
source_impedanceOptional source impedance Z_s, Pa s/m3.
radiation_impedanceOptional radiation impedance Z_r, Pa s/m3.

Returns: A ReactiveSilencerResult.

helmholtz_impedance(
frequencies: ArrayLike,
neck_area: float,
neck_length: float,
cavity_volume: float,
*,
resistance: float = 0.0,
speed_of_sound: float = 343.0,
density: float = 1.206,
) -> _Complex

Acoustic impedance of a Helmholtz side branch (Bies Eq. (8.152)).

with acoustic mass and compliance ; the resonance (Bies Eq. (8.46)) is where the reactance vanishes, leaving : a lossless branch (resistance = 0) shorts the duct there, and a resistive one presents its resistance instead, which is what bounds the peak attenuation.

Parameters

NameDescription
frequenciesFrequencies f, Hz (1-D array).
neck_areaNeck cross-sectional area S_neck, m2.
neck_lengthEffective neck length l_e (with end corrections), m.
cavity_volumeCavity volume V, m3.
resistanceAcoustic resistance R, Pa s/m3 (default 0, lossless).
speed_of_soundSpeed of sound c, m/s.
densityAir density rho, kg/m3.

Returns: The complex branch impedance per frequency, Pa s/m3.

helmholtz_resonator(
frequencies: ArrayLike,
duct_area: float,
neck_area: float,
neck_length: float,
cavity_volume: float,
*,
resistance: float = 0.0,
speed_of_sound: float = 343.0,
density: float = 1.206,
source_impedance: ArrayLike | None = None,
radiation_impedance: ArrayLike | None = None,
) -> ReactiveSilencerResult

Side-branch Helmholtz resonator on a duct (Bies Eqs. (8.144), (8.152)).

Parameters

NameDescription
frequenciesFrequencies f, Hz (1-D array).
duct_areaMain-duct cross-sectional area S_d, m2.
neck_areaResonator neck area S_neck, m2.
neck_lengthEffective neck length l_e, m.
cavity_volumeCavity volume V, m3.
resistanceNeck acoustic resistance R, Pa s/m3 (default 0).
speed_of_soundSpeed of sound c, m/s.
densityAir density rho, kg/m3.
source_impedanceOptional source impedance Z_s, Pa s/m3.
radiation_impedanceOptional radiation impedance Z_r, Pa s/m3.

Returns: A ReactiveSilencerResult; resonances holds .

insertion_loss(
transfer_matrix: _Complex,
*,
source_impedance: ArrayLike,
radiation_impedance: ArrayLike,
) -> NDArray[np.float64]

Insertion loss of a four-pole element for given end impedances.

The attenuation from inserting the element in place of a direct (zero length) connection between a source of internal impedance Z_s and a radiation (termination) impedance Z_r:

Parameters

NameDescription
transfer_matrixA (n_freq, 2, 2) compound matrix.
source_impedanceSource internal acoustic impedance Z_s, Pa s/m3 (scalar or per-frequency, real or complex).
radiation_impedanceTermination/radiation acoustic impedance Z_r, Pa s/m3 (scalar or per-frequency).

Returns: The insertion loss per frequency, dB.

plot_silencer_geometry(
kind: str,
ax: Axes | None = None,
*,
length: float | None = None,
chamber_area: float | None = None,
pipe_area: float | None = None,
inlet_extension: float = 0.0,
outlet_extension: float = 0.0,
duct_area: float | None = None,
neck_area: float | None = None,
neck_length: float | None = None,
cavity_volume: float | None = None,
branch_area: float | None = None,
language: str = 'en',
) -> Axes

Draw a reactive silencer cross-section to scale.

Side cut through the duct axis with equivalent circular diameters (d = 2 sqrt(S / pi)) for every cross-section area, matching the parameters of the four noise_control silencer constructors. A Helmholtz cavity is drawn as the cube of equal volume with its volume annotated.

Parameters

NameDescription
kindOne of "expansion chamber", "extended-tube chamber", "Helmholtz resonator", "quarter-wave resonator" (the ReactiveSilencerResult.kind strings).
axExisting axes, or None to create a figure.
lengthChamber length or quarter-wave tube length, in metres.
chamber_areaChamber cross-section, in m2 (chambers).
pipe_areaInlet/outlet pipe cross-section, in m2 (chambers).
inlet_extensionInlet tube extension into the chamber, in metres.
outlet_extensionOutlet tube extension, in metres.
duct_areaMain duct cross-section, in m2 (side branches).
neck_areaNeck cross-section, in m2 (Helmholtz).
neck_lengthNeck length, in metres (Helmholtz).
cavity_volumeCavity volume, in m3 (Helmholtz).
branch_areaBranch tube cross-section, in m2 (quarter-wave).
languageLabel language, "en" (default) or "es".

Returns: The axes.

quarter_wave_impedance(
frequencies: ArrayLike,
length: float,
area: float,
*,
speed_of_sound: float = 343.0,
density: float = 1.206,
) -> _Complex

Acoustic impedance of a closed quarter-wave side branch (Bies Eq. (8.146)).

; the reactance vanishes at (), where the closed tube presents a pressure node and shorts the duct.

Parameters

NameDescription
frequenciesFrequencies f, Hz (1-D array).
lengthEffective tube length l_e (with end correction), m.
areaTube cross-sectional area S, m2.
speed_of_soundSpeed of sound c, m/s.
densityAir density rho, kg/m3.

Returns: The complex branch impedance per frequency, Pa s/m3.

quarter_wave_resonator(
frequencies: ArrayLike,
duct_area: float,
length: float,
branch_area: float,
*,
speed_of_sound: float = 343.0,
density: float = 1.206,
source_impedance: ArrayLike | None = None,
radiation_impedance: ArrayLike | None = None,
) -> ReactiveSilencerResult

Closed quarter-wave side-branch tube on a duct (Bies Eqs. (8.144), (8.146)).

Parameters

NameDescription
frequenciesFrequencies f, Hz (1-D array).
duct_areaMain-duct cross-sectional area S_d, m2.
lengthEffective branch length l_e, m.
branch_areaBranch tube area S, m2.
speed_of_soundSpeed of sound c, m/s.
densityAir density rho, kg/m3.
source_impedanceOptional source impedance Z_s, Pa s/m3.
radiation_impedanceOptional radiation impedance Z_r, Pa s/m3.

Returns: A ReactiveSilencerResult; resonances holds the odd multiples of within the frequency range.

ReactiveSilencerResult(
frequencies: np.ndarray,
transmission_loss: np.ndarray,
insertion_loss: np.ndarray | None,
transfer_matrix: np.ndarray,
kind: str,
resonances: np.ndarray | None = None,
geometry: dict[str, float] | None = None,
plane_wave_limit: float | None = None,
chain: SilencerChain | None = None,
)

Transmission and insertion loss of a reactive silencer over frequency.

Attributes

NameDescription
frequenciesFrequencies f, Hz.
transmission_lossTransmission loss per frequency, dB.
insertion_lossInsertion loss per frequency, dB, or None when no source/radiation impedance was supplied.
transfer_matrixThe compound (n_freq, 2, 2) four-pole matrix.
kindA short label of the device (e.g. "expansion chamber").
resonancesNotable resonance frequencies, Hz (e.g. the resonator tuning frequency), or None.
geometryThe defining geometry the constructor was called with (keys matching its keyword names, e.g. length/chamber_area/ pipe_area for a chamber), retained so plot_geometry can draw the device; appended after the original fields and None for hand-built results that were not assembled by a SilencerChain.
plane_wave_limitThe first higher-order-mode cut-on frequency of the widest cross section of the device, Hz (Norton & Karczub Eq. 7.6, phonometry.noise_control.duct_modes.plane_wave_limit). The four-pole algebra of this module is one-dimensional and is valid below it; above it several modes propagate at once and the result describes the plane-wave mode only, which is why a PlaneWaveWarning is raised when the analysis reaches past it. None for hand-built results that do not retain their geometry.
chainThe SilencerChain that assembled this result, for a result built by SilencerChain.result, and None otherwise. A chain is a list of four-pole elements rather than a named device, so it carries its geometry element by element instead of in geometry; plot_geometry draws whichever of the two is present.
ReactiveSilencerResult.plot(
ax: Axes | None = None,
*,
language: str = 'en',
**kwargs: Any,
) -> Axes

Plot the transmission (and insertion) loss against frequency.

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

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

Draw the silencer cross-section to scale (dimensioned side cut).

A named device is drawn from its geometry; a result assembled by a SilencerChain is drawn from that chain, duct by duct.

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

Parameters

NameDescription
axExisting axes, or None to create a figure.
languageLabel language, "en" (default) or "es".

Returns: The axes.

Raises

ExceptionWhen
ValueErrorIf the result retains neither its geometry nor the chain that built it.
ReactiveSilencerResult.report(
path: str,
*,
metadata: ReportMetadata | None = None,
engine: str = 'reportlab',
verbose: bool = False,
language: str = 'en',
) -> str

Render a reactive-silencer transmission-loss fiche to path.

Writes a one-page silencer-performance sheet: the method-basis line naming the plane-wave four-pole (transfer-matrix) method (Munjal, Acoustics of Ducts and Mufflers 2nd ed., Eq. (3.27); Bies, Hansen & Howard, Engineering Noise Control 5th ed., sections 8.8-8.9), an optional metadata header (client, device, test environment, instrumentation, climate, date), a per-band table (nominal frequency, the transmission loss TL and, when computed, the insertion loss IL) beside the TL (and IL) curves, the boxed mean transmission loss over the analysis bands with the peak transmission loss and the device kind, an optional verdict row against a declared minimum, and a method-basis strip stating the four-pole transmission-loss relation.

Parameters

NameDescription
pathDestination path of the PDF file.
metadataOptional ReportMetadata supplying the header (client, specimen the device, test_room the test environment, instrumentation, temperature, relative_humidity, pressure, test_date), the footer identity (laboratory, operator, report_id, notes) and, via requirement, a declared minimum mean transmission loss (more transmission loss is better).
engineRendering back end; only "reportlab" is supported.
verboseAccepted for signature symmetry with the other fiches; the silencer table already shows the insertion loss when it was computed.
languageFiche language: "en" (default) or "es".

Returns: The written path as a str.

Raises

ExceptionWhen
ValueErrorIf engine is not "reportlab" or language is unknown.
ImportErrorIf reportlab (or, for the figure, matplotlib) is not installed (pip install phonometry[report]).
shunt_matrix(branch_impedance: ArrayLike) -> _Complex

Four-pole matrix of a side branch of impedance Z_b (Bies Eq. (8.144)).

Parameters

NameDescription
branch_impedanceAcoustic impedance Z_b of the branch, Pa s/m3 (1-D complex array over frequency).

Returns: A (n_freq, 2, 2) complex transfer-matrix array.

SilencerChain(
frequencies: ArrayLike,
*,
speed_of_sound: float = 343.0,
density: float = 1.206,
)

A chain of four-pole elements that remembers the geometry it was given.

duct_matrix, shunt_matrix and cascade build any silencer layout the named devices do not cover, but they return bare matrices: the compound matrix of a hand-built chain is a stack of complex numbers, and nothing in it recalls that the first element was a 300 mm run of 200 mm duct. This class calls the same three functions and keeps the arguments, so the chain can be drawn (plot_geometry) as well as evaluated (result), and the drawing cannot drift from the model because one call produces both.

Elements are added in order from inlet to outlet, and each adder returns the chain so the calls read as the device does:

chain = (
SilencerChain(frequencies)
.duct(0.30, 0.0314)
.shunt(quarter_wave_impedance(frequencies, 0.686, 0.0079))
.duct(0.60, 0.1257)
.duct(0.30, 0.0314)
)

What the drawing may show follows from what the elements know. A duct is drawn to scale from its declared length and area; a shunt declares an impedance, which fixes no length, no area and no volume, so it is marked at the station where it joins the run and nothing about its shape is invented (see plot_geometry).

Parameters

NameDescription
frequenciesFrequencies f, Hz (1-D array), shared by every element of the chain.
speed_of_soundSpeed of sound c, m/s.
densityAir density rho, kg/m3.
SilencerChain.duct(length: float, area: float) -> SilencerChain

Append a straight duct of length L and area S.

Parameters

NameDescription
lengthDuct length L, m. A zero-length duct is the identity matrix, so it is neither computed against nor drawn.
areaCross-sectional area S, m2.

Returns: The chain, so the calls can be written one after another.

property

The recorded elements, in order from inlet to outlet.

Returns: The elements added so far.

property

The analysis frequencies shared by every element, Hz.

Returns: The frequency grid the chain was built on.

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

Draw the chain: its ducts to scale, its branch points marked.

Every duct is drawn at its declared length and equivalent circular diameter d = 2 sqrt(S / pi), so the runs, the area steps between them and the overall length are read off the page. A shunt element holds an impedance and no geometry at all, so it is not drawn as a stub of any length: it is marked with a leader at the station where it joins the run, carrying its label and, when the analysis grid resolves one, the frequency at which it comes closest to shorting the duct.

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

Parameters

NameDescription
axExisting axes, or None to create a figure.
languageLabel language, "en" (default) or "es".

Returns: The axes.

Raises

ExceptionWhen
ValueErrorIf the chain holds no duct of positive length, and so has no geometry and no scale to draw at.
SilencerChain.result(
*,
inlet_area: float,
outlet_area: float,
source_impedance: ArrayLike | None = None,
radiation_impedance: ArrayLike | None = None,
) -> ReactiveSilencerResult

Evaluate the chain into a ReactiveSilencerResult.

The port areas are the pipes the chain is connected between, which transmission_loss needs and the chain itself does not contain: put them in the chain as duct elements if the drawing is to show them.

Parameters

NameDescription
inlet_areaInlet pipe area S_in, m2.
outlet_areaOutlet pipe area S_out, m2.
source_impedanceOptional source impedance Z_s for the insertion loss, Pa s/m3.
radiation_impedanceOptional radiation impedance Z_r for the insertion loss, Pa s/m3.

Returns: The result, carrying a snapshot of this chain so that it can be drawn as well as plotted and reported.

Raises

ExceptionWhen
ValueErrorIf the chain is empty.
SilencerChain.shunt(
branch_impedance: ArrayLike,
*,
label: str | None = None,
) -> SilencerChain

Append a side branch of acoustic impedance Z_b.

The branch is the only element that can be given a label, because it is the only one the drawing cannot identify by its dimensions.

Parameters

NameDescription
branch_impedanceAcoustic impedance Z_b of the branch, Pa s/m3: one value per analysis frequency, or a scalar held constant over the grid.
labelWhat the branch is, e.g. "Helmholtz resonator, 125 Hz". Rendered verbatim in the drawing, in whatever language it is written in.

Returns: The chain, so the calls can be written one after another.

Raises

ExceptionWhen
ValueErrorIf branch_impedance is neither a scalar nor one value per analysis frequency.

property

The compound four-pole matrix of the chain.

Returns: The ordered product cascade makes of the element matrices, (n_freq, 2, 2).

Raises

ExceptionWhen
ValueErrorIf the chain is empty.
SilencerChainElement(
matrix: np.ndarray,
length: float | None = None,
area: float | None = None,
label: str | None = None,
shorting_frequency: float | None = None,
)

One recorded element of a SilencerChain.

The element carries its four-pole matrix and, with it, whatever geometry the call that produced the matrix was given. That is the whole asymmetry of a hand-built chain: duct_matrix is handed a length and an area, so a duct element knows its shape, while shunt_matrix is handed an impedance and nothing else, so a shunt element has no shape to know.

Attributes

NameDescription
matrixThe element’s (n_freq, 2, 2) four-pole matrix.
lengthDuct length L, m, or None for a shunt element.
areaDuct cross-sectional area S, m2, or None for a shunt element.
labelThe name the element was given, or None.
shorting_frequencyFor a shunt element, the analysis frequency at which |Z_b| is least (where the branch comes closest to shorting the duct), or None when that least value sits on an end of the analysis grid, and for every duct element.

property

Whether this is a duct element (an element with a declared area).

Returns: True for a duct element, False for a shunt element.

transmission_loss(
transfer_matrix: _Complex,
*,
inlet_area: float,
outlet_area: float,
speed_of_sound: float = 343.0,
density: float = 1.206,
) -> NDArray[np.float64]

Transmission loss of a four-pole element (Munjal Eq. (3.27), no flow).

with and (Munjal, Acoustics of Ducts and Mufflers 2nd ed., Eq. (3.27)). Do not “restore” the Bies Eq. (8.141) weighting: as printed there the equation fails the sudden-expansion limit for unequal port areas (see docs/ERRATA.md).

Parameters

NameDescription
transfer_matrixA (n_freq, 2, 2) compound matrix.
inlet_areaInlet pipe area S_in, m2.
outlet_areaOutlet pipe area S_out, m2.
speed_of_soundSpeed of sound c, m/s.
densityAir density rho, kg/m3.

Returns: The transmission loss per frequency, dB.