<!-- canonical: https://jmrplens.github.io/phonometry/buildings/design/insulation-prediction/ -->
Source: https://jmrplens.github.io/phonometry/buildings/design/insulation-prediction/

# Predicting Sound Insulation (EN 12354)

A laboratory rating describes an element in isolation; a building also
transmits sound along every flanking path. This page covers the EN 12354
prediction of in-situ performance between rooms from laboratory element data:
the airborne model of EN 12354-1 with its junction vibration reduction
indices, the impact model of EN 12354-2 and the prediction fiches of both. The
third and fourth parts of the same family, which cross the building envelope
instead of an internal partition, are in
[Façade Sound Insulation](https://jmrplens.github.io/phonometry/buildings/insulation/facade-insulation/). The measured quantities the
model is checked against live in
[Field Insulation Measurement (ISO 16283)](https://jmrplens.github.io/phonometry/buildings/insulation/insulation-field/); the
laboratory inputs come from
[Laboratory Insulation Measurement](https://jmrplens.github.io/phonometry/buildings/insulation/insulation-lab/).

## Predicting performance (EN 12354)

A laboratory rating describes an element in isolation, yet the sound a building
actually transmits also travels *around* the partition (along the floor, up the
façade, through the flanking walls), re-radiating into the receiving room. This
**flanking transmission** is the whole difference between the laboratory $R$ and
the field $R'$. EN 12354 predicts the in-situ apparent rating from the
laboratory ratings of the elements plus the vibration transmission of their
junctions.

<picture><source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/jmrplens/phonometry/main/.github/images/diagram_flanking_paths_dark.svg"><img src="https://raw.githubusercontent.com/jmrplens/phonometry/main/.github/images/diagram_flanking_paths.svg" alt="The direct path Dd through the separating element and the three flanking paths Ff, Df and Fd across each junction between a flanking element and the separating element" width="92%"></picture>

Each junction between a flanking element and the separating element carries
three paths, $Ff$ (flanking→flanking), $Df$ (direct→flanking) and $Fd$
(flanking→direct), alongside the single direct path $Dd$.

<picture><source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/jmrplens/phonometry/main/.github/images/anim_flanking_paths_dark.gif"><img src="https://raw.githubusercontent.com/jmrplens/phonometry/main/.github/images/anim_flanking_paths.gif" alt="Animation: energy pulses leave the source room over the direct Dd path and the flanking Ff, Fd and Df paths, shrinking at each element and junction, and every path label lights up as its pulse re-radiates into the receiving room" width="640" height="360" loading="lazy"></picture>

[Watch the high-resolution video (WebM)](https://raw.githubusercontent.com/jmrplens/phonometry/main/.github/images/anim_flanking_paths.webm)

The **simplified single-number model** combines them energetically (Formula 26):

$$
R'_\mathrm{w} = -10 \log_{10}\Big[ 10^{-R_\mathrm{Dd,w}/10}
      + \sum 10^{-R_\mathrm{Ff,w}/10} + \sum 10^{-R_\mathrm{Df,w}/10}
      + \sum 10^{-R_\mathrm{Fd,w}/10} \Big],
$$

with the direct path $R_\mathrm{Dd,w} = R_\mathrm{s,w} + \Delta R_\mathrm{Dd,w}$ (Formula 27) and each
flanking path (Formula 28a)

$$
R_{ij,\mathrm{w}} = \tfrac{R_{i,\mathrm{w}} + R_{j,\mathrm{w}}}{2} + \Delta R_{ij,\mathrm{w}} + K_{ij}
         + 10 \log_{10}\frac{S_\mathrm{s}}{l_0\ l_\mathrm{f}},
$$

where $l_0 = 1$ m is the reference coupling length, $l_\mathrm{f}$ the junction coupling
length and $K_{ij}$ the junction's **vibration reduction index** (Annex E,
empirical in the mass ratio $M = \log_{10}(m'_{\perp,i}/m'_i)$).

<picture><source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/jmrplens/phonometry/main/.github/images/prediction_flanking_demo_dark.svg"><img src="https://raw.githubusercontent.com/jmrplens/phonometry/main/.github/images/prediction_flanking_demo.svg" alt="Per-path sound reduction indices for the EN 12354-1 Annex H.3 example and each path's share of the transmitted energy, showing the direct path dominating at R'w = 52 dB" width="80%"></picture>

```python
import numpy as np
from phonometry import building

# EN 12354-1 Annex H.3: a separating wall Rs,w = 57 dB, area Ss = 11.5 m², with
# four flanking elements. The simplified model reads each junction's Kij at
# 500 Hz from the mass ratio m'perp / m' (Annex E) — here the floor's rigid
# cross-junction (the mass ratio is itself rounded, hence 12.5 vs Annex 12.4):
print(round(building.junction_vibration_reduction("rigid_cross", "through", 1.61), 1))  # 12.5  KFf
print(round(building.junction_vibration_reduction("rigid_cross", "corner",  1.61), 1))  #  8.9  KFd = KDf

# Build each element's three flanking paths (Ff, Df, Fd) from the Annex H
# tabulated Kij, then combine the direct path Dd energetically (Formula 26).
elements = [   # (name, Rw, KFf, KFd = KDf, coupling length lf)
    ("floor",    49, 12.4,  8.9, 4.50),
    ("ceiling",  46, 14.4,  9.2, 4.50),
    ("facade",   42, 12.6,  6.7, 2.55),
    ("int-wall", 33, 33.5, 15.7, 2.55),
]
paths = []
for name, rw, k_ff, k_fd, lf in elements:
    paths += building.flanking_element(label=name, r_flanking=rw, r_separating=57,
                              k_ff=k_ff, k_fd=k_fd, k_df=k_fd,
                              separating_area=11.5, coupling_length=lf)

res = building.predicted_airborne_insulation(r_direct=57.0, flanking_paths=paths)
print(round(res.r_prime_w, 1))                          # 52.2  ->  R'w = 52 dB
print(res.dominant.label, round(res.dominant.fraction, 2))   # Dd 0.33 (direct dominates)

res.plot()   # per-path share of the transmitted energy, largest first (needs matplotlib)
```

<details>
<summary>Show the code for this figure</summary>

```python
import matplotlib.pyplot as plt
from phonometry import building

# Build each element's three flanking paths (Ff, Df, Fd) from the Annex H
# tabulated Kij, then combine the direct path Dd energetically (Formula 26).
elements = [   # (name, Rw, KFf, KFd = KDf, coupling length lf)
    ("floor",    49, 12.4,  8.9, 4.50),
    ("ceiling",  46, 14.4,  9.2, 4.50),
    ("facade",   42, 12.6,  6.7, 2.55),
    ("int-wall", 33, 33.5, 15.7, 2.55),
]
paths = []
for name, rw, k_ff, k_fd, lf in elements:
    paths += building.flanking_element(label=name, r_flanking=rw, r_separating=57,
                              k_ff=k_ff, k_fd=k_fd, k_df=k_fd,
                              separating_area=11.5, coupling_length=lf)
res = building.predicted_airborne_insulation(r_direct=57.0, flanking_paths=paths)

# Per-path sound reduction index and each path's share of the transmitted
# energy for the Annex H.3 result computed above.
labels = [p.label for p in res.paths]
r_w = [p.r_w for p in res.paths]
frac = [100.0 * p.fraction for p in res.paths]

fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(9, 6), sharex=True)
ax1.bar(labels, r_w, color="tab:blue")
ax1.axhline(res.r_prime_w, ls="--", color="k", label=f"R'w = {res.r_prime_w:.1f} dB")
ax1.set_ylabel("Path Rij,w [dB]"); ax1.legend()
ax2.bar(labels, frac, color="tab:orange")
ax2.set_ylabel("Energy share [%]"); ax2.set_xlabel("Transmission path")
for ax in (ax1, ax2):
    ax.tick_params(axis="x", rotation=45)
fig.suptitle("EN 12354-1 Annex H.3 — flanking transmission")
fig.tight_layout()
plt.show()
```

</details>

Every added flanking path strictly lowers $R'_\mathrm{w}$ below the direct $R_\mathrm{Dd,w} = 57$;
`res.paths` exposes each path's share of the transmitted energy so the dominant
path is visible. `flanking_element` is a convenience that builds one junction's
three paths at once; the single-path constructor behind it, `flanking_path`,
builds one `Ff`, `Df` or `Fd` path at a time (Formula 28a). Clause 4.4.2 also
enforces a floor $K_{ij} \ge K_{ij,\min}$ from the junction geometry
(Formula 29). Pass the flanking-element area to
`flanking_element(..., flanking_area=...)` and the clamp is applied
automatically per path; or compute the floor yourself with
`junction_min_vibration_reduction` and pass it to
`flanking_path(..., kij_min=...)`, which raises a below-floor $K_{ij}$ to the
minimum:

```python
from phonometry import building
# Kij,min = 10 lg[lf·l0·(1/Si + 1/Sj)]; large elements give a low (here negative)
# floor, so a realistic tabulated Kij is rarely clamped; but small, light
# elements can push it above the tabulated value (e.g. lf = 4 m, S = 1.5 m²
# gives 7.3 dB, over the 5 dB lightweight floor).
print(round(building.junction_min_vibration_reduction(coupling_length=4.5,
                                             s_i=11.5, s_j=11.5), 1))     # -1.1
```

The impact counterpart (EN 12354-2, Formula 21) is a direct subtraction:
$L'_\mathrm{n,w} = L_\mathrm{n,w,eq} - \Delta L_\mathrm{w} + K$, with the bare-floor equivalent level
$L_\mathrm{n,w,eq} = 164 - 35 \log_{10}(m'/m'_0)$ (Annex B), the covering improvement
$\Delta L_\mathrm{w}$ (ISO 717-2) and the flanking correction $K$ from Table 1.

```python
from phonometry import building

# EN 12354-2 Annex E.3: a 0.14 m concrete floor (m' = 322 kg/m²) with a floating
# floor (ΔLw = 33 dB), rooms one above the other, mean flanking mass 145 kg/m².
ln_eq = building.equivalent_impact_level(322.0)                   # 164 - 35 lg(m')
k = building.impact_flanking_correction(322.0, 145.0)             # Table 1 (sep 322, flk 145)
imp = building.predicted_impact_insulation(ln_w_eq=ln_eq, delta_l_w=33.0, k_correction=k)
print(round(ln_eq, 1), k, round(imp.l_prime_n_w, 1))     # 76.2 2 45.2  ->  L'n,w = 45 dB

# Exact Formula (3): L'nT,w = L'n,w - 10 lg(0.032 V). Annex E.3's own rounding
# of the factor to 10 lg(V/30) sits 0.18 dB below; both give L'nT,w = 43 dB.
print(round(building.standardized_impact_level(imp.l_prime_n_w, 50.0), 1))   # 43.2  L'nT,w

imp.plot()   # the Formula (21) terms as bars: Ln,w,eq - dLw + K -> L'n,w (needs matplotlib)
```

<picture><source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/jmrplens/phonometry/main/.github/images/impact_prediction_terms_dark.svg"><img src="https://raw.githubusercontent.com/jmrplens/phonometry/main/.github/images/impact_prediction_terms.svg" alt="The EN 12354-2 Annex E.3 impact prediction as its Formula 21 terms: the bare-floor equivalent level of 76.2 dB, the minus 33 dB floating-floor improvement, the plus 2 dB flanking correction, and the resulting predicted apparent impact level of 45.2 dB" width="80%"></picture>

*The whole EN 12354-2 simplified model is one subtraction: the massive bare
floor starts at $L_\mathrm{n,w,eq} = 76.2$ dB, the floating floor buys back 33 dB,
and the flanking correction returns 2 dB, landing at $L'_\mathrm{n,w} = 45$ dB.*

<details>
<summary>Show the code for this figure</summary>

```python
import matplotlib.pyplot as plt
import numpy as np
from phonometry import building

# EN 12354-2 Annex E.3: 0.14 m concrete floor (m' = 322 kg/m2), floating
# floor delta-Lw = 33 dB, mean flanking mass 145 kg/m2.
ln_eq = building.equivalent_impact_level(322.0)
k = building.impact_flanking_correction(322.0, 145.0)
imp = building.predicted_impact_insulation(ln_w_eq=ln_eq, delta_l_w=33.0,
                                           k_correction=k)

# One line — the Formula (21) terms as bars:
imp.plot()
plt.show()

# By hand, from the result's fields:
labels = ["Ln,w,eq", "-dLw", "+K", "L'n,w"]
values = [imp.ln_w_eq, -imp.delta_l_w, imp.k_correction, imp.l_prime_n_w]
fig, ax = plt.subplots()
ax.bar(np.arange(4), values)
ax.axhline(0.0, color="k", lw=0.8)
ax.set_xticks(np.arange(4), labels)
ax.set_ylabel("Level / correction [dB]")
ax.set_title(f"L'n,w = {imp.l_prime_n_w:.1f} dB (EN 12354-2 Annex E.3)")
plt.show()
```

</details>

The airborne counterpart of that closure is Formula (5b),
$D_\mathrm{nT} = R' + 10\log_{10}(0.32\,V/S_\mathrm{s})$, exposed as `standardized_level_difference`;
it closes the Annex H.3 example (`standardized_level_difference(52.2, 50.0,
11.5)` gives 53.6 dB, the printed $V/(3S)$ chain 53.8 dB, both rounding to
$D_\mathrm{nT,w} = 54$ dB).

The three insulation guides close a loop: the
[laboratory](https://jmrplens.github.io/phonometry/buildings/insulation/insulation-lab/) measures $R$ and $K_{ij}$ element by element
and junction by junction, this model assembles them into a predicted $R'_\mathrm{w}$,
and the [field measurement](https://jmrplens.github.io/phonometry/buildings/insulation/insulation-field/) checks the built result.
When the measured value lands well below the prediction, look for a
construction defect on the dominant path the model reports: a rigid bridge
across a resilient junction, a missing lining, a leak around the separating
element.

### `junction_vibration_reduction()` / `flanking_element()` parameters

| Parameter | Type | Units | Range / default | Notes |
| :--- | :--- | :--- | :--- | :--- |
| `junction_type` | str | — | `'rigid_cross'` / `'rigid_t'` / `'flexible_t'` / `'lightweight_facade'` / `'lightweight_double_homogeneous'` / `'lightweight_double_coupled'` / `'corner'` / `'thickness_change'` | Junction geometry (Annex E.3-E.9) |
| `path` | str | — | `'through'` ($K_{13}$) / `'corner'` ($K_{12} = K_{23}$) / `'double_leaf'` ($K_{24}$) | Path branch |
| `mass_ratio` | float | — | > 0 | $m'_{\perp,i}/m'_i$ (Formula E.2) |
| `frequency` | float | Hz | default `500` | `flexible_t` and the E.7/E.8 double-leaf junctions are frequency-dependent |
| `r_flanking` / `r_separating` | float | dB | — | Weighted indices of the flanking / separating element |
| `k_ff` / `k_fd` / `k_df` | float | dB | — | Junction $K_{ij}$ for the three paths |
| `separating_area` | float | m² | > 0 | Separating-element area $S_\mathrm{s}$ |
| `coupling_length` | float | m | > 0 | Junction coupling length $l_\mathrm{f}$ |
| `delta_r_ff` / `delta_r_fd` / `delta_r_df` | float | dB | default `0` | Lining improvements per path |
| `flanking_area` | float | m² | default `None` | Flanking-element area $S_\mathrm{F}$; enables the automatic $K_{ij,\min}$ clamp (Clause 4.4.2 / Formula 29) |

### `flanking_path()` parameters

| Parameter | Type | Units | Range / default | Notes |
| :--- | :--- | :--- | :--- | :--- |
| `label` | str | — | — | Display name of the path |
| `kind` | str | — | `'Ff'` / `'Df'` / `'Fd'` | Which flanking branch the path is |
| `r_source` / `r_receive` | float | dB | — | Weighted indices of the source-side / receive-side elements |
| `k_ij` | float | dB | — | Junction vibration-reduction index for this path |
| `separating_area` | float | m² | > 0 | Separating-element area $S_\mathrm{s}$ |
| `coupling_length` | float | m | > 0 | Junction coupling length $l_\mathrm{f}$ |
| `delta_r` | float | dB | default `0` | Lining improvement on this path |
| `kij_min` | float | dB | default `None` | When given, `k_ij` is floored at this Formula (29) minimum |

`predicted_airborne_insulation()` returns an `AirbornePredictionResult`
(`r_prime_w`, `r_direct_w`, `paths` of `PathContribution`, `dominant`);
`predicted_impact_insulation()` an `ImpactPredictionResult` (`l_prime_n_w`,
`ln_w_eq`, `delta_l_w`, `k_correction`). The simplified model carries a reported
standard deviation of about 2 dB (Clause 5).

### EN 12354 prediction report (`.report()`)

Both prediction results write a one-page **prediction** report through a
`report(path)` method. Unlike the measurement fiches, the reported result is an
*estimate* of the in-situ performance from the elements' laboratory data plus
the flanking transmission across the junctions; the sheet states this
explicitly and is labelled a prediction, never a measurement.
`AirbornePredictionResult.report()` renders the predicted apparent sound
reduction index fiche (the transmission-path table beside the per-path
share-of-energy plot, the boxed $R'_\mathrm{w}$); `ImpactPredictionResult.report()`
renders the predicted apparent impact-level fiche (the Formula (21) term table
beside the term plot, the boxed $L'_\mathrm{n,w}$). Each names EN/ISO 12354-1/-2 and the
ISO 717 rating part in its basis line, prints the model's ~2 dB standard
deviation and, when a `requirement` is supplied, adds a PASS/FAIL verdict
(airborne passes at or above it, impact at or below it). `verbose=True` annexes
each transmission path's share of the transmitted energy to the airborne table;
metadata, `language="es"` and the `phonometry[report]` extra behave as in the
measurement fiches.

```python
from phonometry import building, ReportMetadata

# Airborne prediction (EN 12354-1 Annex H.3): a separating wall Rs,w = 57 dB
# flanked by four elements -> R'w = 52 dB.
paths = []
for label, rw, kff, kfd, lf in [
    ("floor", 49.0, 12.4, 8.9, 4.5), ("ceiling", 46.0, 14.4, 9.2, 4.5),
    ("facade", 42.0, 12.6, 6.7, 2.55), ("intwall", 33.0, 33.5, 15.7, 2.55),
]:
    ff, df, fd = building.flanking_element(
        label=label, r_flanking=rw, r_separating=57.0,
        k_ff=kff, k_fd=kfd, k_df=kfd, separating_area=11.5, coupling_length=lf)
    paths += [ff, df, fd]
air = building.predicted_airborne_insulation(r_direct=57.0, flanking_paths=paths)
air.report("Rpw_prediction.pdf", metadata=ReportMetadata(
    specimen="Separating wall, Rs,w = 57 dB", area=11.5,
    source_volume=53.0, receiving_volume=50.0, requirement=50.0,
    notes="Flanking: floor/ceiling/facade/internal wall."))   # R'w = 52 dB

# Impact prediction (EN 12354-2 Annex E.3): a concrete floor (m' = 322 kg/m2)
# with a floating floor (DLw = 33 dB) -> L'n,w = 45 dB.
ln_eq = building.equivalent_impact_level(322.0)
k = building.impact_flanking_correction(322.0, 145.0)
imp = building.predicted_impact_insulation(ln_w_eq=ln_eq, delta_l_w=33.0, k_correction=k)
imp.report("Lnw_prediction.pdf",
           metadata=ReportMetadata(mass_per_area=322.0, requirement=53.0))  # L'n,w = 45 dB
```

[![Predicted airborne EN 12354-1 example report: metadata header, the transmission-path table beside the per-path share-of-energy chart, boxed predicted R'w = 52 dB, the prediction statement and a PASS verdict](https://raw.githubusercontent.com/jmrplens/phonometry/main/.github/reports/iso12354_airborne_prediction_example.webp)](https://raw.githubusercontent.com/jmrplens/phonometry/main/.github/reports/iso12354_airborne_prediction_example.pdf)

[![Predicted impact EN 12354-2 example report: metadata header, the Formula (21) term table beside the term chart, boxed predicted L'n,w = 45 dB, the prediction statement and a PASS verdict against the 53 dB requirement](https://raw.githubusercontent.com/jmrplens/phonometry/main/.github/reports/iso12354_impact_prediction_example.webp)](https://raw.githubusercontent.com/jmrplens/phonometry/main/.github/reports/iso12354_impact_prediction_example.pdf)

## Across the envelope: Parts 3 and 4

The two remaining parts of EN 12354 predict the same way but across the
building envelope rather than between two rooms: EN 12354-3 the airborne
insulation against outdoor sound, EN 12354-4 the sound power an indoor source
radiates outwards. Both are built on the same area-weighted summation of
element transmission factors used above, and both are covered, beside the
ISO 16283-3 measurement they are compared against, in
[Façade Sound Insulation](https://jmrplens.github.io/phonometry/buildings/insulation/facade-insulation/).

## References

- Hopkins, C. (2007). *Sound insulation*. Butterworth-Heinemann.
  ISBN 978-0-7506-6526-1.
  [doi:10.4324/9780080550473](https://doi.org/10.4324/9780080550473).
  The full treatment of flanking transmission and the EN 12354 prediction
  framework, from the vibration reduction index to its statistical basis.

## Standards

EN 12354-1:2000 and EN 12354-2:2000, which give the simplified
flanking-transmission predictions between rooms (Annex E junctions, worked
examples H.3 and E.3). The façade and outdoor-radiation predictions of
EN 12354-3:2000 and EN 12354-4:2000 have their own page, and the absorption
member of the family is EN 12354-6.

**Not covered.** The *detailed* per-band models of both parts are a separate
page, [Detailed per-band prediction (ISO 12354)](https://jmrplens.github.io/phonometry/buildings/design/detailed-prediction/): the
same standard run band by band, with the laboratory element and junction data
converted to their in-situ values before the paths are formed. Use the
simplified model here when only the weighted element ratings are known and the
question is whether the room passes; use the detailed one when the element
spectra exist and the question is which path sets which band. The element
inputs themselves — $R_\mathrm{w}$, $\Delta R_\mathrm{w}$, $\Delta L_\mathrm{w}$, mass per unit area —
are taken as given, from laboratory data or from the mass-law estimates of
[Predicting panel sound insulation](https://jmrplens.github.io/phonometry/buildings/design/panel-sound-insulation/). **EN 12354-5**
(service equipment) is in
[Installed structure-borne sound](https://jmrplens.github.io/phonometry/buildings/design/installed-structure-borne/).

## See also

- [Façade Sound Insulation](https://jmrplens.github.io/phonometry/buildings/insulation/facade-insulation/): the EN 12354-3 and
  EN 12354-4 predictions across the building envelope, with the ISO 16283-3
  measurement they are compared against.
- [Field Insulation Measurement (ISO 16283)](https://jmrplens.github.io/phonometry/buildings/insulation/insulation-field/):
  the measured in-situ quantities the prediction is checked against.
- [Insulation Ratings (ISO 717)](https://jmrplens.github.io/phonometry/buildings/insulation/insulation-ratings/): the reference-curve
  engine behind the predicted $R'_\mathrm{w}$ and $L'_\mathrm{n,w}$.
- [Laboratory Insulation Measurement](https://jmrplens.github.io/phonometry/buildings/insulation/insulation-lab/): the
  ISO 10140 ratings the model consumes.
- [Laboratory Flanking Transmission (ISO 10848)](https://jmrplens.github.io/phonometry/buildings/insulation/flanking-lab/): the
  measured junction vibration reduction index $K_{ij}$ the model consumes.
- [Sound absorption in enclosed spaces (EN 12354-6)](https://jmrplens.github.io/phonometry/buildings/rooms/enclosed-space-absorption/):
  the absorption member of the same EN 12354 family.
- [Dynamic stiffness of resilient materials (EN 29052-1)](https://jmrplens.github.io/phonometry/materials/resilient/dynamic-stiffness/):
  the $s'$ input to the EN 12354-2 floating-floor term.
- API reference: [`building.prediction.simplified_model`](https://jmrplens.github.io/phonometry/reference/api/building/simplified-model/) and [`building.prediction.facade`](https://jmrplens.github.io/phonometry/reference/api/building/facade/).
