Last active
April 22, 2024 09:43
-
-
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)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/**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