Skip to content

Instantly share code, notes, and snippets.

@jsb2505
Last active April 22, 2024 09:43
Show Gist options
  • Save jsb2505/fd9f617d82fbdf71839b3a8b11e4db54 to your computer and use it in GitHub Desktop.
Save jsb2505/fd9f617d82fbdf71839b3a8b11e4db54 to your computer and use it in GitHub Desktop.
A gist of concrete lambda functions to BS EN 1992-1-1 and UK National Annex (Eurocode 2)
/**Poisson's ratio of concrete.
Ref: EC2 §3.1.3(4)
*/
Get_Poissons_Ratio = LAMBDA([isCracked],
LET(
_isCracked, IF(ISOMITTED(isCracked), FALSE, isCracked),
IF(_isCracked,
0, //for cracked concrete
0.2 //for uncracked concrete
)
)
);
/**Shear modulus of concrete (in the elastic range), in GPa.
*/
Get_Shear_Modulus = LAMBDA(E_Gpa, poissons_ratio,
E_Gpa / (2 * (1 + poissons_ratio))
);
/**Strain at peak stress (when σc = f_cm) from the 'schematic' representation of stress-strain relation for structural analysis.
Ref: EC2 §Table 3.1 & Fig 3.2
*/
Get_ε_c1 = LAMBDA(f_ck,
LET(
f_cm, Get_f_cm(f_ck),
MIN(0.7 * f_cm^0.31, 2.8)
)
);
/**Ultimate strain from the 'schematic' representation of stress-strain relation for structural analysis.
Ref: EC2 §Table 3.1 & Fig 3.2
*/
Get_ε_cu1 = LAMBDA(f_ck,
LET(
f_cm, Get_f_cm(f_ck),
IF(f_ck >= 50,
2.8 + 27 * ((98 - f_cm) / 100)^4,
3.5
)
)
);
/**Strain at maximum strength (when σc = f_ck) from the 'parabola-rectangle' representation of stress-strain relation for structural analysis.
Ref: EC2 §Table 3.1 & Fig 3.3
*/
Get_ε_c2 = LAMBDA(f_ck,
IF(f_ck >= 50,
2 + 0.085 * (f_ck - 50)^0.53,
2
)
);
/**Ultimate strain from the 'parabola-rectangle' representation of stress-strain relation for structural analysis.
Ref: EC2 §Table 3.1 & Fig 3.3
*/
Get_ε_cu2 = LAMBDA(f_ck,
IF(f_ck >= 50,
2.6 + 35 * ((90 - f_ck) / 100)^4,
3.5
)
);
/**Strain at maximum strength (when σc = f_ck) from the 'bi-linear' representation of stress-strain relation for structural analysis.
Ref: EC2 §Table 3.1 & Fig 3.4
*/
Get_ε_c3 = LAMBDA(f_ck,
IF(f_ck >= 50,
1.75 + 0.55 * (f_ck - 50)/40,
1.75
)
);
/**Ultimate strain from the 'bi-linear' representation of stress-strain relation for structural analysis.
Ref: EC2 §Table 3.1 & Fig 3.4
*/
Get_ε_cu3 = LAMBDA(f_ck,
IF(f_ck >= 50,
2.6 + 35 * ((90 - f_ck) / 100)^4,
3.5
)
);
/**Target mean cylinder strength at 28 days, in MPa.
Ref: EC2 §Table 3.1
*/
Get_f_cm = LAMBDA(f_ck_28days, f_ck_28days + 8);
/**Target mean cylinder strength (at time t in days), in MPa.
Ref: EC2 §3.1.2(6)(3.1)
*/
Get_f_cm_t = LAMBDA(f_ck_28days, [time_in_days], [cement_class],
LET(
f_ck, f_ck_28days,
f_cm, Get_f_cm(f_ck),
t, IF(ISOMITTED(time_in_days), 28, time_in_days),
_cement_class, IF(ISOMITTED(cement_class), "", cement_class),
β_cc_t, Get_β_cc_t(t, _cement_class),
β_cc_t * f_cm
)
);
/**Cement class type based on binder type and percent or CEM
Ref: §3.6 'Properties of Concrete for use in Eurocode 2' The Concrete Centre.
*/
Get_Cement_Class = LAMBDA([binder_type], [binder_percent], [CEM],
LET(
_binder_type, IF(ISOMITTED(binder_type), "", UPPER(binder_type)),
_binder_percent, IF(ISOMITTED(binder_percent), 0, binder_percent),
_CEM, IF(ISOMITTED(CEM), "", UPPER(CEM)),
IFS(
_binder_type = "GGBS",
IF(_binder_percent < 35, "R",
IF(_binder_percent < 65, "N", "S")
),
OR(_binder_type = "PULVERISED FLY ASH", _binder_type = "PULVERISED FUEL ASH", _binder_type = "FLY ASH", _binder_type = "FUEL ASH", _binder_type = "FA", _binder_type = "PFA"),
IF(_binder_percent < 20, "R",
IF(_binder_percent < 35, "N", "S")
),
OR(_CEM = "CEM 42.5R", _CEM = "CEM 52.5N", _CEM = "CEM 52.5R"), "R",
OR(_CEM = "CEM 32.5R", _CEM = "CEM 42.5N",), "N",
_CEM = "CEM 32.5N", "S",
TRUE, "R"
)
)
);
/**Time strength coefficient.
Ref: EC2 §3.1.2(6)(3.2)
*/
Get_β_cc_t = LAMBDA([time_in_days], [cement_class],
LET(
t, IF(ISOMITTED(time_in_days), 28, time_in_days),
_cement_class, IF(OR(ISOMITTED(cement_class), cement_class = ""), "R", UPPER(cement_class)),
s, IFS(
_cement_class = "R", 0.2,
_cement_class = "N", 0.25,
_cement_class = "S", 0.38
),
EXP(s * (1 - SQRT(28 / t)))
)
);
/**Characterisitic cube strength of concrete at 28 days, in MPa.
Returns f_ck_cube from a concrete grade string given in the format "Cxx/xx"
*/
Get_f_ck_cube = LAMBDA(concrete_grade,
VALUE(TEXTAFTER(concrete_grade,"/"))
);
/**Characterisitic clinder strength of concrete at 28 days, in MPa.
Returns f_ck from a concrete grade string given in the format "Cxx/xx"
*/
Get_f_ck = LAMBDA(concrete_grade,
VALUE(TEXTBEFORE(TEXTAFTER(UPPER(concrete_grade),"C"),"/"))
);
/**Characterisitic cylinder strength of concrete (at time t in days), in MPa.
Ref: EC2 §3.1.2(5)
*/
Get_f_ck_t = LAMBDA(f_ck_28days, time_in_days, [cement_class],
LET(
f_ck, f_ck_28days,
t, time_in_days,
_cement_class, IF(ISOMITTED(cement_Class), "", cement_class),
IFS(
t >= 28, f_ck,
t < 3, "Testing required",
t >= 3, Get_f_cm_t(f_ck, t, _cement_class) - 8
)
)
);
/**Mean tensile strength at 28 days, in MPa.
Ref: EC2 §Table3.1
*/
Get_f_ctm = LAMBDA(f_ck_28days,
LET(
f_ck, f_ck_28days,
IF(
f_ck <= 50,
0.3 * f_ck ^ (2 / 3),
LET(
f_cm, Get_f_cm(f_ck),
2.12 * LN(1 + (f_cm / 10))
)
)
)
);
/**Mean tensile strength (at time t in days), in MPa.
Ref: EC2 §3.1.2(9)(3.4)
*/
Get_f_ctm_t = LAMBDA(f_ck_28days, [time_in_days], [cement_class],
LET(
f_ck, f_ck_28days,
t, IF(ISOMITTED(time_in_days), 28, time_in_days),
_cement_class, IF(ISOMITTED(cement_class), "", cement_class),
α, IF(t < 28, 1, 2/3),
β_cc_t, Get_β_cc_t(t, _cement_class),
f_ctm, Get_f_ctm(f_ck),
f_ctm * β_cc_t^α
)
);
/**Mean flexural tensile strength, in MPa.
Ref: EC2 §3.1.8(1)(3.23)
*/
Get_f_ctm_fl = LAMBDA(section_height_mm, f_ctm,
LET(
h, section_height_mm,
f_ctm * MAX(
1.6 - h / 1000,
1
)
)
);
/**Characteristic tensile strength of concrete (5% fractile), in MPa.
Ref: EC2 §Table 3.1
*/
Get_f_ctk_005 = LAMBDA(f_ctm, 0.7 * f_ctm);
/**Characteristic tensile strength of concrete (95% fractile), in MPa.
Ref: EC2 §Table 3.1
*/
Get_f_ctk_095 = LAMBDA(f_ctm, 1.3 * f_ctm);
/**Design yield strength of reinforcement steel, in MPa.
Ref: EC2 §3.2.7, Fig 3.8
*/
Get_f_yd = LAMBDA(f_yk, [γ_s],
LET(
_γ_s, IF(ISOMITTED(γ_s), 1.15, γ_s),
f_yk / _γ_s
)
);
/**Design compressive strength of concrete, in MPa.
Ref: EC2 §3.1.6(1)P(3.15)
*/
Get_f_cd = LAMBDA(f_ck, [α_cc], [γ_c],
LET(
_α_cc, IF(ISOMITTED(α_cc), 0.85, α_cc),
_γ_c, IF(ISOMITTED(γ_c), 1.5, γ_c),
_α_cc * f_ck / _γ_c
)
);
/**Design tensile strength of concrete, in MPa.
Ref: EC2 §3.1.6(2)P(3.16)
*/
Get_f_ctd = LAMBDA(f_ctk_005, [α_ct], [γ_c],
LET(
_α_ct, IF(ISOMITTED(α_ct), 1, α_ct),
_γ_c, IF(ISOMITTED(γ_c), 1.5, γ_c),
_α_ct * f_ctk_005 / _γ_c
)
);
/**Design tensile strength of concrete (at time t in days), in MPa.
Ref: EC2 §8.10.2.2(8.15)
*/
Get_f_ctd_t = LAMBDA(f_ctm_t, [α_ct], [γ_c],
LET(
_α_ct, IF(ISOMITTED(α_ct), 1, α_ct),
_γ_c, IF(ISOMITTED(γ_c), 1.5, γ_c),
_α_ct * 0.7 * f_ctm_t / _γ_c
)
);
/**Mean secant modulus of elasticity of concrete at 28 days, in GPa.
Ref: EC2 §Table 3.1
*/
Get_E_cm = LAMBDA(f_ck_28days, [aggregate_type],
LET(
f_ck, f_ck_28days,
f_cm, Get_f_cm(f_ck),
_aggregate_type, IF(ISOMITTED(aggregate_type), "", LOWER(aggregate_type)),
mod_factor, IFS(
_aggregate_type = "", 1,
_aggregate_type = "quartzite", 1,
_aggregate_type = "limestone", 0.9,
_aggregate_type = "sandstone", 0.7,
_aggregate_type = "basalt", 1.2
),
mod_factor * 22 * (f_cm / 10)^0.3
)
);
/**Mean secant modulus of elasticity of concrete (at time t in days), in GPa.
Ref: EC2 §3.1.3(3)(3.5)
*/
Get_E_cm_t = LAMBDA(f_ck_28days, time_in_days, [cement_class], [aggregate_type],
LET(
f_ck, f_ck_28days,
_aggregate_type, IF(ISOMITTED(aggregate_type), "", aggregate_type),
_cement_class, IF(ISOMITTED(cement_class), "", cement_class),
t, time_in_days,
f_cm, Get_f_cm(f_ck),
f_cm_t, Get_f_cm_t(f_ck, t, _cement_class),
E_cm, Get_E_cm(f_ck, _aggregate_type),
E_cm * (f_cm_t / f_cm)^0.3
)
);
/**Design modulus of elasticity of concrete, in GPa.
Ref: EC2 §5.8.6(3)(5.20)
*/
Get_E_cd = LAMBDA(E_cm,
LET(
γ_CE, 1.2,
E_cm / γ_CE
)
);
/**Effective modulus of elasticity of concrete due to the effects of creep, in GPa.
Ref: EC2 §7.4.3(5)(7.20)
*/
Get_E_c_eff = LAMBDA(E_cm_28days, final_creep_coefficent,
LET(
ϕ_∞_t0, final_creep_coefficent,
E_cm_28days / (1 + ϕ_∞_t0)
)
);
/**Tangent modulus of elasticity of concrete at 28 days, in GPa.
Ref: EC2 §3.1.4(2)
*/
Get_E_c = LAMBDA(E_cm_28days,
1.05 * E_cm_28days
);
/**Elastic modulus of reinforcing steel, in GPa.
Ref: EC2 §3.2.7(4)
*/
Get_E_s = LAMBDA([elastic_modulus_of_steel],
IF(
OR(ISOMITTED(elastic_modulus_of_steel), NOT(ISNUMBER(elastic_modulus_of_steel))),
200,
elastic_modulus_of_steel
)
);
/**Creep deformation of concrete at time t = ∞ for a constant compressive stress applied at the concrete age t0.
Ref: EC2 §3.1.4(3)(3.6)
*/
Get_ε_∞_t0 = LAMBDA(E_c_GPa, compressive_stress_MPa, final_creep_coefficent,
LET(
ϕ_∞_t0, final_creep_coefficent,
σ_c, compressive_stress_MPa,
E_c, E_c_GPa * 1000,
ϕ_∞_t0 * (σ_c / E_c)
)
);
/**Design ultimate bond strength, in MPa.
Ref: EC2 §8.4.2(2)(8.2)
*/
Get_f_bd = LAMBDA(η_1, η_2, f_ctd, 2.25 * η_1 * η_2 * f_ctd);
/**Coefficient for quality of bond condition and position of bar used for calculating ultimate bond strength.
Ref: EC2 §8.4.3(2) & Fig 8.2
*/
Get_η_1 = LAMBDA(bond_condition, IF(LOWER(bond_condition) = "good", 1, 0.7));
/**Coefficient for bar diameter used for calculating ultimate bond strength.
Ref: EC2 §8.4.3(2)
*/
Get_η_2 = LAMBDA(bar_diameter, LET(ø, bar_diameter, IF(ø <= 32, 1, (132 - ø) / 100)));
/**Basic required anchorage length, in mm.
Ref: EC2 §8.4.3(2)(8.3)
*/
Get_l_b_rqd = LAMBDA(bar_diameter, design_stress_in_bar, ultimate_bond_strength,
LET(
ø, bar_diameter,
σ_sd, design_stress_in_bar,
f_bd, ultimate_bond_strength,
(ø / 4) * (σ_sd / f_bd)
)
);
/**Design stress in bar at the position from where the anchorage is measured from, in MPa.
Ref: EC2 §8.4.3(2)
*/
Get_σ_sd = LAMBDA(A_s_req, A_s_prov, [f_yk],
LET(
_f_yk, IF(ISOMITTED(f_yk), 500, f_yk),
f_yd, Get_f_yd(_f_yk),
(A_s_req / A_s_prov) * f_yd
)
);
/**Minimum anchorage length, in mm.
Ref: EC2 §8.4.4(1)(8.6)(8.7)
*/
Get_l_b_min = LAMBDA(l_b_rqd, bar_diameter, stress_type,
LET(
ø, bar_diameter,
IF(
LOWER(stress_type) = "tension",
MAX(0.3 * l_b_rqd, 10 * ø, 100),
MAX(0.6 * l_b_rqd, 10 * ø, 100)
)
)
);
/**Design anchorage length, in mm.
Ref: EC2 §8.4.4(1)(8.4)(8.5)
*/
Get_l_bd = LAMBDA(α_1, α_2, α_3, α_4, α_5, l_b_rqd, l_b_min,
LET(
product_α_2_3_5, MAX(α_2 * α_3 * α_5, 0.7),
MAX(α_1 * product_α_2_3_5 * α_4 * l_b_rqd, l_b_min)
)
);
/**Minimum lap length, in mm.
Ref: EC2 §8.7.3(1)(8.11)
*/
Get_l_0_min = LAMBDA(l_b_rqd, bar_diameter, α_6,
LET(ø, bar_diameter, MAX(0.3 * α_6 * l_b_rqd, 15 * ø, 200))
);
/**Design lap length, in mm.
Ref: EC2 §8.7.3(1)(8.10)
*/
Get_l_0 = LAMBDA(α_1, α_2, α_3, α_5, α_6, l_b_rqd, bar_diameter, [lapping_bar_gap],
LET(
x, IF(ISOMITTED(lapping_bar_gap),0,lapping_bar_gap),
ø, bar_diameter,
product_α_2_3_5, MAX(α_2 * α_3 * α_5, 0.7),
l_0_min, Get_l_0_min(l_b_rqd, bar_diameter, α_6),
MAX(α_1 * product_α_2_3_5 * α_6 * l_b_rqd, l_0_min) + IF(x > MIN(50, 4 * ø), x, 0)
)
);
/**Design cover based on bar type and position, in mm.
Ref: EC2 §8.4.4(1) Fig 8.3
*/
Get_C_d = LAMBDA(anchorage_type, cover_end, [cover_edge], [bar_gap],
LET(
C, cover_end,
C_1, IF(OR(ISOMITTED(cover_edge), LOWER(anchorage_type) <> "looped"), C, cover_edge),
a, IF(OR(ISOMITTED(bar_gap), LOWER(anchorage_type) = "looped"), C, bar_gap),
MIN(a / 2, C_1, C)
)
);
/**Shape of bars - influencing factor, used for calculating design lap/anchorage length.
Ref: EC2 §8.4.4, Table 8.2
*/
Get_α_1 = LAMBDA(anchorage_type, stress_type, [bar_diameter], [design_cover],
LET(
ø, IF(ISOMITTED(bar_diameter), 1, bar_diameter),
C_d, IF(ISOMITTED(design_cover), 1, design_cover),
IF(
LOWER(stress_type) = "compression",
1,
IF(LOWER(anchorage_type) = "straight", 1, IF(C_d > 3 * ø, 0.7, 1))
)
)
);
/**Concrete cover - influencing factor, used for calculating design lap/anchorage length.
Ref: EC2 §8.4.4, Table 8.2 & Fig 8.3
*/
Get_α_2 = LAMBDA(anchorage_type, stress_type, [bar_diameter], [design_cover],
LET(
ø, IF(ISOMITTED(bar_diameter), 1, bar_diameter),
C_d, IF(ISOMITTED(design_cover), 1, design_cover),
IF(
LOWER(stress_type) = "compression",
1,
IF(
LOWER(anchorage_type) = "straight",
MIN(MAX(1 - 0.15 * (C_d - ø) / ø, 0.7), 1),
MIN(MAX(1 - 0.15 * (C_d - 3 * ø) / ø, 0.7), 1)
)
)
)
);
/**Confinement by unwelded transverse reinforcement (for anchorage length) - influencing factor, used for calculating design anchorage length.
Ref: EC2 §8.4.4, Table 8.2 & Fig 8.4
*/
Get_α_3_anchored = LAMBDA(
member_type,
stress_type,
transverse_type,
bar_diameter,
layout_type,
transverse_area_of_steel,
LET(
ø, bar_diameter,
A_st, transverse_area_of_steel,
A_s, PI() * ø ^ 2 / 4,
A_st_min, A_s * IF(LOWER(member_type) = "beam", 0.25, 0),
K, IF(LOWER(layout_type) = "corner", 0.1, IF(LOWER(layout_type) = "over", 0.05, 0)),
λ, (A_st - A_st_min) / A_s,
IF(
LOWER(stress_type) = "compression",
1,
MIN(MAX(1 - K * λ, 0.7), 1)
)
)
);
/**Confinement by unwelded transverse reinforcement (for lap length) - influencing factor, used for calculating design lap length.
Ref: EC2 §8.4.4, Table 8.2 & Fig 8.4
*/
Get_α_3_lapped = LAMBDA(
member_type,
stress_type,
transverse_type,
bar_diameter,
layout_type,
transverse_area_of_steel,
design_stress_in_bar,
LET(
σ_sd, design_stress_in_bar,
ø, bar_diameter,
A_st, transverse_area_of_steel,
A_s, PI() * ø ^ 2 / 4,
A_st_min, A_s * (σ_sd / 435),
K, IF(LOWER(layout_type) = "corner", 0.1, IF(LOWER(layout_type) = "over", 0.05, 0)),
λ, (A_st - A_st_min) / A_s,
IF(
OR(LOWER(stress_type) = "compression", LOWER(transverse_type) = "welded"),
1,
MIN(MAX(1 - K * λ, 0.7), 1)
)
)
);
/**Confinement by welded transverse reinforcement - influencing factor, used for calculating design lap/anchorage length.
Ref: EC2 §8.4.4, Table 8.2
*/
Get_α_4 = LAMBDA(transverse_type, IF(LOWER(transverse_type) = "welded", 0.7, 1));
/**Confinement by transverse pressure - influencing factor, used for calculating design lap/anchorage length.
Ref: EC2 §8.4.4, Table 8.2
*/
Get_α_5 = LAMBDA(transverse_pressure, LET(p, transverse_pressure, MIN(MAX(1 - 0.04 * p, 0.7), 1)));
/**Percentage of lapped bars - influencing factor, used for calculating design lap length.
Ref: EC2 §8.7.3, Table 8.3 & Fig 8.8
*/
Get_α_6 = LAMBDA([percentage_of_bars_lapped],
LET(
ρ_1, IF(ISOMITTED(percentage_of_bars_lapped),100,percentage_of_bars_lapped),
MIN(MAX((ρ_1 / 25) ^ 0.5, 1), 1.5)
)
);
/**Effective depth factor for shear resistance.
Ref: EC2 §6.2.2(1)
*/
Get_Effective_Depth_Factor = LAMBDA(effective_depth_mm,
MIN(
1 + SQRT(200 / effective_depth_mm),
2
)
);
/**Effective depth to tension reinforcement from compression face, in mm.
Defaults: reinforcement in outside layer, bar diameters = 20mm, link diameter = 10mm.
Ref: EC2 Fig 3.5
*/
Get_Effective_Depth_Tension = LAMBDA(h_mm, cover_nominal_mm, [bar_diameter_mm], [link_diameter_mm], [reinforcement_layer], [transverse_bar_diameter_mm],
LET(
c, cover_nominal_mm,
ø_long, IF(ISOMITTED(bar_diameter_mm), 20, bar_diameter_mm),
ø_trans, IF(ISOMITTED(transverse_bar_diameter_mm), 20, transverse_bar_diameter_mm),
ø_link, IF(ISOMITTED(link_diameter_mm), 10, link_diameter_mm),
layer, IF(ISOMITTED(reinforcement_layer), 1, reinforcement_layer),
h_mm - IF(layer = 1,
c + ø_link + ø_long / 2,
c + MAX(ø_link, ø_trans) + ø_long / 2
)
)
);
/**Effective depth to compression reinforcement from compression face, in mm.
Defaults: reinforcement in outside layer, bar diameters = 20mm, link diameter = 10mm.
Ref: EC2 Fig 3.5
*/
Get_Effective_Depth_Compression = LAMBDA(cover_mm, [bar_diameter_mm], [link_diameter_mm], [reinforcement_layer], [transverse_bar_diameter_mm],
LET(
c, cover_mm,
ø_long, IF(ISOMITTED(bar_diameter_mm), 20, bar_diameter_mm),
ø_trans, IF(ISOMITTED(transverse_bar_diameter_mm), 20, transverse_bar_diameter_mm),
ø_link, IF(ISOMITTED(link_diameter_mm), 10, link_diameter_mm),
layer, IF(ISOMITTED(reinforcement_layer), 1, reinforcement_layer),
IF(layer = 1,
c + ø_link + ø_long / 2,
c + MAX(ø_link, ø_trans) + ø_long / 2
)
)
);
/**The cross-sectional area of a concrete section, in mm^2.
*/
Get_Cross_Sectional_Area_of_Section_mm2 = LAMBDA(h_mm, b_w_mm,
h_mm * b_w_mm
);
/**Minimum shear resistance coefficient.
Ref: EC2 §6.2.2(1)(6.3N)
*/
Get_v_min = LAMBDA(f_ck, effective_depth_mm,
LET(
k, Get_Effective_Depth_Factor(effective_depth_mm),
0.035 * K^(3/2) * SQRT(f_ck)
)
);
/**Minimum shear resistance without shear reinforcement, in kN.
Ref: EC2 §6.2.2(1)(6.2b)
*/
Get_V_Rd_c_min_kN = LAMBDA(f_ck, σ_cp_MPa, b_w_mm, d_mm,
LET(
k_1, 0.15,
v_min, Get_v_min(f_ck, d_mm),
(v_min + k_1 * σ_cp_MPa) * b_w_mm * d_mm / 1000
)
);
/**Shear reduction factor.
Ref: EC2 §6.2.2(1)
*/
Get_C_Rd_c = LAMBDA([γ_c],
LET(
_γ_c, IF(ISOMITTED(γ_c), 1.5, γ_c),
0.18 / _γ_c
)
);
/**Design concrete shear resistance from effective area, in kN.
Ref: EC2 §6.2.2(1)(6.2a&b)
*/
Get_V_Rd_c_kN = LAMBDA(f_ck, σ_cp_MPa, b_w, d, As_prov_tens_per_m, [γ_c],
LET(
V_Rd_c_min, Get_V_Rd_c_min_kN(f_ck, σ_cp_MPa, b_w, d),
_γ_c, IF(ISOMITTED(γ_c), 1.5, γ_c),
C_Rd_c, Get_C_Rd_c(_γ_c),
k_1, 0.15,
k, Get_Effective_Depth_Factor(d),
ρ, Get_Tensile_Reinforcement_Ratio(As_prov_tens_per_m, d),
MAX(
(C_Rd_c * k * (100 * ρ * f_ck)^(1 / 3) + k_1 * σ_cp_MPa) * b_w * d / 1000,
V_Rd_c_min
)
)
);
/**Tensile reinforcement ratio (steel to concrete area).
Ref: EC2 §6.2.2(1)
*/
Get_Tensile_Reinforcement_Ratio = LAMBDA(As_prov_tens_per_m, d_mm,
MIN(
As_prov_tens_per_m / (1000 * d_mm),
0.02
)
);
/**Compressive stress in concrete due to loading or prestressing, in MPa.
Ref: EC2 §6.2.2(1)
*/
Get_Compressive_Stress = LAMBDA(f_ck, d_mm, b_w_mm, [N_Ed_kN], [γ_c],
LET(
N_Ed, MAX(IF(ISOMITTED(N_Ed_kN), 0, N_Ed_kN), 0),
_γ_c, IF(ISOMITTED(γ_c), 1.5, γ_c),
f_cd, Get_f_cd(f_ck, , _γ_c),
MIN(
N_Ed_kN * 10^3 / (d_mm * b_w_mm),
0.2 * f_cd
)
)
);
/**Design concrete shear stress over effective area, in MPa.
*/
Get_Design_Shear_Stress = LAMBDA(V_Ed_kN, b_w_mm, d_mm,
V_Ed_kN * 10^3 / (b_w_mm * d_mm)
);
/**Design concrete shear stress without shear reinforcement, in MPa.
*/
Get_Design_Shear_Strength = LAMBDA(V_Rd_c_kN, b_w_mm, d_mm,
V_Rd_c_kN * 10^3 / (b_w_mm * d_mm)
);
/**Design concrete moment of resistance in kNm from effective area, in kNm.
Ref: EC2 §Fig 3.5 Fig 6.1 (and first principles)
*/
Get_M_Rd_kNm = LAMBDA(f_ck, b_w_mm, d_mm,
// (2091/12500) is the more exact coefficient than 0.167
(2091/12500) * f_ck * b_w_mm * d_mm^2 / 10^6
);
/**The lever arm of the tensile steel or compression concrete about the neutral axis, in mm.
Ref: EC2 §Fig 3.5 Fig 6.1 (and first principles)
*/
Get_Lever_Arm = LAMBDA(M_Rd, M_Ed, d_mm,
LET(
/*
(2091/12500) is the more exact coefficient than 0.167.
K_0 is limited to 0.167 which occurs when M_Ed > M_Rd.
*/
K_0, (2091/12500) * MIN(M_Ed / M_Rd, 1),
MIN(
d_mm * (0.5 + SQRT(0.25 - 3 * K_0 / 3.4)),
0.95 * d_mm
)
)
);
/**K_0 is used to find the lever arm and is limited to 0.167 max.
Ref: EC2 §Fig 3.5, Fig 6.1 (and first principles)
*/
Get_K_0 = LAMBDA(M_Ed_kNm, b_w_mm, d_mm, f_ck,
MIN(M_Ed_kNm *10^6 / (b_w_mm * d_mm^2 * f_ck), 2091/12500)
);
/**Minimum area of longitudinal tension reinforcement, in mm^2/m.
Ref: EC2 §9.2.1.1(1)(9.1N)
*/
Get_A_s_min = LAMBDA(f_ck, d_mm, [f_yk],
LET(
f_ctm, Get_f_ctm(f_ck),
_f_yk, IF(ISOMITTED(f_yk), 500, f_yk),
coeff, MAX(
0.26 * (f_ctm / _f_yk),
0.0013
),
coeff * d_mm * 1000
)
);
/**Maximum area of longitudinal tension or compression reinforcement, in mm^2/m.
Ref: EC2 §9.2.1.1(3)
*/
Get_A_s_max = LAMBDA(h_mm,
0.04 * h_mm * 1000
);
/**Area of longitudinal tensile reinforcement required, in mm^2/m.
Ref: EC2 §Fig 3.5, Fig 6.1 (and first principles)
*/
Get_A_s_req_t = LAMBDA(M_Rd_kNm, M_Ed_kNm, d_mm, b_w_mm, [As_req_compression_per_m], [f_yk],
LET(
As_req_c, IF(ISOMITTED(As_req_compression_per_m), 0, As_req_compression_per_m),
_f_yk, IF(ISOMITTED(f_yk), 500, f_yk),
f_yd, Get_f_yd(_f_yk),
z, Get_Lever_Arm(M_Rd_kNm, M_Ed_kNm, d_mm),
IF(As_req_c > 0,
(1000 / b_w_mm) * M_Rd_kNm * 10^6 / (f_yd * z) + As_req_c,
(1000 / b_w_mm) * M_Ed_kNm * 10^6 / (f_yd * z)
)
)
);
/**Area of longitudinal compressive reinforcement required, in mm^2/m.
Ref: EC2 §Fig 3.5, Fig 6.1 (and first principles)
*/
Get_A_s_req_c = LAMBDA(M_Rd_kNm, M_Ed_kNm, d_mm, d_2_mm, b_w_mm, [f_yk],
LET(
_f_yk, IF(ISOMITTED(f_yk), 500, f_yk),
f_yd, Get_f_yd(_f_yk),
z, d_mm - d_2_mm,
MAX(
(1000 / b_w_mm) * ((M_Ed_kNm - M_Rd_kNm)* 10^6) / (f_yd * z),
0
)
)
);
/**Strength reduction factor for concrete cracked in shear, in MPa.
Ref: EC2 §6.2.2(6)(6.6N)
*/
Get_v = LAMBDA(f_ck,
0.6 * (1 - f_ck / 250)
);
/**The design stress in reinforcement, in N/mm^2.
*/
Get_Reinforcement_Design_Stress = LAMBDA(design_force_kN, design_resistance_kN, [f_yk],
LET(
_f_yk, IF(ISOMITTED(f_yk), 500, f_yk),
f_yd, Get_f_yd(_f_yk),
f_yd * design_force_kN / design_resistance_kN
)
);
/**Strength reduction factor for concrete cracked in shear, in MPa.
Ref: EC2 §6.2.3(3)
*/
Get_v_1 = LAMBDA(f_ck, [reinforcement_angle_degs], [shear_reinforcement_design_stress], [f_yk],
LET(
α_rads, IF(ISOMITTED(reinforcement_angle_degs), PI()/2, RADIANS(reinforcement_angle_degs)),
_f_yk, IF(ISOMITTED(f_yk), 500, f_yk),
f_yd, Get_f_yd(_f_yk),
σ_yd_τ, IF(ISOMITTED(shear_reinforcement_design_stress), f_yd, shear_reinforcement_design_stress),
stress_ratio, σ_yd_τ / _f_yk,
IF(stress_ratio < 0.8,
IF(f_ck <= 60,
0.54 * (1 - 0.5 * COS(α_rads)),
(0.84 - f_ck / 200) * (1 - 0.5 * COS(α_rads))
),
Get_v(f_ck) * (1 - 0.5 * COS(α_rads))
)
)
);
/**Maximum design shear resistance of concrete with shear reinforcement from compression of concrete strut, in kN.
(Will always match V_Ed when 21.8° ≤ θ ≤ 45°)
Ref: EC2 §6.2.3(4)(6.14)
*/
Get_V_Rd_max_kN = LAMBDA(f_ck, b_w_mm, d_mm, [strut_angle_degs], [reinforcement_angle_degs], [σ_cp], [M_Ed_kNm], [α_cc_τ], [f_yk],
LET(
M_Rd_kNm, Get_M_Rd_kNm(f_ck, b_w_mm, d_mm),
α_rads, IF(ISOMITTED(reinforcement_angle_degs), PI()/2, RADIANS(reinforcement_angle_degs)),
_α_cc_τ, IF(ISOMITTED(α_cc_τ), 1, α_cc_τ),
_f_yk, IF(ISOMITTED(f_yk), 500, f_yk),
v_1, Get_v_1(f_ck, DEGREES(α_rads), , _f_yk),
f_cd_τ, Get_f_cd(f_ck, _α_cc_τ),
f_cd_c, Get_f_cd(f_ck, 0.85),
// Limits angle to between 21.8° to 45° (1 ≤ COT(θ) ≤ 2.5)
θ_degs, IF(
OR(ISOMITTED(strut_angle_degs), NOT(ISNUMBER(strut_angle_degs))),
45,
strut_angle_degs
),
θ_rads, RADIANS(MIN(MAX(θ_degs, DEGREES(ACOT(2.5))), 45)),
// If M_Ed is not given then z = 0.9d. Ref: EC2 Fig 6.5
is_z_approx, IF(ISOMITTED(M_Ed_kNm), TRUE, FALSE),
z, IF(is_z_approx, 0.9 * d_mm, Get_Lever_Arm(M_Rd_kNm, M_Ed_kNm, d_mm)),
α_cw, IFS(
ISOMITTED(σ_cp), 1,
σ_cp <= 0.25 * f_cd_c, 1 + σ_cp / f_cd_c,
σ_cp <= 0.5 * f_cd_c, 1.25,
σ_cp < f_cd_c, 2.5 * (1 - σ_cp/ f_cd_c)
),
(α_cw * b_w_mm * z * v_1 * f_cd_τ * (COT(θ_rads) + COT(α_rads)) / (1 + (COT(θ_rads))^2)) / 10^3
)
);
/**Maximum design shear resistance of concrete with shear reinforcement from failure of the stirrups, in kN.
Ref: EC2 §6.2.3(4)(6.13)
*/
Get_V_Rd_s_kN = LAMBDA(f_ck, b_w_mm, d_mm, area_of_shear_steel_prov_mm2, link_spacing_mm, [strut_angle_degs], [reinforcement_angle_degs], [M_Ed_kNm], [f_yk],
LET(
M_Rd_kNm, Get_M_Rd_kNm(f_ck, b_w_mm, d_mm),
A_sw, area_of_shear_steel_prov_mm2,
α_rads, IF(ISOMITTED(reinforcement_angle_degs), PI()/2, RADIANS(reinforcement_angle_degs)),
// Limits angle to between 21.8° to 45° (1 ≤ COT(θ) ≤ 2.5)
θ_degs, IF(
OR(ISOMITTED(strut_angle_degs), NOT(ISNUMBER(strut_angle_degs))),
45,
strut_angle_degs
),
θ_rads, RADIANS(MIN(MAX(θ_degs, DEGREES(ACOT(2.5))), 45)),
// If M_Ed is not given then z = 0.9d. Ref: EC2 Fig 6.5
is_z_approx, IF(ISOMITTED(M_Ed_kNm), TRUE, FALSE),
z, IF(is_z_approx, 0.9 * d_mm, Get_Lever_Arm(M_Rd_kNm, M_Ed_kNm, d_mm)),
_f_yk, IF(ISOMITTED(f_yk), 500, f_yk),
f_ywd, Get_f_yd(_f_yk),
s, link_spacing_mm,
IFERROR((A_sw / s) * z * f_ywd * (COT(θ_rads) + COT(α_rads)) * SIN(α_rads) / 1000, 0)
)
);
/**Minimum ratio of shear reinforcement.
Ref: EC2 §9.2.2(5)(9.5N)
*/
Get_ρ_w_min = LAMBDA(f_ck, [f_yk],
LET(
_f_yk, IF(ISOMITTED(f_yk), 500, f_yk),
0.08 * SQRT(f_ck) / _f_yk
)
);
/**Ratio of shear reinforcement.
Ref: EC2 §9.2.2(5)(9.4)
*/
Get_ρ_w = LAMBDA(area_of_shear_steel_mm2, link_spacing_mm, b_w_mm, [reinforcement_angle_degs],
LET(
A_sw, area_of_shear_steel_mm2,
s, link_spacing_mm,
α_rads, IF(ISOMITTED(reinforcement_angle_degs), PI()/2, RADIANS(reinforcement_angle_degs)),
A_sw / (s * b_w_mm * SIN(α_rads))
)
);
/**Cross-sectional area of shear reinforcement required, in mm^2.
Link spacing ≠ 0.
*/
Get_A_sw_req = LAMBDA(V_Ed_kN, link_spacing_mm, strut_angle_degs, f_ck, b_w_mm, d_mm, [M_Ed_kNm], [reinforcement_angle_degs], [f_yk],
LET(
s, link_spacing_mm,
M_Rd_kNm, Get_M_Rd_kNm(f_ck, b_w_mm, d_mm),
_f_yk, IF(ISOMITTED(f_yk), 500, f_yk),
f_ywd, Get_f_yd(_f_yk),
α_rads, IF(ISOMITTED(reinforcement_angle_degs), PI()/2, RADIANS(reinforcement_angle_degs)),
θ_degs, IF(
NOT(ISNUMBER(strut_angle_degs)),
45,
strut_angle_degs
),
θ_rads, RADIANS(MIN(MAX(θ_degs, DEGREES(ACOT(2.5))), 45)),
// If M_Ed is not given then z is found approximately from d. Ref: EC2 Fig 6.5
is_z_approx, IF(ISOMITTED(M_Ed_kNm), TRUE, FALSE),
z, IF(is_z_approx, 0.9 * d_mm, Get_Lever_Arm(M_Rd_kNm, M_Ed_kNm, d_mm)),
A_sw_req, s * V_Ed_kN * 10^3 / (z * f_ywd * COT(θ_rads)),
A_sw_min, Get_A_sw_min(s, b_w_mm, f_ck, DEGREES(α_rads), _f_yk),
IF(s = 0,
"Link spacing ≠ 0",
MAX(A_sw_req, A_sw_min)
)
)
);
/**Minimum cross-sectional area of shear reinforcement required, in mm^2.
Link spacing ≠ 0.
*/
Get_A_sw_min = LAMBDA(link_spacing_mm, b_w_mm, f_ck, [reinforcement_angle_degs], [f_yk],
LET(
s, link_spacing_mm,
_f_yk, IF(ISOMITTED(f_yk), 500, f_yk),
α_rads, IF(ISOMITTED(reinforcement_angle_degs), PI()/2, RADIANS(reinforcement_angle_degs)),
ρ_w_min, Get_ρ_w_min(f_ck, _f_yk),
IF(s = 0,
"Link spacing ≠ 0",
s * ρ_w_min * b_w_mm * SIN(α_rads)
)
)
);
/**Cross-sectional area of shear reinforcement provided, in mm^2.
*/
Get_A_sw_prov = LAMBDA(bar_diameter_mm, number_of_legs,
number_of_legs * PI() * bar_diameter_mm^2 / 4
);
/**Cross-sectional area of longitudinal reinforcement provided, in mm^2/m.
*/
Get_A_s_prov = LAMBDA(bar_diameter_mm, spacing_mm,
(1000 / spacing_mm) * PI() * bar_diameter_mm^2 / 4
);
/**Maximum longitudinal spacing between shear links, in mm.
Ref: EC2 §9.2.2(6)(9.6N)
*/
Get_Max_Link_Spacing_Longitudinal = LAMBDA(d_mm, [reinforcement_angle_degs],
LET(
α_rads, IF(ISOMITTED(reinforcement_angle_degs), PI()/2, RADIANS(reinforcement_angle_degs)),
0.75 * d_mm * (1 + COT(α_rads))
)
);
/**Maximum transverse spacing between shear links, in mm.
Ref: EC2 §9.2.2(8)(9.8N)
*/
Get_Max_Link_Spacing_Transverse = LAMBDA(d_mm,
MIN(0.75 * d_mm, 600)
);
/**Additional tensile force in longitudinal reinforcement due to shear force, in kN.
θ limited to between 21.8° to 45°.
*/
Get_Tensile_Force_Due_To_Shear = LAMBDA(V_Ed_kN, [strut_angle_degs],
LET(
θ_rads, RADIANS(IF(
ISOMITTED(strut_angle_degs), 45,
MIN(MAX(strut_angle_degs, DEGREES(ACOT(2.5))), 45)
)),
0.5 * V_Ed_kN / TAN(θ_rads)
)
);
/**A helper function used for the recurssive part of the Get_Angle_of_Strut function to find angle of concrete compression strut.
*/
Find_θ_with_α = LAMBDA(β, α, V_Ed, θ_i,
DEGREES(ACOT((V_Ed * 10^3 / (β * (SIN(RADIANS(θ_i)))^2)) - COT(RADIANS(α))))
);
/**Returns the actual angle of inclination of the actual concrete struts.
Only valid for shear bars at 90°.
If greater than 45degs returns "θ > 45°, Redesign Section"
*/
Find_θ = LAMBDA(f_ck, b_w_mm, d_mm, V_Ed_kN, [M_Ed_kNm], [α_cc_τ], [f_yk],
LET(
M_Rd_kNm, Get_M_Rd_kNm(f_ck, b_w_mm, d_mm),
_α_cc_τ, IF(ISOMITTED(α_cc_τ), 1, α_cc_τ),
_f_yk, IF(ISOMITTED(f_yk), 500, f_yk),
// If M_Ed is not given then z is found approximately from d. Ref: EC2 Fig6.5
is_z_approx, IF(ISOMITTED(M_Ed_kNm), TRUE, FALSE),
z, IF(is_z_approx, 0.9 * d_mm, Get_Lever_Arm(M_Rd_kNm, M_Ed_kNm, d_mm)),
v_1, Get_v_1(f_ck, , _f_yk),
f_cd_τ, Get_f_cd(f_ck, _α_cc_τ),
IFERROR(
0.5 * DEGREES(ASIN(2 * V_Ed_kN * 10^3 / (b_w_mm * z * v_1 * f_cd_τ))),
"θ > 45°, Redesign Section"
)
)
);
/**Returns the actual angle of inclination of the actual concrete struts.
Valid for inclined shear bars.
If greater than 45degs returns "θ > 45°, Redesign Section"
*/
Get_Angle_of_Strut = LAMBDA(f_ck, b_w_mm, d_mm, V_Ed_kN, [reinforcement_angle_degs], [σ_cp], [M_Ed_kNm], [α_cc_τ], [f_yk], [θ_0], [counter],
LET(
α_degs, IF(ISOMITTED(reinforcement_angle_degs), 90, reinforcement_angle_degs),
M_Rd_kNm, Get_M_Rd_kNm(f_ck, b_w_mm, d_mm),
_α_cc_τ, IF(ISOMITTED(α_cc_τ), 1, α_cc_τ),
_f_yk, IF(ISOMITTED(f_yk), 500, f_yk),
// If M_Ed is omitted (required to find V_Rd_max) then the ratio M_Ed/M_Rd is set to 25/41 which equates z = 0.9d
_M_Ed_kNm, IF(ISOMITTED(M_Ed_kNm), 25 * M_Rd_kNm / 41, M_Ed_kNm),
z, Get_Lever_Arm(M_Rd_kNm, _M_Ed_kNm, d_mm),
v_1, Get_v_1(f_ck, α_degs, , _f_yk),
f_cd_τ, Get_f_cd(f_ck, _α_cc_τ),
f_cd_c, Get_f_cd(f_ck, 0.85),
_σ_cp, IF(ISOMITTED(σ_cp), 0, σ_cp),
α_cw, IFS(
_σ_cp <= 0.25 * f_cd_c, 1 + _σ_cp / f_cd_c,
_σ_cp <= 0.5 * f_cd_c, 1.25,
_σ_cp < f_cd_c, 2.5 * (1 - _σ_cp/ f_cd_c)
),
β, α_cw * b_w_mm * z * v_1 * f_cd_τ,
// Sets initial guess of strut angle to angle when stirrup angle is 90degs which should be close
_θ_0, IF(
OR(ISOMITTED(θ_0), α_degs = 90),
Find_θ(f_ck, b_w_mm, d_mm, V_Ed_kN, _M_Ed_kNm, _α_cc_τ, _f_yk),
θ_0
),
//Finds strut angle with stirrups at an angle
θ_i, Find_θ_with_α(β, α_degs, V_Ed_kN, _θ_0),
//For iteration
adjuster, IF(
θ_i > _θ_0,
-0.9*(θ_i - _θ_0),
0.9*(_θ_0 - θ_i)
),
θ_next, _θ_0 + adjuster,
_counter, IF(ISOMITTED(counter), 0, counter + 1),
IFERROR(IF(_counter < 10,
IFS(
θ_next >= 45, "θ > 45°, Redesign Section",
ABS(adjuster) < 0.01, θ_next,
θ_next < 45, Get_Angle_of_Strut(f_ck, b_w_mm, d_mm, V_Ed_kN, α_degs, _σ_cp, _M_Ed_kNm, _α_cc_τ, _f_yk, θ_next, _counter)
),
"Could not converge"
), "θ > 45°, Redesign Section"
)
)
);
/**Minimum spacing of reinforcement, in mm.
*/
Get_Min_Bar_Spacing_mm = LAMBDA(bar_diameter_mm, [aggregate_size],
LET(
ø, bar_diameter_mm,
agg_size, IF(ISOMITTED(aggregate_size), 20, aggregate_size),
MAX(ø, agg_size + 5, 20)
)
);
/**Ratio of area of tension steel reinforcement per m to effective area of concrete surrounding tension reinforcement.
Ref: EC2 §7.3.4(2)(7.10)
*/
Get_ρ_p_eff = LAMBDA(area_of_tensions_steel_per_m, h_c_ef, [ξ_1], [A_p],
LET(
A_s, area_of_tensions_steel_per_m,
_ξ_1, IF(OR(ISOMITTED(ξ_1),NOT(ISNONTEXT(ξ_1))), 0, ξ_1),
_A_p, IF(ISOMITTED(A_p), 0, A_p),
A_c_eff, h_c_ef * 1000,
(A_s + _ξ_1 * _A_p)/ A_c_eff
)
);
/**Cover to longitudinal reinforcement, in mm.
*/
Get_Cover_to_Longitudinal_Reinforcement = LAMBDA(cover_nominal_mm, [reinforcement_layer], [link_diameter_mm], [bar_diameter_transverse],
LET(
layer, IF(ISOMITTED(reinforcement_layer), 1, reinforcement_layer),
ø_trans, IF(ISOMITTED(bar_diameter_transverse), 20, bar_diameter_transverse),
ø_link, IF(ISOMITTED(link_diameter_mm), 10, link_diameter_mm),
c, cover_nominal_mm,
IF(layer = 1,
c + ø_link,
c + MAX(ø_link, ø_trans)
)
)
);
/**Maximum crack spacing, in mm.
Ref: EC2 §7.3.4(3)(7.11)
*/
Get_Maximum_Crack_Spacing = LAMBDA(
h_mm,
depth_to_neutral_axis_cracked_mm,
bar_diameter_bottom_mm,
bar_spacing_bottom_mm,
bar_diameter_top_mm,
bar_spacing_top_mm,
cover_to_longitudinal_rebar_mm,
ρ_p_eff,
[load_type],
[is_high_bond_bar],
LET(
ø_1, bar_diameter_top_mm,
ø_2, bar_diameter_bottom_mm,
n_1, 1000 / bar_spacing_top_mm,
n_2, 1000 / bar_spacing_bottom_mm,
_load_type, IF(ISOMITTED(load_type), "bending", LOWER(load_type)),
x_c, IF(_load_type = "bending",
depth_to_neutral_axis_cracked_mm,
0
),
//! Need to look at this and see if is only those bars within the tensile zone or not
ø_eq, (n_1 * ø_1^2 + n_2 * ø_2^2) / (n_1 * ø_1 + n_2 * ø_2),
//! Using the same approach used for equivalent diameter to find an equivalent spacing of multiple bars
max_spacing, (n_1^2 * ø_1 + n_2^2 * ø_2) / (n_1 * ø_1 + n_2 * ø_2),
_is_high_bond_bar, IF(ISOMITTED(is_high_bond_bar), TRUE, is_high_bond_bar),
k_1, IF(_is_high_bond_bar, 0.8, 1.6),
k_2, IF(_load_type = "bending",
0.5,
1
),
k_3, 3.4,
k_4, 0.425,
C, cover_to_longitudinal_rebar_mm,
S_r_max, k_3 * C + k_1 * k_2 * k_4 * ø_eq / ρ_p_eff,
IF(OR(max_spacing > 5 * (C + ø_eq / 2), _is_high_bond_bar <> TRUE),
1.3 * (h_mm - x_c),
S_r_max
)
)
);
/**Effective height of concrete surrounding tension reinforcement, in mm.
Ref: EC2 §7.3.2(3) & Fig 7.1
*/
Get_h_c_ef = LAMBDA(height_of_section_mm, effective_depth_from_opposite_face_mm, depth_to_neutral_axis_uncracked_from_opposite_face_mm,
LET(
h, height_of_section_mm,
d, effective_depth_from_opposite_face_mm,
x_u, depth_to_neutral_axis_uncracked_from_opposite_face_mm,
MIN(
2.5 * (h - d),
(h - x_u) / 3,
h / 2
)
)
);
/**Coefficient for non-uniform, self-equilibrium stress used for minimum crack width calculation.
Ref: EC2 §7.3.2(2)(7.1)
*/
Get_k = LAMBDA(web_height, [flange_width],
LET(
_flange_width, IF(ISOMITTED(flange_width), 800, flange_width),
h, MIN(web_height, _flange_width),
IFS(
h <= 300, 1,
h >= 800, 0.65,
h < 800, FORECAST(h, {1, 0.65}, {300, 800})
)
)
);
/**Factor for minimum crack reinforcement taking into account stress distribution within the section.
load_type = "pure tension" or "bending"
Ref: EC2 §7.3.2(2)(7.1)
*/
Get_k_c = LAMBDA(f_ck28days, N_Ed_kN, h_mm, b_w_mm, [load_type], [time_in_days], [cement_class],
LET(
t, IF(ISOMITTED(time_in_days), 28, time_in_days),
_load_type, IF(ISOMITTED(load_type), "bending", LOWER(load_type)),
_cement_class, IF(ISOMITTED(cement_class), "", cement_class),
σ_c, N_Ed_kN * 1000 / (h_mm * b_w_mm),
h_star, IF(h_mm < 1000,
h_mm,
1000
),
k_1, IF(
N_Ed_kN >= 0, 1.5, //Code doesn't say what to use if N_Ed = 0. This is conservative.
(2 * h_star) / (3 * h_mm)
),
f_ct_eff, Get_f_ctm_t(f_ck28days, t, _cement_class),
IF(_load_type = "bending",
MIN(0.4 * (1 - σ_c / (k_1 * (h_mm / h_star) * f_ct_eff)), 1),
1
)
)
);
/**Minimum area of reinforcement to control cracking, in mm^2/m.
Ref: EC2 §7.3.2(2)(7.1)
*/
Get_A_s_min_crack = LAMBDA(h_c_ef, f_ck, σ_s, k, k_c, [time_in_days], [cement_class],
LET(
t, MIN(IF(ISOMITTED(time_in_days), 28, time_in_days), 28),
_cement_class, IF(ISOMITTED(cement_class), "", cement_class),
f_ct_eff, Get_f_ctm_t(f_ck, t, _cement_class),
k_c,
k,
k_c * k * f_ct_eff * h_c_ef * 1000 / σ_s
)
);
/**Crack width, in mm.
Ref: EC2 §7.3.4(1)(7.8)
*/
Get_Crack_Width = LAMBDA(maximum_crack_spacing_mm, ε_cr,
maximum_crack_spacing_mm * ε_cr
);
/**Crack width factor depending on duration of loading.
Ref: EC2 §7.3.4(2)
*/
Get_k_t = LAMBDA(duration_of_loading,
IF(LOWER(duration_of_loading) = "short-term", 0.6, 0.4)
);
/**Crack strain = difference in mean strains between reinforcement and concrete, ε_sm - ε_cm.
duration_of_loading = "short-term" or "long-term" (default).
Ref: EC2 §7.3.4(2)(7.9)
*/
Get_ε_cr = LAMBDA(f_ck28days, σ_s, ρ_p_eff, [aggregate_type], [time_in_days], [cement_class], [duration_of_loading],
LET(
t, MIN(IF(ISOMITTED(time_in_days), 28, time_in_days), 28),
_cement_class, IF(ISOMITTED(cement_class), "", cement_class),
_aggregate_type, IF(ISOMITTED(aggregate_type), "", aggregate_type),
_duration_of_loading, IF(ISOMITTED(duration_of_loading), "long-term", duration_of_loading),
k_t, Get_k_t(_duration_of_loading),
E_cm, Get_E_cm(f_ck28days, _aggregate_type) * 10^3,
E_s, Get_E_s() * 10^3,
α_e, E_s / E_cm,
f_ct_eff, Get_f_ctm_t(f_ck28days, t, _cement_class),
MAX(
(σ_s - k_t * (f_ct_eff / ρ_p_eff) * (1 + α_e * ρ_p_eff)) / E_s,
0.6 * σ_s / E_s
)
)
);
/**Bar diameter required based on reinforcemnt required and a given bar spacing, in mm.
By default bar diameter is rounded up to nearest bar size.
*/
Get_Bar_Diameter_Req = LAMBDA(As_req, bar_spacing_mm, [isRoundedUp],
LET(
_isRoundedUp, IF(ISOMITTED(isRoundedUp), TRUE, isRoundedUp),
ø, SQRT(4 * As_req * bar_spacing_mm / (1000 * PI())),
bars, {40, 32, 25, 20, 16, 12, 10, 8},
IF(_isRoundedUp,
IFNA(INDEX(bars, MATCH(ø, bars, -1)), ø),
ø
)
)
);
/**Bar spacing required based on reinforcemnt required and a given bar diameter, in mm.
By default bar spacing is rounded down to nearest 25mm.
*/
Get_Bar_Spacing_Req = LAMBDA(As_req, bar_diameter_mm, [isRoundedDown], [roundTo_mm],
LET(
_isRoundedDown, IF(ISOMITTED(isRoundedDown), TRUE, isRoundedDown),
_roundTo_mm, IF(ISOMITTED(roundTo_mm), 25, roundTo_mm),
spacing, 1000 * PI() * bar_diameter_mm^2 / (4 * As_req),
IF(_isRoundedDown,
FLOOR.MATH(spacing, _RoundTo_mm),
spacing
)
)
);
/**Cracking moment. The bending moment at which a section cracks in flexure, in kNm.
*/
Get_Cracking_Moment_kNm = LAMBDA(f_ctm_fl, elastic_section_modulus_mm3,
f_ctm_fl * elastic_section_modulus_mm3 / 10^6
);
Get_Concrete_Properties_Over_Time = LAMBDA(
concrete_grade,
section_height_mm,
[start_time_in_days],
[end_time_in_days],
[cement_class],
[aggregate_type],
[display_headers],
[properties],
[t],
LET(
_display_headers, IFERROR(IF(ISOMITTED(display_headers), FALSE, display_headers), FALSE),
_aggregate_type, IF(ISOMITTED(aggregate_type), "", aggregate_type),
_cement_class, IF(ISOMITTED(cement_class), "", cement_Class),
t_0, IF(OR(ISOMITTED(start_time_in_days), start_time_in_days < 3), 3 , start_time_in_days),
t_end, MAX(IF(ISOMITTED(end_time_in_days), 28, end_time_in_days), t_0),
t, MAX(MIN(IF(ISOMITTED(t), t_0, t), t_end), t_0),
h, section_height_mm,
f_ck, Get_f_ck(concrete_grade),
f_ck_t, Get_f_ck_t(f_ck, t, _cement_class),
f_cd_τ_t, Get_f_cd(f_ck_t, 1),
f_cd_t, Get_f_cd(f_ck_t),
f_cm, Get_f_cm(f_ck),
f_cm_t, Get_f_cm_t(f_ck, t, _cement_class),
f_ctm_t, Get_f_ctm_t(f_ck, t, _cement_class),
f_ctm_fl_t, Get_f_ctm_fl(h, f_ctm_t),
E_cm_t, Get_E_cm_t(f_ck, t, _cement_class, _aggregate_type),
E_c_t, Get_E_c(E_cm_t),
properties_t, HSTACK(t, f_ck_t, f_cd_τ_t, f_cd_t, f_cm_t, f_ctm_t, f_ctm_fl_t, E_cm_t, E_c_t),
_properties, IF(ISOMITTED(properties), properties_t, VSTACK(properties, properties_t)),
// RECURRSIVE LOOP
//For iteration
t_plus1, t + 1,
IF(t_plus1 > t_end,
LET(
headers, {"t in days", "f_ck_t", "f_cd_τ_t", "f_cd_t", "f_cm_t", "f_ctm_t", "f_ctm_fl_t", "E_cm_t", "E_c_t"},
IF(_display_headers, VSTACK(headers, _properties), _properties)
),
Get_Concrete_Properties_Over_Time(
concrete_grade,
section_height_mm,
t_0,
t_end,
_cement_class,
_aggregate_type,
display_headers,
_properties,
t_plus1
)
)
)
);
/**The depth to the neutral axis for an uncracked concrete section from the compression face, in mm.
*/
Get_Depth_to_Neutral_Axis_Uncracked_mm = LAMBDA(breadth_mm, height_mm, As_prov_compression_per_m, As_prov_tension_per_m, d_compression_mm, d_tension_mm, E_LT_GPa,
LET(
b, breadth_mm,
h, height_mm,
As_comp, As_prov_compression_per_m * (b / 1000),
As_tens, As_prov_tension_per_m * (b / 1000),
d_2, d_compression_mm,
d, d_tension_mm,
E_s_GPa, Get_E_s(),
α_e, E_s_GPa / E_LT_GPa, // modular ratio
A_gross, b * h,
A_eff_comp, (α_e - 1) * As_comp,
A_eff_tens, (α_e - 1) * As_tens,
(A_gross * h / 2 + A_eff_comp * d_2 + A_eff_tens * d) / SUM(A_gross, A_eff_comp, A_eff_tens)
)
);
/**The depth to the neutral axis for a cracked concrete section from the compression face, in mm.
*/
Get_Depth_to_Neutral_Axis_Cracked_mm = LAMBDA(breadth_mm, As_prov_compression_per_m, As_prov_tension_per_m, d_compression_mm, d_tension_mm, E_LT_GPa,
LET(
b, breadth_mm,
As_comp, As_prov_compression_per_m * (b / 1000),
As_tens, As_prov_tension_per_m * (b / 1000),
d_2, d_compression_mm,
d, d_tension_mm,
E_s_GPa, Get_E_s(),
α_e, E_s_GPa / E_LT_GPa, // modular ratio
K_1, As_tens * α_e + As_comp * (α_e - 1),
K_2, As_tens * d * α_e + As_comp * d_2 * (α_e - 1),
// Equation from "How to Design Concrete Structures Using Eurocode 2 Chapter-8, Panel-2"
(1 / b) * (SQRT(K_1^2 + 2 * b * K_2) - K_1)
)
);
/**The second moment of area of an uncracked reinforced-concrete section, in mm^4.
Depths are to be given from the compression face.
*/
Get_I_Uncracked_mm4 = LAMBDA(breadth_mm, height_mm, As_prov_compression_per_m, As_prov_tension_per_m, d_compression_mm, d_tension_mm, E_LT_GPa,
LET(
b, breadth_mm,
h, height_mm,
As_comp_per_m, As_prov_compression_per_m,
As_tens_per_m, As_prov_tension_per_m,
As_comp, As_comp_per_m * (b / 1000),
As_tens, As_tens_per_m * (b / 1000),
d_2, d_compression_mm,
d, d_tension_mm,
E_s_GPa, Concrete.Get_E_s(),
// Calculatating centroid of equivalent section from top fiber
α_e, E_s_GPa / E_LT_GPa, // modular ratio
A_gross, b * h,
A_eff_comp, (α_e - 1) * As_comp,
A_eff_tens, (α_e - 1) * As_tens,
// Distance to neutral axis from top
x_u, Get_Depth_to_Neutral_Axis_Uncracked_mm(b, h, As_comp_per_m, As_tens_per_m, d_2, d, E_LT_GPa),
// Equation from "How to Design Concrete Structures Using Eurocode 2 Chapter-8, Panel-2"
(b * h^3 / 12) + b * h * (h/2 - x_u)^2 + (α_e - 1) * (As_tens * (d - x_u)^2 + As_comp * (x_u - d_2)^2)
)
);
/**The second moment of area of a cracked reinforced-concrete section, in mm^4.
Depths are to be given from the compression face.
*/
Get_I_Cracked_mm4 = LAMBDA(breadth_mm, As_prov_compression_per_m, As_prov_tension_per_m, d_compression_mm, d_tension_mm, E_LT_GPa,
LET(
b, breadth_mm,
As_comp_per_m, As_prov_compression_per_m,
As_tens_per_m, As_prov_tension_per_m,
As_comp, As_comp_per_m * (b / 1000),
As_tens, As_tens_per_m * (b / 1000),
d_2, d_compression_mm,
d, d_tension_mm,
E_s_GPa, Concrete.Get_E_s(),
// Calculatating centroid of equivalent section from top fiber
α_e, E_s_GPa / E_LT_GPa, // modular ratio
A_eff_comp, (α_e - 1) * As_comp,
A_eff_tens, (α_e - 1) * As_tens,
// Distance to neutral axis from top
x_c, Get_Depth_to_Neutral_Axis_Cracked_mm(b, As_comp_per_m, As_tens_per_m, d_2, d, E_LT_GPa),
// Equation from "How to Design Concrete Structures Using Eurocode 2 Chapter-8, Panel-2"
(b * x_c^3 / 3) + α_e * As_tens * (d - x_c)^2 + (α_e - 1) * As_comp * (d_2 - x_c)^2
)
);
/**Elastic section modulus in mm^3.
The depth to the neutral axis given must be measured from the compression face.
*/
Get_Elastic_Section_Modulus_mm3 = LAMBDA(second_moment_of_area_mm4, height_mm, [neutral_axis_depth],
LET(
h, height_mm,
x_u, IF(ISOMITTED(neutral_axis_depth), h / 2, neutral_axis_depth),
I, second_moment_of_area_mm4,
I / (h - x_u)
)
);
/**The distribution coefficient is used to find flexural curvature or deflection.
Use: β = 0.5 for sustained loads (default), β = 1.0 for short-term loading & β = 0.7 for construction loads.
Ref: EC2 §7.4.3(3)(7.19)
*/
Get_Distribution_Coefficient_ζ = LAMBDA(cracking_moment, bending_moment, [β],
LET(
M_cr, cracking_moment,
M, bending_moment,
_β, IF(ISOMITTED(β), 0.5, β),
1 - _β * (M_cr / M)^2
)
);
/**Autogenous shrinkage strain (at time t in days), in με.
Ref: EC2 §3.1.4(6)(3.11)
*/
Get_Autogenous_Shrinkage_Strain_time_ε_ca_t = LAMBDA(f_ck28days, time_in_days,
LET(
t, time_in_days,
ε_ca_∞, Get_Autogenous_Shrinkage_Strain_final_ε_ca_∞(f_ck28days),
β_as_t, 1 - EXP(-0.2 * SQRT(t)),
β_as_t * ε_ca_∞
)
);
/**Final autogenous shrinkage strain, in με.
Ref: EC2 §3.1.4(6)(3.12)
*/
Get_Autogenous_Shrinkage_Strain_final_ε_ca_∞ = LAMBDA(f_ck28days,
2.5 * (f_ck28days - 10)
);
/**Autogenous shrinkage strain at time t in days (με). Binder types = {"portland cement", "silica fume", "fly ash", "ggbs"}
percent_binder should be given if binder_type is given. percent binder is given as a percent of total binder weight.
Ref: CIRIA C766 A4.6
*/
Get_Autogenous_Shrinkage_Strain_CIRIA_C766 = LAMBDA(time_in_days, water_binder_ratio, [binder_type], [percent_binder],
LET(
t, time_in_days,
w_b, water_binder_ratio,
_binder, IF(ISOMITTED(binder_type), "portland cement", LOWER(binder_type)),
_percent_binder, IF(ISOMITTED(percent_binder), 0, percent_binder),
ε_ca_CEM_1, 240 * t^0.15 - 650 * (w_b),
// The mod_factor is a tuple of: {percent change to ε_ca_CEM_1, for every percent of binder}
mod_factor, IFS(
_binder = "portland cement", {1, 0},
_binder = "silica fume", {0.1, 1}, //i.e increase by 10% for every 1% of silica fume
OR(_binder = "pulverised fly ash", _binder = "pulverised fuel ash", _binder = "fly ash", _binder = "fuel ash", _binder = "fa", _binder = "pfa"),
{-0.01, 1}, //i.e reduce by 1% for every 1% of fly ash
_binder = "ggbs", {0.08, 0.1} //i.e increase by 8% for every 10% of ggbs
),
IFNA(ε_ca_CEM_1 + (ε_ca_CEM_1 * PRODUCT(mod_factor) * _percent_binder),"Invalid binder")
)
);
/**Basic drying shrinkage strain, in με.
Ref: EC2 §3.1.4(6)(3.9) & Annex B.2 (B.11)(B.12)
*/
Get_Basic_Drying_Shrinkage_Strain_ε_cd_0 = LAMBDA(f_ck28days, relative_humidity_percent, [cement_class],
LET(
f_ck, f_ck28days,
_cement_class, IF(ISOMITTED(cement_class), "R", UPPER(cement_class)),
f_cm, Get_f_cm(f_ck),
f_cmo, 10,
α_ds1, IFS(
_cement_class = "S", 3,
_cement_class = "N", 4,
_cement_class = "R", 6
),
α_ds2, IFS(
_cement_class = "S", 0.13,
_cement_class = "N", 0.12,
_cement_class = "R", 0.11
),
RH, relative_humidity_percent,
RH_0, 100,
β_RH, 1.55 * (1 - (RH / RH_0)^3),
0.85 * β_RH * ((220 + 110 * α_ds1) * EXP(-α_ds2 * f_cm / f_cmo))
)
);
/**Basic drying shrinkage strain (at time t in days), in με.
Ref: EC2 §3.1.4(6)(3.9)
*/
Get_Drying_Shrinkage_Strain_ε_cd_t = LAMBDA(
f_ck28days,
relative_humidity_percent,
cross_sectional_area_mm2,
perimeter_exposed_to_drying_mm,
time_in_days_at_consideration,
time_in_days_of_beginning_of_drying,
[cement_class],
LET(
A_c, cross_sectional_area_mm2,
u, perimeter_exposed_to_drying_mm,
RH, relative_humidity_percent,
h_0, Get_h_0(A_c, u),
t, time_in_days_at_consideration,
t_s, time_in_days_of_beginning_of_drying,
_cement_class, IF(ISOMITTED(cement_class), "R", UPPER(cement_class)),
ε_cd_∞, Get_Final_Drying_Shrinkage_Strain_ε_cd_∞(f_ck28days, RH, A_c, u, _cement_class),
β_as_t, (t - t_s) / ((t - t_s) + 0.04 * SQRT(h_0^3)),
β_as_t * ε_cd_∞
)
);
/**Final drying shrinkage strain, in με.
Ref: EC2 §3.1.4(6)(3.8)(3.9) & Table 3.3
*/
Get_Final_Drying_Shrinkage_Strain_ε_cd_∞ = LAMBDA(
f_ck28days,
relative_humidity_percent,
cross_sectional_area_mm2,
perimeter_exposed_to_drying_mm,
[cement_class],
LET(
_cement_class, IF(ISOMITTED(cement_class), "R", UPPER(cement_class)),
ε_cd_0, Get_Basic_Drying_Shrinkage_Strain_ε_cd_0(f_ck28days, relative_humidity_percent, _cement_class),
A_c, cross_sectional_area_mm2,
u, perimeter_exposed_to_drying_mm,
h_0, Get_h_0(A_c, u),
// Linearly interpolating between values of h_0 for k_h from Table 3.3
k_h, IFS(
h_0 <= 100, 1,
h_0 >= 500, 0.7,
h_0 <= 200, FORECAST(h_0, {1, 0.85}, {100, 200}),
h_0 <= 300, FORECAST(h_0, {0.85, 0.75}, {200, 300}),
h_0 <= 500, FORECAST(h_0, {0.75, 0.7}, {300, 500})
),
k_h * ε_cd_0
)
);
/**Total free shrinkage strain, in με.
Ref: EC2 §3.1.4(3.8)
*/
Get_Total_Shrinkage_Strain_ε_cs = LAMBDA(drying_shrinkage_strain_ε_cd, autogenous_shrinkage_strain_ε_ca,
drying_shrinkage_strain_ε_cd + autogenous_shrinkage_strain_ε_ca
);
/**Long-term elastic modulus of concrete considering creep and loading history, in GPa.
Five loads max. Possible loads: striking formwork, casting floor above, partitions, finishes etc.
*/
Get_E_LT = LAMBDA(
E_cm_28days,
serviceability_load_1,
final_creep_coefficient_1,
[serviceability_load_2],
[final_creep_coefficient_2],
[serviceability_load_3],
[final_creep_coefficient_3],
[serviceability_load_4],
[final_creep_coefficient_4],
[serviceability_load_5],
[final_creep_coefficient_5],
LET(
E_cm, E_cm_28days,
W_1, serviceability_load_1,
ϕ_∞_t0_1, final_creep_coefficient_1,
E_c_eff_1, Get_E_c_eff(E_cm_28days, ϕ_∞_t0_1),
W_2, IF(ISOMITTED(serviceability_load_2), 0, serviceability_load_2),
ϕ_∞_t0_2, IF(OR(ISOMITTED(final_creep_coefficient_2), W_2 = 0), 0, final_creep_coefficient_2),
E_c_eff_2, Get_E_c_eff(E_cm_28days, ϕ_∞_t0_2),
W_3, IF(ISOMITTED(serviceability_load_3), 0, serviceability_load_3),
ϕ_∞_t0_3, IF(OR(ISOMITTED(final_creep_coefficient_3), W_3 = 0), 0, final_creep_coefficient_3),
E_c_eff_3, Get_E_c_eff(E_cm_28days, ϕ_∞_t0_3),
W_4, IF(ISOMITTED(serviceability_load_4), 0, serviceability_load_4),
ϕ_∞_t0_4, IF(OR(ISOMITTED(final_creep_coefficient_4), W_4 = 0), 0, final_creep_coefficient_4),
E_c_eff_4, Get_E_c_eff(E_cm_28days, ϕ_∞_t0_4),
W_5, IF(ISOMITTED(serviceability_load_5), 0, serviceability_load_5),
ϕ_∞_t0_5, IF(OR(ISOMITTED(final_creep_coefficient_5), W_5 = 0), 0, final_creep_coefficient_5),
E_c_eff_5, Get_E_c_eff(E_cm_28days, ϕ_∞_t0_5),
SUM(W_1, W_2, W_3, W_4, W_5) / SUM(W_1/E_c_eff_1, W_2/E_c_eff_2, W_3/E_c_eff_3, W_4/E_c_eff_4, W_5/E_c_eff_5)
)
);
/**Notional size of member. Used for determining creep factor.
Ref: EC2 §3.1.4(5)
*/
Get_h_0 = LAMBDA(cross_sectional_area_mm2, perimeter_exposed_to_drying_mm,
LET(
A_c, cross_sectional_area_mm2,
u, perimeter_exposed_to_drying_mm,
2 * A_c / u
)
);
/**Flexural curvature is used to find deflection. Units: 1/m.
Curvature = 1 / r_fl, where r_fl = flexural radius in m.
Ref: EC2 §7.4.3(3)(7.18)
*/
Get_Flexural_Curvature = LAMBDA(moment_quasi_perm_kNm, distribution_coefficient_ζ, uncracked_I_mm4, cracked_I_mm4, E_LT_GPa,
LET(
ζ, distribution_coefficient_ζ,
E_e, E_LT_GPa * 1000,
I_u, uncracked_I_mm4,
I_c, cracked_I_mm4,
M_QP, moment_quasi_perm_kNm * 10^6,
(M_QP / E_e) * (ζ / I_c + (1 - ζ) / I_u) / 1000
)
);
/**Shrinkage curvature is used to find deflection. Units: 1/m.
Curvature = 1 / r_cs, where r_cs = shrinkage radius in m.
Ref: EC2 §7.4.3(6)(7.21)
*/
Get_Shrinkage_Curvature = LAMBDA(
breadth_mm,
height_mm,
As_prov_compression_per_m,
As_prov_tension_per_m,
d_compression_mm,
d_tension_mm,
E_LT_GPa,
distribution_coefficient_ζ,
total_shrinkage_strain_ε_cs_με, //drying + autogenous
LET(
b, breadth_mm,
h, height_mm,
As_comp_per_m, As_prov_compression_per_m,
As_tens_per_m, As_prov_tension_per_m,
As_comp, As_comp_per_m * (b / 1000),
As_tens, As_tens_per_m * (b / 1000),
d_2, d_compression_mm,
d, d_tension_mm,
E_s_GPa, Get_E_s(),
ζ, distribution_coefficient_ζ,
ε_cs, total_shrinkage_strain_ε_cs_με,
α_e, E_s_GPa / E_LT_GPa, // modular ratio
// Distance to neutral axis from top
x_u, Get_Depth_to_Neutral_Axis_Uncracked_mm(b, h, As_comp_per_m, As_tens_per_m, d_2, d, E_LT_GPa),
x_c, Get_Depth_to_Neutral_Axis_Cracked_mm(b, As_comp_per_m, As_tens_per_m, d_2, d, E_LT_GPa),
I_u, Get_I_Uncracked_mm4(b, h, As_comp_per_m, As_tens_per_m, d_2, d, E_LT_GPa),
I_c, Get_I_Cracked_mm4(b, As_comp_per_m, As_tens_per_m, d_2, d, E_LT_GPa),
S_u, As_tens * (d - x_u) - As_comp * (x_u - d_2),
S_c, As_tens * (d - x_c) - As_comp * (x_c - d_2),
(α_e * ε_cs) * (ζ * S_u / I_u + (1 - ζ) * S_c / I_c)
)
);
/**Ratio of redistributed moment to the elastic bending moment.
Ref: EC2 §5.5(4)(5.10a&b)
*/
Get_Ratio_of_Redistributed_Moment_to_Elastic_Moment_δ = LAMBDA(f_ck28days, depth_to_uncracked_neutral_axis_mm, effective_depth_mm,
LET(
x_u, depth_to_uncracked_neutral_axis_mm,
d, effective_depth_mm,
ε_cu2, Get_ε_cu2(f_ck28days),
k_1, 0.4,
k_2, 0.6 + 0.0014 / ε_cu2,
k_1 + k_2 * x_u / d
)
);
/**Total curvature is used to find deflection. Units: 1/m.
Ref: EC2 §7.4.3(3)(7.18)
*/
Get_Total_Curvature = LAMBDA(flexural_curvature, shrinkage_curvature,
flexural_curvature + shrinkage_curvature
);
/**Allowable span to depth ratio.
K = 1.0 for simply supported member.
K = 1.3 for end span of continuous member.
K = 1.5 for interior span of continuous member.
K = 1.2 for flat slabs (with longer span).
K = 0.4 for cantilever.
effective_length_modification_factor is used for long members supporting brittle partitions.
For beams = 7 / l_eff, for slabs = 8.5 / l_eff.
l_eff = length from centre-lines of supports.
Ref: EC2 §7.4.2(2)(7.16.a)(7.16.b)
*/
Get_Allowable_Span_to_Depth_Ratio = LAMBDA(
f_ck28days,
b_w_mm,
d_mm,
As_req_compression_per_m,
As_req_tension_per_m,
As_prov_tension_per_m,
structural_system_factor,
depth_to_uncracked_neutral_axis_mm,
[effective_length_modification_factor],
[is_moment_redistributed],
[ratio_of_b_eff_to_b_w],
[f_yk],
LET(
f_ck, f_ck28days,
_ratio_of_b_eff_to_b_w, IF(ISOMITTED(ratio_of_b_eff_to_b_w), 1, ratio_of_b_eff_to_b_w),
_l_eff_mod, IF(ISOMITTED(effective_length_modification_factor), 1, effective_length_modification_factor),
_f_yk, IF(ISOMITTED(f_yk), 500, f_yk),
A_s_req_comp_per_m, As_req_compression_per_m,
A_s_req_tens_per_m, As_req_tension_per_m,
A_s_prov_tens_per_m, As_prov_tension_per_m,
A_s_req_comp, (b_w_mm / 1000) * A_s_req_comp_per_m,
A_s_req_tens, (b_w_mm / 1000) *A_s_req_tens_per_m,
A_s_prov_tens, (b_w_mm / 1000) * A_s_prov_tens_per_m,
ρ_0, SQRT(f_ck) / 10^3,
ρ_tens, A_s_req_tens / (b_w_mm * d_mm),
ρ_comp, A_s_req_comp / (b_w_mm * d_mm),
_is_moment_redistributed, IF(ISOMITTED(is_moment_redistributed), FALSE, is_moment_redistributed),
x_u, depth_to_uncracked_neutral_axis_mm,
δ, IF(_is_moment_redistributed, Get_Ratio_of_Redistributed_Moment_to_Elastic_Moment_δ(f_ck, x_u, d_mm), 1),
K, structural_system_factor,
F_1, IFS(
_ratio_of_b_eff_to_b_w = 1, 1,
_ratio_of_b_eff_to_b_w >= 3, 0.8,
_ratio_of_b_eff_to_b_w < 3, FORECAST(_ratio_of_b_eff_to_b_w, {1, 0.8}, {1, 3})
),
F_2, _l_eff_mod,
F_3, MIN(
(500 * A_s_prov_tens * δ) / (_f_yk * A_s_req_tens),
1.5
),
N, IF(ρ_tens <= ρ_0,
11 + 1.5 * SQRT(f_ck) * ρ_0 / ρ_tens + 3.2 * SQRT(f_ck) * (ρ_0 / ρ_tens - 1)^(3/2),
11 + 1.5 * SQRT(f_ck) * ρ_0 / (ρ_tens - ρ_comp) + (1 / 12) * SQRT(f_ck) * SQRT(ρ_comp / ρ_0)
),
l_d_ratio, N * K * F_1 * F_2 * F_3,
MIN(40 * K, l_d_ratio)
)
);
/**Finds minimum height of section to satisfy ULS.
*/
Find_Height_of_Section_mm = LAMBDA(
width_mm,
M_Ed_kNm,
V_Ed_kN,
concrete_grade,
c_nom_top,
c_nom_bottom,
bar_diameter_compression,
bar_diameter_tension,
bar_spacing_compression,
bar_spacing_tension,
[link_diameter],
[link_spacing],
[number_of_link_legs],
[cement_class],
[aggregate_type],
[angle_of_links_degs],
[top_bar_layer],
[bottom_bar_layer],
[bar_diameter_trans_top],
[bar_diameter_trans_bottom],
[N_Ed_kN],
[f_yk],
[γ_c],
[initial_height_mm],
[height_increment_mm],
[height_mm],
[counter],
[is_Pass],
LET(
b, width_mm,
M_Ed, M_Ed_kNm,
V_Ed, V_Ed_kN,
f_ck, Get_f_ck(concrete_grade),
ø_comp, bar_diameter_compression,
ø_tens, bar_diameter_tension,
ø_link, IF(ISOMITTED(link_diameter), 10, link_diameter),
s_comp, bar_spacing_compression,
s_tens, bar_spacing_tension,
s_link, IF(ISOMITTED(link_spacing), 200, link_spacing),
legs, IF(ISOMITTED(number_of_link_legs), MIN(ROUNDUP(b / 200, 0), 2), number_of_link_legs),
_cement_class, IF(ISOMITTED(cement_class), "", cement_class),
_aggregate_type, IF(ISOMITTED(aggregate_type), "", aggregate_type),
α_degs, IF(ISOMITTED(angle_of_links_degs), 90, angle_of_links_degs),
top_layer, IF(ISOMITTED(top_bar_layer), 1, top_bar_layer),
bottom_layer, IF(ISOMITTED(bottom_bar_layer), 1, bottom_bar_layer),
ø_trans_top, IF(ISOMITTED(bar_diameter_trans_top), 20, bar_diameter_trans_top),
ø_trans_bottom, IF(ISOMITTED(bar_diameter_trans_bottom), 20, bar_diameter_trans_bottom),
N_Ed, IF(ISOMITTED(N_Ed_kN), 0, N_Ed_kN),
_f_yk, IF(ISOMITTED(f_yk), 500, f_yk),
_γ_c, IF(ISOMITTED(γ_c), 1.5, γ_c),
α_cc, 0.85,
α_cc_τ, 1,
h_increment, ABS(IF(ISOMITTED(height_increment_mm), 10, height_increment_mm)),
h_0, IF(ISOMITTED(initial_height_mm), 400, initial_height_mm),
h, IF(ISOMITTED(height_mm), h_0, height_mm),
d, Get_Effective_Depth_Tension(h, c_nom_bottom, ø_tens, ø_link, bottom_layer, ø_trans_bottom),
d_2, Get_Effective_Depth_Compression(c_nom_top, ø_comp, ø_link, top_layer, ø_trans_top),
// Bending Check
M_Rd, Get_M_Rd_kNm(f_ck, b, d),
As_min, Get_A_s_min(f_ck, d, _f_yk),
As_max, Get_A_s_max(h),
As2_req, Get_A_s_req_c(M_Rd, M_Ed, d, d_2, b, _f_yk),
As_req, Get_A_s_req_t(M_Rd, M_Ed, d, b, As2_req, _f_yk),
As2_prov, Get_A_s_prov(ø_comp, s_comp),
As_prov, Get_A_s_prov(ø_tens, s_tens),
UR_bending_comp, As2_req / As2_prov,
UR_bending_tens, IF(As_prov > As_max, MAX(As_req, As_max), As_req) / As_prov,
// Shear Checks
// Unreinforced
f_cd, Get_f_cd(f_ck,,γ_c),
σ_cp, Get_Compressive_Stress(f_ck, d, b, N_Ed, _γ_c),
v_min, Get_v_min(f_ck, d),
V_Rd_c, Get_V_Rd_c_kN(f_ck, σ_cp, b, d, As_prov, _γ_c),
UR_shear_unreinforced, V_Ed / V_Rd_c,
// Reinforced
is_Reinforced, IF(
OR(
ISOMITTED(link_diameter),
ISOMITTED(link_spacing),
ISOMITTED(number_of_link_legs),
s_link = 0,
ø_link = 0,
legs = 0
),
FALSE,
TRUE
),
V_Rd, IF(is_Reinforced,
LET(
Asw_prov, Get_A_sw_prov(ø_link, legs),
θ_actual, Get_Angle_of_Strut(f_ck, b, d, V_Ed, α_degs, σ_cp, , α_cc_τ),
V_Rd_s, Get_V_Rd_s_kN(f_ck, b, d, Asw_prov, s_link, θ_actual, α_degs, , _f_yk),
V_Rd_max, Get_V_Rd_max_kN(f_ck, b, d, θ_actual, α_degs, σ_cp, , α_cc_τ, _f_yk),
MIN(V_Rd_s, V_Rd_max)
)
),
UR_shear_reinforced, V_Ed / V_Rd,
// Checking if all checks are passed or not
is_Pass_prev, IF(ISOMITTED(is_Pass), FALSE, is_Pass),
is_Pass, IF(is_Reinforced,
IF(AND(
UR_bending_comp <= 1,
UR_bending_tens <= 1,
UR_shear_reinforced <= 1
),
TRUE,
FALSE
),
IF(AND(
UR_bending_comp <= 1,
UR_bending_tens <= 1,
UR_shear_unreinforced <= 1
),
TRUE,
FALSE
)
),
// Iteration count
_counter, IF(ISOMITTED(counter), 0, counter + 1),
can_Stop_Iterating, IF(
OR(
AND(is_Pass = TRUE, is_Pass_prev = FALSE, _counter <> 0),
AND(is_Pass = FALSE, is_Pass_prev = TRUE),
),
TRUE,
FALSE
),
h_next, h + h_increment * IF(is_Pass, -1, 1),
IF(can_Stop_Iterating,
IF(is_Pass, h, h_next),
IF(_counter = 100,
"Could not converge",
Find_Height_of_Section_mm(
b,
M_Ed,
V_Ed,
concrete_grade,
c_nom_top,
c_nom_bottom,
ø_comp,
ø_tens,
s_comp,
s_tens,
ø_link,
s_link,
legs,
_cement_class,
_aggregate_type,
α_degs,
top_layer,
bottom_layer,
ø_trans_top,
ø_trans_bottom,
N_Ed,
_f_yk,
_γ_c,
h_0,
h_increment,
h_next,
_counter,
is_Pass
)
)
)
)
);
/**Maximum allowable bar diameter for a given bar stress and crack width based on Table 7.2N.
Ref: EC2 §7.3.3(2) & Table 7.2N
*/
Get_Max_Bar_Diameter_for_Crack_Control = LAMBDA(steel_stress_quasi_perm_MPa, crack_width_limit_mm, [isRoundedDown],
LET(
_isRoundedDown, IF(ISOMITTED(isRoundedDown), TRUE, isRoundedDown),
σ_s, steel_stress_quasi_perm_MPa,
w_max, VALUE(crack_width_limit_mm),
// Table 7.2N
// Headers: stress, w_k = 0.4, w_k = 0.3, w_k = 0.2
//! Extra low stress row added: not in code but ok looking at Concrete Centre graphs
stress_bar_table, {
120, 40, 40, 32;
160, 40, 32, 25;
200, 32, 25, 16;
240, 20, 16, 12;
280, 16, 12, 8;
320, 12, 10, 6;
360, 10, 8, 5;
400, 8, 6, 4;
450, 6, 5, "-"
},
// Bar column to take for lookup
bar_column_index, IFS(
w_max >= 0.4, 2,
w_max = 0.3, 3,
w_max = 0.2, 4
),
stress_bar_table_decending, SORT(stress_bar_table, 1, -1),
stresses_descending, CHOOSECOLS(stress_bar_table_decending, 1),
bars_ascending, CHOOSECOLS(stress_bar_table_decending, bar_column_index),
σ_s_row_index_higher, MATCH(σ_s, stresses_descending, -1),
σ_s_row_index_lower, MIN(σ_s_row_index_higher + 1, ROWS(stress_bar_table)),
σ_s_row_lower, INDEX(stresses_descending, σ_s_row_index_lower),
σ_s_row_higher, INDEX(stresses_descending, σ_s_row_index_higher),
larger_bar_diameter, INDEX(bars_ascending, σ_s_row_index_lower),
smaller_bar_diameter, INDEX(bars_ascending, σ_s_row_index_higher),
stress_range, HSTACK(σ_s_row_lower, σ_s_row_higher),
smaller_bar_area, PI() * smaller_bar_diameter^2 / 4,
larger_bar_area, PI() * larger_bar_diameter^2 / 4,
area_range, HSTACK(larger_bar_area, smaller_bar_area),
area_exact, IF(larger_bar_diameter = smaller_bar_diameter,
larger_bar_area,
FORECAST(σ_s, area_range, stress_range)
),
equivalent_bar_diameter, SQRT(4 * area_exact / PI()),
bars, {4, 5, 6, 8, 10, 12, 16, 20, 25, 32, 40},
nearest_smaller_bar_diameter_index, MATCH(equivalent_bar_diameter, bars, 1),
IFNA(
IF(_isRoundedDown,
INDEX(bars_ascending, nearest_smaller_bar_diameter_index),
equivalent_bar_diameter
),
"Stress too high"
)
)
);
Get_Max_Bar_Diameter_for_Crack_Control_Modified = LAMBDA(
f_ck,
k_c,
h_mm,
d_mm,
depth_to_neutral_axis_uncracked_mm,
ø_max_crack_star,
[load_type],
[isRoundedDown],
LET(
_isRoundedDown, IF(ISOMITTED(isRoundedDown), TRUE, isRoundedDown),
f_ctm, Get_f_ctm(f_ck),
x_u, depth_to_neutral_axis_uncracked_mm,
h_cr, h_mm - x_u,
_load_type, IF(ISOMITTED(load_type), "bending", LOWER(load_type)),
ø_max_crack, IFNA(
ø_max_crack_star * IF(_load_type = "bending",
(f_ctm / 2.9) * k_c * h_cr / (2 * (h_mm - d_mm)),
// for pure tension, x_u = 0, therefore h_cr = h
(f_ctm / 2.9) * h_mm / (8 * (h_mm - d_mm))
),
"Stress too high"
),
IF(AND(_isRoundedDown, ISNONTEXT(ø_max_crack)),
LET(
bars, {4, 5, 6, 8, 10, 12, 16, 20, 25, 32, 40},
nearest_smaller_bar_diameter_index, MATCH(ø_max_crack, bars, 1),
INDEX(bars, nearest_smaller_bar_diameter_index)
),
ø_max_crack
)
)
);
/**Maximum allowable bar spacing for a given bar stress and crack width based on Table 7.3N.
Ref: EC2 §7.3.3(2) & Table 7.3N
*/
Get_Max_Bar_Spacing_for_Crack_Control = LAMBDA(steel_stress_quasi_perm_MPa, crack_width_limit_mm, [isRoundedDown], [roundTo_mm],
LET(
_isRoundedDown, IF(ISOMITTED(isRoundedDown), TRUE, isRoundedDown),
_roundTo_mm, IF(ISOMITTED(roundTo_mm), 25, roundTo_mm),
σ_s, steel_stress_quasi_perm_MPa,
w_max, VALUE(crack_width_limit_mm),
// Table 7.3N
// Headers: stress, w_k = 0.4, w_k = 0.3, w_k = 0.2
stress_spacing_table, {
160, 300, 300, 200;
200, 300, 250, 150;
240, 250, 200, 100;
280, 200, 150, 50;
320, 150, 100, "-";
360, 100, 50, "-"
},
// Bar column to take for lookup
spacing_column_index, IFS(
w_max >= 0.4, 2,
w_max = 0.3, 3,
w_max = 0.2, 4
),
stress_bar_table_decending, SORT(stress_spacing_table, 1, -1),
stresses, CHOOSECOLS(stress_bar_table_decending, 1),
σ_s_row_index_lower, MATCH(σ_s, stresses, -1),
σ_s_row_index_upper, MIN(σ_s_row_index_lower + 1, ROWS(stress_spacing_table)),
σ_s_row_lower, INDEX(stresses, σ_s_row_index_lower),
σ_s_row_upper, INDEX(stresses, σ_s_row_index_upper),
lower_spacing, INDEX(stress_bar_table_decending, σ_s_row_index_lower, spacing_column_index),
upper_spacing, INDEX(stress_bar_table_decending, σ_s_row_index_upper, spacing_column_index),
stress_range, HSTACK(σ_s_row_lower, σ_s_row_upper),
spacing_range, HSTACK(lower_spacing, upper_spacing),
spacing_exact, IF(lower_spacing = upper_spacing,
upper_spacing,
FORECAST(σ_s, spacing_range, stress_range)
),
IFNA(
IF(_isRoundedDown,
FLOOR.MATH(spacing_exact, _RoundTo_mm),
spacing_exact
),
"Stress too high"
)
)
);
/**Solver for maximum allowable bar spacing for a given bar stress and crack width based on Table 7.3N.
Ref: EC2 §7.3.3(2) & Table 7.3N
*/
Find_Max_Spacing_for_Crack_Control_Iteratively = LAMBDA(
w_max,
M_QP,
M_Ed,
As_req_ULS_per_m,
ø_prov,
[isRoundedDown],
[roundTo_mm],
[S_prov],
[counter],
LET(
_isRoundedDown, IF(ISOMITTED(isRoundedDown), TRUE, isRoundedDown),
_roundTo_mm, IF(ISOMITTED(roundTo_mm), 25, roundTo_mm),
S_0, IFS(
w_max = 0.4, 300,
w_max = 0.3, 300,
w_max = 0.2, 200
),
_S_prov, IF(ISOMITTED(S_prov), S_0, S_prov),
As_req, As_req_ULS_per_m,
As_prov, Get_A_s_prov(ø_prov, _S_prov),
σ_s_QP, Get_σ_sd(As_req, As_prov) * (M_QP / M_Ed),
S_max, Get_Max_Bar_Spacing_for_Crack_Control(σ_s_QP, w_max, FALSE),
isStressTooHigh, IF(ISTEXT(S_max), TRUE, FALSE),
_counter, IF(ISOMITTED(counter), 0, counter + 1),
IF(_counter < 50,
IF(isStressTooHigh,
Find_Max_Spacing_for_Crack_Control_Iteratively(w_max, M_QP, M_Ed, As_req_ULS_per_m, ø_prov, _isRoundedDown, _roundTo_mm, _S_prov - 5, _counter),
IF(S_max <= _S_prov,
Find_Max_Spacing_for_Crack_Control_Iteratively(w_max, M_QP, M_Ed, As_req_ULS_per_m, ø_prov, _isRoundedDown, _roundTo_mm, _S_prov - 5, _counter),
Get_Max_Bar_Spacing_for_Crack_Control(σ_s_QP, w_max, _isRoundedDown, _roundTo_mm)
)
),
Get_Max_Bar_Spacing_for_Crack_Control(σ_s_QP, w_max, _isRoundedDown, _roundTo_mm)
)
)
);
/**Solver for maximum allowable bar spacing for a given bar stress and crack width based on Table 7.3N.
Ref: EC2 §7.3.3(2) & Table 7.3N
*/
Find_Max_Bar_Diameter_for_Crack_Control_Iteratively = LAMBDA(
w_max,
M_QP,
M_Ed,
S_prov,
A_s_req_comp_per_m,
A_s_prov_comp_per_m,
h,
b,
f_ck,
c_nom,
k_c,
depth_to_comp_bars_mm,
[ø_link],
[reinforcement_layer],
[ø_trans],
[f_yk],
[load_type],
[aggregate_type],
[isRoundedDown],
[ø_prov],
[counter],
LET(
_isRoundedDown, IF(ISOMITTED(isRoundedDown), FALSE, isRoundedDown),
d_2, depth_to_comp_bars_mm,
_aggregate_type, IF(ISOMITTED(aggregate_type), "", aggregate_type),
E_cm, Get_E_cm(f_ck, _aggregate_type),
_load_type, IF(ISOMITTED(load_type), "bending", LOWER(load_type)),
_ø_trans, IF(ISOMITTED(ø_trans), 20, ø_trans),
_ø_link, IF(ISOMITTED(ø_link), 10, ø_link),
_layer, IF(ISOMITTED(reinforcement_layer), 1, reinforcement_layer),
ø_0, IFS(
w_max = 0.4, 40,
w_max = 0.3, 40,
w_max = 0.2, 32
),
_ø_prov, IF(ISOMITTED(ø_prov), ø_0, ø_prov),
d, Get_Effective_Depth_Tension(h, c_nom, _ø_prov, _ø_link, _layer, _ø_trans),
As_prov_init, Get_A_s_prov(_ø_prov, S_prov),
M_Rd, Get_M_Rd_kNm(f_ck, b, d),
_f_yk, IF(ISOMITTED(f_yk), 500, f_yk),
As_req, Get_A_s_req_t(M_Rd, M_Ed, d, b, A_s_req_comp_per_m, _f_yk),
σ_s_QP, Get_σ_sd(As_req, As_prov_init) * (M_QP / M_Ed),
ø_max_exact_unmodified, Get_Max_Bar_Diameter_for_Crack_Control(σ_s_QP, w_max, FALSE),
As_prov, Get_A_s_prov(ø_max_exact_unmodified, S_prov),
x_u, Get_Depth_to_Neutral_Axis_Uncracked_mm(b, h, A_s_prov_comp_per_m, As_prov, d_2, d, E_cm),
ø_max_exact_modified, Get_Max_Bar_Diameter_for_Crack_Control_Modified(f_ck, k_c, h, d, x_u, ø_max_exact_unmodified, _load_type, _isRoundedDown),
isStressTooHigh, IF(OR(ISTEXT(ø_max_exact_modified), ISTEXT(ø_max_exact_unmodified)), TRUE, FALSE),
_counter, IF(ISOMITTED(counter), 0, counter + 1),
ø_prov_area, PI() * _ø_prov^2 / 4,
ø_max_area, PI() * ø_max_exact_modified^2 / 4,
ø_prov_next, SQRT(4 * 0.95 * ø_prov_area / PI()),
IF(_counter < 50,
IF(isStressTooHigh,
"Stress too high",
IF(_isRoundedDown, // Escapes here with rounded value
ø_max_exact_modified,
// Escape condition
IF(ø_max_exact_modified > _ø_prov,
//Escape condition met, runs again to return an actual bar size (rounds down to nearest)
// By rounding bar diameter down, stress threshold validation may be invalidated
Find_Max_Bar_Diameter_for_Crack_Control_Iteratively(
w_max,
M_QP,
M_Ed,
S_prov,
A_s_req_comp_per_m,
A_s_prov_comp_per_m,
h,
b,
f_ck,
c_nom,
k_c,
d_2,
_ø_link,
_layer,
_ø_trans,
_f_yk,
_load_type,
_aggregate_type,
TRUE,
_ø_prov,
_counter - 1
),
// Keeps iterating until escape condition met or function results in 'Stress too high' condition
Find_Max_Bar_Diameter_for_Crack_Control_Iteratively(
w_max,
M_QP,
M_Ed,
S_prov,
A_s_req_comp_per_m,
A_s_prov_comp_per_m,
h,
b,
f_ck,
c_nom,
k_c,
d_2,
_ø_link,
_layer,
_ø_trans,
_f_yk,
_load_type,
_aggregate_type,
_isRoundedDown,
ø_prov_next,
_counter
)
)
)
),
"Stress too high"
)
)
);
/**The stress in concrete in a cracked section from quasi-permanent bending moment, in N/mm^2.
*/
Get_Concrete_Stress_Cracked_Doubly_Reinforced = LAMBDA(M_QP_kNm, A_s2_prov_per_m, d_mm, d_2_mm, modular_ratio, depth_to_neutral_axis_cracked_mm,
LET(
M_QP, M_QP_kNm * 10^6,
A_s2, A_s2_prov_per_m,
α_e, modular_ratio,
b, 1000,
d, d_mm,
d_2, d_2_mm,
x_c, depth_to_neutral_axis_cracked_mm,
M_QP / (A_s2 * (d - d_2) * (α_e - 1) * ((x_c - d_2) / x_c) + b * (x_c / 2) * (d - x_c / 3))
)
);
/**The stress in reinforcement in a cracked section from quasi-permanent bending moment, in N/mm^2.
*/
Get_Reinforcement_Stress_Cracked_Doubly_Reinforced = LAMBDA(concrete_stress_cracked_MPa, modular_ratio, effective_depth_mm, depth_to_neutral_axis_cracked_mm,
LET(
σ_c, concrete_stress_cracked_MPa,
α_e, modular_ratio,
d, effective_depth_mm,
x_c, depth_to_neutral_axis_cracked_mm,
σ_c * α_e * (d - x_c) / x_c
)
);
/**Tensile stress in reinforcement from bending, in N/mm^2
*/
Get_Reinforcement_Stress_Cracked_Singly_Reinforced = LAMBDA(M_QP_kNm, A_s_prov_per_m, d_mm, depth_to_neutral_axis_cracked_mm,
LET(
M_QP, M_QP_kNm * 10^6,
A_s, A_s_prov_per_m,
x_c, depth_to_neutral_axis_cracked_mm,
M_QP / (A_s * (d_mm - x_c / 3))
)
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment