From 3d5ab1db698d6256c7f3cae0d527228cdf7e535d Mon Sep 17 00:00:00 2001 From: GerjanDorgelo Date: Sun, 4 May 2025 16:09:09 +0200 Subject: [PATCH 1/6] Add formulas 6.39, 6.40, 6.40af, and 6.40aw for reduced bending moment resistance in Eurocode - Implemented Form6Dot39ReducedBendingMomentResistance for formula 6.39. - Implemented Form6Dot40ReducedBendingMomentResistance for formula 6.40. - Implemented Form6Dot40afHollowSections and Form6Dot40afWeldedBoxSections for formula 6.40af. - Implemented Form6Dot40awHollowSections and Form6Dot40awWeldedBoxSections for formula 6.40aw. - Added tests for all new formulas to ensure correct evaluation and error handling. - Updated documentation to reflect the addition of new formulas and their descriptions. --- .../formula_6_39.py | 81 +++++++++ .../formula_6_40.py | 81 +++++++++ .../formula_6_40af.py | 155 ++++++++++++++++++ .../formula_6_40aw.py | 155 ++++++++++++++++++ .../eurocode/ec3_1993_1_1_2016/formulas.md | 6 +- .../test_formula_6_39.py | 77 +++++++++ .../test_formula_6_40.py | 77 +++++++++ .../test_formula_6_40af.py | 131 +++++++++++++++ .../test_formula_6_40aw.py | 131 +++++++++++++++ 9 files changed, 892 insertions(+), 2 deletions(-) create mode 100644 blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_39.py create mode 100644 blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_40.py create mode 100644 blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_40af.py create mode 100644 blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_40aw.py create mode 100644 tests/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/test_formula_6_39.py create mode 100644 tests/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/test_formula_6_40.py create mode 100644 tests/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/test_formula_6_40af.py create mode 100644 tests/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/test_formula_6_40aw.py diff --git a/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_39.py b/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_39.py new file mode 100644 index 000000000..30514c959 --- /dev/null +++ b/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_39.py @@ -0,0 +1,81 @@ +"""Formula 6.39 from NEN-EN 1993-1-1+C2+A1:2016: Chapter 6 - Ultimate Limit State.""" + +from blueprints.codes.eurocode.nen_en_1993_1_1_c2_a1_2016 import NEN_EN_1993_1_1_C2_A1_2016 +from blueprints.codes.formula import Formula +from blueprints.codes.latex_formula import LatexFormula, latex_replace_symbols +from blueprints.type_alias import DIMENSIONLESS, NMM +from blueprints.validations import raise_if_less_or_equal_to_zero, raise_if_negative + + +class Form6Dot39ReducedBendingMomentResistance(Formula): + r"""Class representing formula 6.39 for the calculation of [$M_{N,y,Rd}$].""" + + label = "6.39" + source_document = NEN_EN_1993_1_1_C2_A1_2016 + + def __init__( + self, + mpl_y_rd: NMM, + n: DIMENSIONLESS, + a_w: DIMENSIONLESS, + ) -> None: + r"""[$M_{N,y,Rd}$] Calculation of the reduced bending moment [$Nmm$]. + + NEN-EN 1993-1-1+C2+A1:2016 art.6.2.9 - Formula (6.39) + + Parameters + ---------- + mpl_y_rd : NMM + [$M_{pl,y,Rd}$] Plastic bending moment resistance about the y-axis [$Nmm$]. + n : DIMENSIONLESS + [$n$] Axial force ratio, see equation 6.38n (dimensionless). + a_w : DIMENSIONLESS + [$a_w$] Reduction factor for the web (dimensionless). + """ + super().__init__() + self.mpl_y_rd = mpl_y_rd + self.n = n + self.a_w = a_w + + @staticmethod + def _evaluate( + mpl_y_rd: NMM, + n: DIMENSIONLESS, + a_w: DIMENSIONLESS, + ) -> NMM: + """Evaluates the formula, for more information see the __init__ method.""" + raise_if_negative(mpl_y_rd=mpl_y_rd, n=n, a_w=a_w) + raise_if_less_or_equal_to_zero(denominator=(1 - 0.5 * a_w)) + + return min(mpl_y_rd * (1 - n) / (1 - 0.5 * a_w), mpl_y_rd) + + def latex(self) -> LatexFormula: + """Returns LatexFormula object for formula 6.39.""" + _equation: str = r"\min \left( M_{pl,y,Rd} \cdot \frac{1 - n}{1 - 0.5 \cdot a_w}, M_{pl,y,Rd} \right)" + _numeric_equation: str = latex_replace_symbols( + _equation, + { + r"M_{pl,y,Rd}": f"{self.mpl_y_rd:.3f}", + r" n": f" {self.n:.3f}", + r"a_w": f"{self.a_w:.3f}", + }, + False, + ) + _numeric_equation_with_units: str = latex_replace_symbols( + _equation, + { + r"M_{pl,y,Rd}": rf"{self.mpl_y_rd:.3f} \ Nmm", + r" n": rf" {self.n:.3f}", + r"a_w": rf"{self.a_w:.3f}", + }, + False, + ) + return LatexFormula( + return_symbol=r"M_{N,y,Rd}", + result=f"{self:.3f}", + equation=_equation, + numeric_equation=_numeric_equation, + numeric_equation_with_units=_numeric_equation_with_units, + comparison_operator_label=r"=", + unit="Nmm", + ) diff --git a/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_40.py b/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_40.py new file mode 100644 index 000000000..ded61db50 --- /dev/null +++ b/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_40.py @@ -0,0 +1,81 @@ +"""Formula 6.40 from NEN-EN 1993-1-1+C2+A1:2016: Chapter 6 - Ultimate Limit State.""" + +from blueprints.codes.eurocode.nen_en_1993_1_1_c2_a1_2016 import NEN_EN_1993_1_1_C2_A1_2016 +from blueprints.codes.formula import Formula +from blueprints.codes.latex_formula import LatexFormula, latex_replace_symbols +from blueprints.type_alias import DIMENSIONLESS, NMM +from blueprints.validations import raise_if_less_or_equal_to_zero, raise_if_negative + + +class Form6Dot40ReducedBendingMomentResistance(Formula): + r"""Class representing formula 6.40 for the calculation of [$M_{N,z,Rd}$].""" + + label = "6.40" + source_document = NEN_EN_1993_1_1_C2_A1_2016 + + def __init__( + self, + mpl_z_rd: NMM, + n: DIMENSIONLESS, + a_f: DIMENSIONLESS, + ) -> None: + r"""[$M_{N,z,Rd}$] Calculation of the reduced bending moment [$Nmm$]. + + NEN-EN 1993-1-1+C2+A1:2016 art.6.2.9 - Formula (6.40) + + Parameters + ---------- + mpl_z_rd : NMM + [$M_{pl,z,Rd}$] Plastic bending moment resistance about the z-axis [$Nmm$]. + n : DIMENSIONLESS + [$n$] Axial force ratio, see equation 6.38n (dimensionless). + a_f : DIMENSIONLESS + [$a_f$] Reduction factor for the flange (dimensionless). + """ + super().__init__() + self.mpl_z_rd = mpl_z_rd + self.n = n + self.a_f = a_f + + @staticmethod + def _evaluate( + mpl_z_rd: NMM, + n: DIMENSIONLESS, + a_f: DIMENSIONLESS, + ) -> NMM: + """Evaluates the formula, for more information see the __init__ method.""" + raise_if_negative(mpl_z_rd=mpl_z_rd, n=n, a_f=a_f) + raise_if_less_or_equal_to_zero(denominator=(1 - 0.5 * a_f)) + + return min(mpl_z_rd * (1 - n) / (1 - 0.5 * a_f), mpl_z_rd) + + def latex(self) -> LatexFormula: + """Returns LatexFormula object for formula 6.40.""" + _equation: str = r"\min \left( M_{pl,z,Rd} \cdot \frac{1 - n}{1 - 0.5 \cdot a_f}, M_{pl,z,Rd} \right)" + _numeric_equation: str = latex_replace_symbols( + _equation, + { + r"M_{pl,z,Rd}": f"{self.mpl_z_rd:.3f}", + r" n": f" {self.n:.3f}", + r"a_f": f"{self.a_f:.3f}", + }, + False, + ) + _numeric_equation_with_units: str = latex_replace_symbols( + _equation, + { + r"M_{pl,z,Rd}": rf"{self.mpl_z_rd:.3f} \ Nmm", + r" n": rf" {self.n:.3f}", + r"a_f": rf"{self.a_f:.3f}", + }, + False, + ) + return LatexFormula( + return_symbol=r"M_{N,z,Rd}", + result=f"{self:.3f}", + equation=_equation, + numeric_equation=_numeric_equation, + numeric_equation_with_units=_numeric_equation_with_units, + comparison_operator_label=r"=", + unit="Nmm", + ) diff --git a/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_40af.py b/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_40af.py new file mode 100644 index 000000000..a809bccb2 --- /dev/null +++ b/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_40af.py @@ -0,0 +1,155 @@ +"""Formula 6.40af from NEN-EN 1993-1-1+C2+A1:2016: Chapter 6 - Ultimate Limit State.""" + +from blueprints.codes.eurocode.nen_en_1993_1_1_c2_a1_2016 import NEN_EN_1993_1_1_C2_A1_2016 +from blueprints.codes.formula import Formula +from blueprints.codes.latex_formula import LatexFormula, latex_replace_symbols +from blueprints.type_alias import DIMENSIONLESS, MM, MM2 +from blueprints.validations import raise_if_less_or_equal_to_zero, raise_if_negative + + +class Form6Dot40afHollowSections(Formula): + r"""Class representing formula 6.40af for [$a_f$] in hollow sections.""" + + label = "6.40af_hollow" + source_document = NEN_EN_1993_1_1_C2_A1_2016 + + def __init__( + self, + a: MM2, + h: MM, + t: MM, + ) -> None: + r"""[$a_f$] Calculation of the reduction factor for hollow sections (dimensionless). + + NEN-EN 1993-1-1+C2+A1:2016 art.6.2.9 - Formula (6.40af) + + Parameters + ---------- + a : MM2 + [$A$] Total cross-sectional area [$mm^2$]. + h : MM + [$h$] Height of the section [$mm$]. + t : MM + [$t$] Thickness of the section [$mm$]. + """ + super().__init__() + self.a = a + self.h = h + self.t = t + + @staticmethod + def _evaluate( + a: MM2, + h: MM, + t: MM, + ) -> DIMENSIONLESS: + """Evaluates the formula, for more information see the __init__ method.""" + raise_if_negative(a=a, h=h, t=t) + raise_if_less_or_equal_to_zero(denominator=a) + + return min((a - 2 * h * t) / a, 0.5) + + def latex(self) -> LatexFormula: + """Returns LatexFormula object for formula 6.40af.""" + _equation: str = r"\min \left( \frac{A - 2 \cdot h \cdot t}{A}, 0.5 \right)" + _numeric_equation: str = latex_replace_symbols( + _equation, + { + r"A": f"{self.a:.3f}", + r" h": f" {self.h:.3f}", + r" t": f" {self.t:.3f}", + }, + False, + ) + _numeric_equation_with_units: str = latex_replace_symbols( + _equation, + { + r"A": rf"{self.a:.3f} \ mm^2", + r" h": rf" {self.h:.3f} \ mm", + r" t": rf" {self.t:.3f} \ mm", + }, + False, + ) + return LatexFormula( + return_symbol=r"a_f", + result=f"{self:.3f}", + equation=_equation, + numeric_equation=_numeric_equation, + numeric_equation_with_units=_numeric_equation_with_units, + comparison_operator_label=r"=", + unit="-", + ) + + +class Form6Dot40afWeldedBoxSections(Formula): + r"""Class representing formula 6.40af for [$a_f$] in welded box sections.""" + + label = "6.40af_welded_box" + source_document = NEN_EN_1993_1_1_C2_A1_2016 + + def __init__( + self, + a: MM2, + h: MM, + t_w: MM, + ) -> None: + r"""[$a_f$] Calculation of the reduction factor for welded box sections (dimensionless). + + NEN-EN 1993-1-1+C2+A1:2016 art.6.2.9 - Formula (6.40af) + + Parameters + ---------- + a : MM2 + [$A$] Total cross-sectional area [$mm^2$]. + h : MM + [$h$] Height of the section [$mm$]. + t_w : MM + [$t_w$] Web thickness [$mm$]. + """ + super().__init__() + self.a = a + self.h = h + self.t_w = t_w + + @staticmethod + def _evaluate( + a: MM2, + h: MM, + t_w: MM, + ) -> DIMENSIONLESS: + """Evaluates the formula, for more information see the __init__ method.""" + raise_if_negative(a=a, h=h, t_w=t_w) + raise_if_less_or_equal_to_zero(denominator=a) + + return min((a - 2 * h * t_w) / a, 0.5) + + def latex(self) -> LatexFormula: + """Returns LatexFormula object for formula 6.40af.""" + _equation: str = r"\min \left( \frac{A - 2 \cdot h \cdot t_w}{A}, 0.5 \right)" + _numeric_equation: str = latex_replace_symbols( + _equation, + { + r"A": f"{self.a:.3f}", + r" h": f" {self.h:.3f}", + r"t_w": f"{self.t_w:.3f}", + }, + False, + ) + _numeric_equation_with_units: str = latex_replace_symbols( + _equation, + { + r"A": rf"{self.a:.3f} \ mm^2", + r" h": rf" {self.h:.3f} \ mm", + r"t_w": rf"{self.t_w:.3f} \ mm", + }, + False, + ) + return LatexFormula( + return_symbol=r"a_f", + result=f"{self:.3f}", + equation=_equation, + numeric_equation=_numeric_equation, + numeric_equation_with_units=_numeric_equation_with_units, + comparison_operator_label=r"=", + unit="-", + ) diff --git a/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_40aw.py b/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_40aw.py new file mode 100644 index 000000000..7b76ec474 --- /dev/null +++ b/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_40aw.py @@ -0,0 +1,155 @@ +"""Formula 6.40aw from NEN-EN 1993-1-1+C2+A1:2016: Chapter 6 - Ultimate Limit State.""" + +from blueprints.codes.eurocode.nen_en_1993_1_1_c2_a1_2016 import NEN_EN_1993_1_1_C2_A1_2016 +from blueprints.codes.formula import Formula +from blueprints.codes.latex_formula import LatexFormula, latex_replace_symbols +from blueprints.type_alias import DIMENSIONLESS, MM, MM2 +from blueprints.validations import raise_if_less_or_equal_to_zero, raise_if_negative + + +class Form6Dot40awHollowSections(Formula): + r"""Class representing formula 6.40aw for [$a_w$] in hollow sections.""" + + label = "6.40aw_hollow" + source_document = NEN_EN_1993_1_1_C2_A1_2016 + + def __init__( + self, + a: MM2, + b: MM, + t: MM, + ) -> None: + r"""[$a_w$] Calculation of the reduction factor for hollow sections (dimensionless). + + NEN-EN 1993-1-1+C2+A1:2016 art.6.2.9 - Formula (6.40aw) + + Parameters + ---------- + a : MM2 + [$A$] Total cross-sectional area [$mm^2$]. + b : MM + [$b$] Width of the section [$mm$]. + t : MM + [$t$] Thickness of the section [$mm$]. + """ + super().__init__() + self.a = a + self.b = b + self.t = t + + @staticmethod + def _evaluate( + a: MM2, + b: MM, + t: MM, + ) -> DIMENSIONLESS: + """Evaluates the formula, for more information see the __init__ method.""" + raise_if_negative(a=a, b=b, t=t) + raise_if_less_or_equal_to_zero(denominator=a) + + return min((a - 2 * b * t) / a, 0.5) + + def latex(self) -> LatexFormula: + """Returns LatexFormula object for formula 6.40aw.""" + _equation: str = r"\min \left( \frac{A - 2 \cdot b \cdot t}{A}, 0.5 \right)" + _numeric_equation: str = latex_replace_symbols( + _equation, + { + r"A": f"{self.a:.3f}", + r"b": f"{self.b:.3f}", + r" t": f" {self.t:.3f}", + }, + False, + ) + _numeric_equation_with_units: str = latex_replace_symbols( + _equation, + { + r"A": rf"{self.a:.3f} \ mm^2", + r"b": rf"{self.b:.3f} \ mm", + r" t": rf" {self.t:.3f} \ mm", + }, + False, + ) + return LatexFormula( + return_symbol=r"a_w", + result=f"{self:.3f}", + equation=_equation, + numeric_equation=_numeric_equation, + numeric_equation_with_units=_numeric_equation_with_units, + comparison_operator_label=r"=", + unit="-", + ) + + +class Form6Dot40awWeldedBoxSections(Formula): + r"""Class representing formula 6.40aw for [$a_w$] in welded box sections.""" + + label = "6.40aw_welded_box" + source_document = NEN_EN_1993_1_1_C2_A1_2016 + + def __init__( + self, + a: MM2, + b: MM, + t_f: MM, + ) -> None: + r"""[$a_w$] Calculation of the reduction factor for welded box sections (dimensionless). + + NEN-EN 1993-1-1+C2+A1:2016 art.6.2.9 - Formula (6.40aw) + + Parameters + ---------- + a : MM2 + [$A$] Total cross-sectional area [$mm^2$]. + b : MM + [$b$] Width of the section [$mm$]. + t_f : MM + [$t_f$] Flange thickness [$mm$]. + """ + super().__init__() + self.a = a + self.b = b + self.t_f = t_f + + @staticmethod + def _evaluate( + a: MM2, + b: MM, + t_f: MM, + ) -> DIMENSIONLESS: + """Evaluates the formula, for more information see the __init__ method.""" + raise_if_negative(a=a, b=b, t_f=t_f) + raise_if_less_or_equal_to_zero(denominator=a) + + return min((a - 2 * b * t_f) / a, 0.5) + + def latex(self) -> LatexFormula: + """Returns LatexFormula object for formula 6.40aw.""" + _equation: str = r"\min \left( \frac{A - 2 \cdot b \cdot t_f}{A}, 0.5 \right)" + _numeric_equation: str = latex_replace_symbols( + _equation, + { + r"A": f"{self.a:.3f}", + r"b": f"{self.b:.3f}", + r"t_f": f"{self.t_f:.3f}", + }, + False, + ) + _numeric_equation_with_units: str = latex_replace_symbols( + _equation, + { + r"A": rf"{self.a:.3f} \ mm^2", + r"b": rf"{self.b:.3f} \ mm", + r"t_f": rf"{self.t_f:.3f} \ mm", + }, + False, + ) + return LatexFormula( + return_symbol=r"a_w", + result=f"{self:.3f}", + equation=_equation, + numeric_equation=_numeric_equation, + numeric_equation_with_units=_numeric_equation_with_units, + comparison_operator_label=r"=", + unit="-", + ) diff --git a/docs/objects_overview/eurocode/ec3_1993_1_1_2016/formulas.md b/docs/objects_overview/eurocode/ec3_1993_1_1_2016/formulas.md index d775785ce..aa0018a17 100644 --- a/docs/objects_overview/eurocode/ec3_1993_1_1_2016/formulas.md +++ b/docs/objects_overview/eurocode/ec3_1993_1_1_2016/formulas.md @@ -63,8 +63,10 @@ Total of 108 formulas present. | 6.36 | :x: | | | | 6.37 | :x: | | | | 6.38 | :x: | | | -| 6.39 | :x: | | | -| 6.40 | :x: | | | +| 6.39 | :heavy_check_mark: | | Form6Dot39ReducedBendingMomentResistance | +| 6.40 | :heavy_check_mark: | | Form6Dot40ReducedBendingMomentResistance | +| 6.40 a_w | :heavy_check_mark: | | Form6Dot40awHollowSections and Form6Dot40awWeldedBoxSections | +| 6.40 a_f | :heavy_check_mark: | | Form6Dot40afHollowSections and Form6Dot40afWeldedBoxSections | | 6.41 | :x: | | | | 6.42 | :x: | | | | 6.43 | :x: | | | diff --git a/tests/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/test_formula_6_39.py b/tests/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/test_formula_6_39.py new file mode 100644 index 000000000..84ab2d86e --- /dev/null +++ b/tests/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/test_formula_6_39.py @@ -0,0 +1,77 @@ +"""Testing formula 6.39 of NEN-EN 1993-1-1+C2+A1:2016.""" + +import pytest + +from blueprints.codes.eurocode.nen_en_1993_1_1_c2_a1_2016.chapter_6_ultimate_limit_state.formula_6_39 import Form6Dot39ReducedBendingMomentResistance +from blueprints.validations import LessOrEqualToZeroError, NegativeValueError + + +class TestForm6Dot39ReducedBendingMomentResistance: + """Validation for formula 6.39 from NEN-EN 1993-1-1+C2+A1:2016.""" + + def test_evaluation(self) -> None: + """Tests the evaluation of the result.""" + mpl_y_rd = 5000.0 + n = 0.2 + a_w = 0.3 + + formula = Form6Dot39ReducedBendingMomentResistance(mpl_y_rd=mpl_y_rd, n=n, a_w=a_w) + manually_calculated_result = 4705.882 # Nmm + + assert formula == pytest.approx(expected=manually_calculated_result, rel=1e-4) + + @pytest.mark.parametrize( + ("mpl_y_rd", "n", "a_w"), + [ + (-5000.0, 0.2, 0.3), # mpl_y_rd is negative + (5000.0, -0.2, 0.3), # n is negative + (5000.0, 0.2, -0.3), # a_w is negative + ], + ) + def test_raise_error_when_invalid_values_are_given(self, mpl_y_rd: float, n: float, a_w: float) -> None: + """Test invalid values.""" + with pytest.raises((NegativeValueError, LessOrEqualToZeroError)): + Form6Dot39ReducedBendingMomentResistance(mpl_y_rd=mpl_y_rd, n=n, a_w=a_w) + + @pytest.mark.parametrize( + ("mpl_y_rd", "n", "a_w"), + [ + (5000.0, 0.2, 2.0), # denominator (1 - 0.5 * a_w) <= 0 + ], + ) + def test_raise_error_when_denominator_is_invalid(self, mpl_y_rd: float, n: float, a_w: float) -> None: + """Test invalid denominator.""" + with pytest.raises(LessOrEqualToZeroError): + Form6Dot39ReducedBendingMomentResistance(mpl_y_rd=mpl_y_rd, n=n, a_w=a_w) + + @pytest.mark.parametrize( + ("representation", "expected"), + [ + ( + "complete", + r"M_{N,y,Rd} = \min \left( M_{pl,y,Rd} \cdot \frac{1 - n}{1 - 0.5 \cdot a_w}, M_{pl,y,Rd} \right) = " + r"\min \left( 5000.000 \cdot \frac{1 - 0.200}{1 - 0.5 \cdot 0.300}, 5000.000 \right) = 4705.882 \ Nmm", + ), + ( + "complete_with_units", + r"M_{N,y,Rd} = \min \left( M_{pl,y,Rd} \cdot \frac{1 - n}{1 - 0.5 \cdot a_w}, M_{pl,y,Rd} \right) = " + r"\min \left( 5000.000 \ Nmm \cdot \frac{1 - 0.200}{1 - 0.5 \cdot 0.300}, 5000.000 \ Nmm \right) = 4705.882 \ Nmm", + ), + ("short", r"M_{N,y,Rd} = 4705.882 \ Nmm"), + ], + ) + def test_latex(self, representation: str, expected: str) -> None: + """Test the latex representation of the formula.""" + mpl_y_rd = 5000.0 + n = 0.2 + a_w = 0.3 + + latex = Form6Dot39ReducedBendingMomentResistance(mpl_y_rd=mpl_y_rd, n=n, a_w=a_w).latex() + + actual = { + "complete": latex.complete, + "complete_with_units": latex.complete_with_units, + "short": latex.short, + } + + assert expected == actual[representation], f"{representation} representation failed." diff --git a/tests/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/test_formula_6_40.py b/tests/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/test_formula_6_40.py new file mode 100644 index 000000000..bded06230 --- /dev/null +++ b/tests/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/test_formula_6_40.py @@ -0,0 +1,77 @@ +"""Testing formula 6.40 of NEN-EN 1993-1-1+C2+A1:2016.""" + +import pytest + +from blueprints.codes.eurocode.nen_en_1993_1_1_c2_a1_2016.chapter_6_ultimate_limit_state.formula_6_40 import Form6Dot40ReducedBendingMomentResistance +from blueprints.validations import LessOrEqualToZeroError, NegativeValueError + + +class TestForm6Dot40ReducedBendingMomentResistance: + """Validation for formula 6.40 from NEN-EN 1993-1-1+C2+A1:2016.""" + + def test_evaluation(self) -> None: + """Tests the evaluation of the result.""" + mpl_z_rd = 6000.0 + n = 0.3 + a_f = 0.4 + + formula = Form6Dot40ReducedBendingMomentResistance(mpl_z_rd=mpl_z_rd, n=n, a_f=a_f) + manually_calculated_result = 5250.0 # Nmm + + assert formula == pytest.approx(expected=manually_calculated_result, rel=1e-4) + + @pytest.mark.parametrize( + ("mpl_z_rd", "n", "a_f"), + [ + (-6000.0, 0.3, 0.4), # mpl_z_rd is negative + (6000.0, -0.3, 0.4), # n is negative + (6000.0, 0.3, -0.4), # a_f is negative + ], + ) + def test_raise_error_when_invalid_values_are_given(self, mpl_z_rd: float, n: float, a_f: float) -> None: + """Test invalid values.""" + with pytest.raises((NegativeValueError, LessOrEqualToZeroError)): + Form6Dot40ReducedBendingMomentResistance(mpl_z_rd=mpl_z_rd, n=n, a_f=a_f) + + @pytest.mark.parametrize( + ("mpl_z_rd", "n", "a_f"), + [ + (6000.0, 0.3, 2.0), # denominator (1 - 0.5 * a_f) <= 0 + ], + ) + def test_raise_error_when_denominator_is_invalid(self, mpl_z_rd: float, n: float, a_f: float) -> None: + """Test invalid denominator.""" + with pytest.raises(LessOrEqualToZeroError): + Form6Dot40ReducedBendingMomentResistance(mpl_z_rd=mpl_z_rd, n=n, a_f=a_f) + + @pytest.mark.parametrize( + ("representation", "expected"), + [ + ( + "complete", + r"M_{N,z,Rd} = \min \left( M_{pl,z,Rd} \cdot \frac{1 - n}{1 - 0.5 \cdot a_f}, M_{pl,z,Rd} \right) = " + r"\min \left( 6000.000 \cdot \frac{1 - 0.300}{1 - 0.5 \cdot 0.400}, 6000.000 \right) = 5250.000 \ Nmm", + ), + ( + "complete_with_units", + r"M_{N,z,Rd} = \min \left( M_{pl,z,Rd} \cdot \frac{1 - n}{1 - 0.5 \cdot a_f}, M_{pl,z,Rd} \right) = " + r"\min \left( 6000.000 \ Nmm \cdot \frac{1 - 0.300}{1 - 0.5 \cdot 0.400}, 6000.000 \ Nmm \right) = 5250.000 \ Nmm", + ), + ("short", r"M_{N,z,Rd} = 5250.000 \ Nmm"), + ], + ) + def test_latex(self, representation: str, expected: str) -> None: + """Test the latex representation of the formula.""" + mpl_z_rd = 6000.0 + n = 0.3 + a_f = 0.4 + + latex = Form6Dot40ReducedBendingMomentResistance(mpl_z_rd=mpl_z_rd, n=n, a_f=a_f).latex() + + actual = { + "complete": latex.complete, + "complete_with_units": latex.complete_with_units, + "short": latex.short, + } + + assert expected == actual[representation], f"{representation} representation failed." diff --git a/tests/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/test_formula_6_40af.py b/tests/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/test_formula_6_40af.py new file mode 100644 index 000000000..6e25c7bbb --- /dev/null +++ b/tests/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/test_formula_6_40af.py @@ -0,0 +1,131 @@ +"""Testing formula 6.40af of NEN-EN 1993-1-1+C2+A1:2016.""" + +import pytest + +from blueprints.codes.eurocode.nen_en_1993_1_1_c2_a1_2016.chapter_6_ultimate_limit_state.formula_6_40af import ( + Form6Dot40afHollowSections, + Form6Dot40afWeldedBoxSections, +) +from blueprints.validations import LessOrEqualToZeroError, NegativeValueError + + +class TestForm6Dot40afHollowSections: + """Validation for formula 6.40af (hollow sections) from NEN-EN 1993-1-1+C2+A1:2016.""" + + def test_evaluation(self) -> None: + """Tests the evaluation of the result.""" + a = 7000.0 # updated default value + h = 300.0 + t = 10.0 + + formula = Form6Dot40afHollowSections(a=a, h=h, t=t) + manually_calculated_result = 0.14285714285 # dimensionless + + assert formula == pytest.approx(expected=manually_calculated_result, rel=1e-4) + + @pytest.mark.parametrize( + ("a", "h", "t"), + [ + (-7000.0, 300.0, 10.0), # a is negative + (7000.0, -300.0, 10.0), # h is negative + (7000.0, 300.0, -10.0), # t is negative + ], + ) + def test_raise_error_when_invalid_values_are_given(self, a: float, h: float, t: float) -> None: + """Test invalid values.""" + with pytest.raises((NegativeValueError, LessOrEqualToZeroError)): + Form6Dot40afHollowSections(a=a, h=h, t=t) + + @pytest.mark.parametrize( + ("representation", "expected"), + [ + ( + "complete", + r"a_f = \min \left( \frac{A - 2 \cdot h \cdot t}{A}, 0.5 \right) = " + r"\min \left( \frac{7000.000 - 2 \cdot 300.000 \cdot 10.000}{7000.000}, 0.5 \right) = 0.143 \ -", + ), + ( + "complete_with_units", + r"a_f = \min \left( \frac{A - 2 \cdot h \cdot t}{A}, 0.5 \right) = " + r"\min \left( \frac{7000.000 \ mm^2 - 2 \cdot 300.000 \ mm \cdot 10.000 \ mm}" + r"{7000.000 \ mm^2}, 0.5 \right) = 0.143 \ -", + ), + ("short", r"a_f = 0.143 \ -"), + ], + ) + def test_latex(self, representation: str, expected: str) -> None: + """Test the latex representation of the formula.""" + a = 7000.0 # updated default value + h = 300.0 + t = 10.0 + + latex = Form6Dot40afHollowSections(a=a, h=h, t=t).latex() + + actual = { + "complete": latex.complete, + "complete_with_units": latex.complete_with_units, + "short": latex.short, + } + + assert expected == actual[representation], f"{representation} representation failed." + + +class TestForm6Dot40afWeldedBoxSections: + """Validation for formula 6.40af (welded box sections) from NEN-EN 1993-1-1+C2+A1:2016.""" + + def test_evaluation(self) -> None: + """Tests the evaluation of the result.""" + a = 7000.0 # updated default value + h = 300.0 + t_w = 10.0 + + formula = Form6Dot40afWeldedBoxSections(a=a, h=h, t_w=t_w) + manually_calculated_result = 0.14285714285 # dimensionless + + assert formula == pytest.approx(expected=manually_calculated_result, rel=1e-4) + + @pytest.mark.parametrize( + ("a", "h", "t_w"), + [ + (-7000.0, 300.0, 10.0), # a is negative + (7000.0, -300.0, 10.0), # h is negative + (7000.0, 300.0, -10.0), # t_w is negative + ], + ) + def test_raise_error_when_invalid_values_are_given(self, a: float, h: float, t_w: float) -> None: + """Test invalid values.""" + with pytest.raises((NegativeValueError, LessOrEqualToZeroError)): + Form6Dot40afWeldedBoxSections(a=a, h=h, t_w=t_w) + + @pytest.mark.parametrize( + ("representation", "expected"), + [ + ( + "complete", + r"a_f = \min \left( \frac{A - 2 \cdot h \cdot t_w}{A}, 0.5 \right) = " + r"\min \left( \frac{7000.000 - 2 \cdot 300.000 \cdot 10.000}{7000.000}, 0.5 \right) = 0.143 \ -", + ), + ( + "complete_with_units", + r"a_f = \min \left( \frac{A - 2 \cdot h \cdot t_w}{A}, 0.5 \right) = " + r"\min \left( \frac{7000.000 \ mm^2 - 2 \cdot 300.000 \ mm \cdot 10.000 \ mm}" + r"{7000.000 \ mm^2}, 0.5 \right) = 0.143 \ -", + ), + ("short", r"a_f = 0.143 \ -"), + ], + ) + def test_latex(self, representation: str, expected: str) -> None: + """Test the latex representation of the formula.""" + a = 7000.0 # updated default value + h = 300.0 + t_w = 10.0 + + latex = Form6Dot40afWeldedBoxSections(a=a, h=h, t_w=t_w).latex() + + actual = { + "complete": latex.complete, + "complete_with_units": latex.complete_with_units, + "short": latex.short, + } + + assert expected == actual[representation], f"{representation} representation failed." diff --git a/tests/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/test_formula_6_40aw.py b/tests/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/test_formula_6_40aw.py new file mode 100644 index 000000000..5c130189f --- /dev/null +++ b/tests/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/test_formula_6_40aw.py @@ -0,0 +1,131 @@ +"""Testing formula 6.40aw of NEN-EN 1993-1-1+C2+A1:2016.""" + +import pytest + +from blueprints.codes.eurocode.nen_en_1993_1_1_c2_a1_2016.chapter_6_ultimate_limit_state.formula_6_40aw import ( + Form6Dot40awHollowSections, + Form6Dot40awWeldedBoxSections, +) +from blueprints.validations import LessOrEqualToZeroError, NegativeValueError + + +class TestForm6Dot40awHollowSections: + """Validation for formula 6.40aw (hollow sections) from NEN-EN 1993-1-1+C2+A1:2016.""" + + def test_evaluation(self) -> None: + """Tests the evaluation of the result.""" + a = 7000.0 # updated default value + b = 200.0 + t = 10.0 + + formula = Form6Dot40awHollowSections(a=a, b=b, t=t) + manually_calculated_result = 0.42857142857 # dimensionless + + assert formula == pytest.approx(expected=manually_calculated_result, rel=1e-4) + + @pytest.mark.parametrize( + ("a", "b", "t"), + [ + (-7000.0, 200.0, 10.0), # a is negative + (7000.0, -200.0, 10.0), # b is negative + (7000.0, 200.0, -10.0), # t is negative + ], + ) + def test_raise_error_when_invalid_values_are_given(self, a: float, b: float, t: float) -> None: + """Test invalid values.""" + with pytest.raises((NegativeValueError, LessOrEqualToZeroError)): + Form6Dot40awHollowSections(a=a, b=b, t=t) + + @pytest.mark.parametrize( + ("representation", "expected"), + [ + ( + "complete", + r"a_w = \min \left( \frac{A - 2 \cdot b \cdot t}{A}, 0.5 \right) = " + r"\min \left( \frac{7000.000 - 2 \cdot 200.000 \cdot 10.000}{7000.000}, 0.5 \right) = 0.429 \ -", + ), + ( + "complete_with_units", + r"a_w = \min \left( \frac{A - 2 \cdot b \cdot t}{A}, 0.5 \right) = " + r"\min \left( \frac{7000.000 \ mm^2 - 2 \cdot 200.000 \ mm \cdot 10.000 \ mm}" + r"{7000.000 \ mm^2}, 0.5 \right) = 0.429 \ -", + ), + ("short", r"a_w = 0.429 \ -"), + ], + ) + def test_latex(self, representation: str, expected: str) -> None: + """Test the latex representation of the formula.""" + a = 7000.0 # updated default value + b = 200.0 + t = 10.0 + + latex = Form6Dot40awHollowSections(a=a, b=b, t=t).latex() + + actual = { + "complete": latex.complete, + "complete_with_units": latex.complete_with_units, + "short": latex.short, + } + + assert expected == actual[representation], f"{representation} representation failed." + + +class TestForm6Dot40awWeldedBoxSections: + """Validation for formula 6.40aw (welded box sections) from NEN-EN 1993-1-1+C2+A1:2016.""" + + def test_evaluation(self) -> None: + """Tests the evaluation of the result.""" + a = 7000.0 # updated default value + b = 200.0 + t_f = 10.0 + + formula = Form6Dot40awWeldedBoxSections(a=a, b=b, t_f=t_f) + manually_calculated_result = 0.42857142857 # dimensionless + + assert formula == pytest.approx(expected=manually_calculated_result, rel=1e-4) + + @pytest.mark.parametrize( + ("a", "b", "t_f"), + [ + (-7000.0, 200.0, 10.0), # a is negative + (7000.0, -200.0, 10.0), # b is negative + (7000.0, 200.0, -10.0), # t_f is negative + ], + ) + def test_raise_error_when_invalid_values_are_given(self, a: float, b: float, t_f: float) -> None: + """Test invalid values.""" + with pytest.raises((NegativeValueError, LessOrEqualToZeroError)): + Form6Dot40awWeldedBoxSections(a=a, b=b, t_f=t_f) + + @pytest.mark.parametrize( + ("representation", "expected"), + [ + ( + "complete", + r"a_w = \min \left( \frac{A - 2 \cdot b \cdot t_f}{A}, 0.5 \right) = " + r"\min \left( \frac{7000.000 - 2 \cdot 200.000 \cdot 10.000}{7000.000}, 0.5 \right) = 0.429 \ -", + ), + ( + "complete_with_units", + r"a_w = \min \left( \frac{A - 2 \cdot b \cdot t_f}{A}, 0.5 \right) = " + r"\min \left( \frac{7000.000 \ mm^2 - 2 \cdot 200.000 \ mm \cdot 10.000 \ mm}" + r"{7000.000 \ mm^2}, 0.5 \right) = 0.429 \ -", + ), + ("short", r"a_w = 0.429 \ -"), + ], + ) + def test_latex(self, representation: str, expected: str) -> None: + """Test the latex representation of the formula.""" + a = 7000.0 # updated default value + b = 200.0 + t_f = 10.0 + + latex = Form6Dot40awWeldedBoxSections(a=a, b=b, t_f=t_f).latex() + + actual = { + "complete": latex.complete, + "complete_with_units": latex.complete_with_units, + "short": latex.short, + } + + assert expected == actual[representation], f"{representation} representation failed." From f1bdfc0d457c5ca282cabf142f914a59d6504e9f Mon Sep 17 00:00:00 2001 From: GerjanDorgelo Date: Mon, 5 May 2025 09:09:34 +0200 Subject: [PATCH 2/6] Update references in formulas 6.39, 6.40, 6.40af, and 6.40aw to NEN-EN 1993-1-1+C2+A1:2016 art.6.2.9.1(5) and add formula 6.41 for bi-axial bending check. --- .../chapter_6_ultimate_limit_state/formula_6_39.py | 2 +- .../chapter_6_ultimate_limit_state/formula_6_40.py | 2 +- .../chapter_6_ultimate_limit_state/formula_6_40af.py | 4 ++-- .../chapter_6_ultimate_limit_state/formula_6_40aw.py | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_39.py b/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_39.py index 30514c959..f27324183 100644 --- a/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_39.py +++ b/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_39.py @@ -21,7 +21,7 @@ def __init__( ) -> None: r"""[$M_{N,y,Rd}$] Calculation of the reduced bending moment [$Nmm$]. - NEN-EN 1993-1-1+C2+A1:2016 art.6.2.9 - Formula (6.39) + NEN-EN 1993-1-1+C2+A1:2016 art.6.2.9.1(5) - Formula (6.39) Parameters ---------- diff --git a/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_40.py b/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_40.py index ded61db50..7242200f8 100644 --- a/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_40.py +++ b/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_40.py @@ -21,7 +21,7 @@ def __init__( ) -> None: r"""[$M_{N,z,Rd}$] Calculation of the reduced bending moment [$Nmm$]. - NEN-EN 1993-1-1+C2+A1:2016 art.6.2.9 - Formula (6.40) + NEN-EN 1993-1-1+C2+A1:2016 art.6.2.9.1(5) - Formula (6.40) Parameters ---------- diff --git a/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_40af.py b/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_40af.py index a809bccb2..37d2d0316 100644 --- a/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_40af.py +++ b/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_40af.py @@ -21,7 +21,7 @@ def __init__( ) -> None: r"""[$a_f$] Calculation of the reduction factor for hollow sections (dimensionless). - NEN-EN 1993-1-1+C2+A1:2016 art.6.2.9 - Formula (6.40af) + NEN-EN 1993-1-1+C2+A1:2016 art.6.2.9.1(5) - Formula (6.40af) Parameters ---------- @@ -95,7 +95,7 @@ def __init__( ) -> None: r"""[$a_f$] Calculation of the reduction factor for welded box sections (dimensionless). - NEN-EN 1993-1-1+C2+A1:2016 art.6.2.9 - Formula (6.40af) + NEN-EN 1993-1-1+C2+A1:2016 art.6.2.9.1(5) - Formula (6.40af) Parameters ---------- diff --git a/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_40aw.py b/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_40aw.py index 7b76ec474..f33622de5 100644 --- a/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_40aw.py +++ b/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_40aw.py @@ -21,7 +21,7 @@ def __init__( ) -> None: r"""[$a_w$] Calculation of the reduction factor for hollow sections (dimensionless). - NEN-EN 1993-1-1+C2+A1:2016 art.6.2.9 - Formula (6.40aw) + NEN-EN 1993-1-1+C2+A1:2016 art.6.2.9.1(5) - Formula (6.40aw) Parameters ---------- @@ -95,7 +95,7 @@ def __init__( ) -> None: r"""[$a_w$] Calculation of the reduction factor for welded box sections (dimensionless). - NEN-EN 1993-1-1+C2+A1:2016 art.6.2.9 - Formula (6.40aw) + NEN-EN 1993-1-1+C2+A1:2016 art.6.2.9.1(5) - Formula (6.40aw) Parameters ---------- From d0b040a30fec5285dfb0717c5bb33ec9702aa354 Mon Sep 17 00:00:00 2001 From: GerjanDorgelo Date: Tue, 3 Jun 2025 19:52:48 +0200 Subject: [PATCH 3/6] Update blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_39.py Co-authored-by: rick <145433945+viktor-rick@users.noreply.github.com> --- .../chapter_6_ultimate_limit_state/formula_6_39.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_39.py b/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_39.py index f27324183..6833e3509 100644 --- a/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_39.py +++ b/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_39.py @@ -30,7 +30,7 @@ def __init__( n : DIMENSIONLESS [$n$] Axial force ratio, see equation 6.38n (dimensionless). a_w : DIMENSIONLESS - [$a_w$] Reduction factor for the web (dimensionless). + [$a_w$] Reduction factor for the web (dimensionless), see equation 6.39aw. """ super().__init__() self.mpl_y_rd = mpl_y_rd From 5f9a6a4c9c4c93a055024880efd85b21fa25117a Mon Sep 17 00:00:00 2001 From: GerjanDorgelo Date: Tue, 3 Jun 2025 19:54:29 +0200 Subject: [PATCH 4/6] Apply suggestions from code review Co-authored-by: rick <145433945+viktor-rick@users.noreply.github.com> --- .../chapter_6_ultimate_limit_state/formula_6_40aw.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_40aw.py b/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_40aw.py index f33622de5..942b3af46 100644 --- a/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_40aw.py +++ b/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_40aw.py @@ -1,4 +1,4 @@ -"""Formula 6.40aw from NEN-EN 1993-1-1+C2+A1:2016: Chapter 6 - Ultimate Limit State.""" +"""Formula 6.39aw from NEN-EN 1993-1-1+C2+A1:2016: Chapter 6 - Ultimate Limit State.""" from blueprints.codes.eurocode.nen_en_1993_1_1_c2_a1_2016 import NEN_EN_1993_1_1_C2_A1_2016 from blueprints.codes.formula import Formula From 999505080dadc76cb2a9275a6764a7b6078f9cda Mon Sep 17 00:00:00 2001 From: GerjanDorgelo Date: Tue, 3 Jun 2025 19:58:52 +0200 Subject: [PATCH 5/6] rename 6.40aw tp 6.39aw --- .../{formula_6_40aw.py => formula_6_39aw.py} | 18 +++++++++--------- ...ormula_6_40aw.py => test_formula_6_39aw.py} | 8 ++++---- 2 files changed, 13 insertions(+), 13 deletions(-) rename blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/{formula_6_40aw.py => formula_6_39aw.py} (89%) rename tests/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/{test_formula_6_40aw.py => test_formula_6_39aw.py} (95%) diff --git a/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_40aw.py b/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_39aw.py similarity index 89% rename from blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_40aw.py rename to blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_39aw.py index f33622de5..49675f1e1 100644 --- a/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_40aw.py +++ b/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_39aw.py @@ -1,4 +1,4 @@ -"""Formula 6.40aw from NEN-EN 1993-1-1+C2+A1:2016: Chapter 6 - Ultimate Limit State.""" +"""Formula 6.39aw from NEN-EN 1993-1-1+C2+A1:2016: Chapter 6 - Ultimate Limit State.""" from blueprints.codes.eurocode.nen_en_1993_1_1_c2_a1_2016 import NEN_EN_1993_1_1_C2_A1_2016 from blueprints.codes.formula import Formula @@ -8,9 +8,9 @@ class Form6Dot40awHollowSections(Formula): - r"""Class representing formula 6.40aw for [$a_w$] in hollow sections.""" + r"""Class representing formula 6.39aw for [$a_w$] in hollow sections.""" - label = "6.40aw_hollow" + label = "6.39aw_hollow" source_document = NEN_EN_1993_1_1_C2_A1_2016 def __init__( @@ -21,7 +21,7 @@ def __init__( ) -> None: r"""[$a_w$] Calculation of the reduction factor for hollow sections (dimensionless). - NEN-EN 1993-1-1+C2+A1:2016 art.6.2.9.1(5) - Formula (6.40aw) + NEN-EN 1993-1-1+C2+A1:2016 art.6.2.9.1(5) - Formula (6.39aw) Parameters ---------- @@ -50,7 +50,7 @@ def _evaluate( return min((a - 2 * b * t) / a, 0.5) def latex(self) -> LatexFormula: - """Returns LatexFormula object for formula 6.40aw.""" + """Returns LatexFormula object for formula 6.39aw.""" _equation: str = r"\min \left( \frac{A - 2 \cdot b \cdot t}{A}, 0.5 \right)" _numeric_equation: str = latex_replace_symbols( _equation, @@ -82,9 +82,9 @@ def latex(self) -> LatexFormula: class Form6Dot40awWeldedBoxSections(Formula): - r"""Class representing formula 6.40aw for [$a_w$] in welded box sections.""" + r"""Class representing formula 6.39aw for [$a_w$] in welded box sections.""" - label = "6.40aw_welded_box" + label = "6.39aw_welded_box" source_document = NEN_EN_1993_1_1_C2_A1_2016 def __init__( @@ -95,7 +95,7 @@ def __init__( ) -> None: r"""[$a_w$] Calculation of the reduction factor for welded box sections (dimensionless). - NEN-EN 1993-1-1+C2+A1:2016 art.6.2.9.1(5) - Formula (6.40aw) + NEN-EN 1993-1-1+C2+A1:2016 art.6.2.9.1(5) - Formula (6.39aw) Parameters ---------- @@ -124,7 +124,7 @@ def _evaluate( return min((a - 2 * b * t_f) / a, 0.5) def latex(self) -> LatexFormula: - """Returns LatexFormula object for formula 6.40aw.""" + """Returns LatexFormula object for formula 6.39aw.""" _equation: str = r"\min \left( \frac{A - 2 \cdot b \cdot t_f}{A}, 0.5 \right)" _numeric_equation: str = latex_replace_symbols( _equation, diff --git a/tests/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/test_formula_6_40aw.py b/tests/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/test_formula_6_39aw.py similarity index 95% rename from tests/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/test_formula_6_40aw.py rename to tests/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/test_formula_6_39aw.py index 5c130189f..eb6a4b915 100644 --- a/tests/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/test_formula_6_40aw.py +++ b/tests/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/test_formula_6_39aw.py @@ -1,8 +1,8 @@ -"""Testing formula 6.40aw of NEN-EN 1993-1-1+C2+A1:2016.""" +"""Testing formula 6.39aw of NEN-EN 1993-1-1+C2+A1:2016.""" import pytest -from blueprints.codes.eurocode.nen_en_1993_1_1_c2_a1_2016.chapter_6_ultimate_limit_state.formula_6_40aw import ( +from blueprints.codes.eurocode.nen_en_1993_1_1_c2_a1_2016.chapter_6_ultimate_limit_state.formula_6_39aw import ( Form6Dot40awHollowSections, Form6Dot40awWeldedBoxSections, ) @@ -10,7 +10,7 @@ class TestForm6Dot40awHollowSections: - """Validation for formula 6.40aw (hollow sections) from NEN-EN 1993-1-1+C2+A1:2016.""" + """Validation for formula 6.39aw (hollow sections) from NEN-EN 1993-1-1+C2+A1:2016.""" def test_evaluation(self) -> None: """Tests the evaluation of the result.""" @@ -71,7 +71,7 @@ def test_latex(self, representation: str, expected: str) -> None: class TestForm6Dot40awWeldedBoxSections: - """Validation for formula 6.40aw (welded box sections) from NEN-EN 1993-1-1+C2+A1:2016.""" + """Validation for formula 6.39aw (welded box sections) from NEN-EN 1993-1-1+C2+A1:2016.""" def test_evaluation(self) -> None: """Tests the evaluation of the result.""" From 15cc6bd25e5b92f063eb85d150552db31b9ba6da Mon Sep 17 00:00:00 2001 From: GerjanDorgelo Date: Tue, 3 Jun 2025 20:02:03 +0200 Subject: [PATCH 6/6] Rename classes for formula 6.39aw to reflect correct numbering in hollow and welded box sections --- .../formula_6_39aw.py | 4 ++-- .../eurocode/ec3_1993_1_1_2016/formulas.md | 2 +- .../test_formula_6_39aw.py | 20 +++++++++---------- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_39aw.py b/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_39aw.py index 49675f1e1..016f344d6 100644 --- a/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_39aw.py +++ b/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_39aw.py @@ -7,7 +7,7 @@ from blueprints.validations import raise_if_less_or_equal_to_zero, raise_if_negative -class Form6Dot40awHollowSections(Formula): +class Form6Dot39awHollowSections(Formula): r"""Class representing formula 6.39aw for [$a_w$] in hollow sections.""" label = "6.39aw_hollow" @@ -81,7 +81,7 @@ def latex(self) -> LatexFormula: ) -class Form6Dot40awWeldedBoxSections(Formula): +class Form6Dot39awWeldedBoxSections(Formula): r"""Class representing formula 6.39aw for [$a_w$] in welded box sections.""" label = "6.39aw_welded_box" diff --git a/docs/objects_overview/eurocode/ec3_1993_1_1_2016/formulas.md b/docs/objects_overview/eurocode/ec3_1993_1_1_2016/formulas.md index 8df0ef888..e409b5297 100644 --- a/docs/objects_overview/eurocode/ec3_1993_1_1_2016/formulas.md +++ b/docs/objects_overview/eurocode/ec3_1993_1_1_2016/formulas.md @@ -64,8 +64,8 @@ Total of 108 formulas present. | 6.37 | :x: | | | | 6.38 | :x: | | | | 6.39 | :heavy_check_mark: | | Form6Dot39ReducedBendingMomentResistance | +| 6.39 a_w | :heavy_check_mark: | | Form6Dot39awHollowSections and Form6Dot39awWeldedBoxSections | | 6.40 | :heavy_check_mark: | | Form6Dot40ReducedBendingMomentResistance | -| 6.40 a_w | :heavy_check_mark: | | Form6Dot40awHollowSections and Form6Dot40awWeldedBoxSections | | 6.40 a_f | :heavy_check_mark: | | Form6Dot40afHollowSections and Form6Dot40afWeldedBoxSections | | 6.41 | :heavy_check_mark: | | Form6Dot41BiaxialBendingCheck | | 6.42 | :x: | | | diff --git a/tests/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/test_formula_6_39aw.py b/tests/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/test_formula_6_39aw.py index eb6a4b915..30c30fe06 100644 --- a/tests/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/test_formula_6_39aw.py +++ b/tests/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/test_formula_6_39aw.py @@ -3,13 +3,13 @@ import pytest from blueprints.codes.eurocode.nen_en_1993_1_1_c2_a1_2016.chapter_6_ultimate_limit_state.formula_6_39aw import ( - Form6Dot40awHollowSections, - Form6Dot40awWeldedBoxSections, + Form6Dot39awHollowSections, + Form6Dot39awWeldedBoxSections, ) from blueprints.validations import LessOrEqualToZeroError, NegativeValueError -class TestForm6Dot40awHollowSections: +class TestForm6Dot39awHollowSections: """Validation for formula 6.39aw (hollow sections) from NEN-EN 1993-1-1+C2+A1:2016.""" def test_evaluation(self) -> None: @@ -18,7 +18,7 @@ def test_evaluation(self) -> None: b = 200.0 t = 10.0 - formula = Form6Dot40awHollowSections(a=a, b=b, t=t) + formula = Form6Dot39awHollowSections(a=a, b=b, t=t) manually_calculated_result = 0.42857142857 # dimensionless assert formula == pytest.approx(expected=manually_calculated_result, rel=1e-4) @@ -34,7 +34,7 @@ def test_evaluation(self) -> None: def test_raise_error_when_invalid_values_are_given(self, a: float, b: float, t: float) -> None: """Test invalid values.""" with pytest.raises((NegativeValueError, LessOrEqualToZeroError)): - Form6Dot40awHollowSections(a=a, b=b, t=t) + Form6Dot39awHollowSections(a=a, b=b, t=t) @pytest.mark.parametrize( ("representation", "expected"), @@ -59,7 +59,7 @@ def test_latex(self, representation: str, expected: str) -> None: b = 200.0 t = 10.0 - latex = Form6Dot40awHollowSections(a=a, b=b, t=t).latex() + latex = Form6Dot39awHollowSections(a=a, b=b, t=t).latex() actual = { "complete": latex.complete, @@ -70,7 +70,7 @@ def test_latex(self, representation: str, expected: str) -> None: assert expected == actual[representation], f"{representation} representation failed." -class TestForm6Dot40awWeldedBoxSections: +class TestForm6Dot39awWeldedBoxSections: """Validation for formula 6.39aw (welded box sections) from NEN-EN 1993-1-1+C2+A1:2016.""" def test_evaluation(self) -> None: @@ -79,7 +79,7 @@ def test_evaluation(self) -> None: b = 200.0 t_f = 10.0 - formula = Form6Dot40awWeldedBoxSections(a=a, b=b, t_f=t_f) + formula = Form6Dot39awWeldedBoxSections(a=a, b=b, t_f=t_f) manually_calculated_result = 0.42857142857 # dimensionless assert formula == pytest.approx(expected=manually_calculated_result, rel=1e-4) @@ -95,7 +95,7 @@ def test_evaluation(self) -> None: def test_raise_error_when_invalid_values_are_given(self, a: float, b: float, t_f: float) -> None: """Test invalid values.""" with pytest.raises((NegativeValueError, LessOrEqualToZeroError)): - Form6Dot40awWeldedBoxSections(a=a, b=b, t_f=t_f) + Form6Dot39awWeldedBoxSections(a=a, b=b, t_f=t_f) @pytest.mark.parametrize( ("representation", "expected"), @@ -120,7 +120,7 @@ def test_latex(self, representation: str, expected: str) -> None: b = 200.0 t_f = 10.0 - latex = Form6Dot40awWeldedBoxSections(a=a, b=b, t_f=t_f).latex() + latex = Form6Dot39awWeldedBoxSections(a=a, b=b, t_f=t_f).latex() actual = { "complete": latex.complete,