Module: vernastruct.modules.roofs.service.RoofDesignService with
code_profile="EC" (delegating to the VC-10-verified
vernastruct.codes.ec5.check_round_timber_beam_ec5)
Code basis: EN 1995-1-1 limit-state design of the secondary joists inside
the full roof workflow: load takeoff (t/m² layers → kN/m line loads, dead/live
kept separate for 1.35G + 1.5Q), smallest-passing-diameter selection, EN 338
characteristic strengths from the material library, EN 1998-3 confidence
factor. Completes the roof half of roadmap task 2.1.
Status: ✅ PASS — software matches hand calculation exactly.
A heritage roof re-joisted in imported pine, assessed to the Eurocode profile. This is the first case exercising the characteristic-strength data added to the timber library:
pine_imported → EN 338:2016 class C22 (f_m,k = 22 MPa, f_v,k = 3.8
MPa, E_0,mean = 10.0 GPa, ρ_k = 340 kg/m³ — values cross-checked against
the Holzforschung Austria dataholz.eu datasheet, which reproduces EN
338:2016 Table 1; E_0,mean matches the library's existing mean E).| Input | Symbol | Value |
|---|---|---|
| Dead load (roof layers) | D | 0.25 t/m² (25 cm × 1000 kg/m³ fill) |
| Live load | L | 150 kg/m² = 0.15 t/m² |
| Joist spacing | s | 0.40 m |
| Joist span | ℓ | 3.00 m |
| Timber self-weight | — | excluded (clean hand numbers) |
| Material | — | pine_imported = EN 338 C22 |
| Service class | — | 2 (moisture 12% ≤ 20%) → k_mod 0.80, k_def 0.80 |
| Load duration | — | medium |
| Deflection limits | — | w_inst ≤ ℓ/360, w_fin ≤ ℓ/240 (GUI defaults) |
| Knowledge level | — | KL3 → CF 1.00 |
Line loads (TON_TO_KN = 9.80665):
w_G = 0.25 × 0.40 × 9.80665 = 0.980665 kN/m
w_Q = 0.15 × 0.40 × 9.80665 = 0.588399 kN/m
w_d = 1.35 w_G + 1.5 w_Q = 2.206496 kN/m
First standard diameter d = 150 mm:
W = π·0.15³/32 = 3.31340×10⁻⁴ m³ I = π·0.15⁴/64 = 2.48505×10⁻⁵ m⁴
A = π·0.075² = 1.76715×10⁻² m²
M_d = w_d ℓ²/8 = 2.482308 kN·m V_d = w_d ℓ/2 = 3.309744 kN
σ_m,d = M_d/W = 7.4917 MPa
f_m,d = k_mod·k_h·f_m,k/γ_M = 0.80 × 1.0 × 22/1.3 = 13.5385 MPa (k_h = 1.0, d ≥ 150)
util_bending = 0.5534 ✓
τ_d = 4V_d/(3·k_cr·A) = 0.37272 MPa (k_cr = 0.67, §6.1.7 — added after VC-15)
f_v,d = 0.80 × 3.8/1.3 = 2.33846 MPa
util_shear = 0.1594 ✓
w_char = w_G + w_Q = 1.569064 kN/m (unfactored, characteristic combination)
w_inst = 5·w·ℓ⁴/(384·E·I) = 5×1569.064×81/(384×10×10⁹×2.48505×10⁻⁵)
= 6.6593 mm vs ℓ/360 = 8.333 mm → util 0.799 ✓
w_fin = w_inst(1 + k_def) = 6.6593 × 1.8 = 11.9868 mm
vs ℓ/240 = 12.500 mm → util 0.9589 ✓ ← GOVERNS
Selection: d = 150 mm passes all four checks → chosen (smallest first). Governing utilization 0.959, final (creep) deflection.
Iteration variant (span 4.0 m, same loads): 150 mm fails w_inst (21.05 > 11.11 mm), 180 mm fails w_fin (18.27 > 16.67 mm), 200 mm passes → service must report candidates [150, 180, 200] and choose 200.
RoofDesignService().design(...) with code_profile="EC" reproduces every
number above to the stated precision (tests/test_codes.py::
test_vc12_roof_service_ec5_matches_hand_calc and
::test_vc12_ec5_selection_iterates_diameters, pinned as regression tests).
Companion tests verify: KL2 divides strength (not stiffness) by 1.20;
derived-species designs are forced to CF = 1.35 with an explanatory warning;
the default NDS profile is untouched; single-module PDF/Excel reports render
the EN 1995-1-1 table.
Every case in this manual is pinned as an automated regression test that runs on every build — no future change can silently break a verified result. © 2026 Hesham Salama.