From 9a4c508c54f79bbd670c0579378871ef6a4db39e Mon Sep 17 00:00:00 2001 From: GerjanDorgelo Date: Fri, 2 May 2025 08:44:18 +0200 Subject: [PATCH 1/9] Add formulas 6.29, 6.29rho, and 6.30 with corresponding tests for reduced yield strength and plastic resistance moment --- .../formula_6_29.py | 74 ++++++++ .../formula_6_29rho.py | 149 +++++++++++++++ .../formula_6_30.py | 113 ++++++++++++ .../test_formula_6_29.py | 68 +++++++ .../test_formula_6_29rho.py | 171 ++++++++++++++++++ .../test_formula_6_30.py | 143 +++++++++++++++ 6 files changed, 718 insertions(+) create mode 100644 blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_29.py create mode 100644 blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_29rho.py create mode 100644 blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_30.py create mode 100644 tests/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/test_formula_6_29.py create mode 100644 tests/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/test_formula_6_29rho.py create mode 100644 tests/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/test_formula_6_30.py diff --git a/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_29.py b/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_29.py new file mode 100644 index 000000000..2c0f14fc1 --- /dev/null +++ b/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_29.py @@ -0,0 +1,74 @@ +"""Formula 6.29 from NEN-EN 1993-1-1+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, MPA +from blueprints.validations import raise_if_negative + + +class Form6Dot29ReducedYieldStrength(Formula): + r"""Class representing formula 6.29 for the calculation of reduced yield strength.""" + + label = "6.29" + source_document = NEN_EN_1993_1_1_C2_A1_2016 + + def __init__( + self, + rho: DIMENSIONLESS, + f_y: MPA, + ) -> None: + r"""[$f_{y,red}$] Calculation of reduced yield strength [$MPa$]. + + NEN-EN 1993-1-1+A1:2016 art.6.2.8(3) - Formula (6.29) + + Parameters + ---------- + rho : DIMENSIONLESS + [$\rho$] Reduction factor for shear force, see 6.2.8(3) (dimensionless). + f_y : MPA + [$f_y$] Yield strength of the material [$MPa$]. + """ + super().__init__() + self.rho = rho + self.f_y = f_y + + @staticmethod + def _evaluate( + rho: DIMENSIONLESS, + f_y: MPA, + ) -> MPA: + """Evaluates the formula, for more information see the __init__ method.""" + one_minus_rho = 1 - rho + raise_if_negative(rho=rho, f_y=f_y, one_minus_rho=one_minus_rho) + + return (1 - rho) * f_y + + def latex(self) -> LatexFormula: + """Returns LatexFormula object for formula 6.29.""" + _equation: str = r"(1 - \rho) \cdot f_y" + _numeric_equation: str = latex_replace_symbols( + _equation, + { + r"\rho": f"{self.rho:.3f}", + r"f_y": f"{self.f_y:.3f}", + }, + False, + ) + _numeric_equation_with_units: str = latex_replace_symbols( + _equation, + { + r"\rho": rf"{self.rho:.3f}", + r"f_y": rf"{self.f_y:.3f} \ MPa", + }, + True, + ) + return LatexFormula( + return_symbol=r"f_{y,red}", + result=f"{self:.3f}", + equation=_equation, + numeric_equation=_numeric_equation, + numeric_equation_with_units=_numeric_equation_with_units, + comparison_operator_label="=", + unit="MPa", + ) diff --git a/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_29rho.py b/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_29rho.py new file mode 100644 index 000000000..33960dba8 --- /dev/null +++ b/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_29rho.py @@ -0,0 +1,149 @@ +"""Formula 6.29rho 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, N +from blueprints.validations import raise_if_less_or_equal_to_zero, raise_if_negative + + +class Form6Dot29Rho(Formula): + r"""Class representing formula 6.29rho for the calculation of [$\rho$].""" + + label = "6.29rho" + source_document = NEN_EN_1993_1_1_C2_A1_2016 + + def __init__( + self, + v_ed: N, + v_pl_rd: N, + ) -> None: + r"""[$\rho$] Calculation of the reduction factor [$\text{dimensionless}$]. + + NEN-EN 1993-1-1+C2+A1:2016 art.6.2.10(3) - Formula (6.29rho) + + Parameters + ---------- + v_ed : N + [$V_{Ed}$] Design shear force [$N$]. + v_pl_rd : N + [$V_{pl,Rd}$] Plastic shear resistance, obtained from 6.2.6(2) [$N$]. + + Note, see also 6.2.10(3) + """ + super().__init__() + self.v_ed = v_ed + self.v_pl_rd = v_pl_rd + + @staticmethod + def _evaluate( + v_ed: N, + v_pl_rd: N, + ) -> DIMENSIONLESS: + """Evaluates the formula, for more information see the __init__ method.""" + raise_if_less_or_equal_to_zero(v_pl_rd=v_pl_rd) + raise_if_negative(v_ed=v_ed) + + if v_ed <= 0.5 * v_pl_rd: + return 0 + return ((2 * v_ed / v_pl_rd) - 1) ** 2 + + def latex(self) -> LatexFormula: + """Returns LatexFormula object for formula 6.29rho.""" + _equation: str = r"\max\left(0, \left( \frac{2 \cdot V_{Ed}}{V_{pl,Rd}} - 1 \right) \right)^2" + _numeric_equation: str = latex_replace_symbols( + _equation, + { + r"V_{Ed}": f"{self.v_ed:.3f}", + r"V_{pl,Rd}": f"{self.v_pl_rd:.3f}", + }, + False, + ) + _numeric_equation_with_units: str = latex_replace_symbols( + _equation, + { + r"V_{Ed}": rf"{self.v_ed:.3f} \ N", + r"V_{pl,Rd}": rf"{self.v_pl_rd:.3f} \ N", + }, + True, + ) + return LatexFormula( + return_symbol=r"\rho", + result=f"{self:.3f}", + equation=_equation, + numeric_equation=_numeric_equation, + numeric_equation_with_units=_numeric_equation_with_units, + comparison_operator_label="=", + unit="-", + ) + + +class Form6Dot29RhoWithTorsion(Formula): + r"""Class representing formula 6.29rho with torsion for the calculation of [$\rho$].""" + + label = "6.29rho_with_torsion" + source_document = NEN_EN_1993_1_1_C2_A1_2016 + + def __init__( + self, + v_ed: N, + v_pl_t_rd: N, + ) -> None: + r"""[$\rho$] Calculation of the reduction factor with torsion [$\text{dimensionless}$]. + + NEN-EN 1993-1-1+C2+A1:2016 art.6.2.7(4) - Formula (6.29rho with torsion) + + Parameters + ---------- + v_ed : N + [$V_{Ed}$] Design shear force [$N$]. + v_pl_t_rd : N + [$V_{pl,T,Rd}$] Plastic shear resistance with torsion [$N$]. + + Note, see also 6.2.7 + """ + super().__init__() + self.v_ed = v_ed + self.v_pl_t_rd = v_pl_t_rd + + @staticmethod + def _evaluate( + v_ed: N, + v_pl_t_rd: N, + ) -> DIMENSIONLESS: + """Evaluates the formula, for more information see the __init__ method.""" + raise_if_less_or_equal_to_zero(v_pl_t_rd=v_pl_t_rd) + raise_if_negative(v_ed=v_ed) + + if v_ed <= 0.5 * v_pl_t_rd: + return 0 + return ((2 * v_ed / v_pl_t_rd) - 1) ** 2 + + def latex(self) -> LatexFormula: + """Returns LatexFormula object for formula 6.29rho with torsion.""" + _equation: str = r"\max\left(0, \left( \frac{2 \cdot V_{Ed}}{V_{pl,T,Rd}} - 1 \right) \right)^2" + _numeric_equation: str = latex_replace_symbols( + _equation, + { + r"V_{Ed}": f"{self.v_ed:.3f}", + r"V_{pl,T,Rd}": f"{self.v_pl_t_rd:.3f}", + }, + False, + ) + _numeric_equation_with_units: str = latex_replace_symbols( + _equation, + { + r"V_{Ed}": rf"{self.v_ed:.3f} \ N", + r"V_{pl,T,Rd}": rf"{self.v_pl_t_rd:.3f} \ N", + }, + True, + ) + return LatexFormula( + return_symbol=r"\rho", + result=f"{self:.3f}", + equation=_equation, + numeric_equation=_numeric_equation, + numeric_equation_with_units=_numeric_equation_with_units, + comparison_operator_label="=", + unit="-", + ) diff --git a/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_30.py b/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_30.py new file mode 100644 index 000000000..af1909c59 --- /dev/null +++ b/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_30.py @@ -0,0 +1,113 @@ +"""Formula 6.30 from NEN-EN 1993-1-1+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, MM3, MPA, NMM +from blueprints.validations import raise_if_less_or_equal_to_zero, raise_if_negative + + +class Form6Dot30ReducedPlasticResistanceMoment(Formula): + r"""Class representing formula 6.30 for the calculation of [$M_{y,v,Rd}$].""" + + label = "6.30" + source_document = NEN_EN_1993_1_1_C2_A1_2016 + + def __init__( + self, + w_pl_y: MM3, + rho: DIMENSIONLESS, + h_w: MM, + t_w: MM, + f_y: MPA, + gamma_m0: DIMENSIONLESS, + m_y_c_rd: NMM, + ) -> None: + r"""[$M_{y,v,Rd}$] Reduced design plastic resistance moment [$Nmm$]. + + NEN-EN 1993-1-1+A1:2016 art.6.2.8(5) - Formula (6.30) + + Parameters + ---------- + w_pl_y : MM3 + [$W_{pl,y}$] Plastic section modulus about the y axis [$mm^3$]. + rho : DIMENSIONLESS + [$\rho$] Shear force ratio (see 6.2.8 (3) or (4)) [-]. + h_w : MM + [$h_w$] Web height [$mm$]. + t_w : MM + [$t_w$] Web thickness [$mm$]. + f_y : MPA + [$f_y$] Yield strength of the material [$MPa$]. + gamma_m0 : DIMENSIONLESS + [$\gamma_{M0}$] Partial safety factor for resistance of cross-sections [-]. + m_y_c_rd : NMM + [$M_{y,c,Rd}$] Design resistance moment, obtained from 6.2.5(2) [$Nmm$]. + """ + super().__init__() + self.w_pl_y = w_pl_y + self.rho = rho + self.h_w = h_w + self.t_w = t_w + self.f_y = f_y + self.gamma_m0 = gamma_m0 + self.m_y_c_rd = m_y_c_rd + + @staticmethod + def _evaluate( + w_pl_y: MM3, + rho: DIMENSIONLESS, + h_w: MM, + t_w: MM, + f_y: MPA, + gamma_m0: DIMENSIONLESS, + m_y_c_rd: NMM, + ) -> NMM: + """Evaluates the formula, for more information see the __init__ method.""" + raise_if_negative(w_pl_y=w_pl_y, rho=rho, h_w=h_w, f_y=f_y, m_y_c_rd=m_y_c_rd) + raise_if_less_or_equal_to_zero(gamma_m0=gamma_m0, t_w=t_w) + + a_w = h_w * t_w + m_y_v_rd = (w_pl_y - (rho * a_w**2) / (4 * t_w)) * f_y / gamma_m0 + return min(m_y_v_rd, m_y_c_rd) + + def latex(self) -> LatexFormula: + """Returns LatexFormula object for formula 6.30.""" + _equation: str = ( + r"\min\left(\frac{\left[W_{pl,y} - \frac{\rho \cdot (h_w \cdot t_w)^2}{4 \cdot t_w}\right] \cdot f_y}{\gamma_{M0}}, M_{y,c,Rd}\right)" + ) + _numeric_equation: str = latex_replace_symbols( + _equation, + { + r"W_{pl,y}": f"{self.w_pl_y:.3f}", + r"\rho": f"{self.rho:.3f}", + r"h_w": f"{self.h_w:.3f}", + r"t_w": f"{self.t_w:.3f}", + r"f_y": f"{self.f_y:.3f}", + r"\gamma_{M0}": f"{self.gamma_m0:.3f}", + r"M_{y,c,Rd}": f"{self.m_y_c_rd:.3f}", + }, + False, + ) + _numeric_equation_with_units: str = latex_replace_symbols( + _equation, + { + r"W_{pl,y}": rf"{self.w_pl_y:.3f} \ mm^3", + r"\rho": rf"{self.rho:.3f}", + r"h_w": rf"{self.h_w:.3f} \ mm", + r"t_w": rf"{self.t_w:.3f} \ mm", + r"f_y": rf"{self.f_y:.3f} \ MPa", + r"\gamma_{M0}": rf"{self.gamma_m0:.3f}", + r"M_{y,c,Rd}": rf"{self.m_y_c_rd:.3f} \ Nmm", + }, + False, + ) + return LatexFormula( + return_symbol=r"M_{y,v,Rd}", + result=f"{self:.3f}", + equation=_equation, + numeric_equation=_numeric_equation, + numeric_equation_with_units=_numeric_equation_with_units, + comparison_operator_label="=", + unit="Nmm", + ) diff --git a/tests/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/test_formula_6_29.py b/tests/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/test_formula_6_29.py new file mode 100644 index 000000000..52a3e7ff8 --- /dev/null +++ b/tests/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/test_formula_6_29.py @@ -0,0 +1,68 @@ +"""Testing formula 6.29 of NEN-EN 1993-1-1+A1:2016.""" + +import pytest + +from blueprints.codes.eurocode.nen_en_1993_1_1_c2_a1_2016.chapter_6_ultimate_limit_state.formula_6_29 import Form6Dot29ReducedYieldStrength +from blueprints.validations import LessOrEqualToZeroError, NegativeValueError + + +class TestForm6Dot29ReducedYieldStrength: + """Validation for formula 6.29 from NEN-EN 1993-1-1+A1:2016.""" + + def test_evaluation(self) -> None: + """Tests the evaluation of the result.""" + # Example values + rho = 0.75 + f_y = 355.0 # MPa + + # Object to test + formula = Form6Dot29ReducedYieldStrength(rho=rho, f_y=f_y) + + # Expected result, manually calculated + manually_calculated_result = 88.75 # MPa + + assert formula == pytest.approx(expected=manually_calculated_result, rel=1e-4) + + @pytest.mark.parametrize( + ("rho", "f_y"), + [ + (-0.75, 355.0), # rho is negative + (0.75, -355.0), # f_y is negative + (1.75, 355.0), # one_minus_rho is negative + ], + ) + def test_raise_error_when_invalid_values_are_given(self, rho: float, f_y: float) -> None: + """Test invalid values.""" + with pytest.raises((NegativeValueError, LessOrEqualToZeroError)): + Form6Dot29ReducedYieldStrength(rho=rho, f_y=f_y) + + @pytest.mark.parametrize( + ("representation", "expected"), + [ + ( + "complete", + r"f_{y,red} = (1 - \rho) \cdot f_y = (1 - 0.750) \cdot 355.000 = 88.750 \ MPa", + ), + ( + "complete_with_units", + r"f_{y,red} = (1 - \rho) \cdot f_y = (1 - 0.750) \cdot 355.000 \ MPa = 88.750 \ MPa", + ), + ("short", r"f_{y,red} = 88.750 \ MPa"), + ], + ) + def test_latex(self, representation: str, expected: str) -> None: + """Test the latex representation of the formula.""" + # Example values + rho = 0.75 + f_y = 355.0 # MPa + + # Object to test + latex = Form6Dot29ReducedYieldStrength(rho=rho, f_y=f_y).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_29rho.py b/tests/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/test_formula_6_29rho.py new file mode 100644 index 000000000..c3f9d0018 --- /dev/null +++ b/tests/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/test_formula_6_29rho.py @@ -0,0 +1,171 @@ +"""Testing formula 6.29rho 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_29rho import ( + Form6Dot29Rho, + Form6Dot29RhoWithTorsion, +) +from blueprints.validations import LessOrEqualToZeroError, NegativeValueError + + +class TestForm6Dot29Rho: + """Validation for formula 6.29rho from NEN-EN 1993-1-1+C2+A1:2016.""" + + def test_evaluation(self) -> None: + """Tests the evaluation of the result.""" + # Example values + v_ed = 300.0 + v_pl_rd = 500.0 + + # Object to test + formula = Form6Dot29Rho(v_ed=v_ed, v_pl_rd=v_pl_rd) + + # Expected result, manually calculated + manually_calculated_result = 0.04 # dimensionless + + assert formula == pytest.approx(expected=manually_calculated_result, rel=1e-4) + + def test_evaluation2(self) -> None: + """Tests the evaluation of the result.""" + # Example values + v_ed = 100.0 + v_pl_rd = 500.0 + + # Object to test + formula = Form6Dot29Rho(v_ed=v_ed, v_pl_rd=v_pl_rd) + + # Expected result, manually calculated + manually_calculated_result = 0.0 # dimensionless + + assert formula == pytest.approx(expected=manually_calculated_result, rel=1e-4) + + @pytest.mark.parametrize( + ("v_ed", "v_pl_rd"), + [ + (-300.0, 500.0), # v_ed is negative + ], + ) + def test_raise_error_when_negative_values_are_given(self, v_ed: float, v_pl_rd: float) -> None: + """Test invalid values.""" + with pytest.raises(NegativeValueError): + Form6Dot29Rho(v_ed=v_ed, v_pl_rd=v_pl_rd) + + @pytest.mark.parametrize( + ("v_ed", "v_pl_rd"), + [ + (300.0, 0.0), # v_pl_rd is zero + (300.0, -500.0), # v_pl_rd is negative + ], + ) + def test_raise_error_when_less_or_equal_to_zero_values_are_given(self, v_ed: float, v_pl_rd: float) -> None: + """Test invalid values.""" + with pytest.raises(LessOrEqualToZeroError): + Form6Dot29Rho(v_ed=v_ed, v_pl_rd=v_pl_rd) + + @pytest.mark.parametrize( + ("representation", "expected"), + [ + ( + "complete", + r"\rho = \max\left(0, \left( \frac{2 \cdot V_{Ed}}{V_{pl,Rd}} - 1 \right) \right)^2 = " + r"\max\left(0, \left( \frac{2 \cdot 300.000}{500.000} - 1 \right) \right)^2 = 0.040 \ -", + ), + ( + "complete_with_units", + r"\rho = \max\left(0, \left( \frac{2 \cdot V_{Ed}}{V_{pl,Rd}} - 1 \right) \right)^2 = " + r"\max\left(0, \left( \frac{2 \cdot 300.000 \ N}{500.000 \ N} - 1 \right) \right)^2 = 0.040 \ -", + ), + ("short", r"\rho = 0.040 \ -"), + ], + ) + def test_latex(self, representation: str, expected: str) -> None: + """Test the latex representation of the formula.""" + # Example values + v_ed = 300.0 + v_pl_rd = 500.0 + + # Object to test + latex = Form6Dot29Rho(v_ed=v_ed, v_pl_rd=v_pl_rd).latex() + + actual = { + "complete": latex.complete, + "complete_with_units": latex.complete_with_units, + "short": latex.short, + } + + assert expected == actual[representation], f"{representation} representation failed." + + +class TestForm6Dot29RhoWithTorsion: + """Validation for formula 6.29rho with torsion from NEN-EN 1993-1-1+C2+A1:2016.""" + + def test_evaluation(self) -> None: + """Tests the evaluation of the result.""" + # Example values + v_ed = 600.0 + v_pl_t_rd = 1000.0 + + # Object to test + formula = Form6Dot29RhoWithTorsion(v_ed=v_ed, v_pl_t_rd=v_pl_t_rd) + + # Expected result, manually calculated + manually_calculated_result = 0.04 # dimensionless + + assert formula == pytest.approx(expected=manually_calculated_result, rel=1e-4) + + @pytest.mark.parametrize( + ("v_ed", "v_pl_t_rd"), + [ + (-600.0, 1000.0), # v_ed is negative + ], + ) + def test_raise_error_when_negative_values_are_given(self, v_ed: float, v_pl_t_rd: float) -> None: + """Test invalid values.""" + with pytest.raises(NegativeValueError): + Form6Dot29RhoWithTorsion(v_ed=v_ed, v_pl_t_rd=v_pl_t_rd) + + @pytest.mark.parametrize( + ("v_ed", "v_pl_t_rd"), + [ + (600.0, 0.0), # v_pl_t_rd is zero + (600.0, -1000.0), # v_pl_t_rd is negative + ], + ) + def test_raise_error_when_less_or_equal_to_zero_values_are_given(self, v_ed: float, v_pl_t_rd: float) -> None: + """Test invalid values.""" + with pytest.raises(LessOrEqualToZeroError): + Form6Dot29RhoWithTorsion(v_ed=v_ed, v_pl_t_rd=v_pl_t_rd) + + @pytest.mark.parametrize( + ("representation", "expected"), + [ + ( + "complete", + r"\rho = \max\left(0, \left( \frac{2 \cdot V_{Ed}}{V_{pl,T,Rd}} - 1 \right) \right)^2 = " + r"\max\left(0, \left( \frac{2 \cdot 600.000}{1000.000} - 1 \right) \right)^2 = 0.040 \ -", + ), + ( + "complete_with_units", + r"\rho = \max\left(0, \left( \frac{2 \cdot V_{Ed}}{V_{pl,T,Rd}} - 1 \right) \right)^2 = " + r"\max\left(0, \left( \frac{2 \cdot 600.000 \ N}{1000.000 \ N} - 1 \right) \right)^2 = 0.040 \ -", + ), + ("short", r"\rho = 0.040 \ -"), + ], + ) + def test_latex(self, representation: str, expected: str) -> None: + """Test the latex representation of the formula.""" + # Example values + v_ed = 600.0 + v_pl_t_rd = 1000.0 + + # Object to test + latex = Form6Dot29RhoWithTorsion(v_ed=v_ed, v_pl_t_rd=v_pl_t_rd).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_30.py b/tests/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/test_formula_6_30.py new file mode 100644 index 000000000..1e3294e2c --- /dev/null +++ b/tests/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/test_formula_6_30.py @@ -0,0 +1,143 @@ +"""Testing formula 6.30 of NEN-EN 1993-1-1+A1:2016.""" + +import pytest + +from blueprints.codes.eurocode.nen_en_1993_1_1_c2_a1_2016.chapter_6_ultimate_limit_state.formula_6_30 import Form6Dot30ReducedPlasticResistanceMoment +from blueprints.validations import LessOrEqualToZeroError, NegativeValueError + + +class TestForm6Dot30ReducedPlasticResistanceMoment: + """Validation for formula 6.30 from NEN-EN 1993-1-1+A1:2016.""" + + def test_evaluation(self) -> None: + """Tests the evaluation of the result.""" + # Example values + w_pl_y = 500000.0 # mm^3 + rho = 0.5 # dimensionless + h_w = 300.0 # mm + t_w = 10.0 # mm + f_y = 355.0 # MPa + gamma_m0 = 1.0 # dimensionless + m_y_c_rd = 1e10 # Nmm + + # Object to test + formula = Form6Dot30ReducedPlasticResistanceMoment( + w_pl_y=w_pl_y, + rho=rho, + h_w=h_w, + t_w=t_w, + f_y=f_y, + gamma_m0=gamma_m0, + m_y_c_rd=m_y_c_rd, + ) + + # Expected result, manually calculated + manually_calculated_result = 137562500.0 # Nmm + + assert formula == pytest.approx(expected=manually_calculated_result, rel=1e-4) + + def test_evaluation2(self) -> None: + """Tests the evaluation of the result.""" + # Example values + w_pl_y = 500000.0 # mm^3 + rho = 0.5 # dimensionless + h_w = 300.0 # mm + t_w = 10.0 # mm + f_y = 355.0 # MPa + gamma_m0 = 1.0 # dimensionless + m_y_c_rd = 100.0 # Nmm + + # Object to test + formula = Form6Dot30ReducedPlasticResistanceMoment( + w_pl_y=w_pl_y, + rho=rho, + h_w=h_w, + t_w=t_w, + f_y=f_y, + gamma_m0=gamma_m0, + m_y_c_rd=m_y_c_rd, + ) + + # Expected result, manually calculated + manually_calculated_result = 100.0 # Nmm + + assert formula == pytest.approx(expected=manually_calculated_result, rel=1e-4) + + @pytest.mark.parametrize( + ("w_pl_y", "rho", "h_w", "t_w", "f_y", "gamma_m0", "m_y_c_rd"), + [ + (-500000.0, 0.5, 300.0, 10.0, 355.0, 1.0, 100000000.0), # w_pl_y is negative + (500000.0, -0.5, 300.0, 10.0, 355.0, 1.0, 100000000.0), # rho is negative + (500000.0, 0.5, -300.0, 10.0, 355.0, 1.0, 100000000.0), # h_w is negative + (500000.0, 0.5, 300.0, -10.0, 355.0, 1.0, 100000000.0), # t_w is negative + (500000.0, 0.5, 300.0, 10.0, -355.0, 1.0, 100000000.0), # f_y is negative + (500000.0, 0.5, 300.0, 10.0, 355.0, -1.0, 100000000.0), # gamma_m0 is negative + (500000.0, 0.5, 300.0, 10.0, 355.0, 1.0, -100000000.0), # m_y_c_rd is negative + (500000.0, 0.5, 300.0, 0.0, 355.0, 1.0, 100000000.0), # t_w is zero + (500000.0, 0.5, 300.0, 10.0, 355.0, 0.0, 100000000.0), # gamma_m0 is zero + ], + ) + def test_raise_error_when_negative_values_are_given( + self, w_pl_y: float, rho: float, h_w: float, t_w: float, f_y: float, gamma_m0: float, m_y_c_rd: float + ) -> None: + """Test invalid negative values.""" + with pytest.raises((NegativeValueError, LessOrEqualToZeroError)): + Form6Dot30ReducedPlasticResistanceMoment( + w_pl_y=w_pl_y, + rho=rho, + h_w=h_w, + t_w=t_w, + f_y=f_y, + gamma_m0=gamma_m0, + m_y_c_rd=m_y_c_rd, + ) + + @pytest.mark.parametrize( + ("representation", "expected"), + [ + ( + "complete", + r"M_{y,v,Rd} = \min\left(\frac{\left[W_{pl,y} - \frac{\rho \cdot (h_w \cdot t_w)^2}" + r"{4 \cdot t_w}\right] \cdot f_y}{\gamma_{M0}}, M_{y,c,Rd}\right) = " + r"\min\left(\frac{\left[500000.000 - \frac{0.500 \cdot (300.000 \cdot 10.000)^2}" + r"{4 \cdot 10.000}\right] \cdot 355.000}{1.000}, 10000000000.000\right) = 137562500.000 \ Nmm", + ), + ( + "complete_with_units", + r"M_{y,v,Rd} = \min\left(\frac{\left[W_{pl,y} - \frac{\rho \cdot (h_w \cdot t_w)^2}{4 \cdot t_w}\right] " + r"\cdot f_y}{\gamma_{M0}}, M_{y,c,Rd}\right) = " + r"\min\left(\frac{\left[500000.000 \ mm^3 - \frac{0.500 \cdot (300.000 \ mm \cdot 10.000 \ mm)^2}" + r"{4 \cdot 10.000 \ mm}\right] \cdot 355.000 \ MPa}{1.000}, 10000000000.000 \ Nmm\right) = 137562500.000 \ Nmm", + ), + ("short", r"M_{y,v,Rd} = 137562500.000 \ Nmm"), + ], + ) + def test_latex(self, representation: str, expected: str) -> None: + """Test the latex representation of the formula.""" + # Example values + w_pl_y = 500000.0 # mm^3 + rho = 0.5 # dimensionless + h_w = 300.0 # mm + t_w = 10.0 # mm + f_y = 355.0 # MPa + gamma_m0 = 1.0 # dimensionless + m_y_c_rd = 1e10 # Nmm + + # Object to test + latex = Form6Dot30ReducedPlasticResistanceMoment( + w_pl_y=w_pl_y, + rho=rho, + h_w=h_w, + t_w=t_w, + f_y=f_y, + gamma_m0=gamma_m0, + m_y_c_rd=m_y_c_rd, + ).latex() + + actual = { + "complete": latex.complete, + "complete_with_units": latex.complete_with_units, + "short": latex.short, + } + + assert expected == actual[representation], f"{representation} representation failed." From 9692739d69273452b82ecf2469f7e8557e3e81ec Mon Sep 17 00:00:00 2001 From: GerjanDorgelo Date: Fri, 2 May 2025 08:46:49 +0200 Subject: [PATCH 2/9] Add formulas 6.29 and 6.30 with corresponding object names for reduced yield strength and plastic resistance moment --- docs/objects_overview/eurocode/ec3_1993_1_1_2016/formulas.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) 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..bfebe075a 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 @@ -53,8 +53,9 @@ Total of 108 formulas present. | 6.26 | :x: | | | | 6.27 | :x: | | | | 6.28 | :x: | | | -| 6.29 | :x: | | | -| 6.30 | :x: | | | +| 6.29 | :x: | | Form6Dot29ReducedYieldStrength | +| 6.29 (rho) | :x: | | Form6Dot29Rho and Form6Dot29RhoWithTorsion | +| 6.30 | :x: | | Form6Dot30ReducedPlasticResistanceMoment | | 6.31 | :x: | | | | 6.32 | :x: | | | | 6.33 | :x: | | | From f81613497b4465d3597da023dc765688180e38ec Mon Sep 17 00:00:00 2001 From: GerjanDorgelo Date: Fri, 2 May 2025 08:50:37 +0200 Subject: [PATCH 3/9] Add additional test for formula 6.29rho with torsion to validate evaluation results --- .../test_formula_6_29rho.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tests/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/test_formula_6_29rho.py b/tests/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/test_formula_6_29rho.py index c3f9d0018..018d580dd 100644 --- a/tests/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/test_formula_6_29rho.py +++ b/tests/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/test_formula_6_29rho.py @@ -114,6 +114,20 @@ def test_evaluation(self) -> None: assert formula == pytest.approx(expected=manually_calculated_result, rel=1e-4) + def test_evaluation2(self) -> None: + """Tests the evaluation of the result.""" + # Example values + v_ed = 100.0 + v_pl_t_rd = 1000.0 + + # Object to test + formula = Form6Dot29RhoWithTorsion(v_ed=v_ed, v_pl_t_rd=v_pl_t_rd) + + # Expected result, manually calculated + manually_calculated_result = 0.00 # dimensionless + + assert formula == pytest.approx(expected=manually_calculated_result, rel=1e-4) + @pytest.mark.parametrize( ("v_ed", "v_pl_t_rd"), [ From db85ed0c8da44efdb8dc474011da7f0fac32a601 Mon Sep 17 00:00:00 2001 From: GerjanDorgelo Date: Fri, 2 May 2025 10:31:29 +0200 Subject: [PATCH 4/9] Update latex representation for formula 6.29rho and its torsion variant to include conditional cases --- .../formula_6_29rho.py | 18 +++++++--- .../test_formula_6_29rho.py | 36 ++++++++++++++----- 2 files changed, 42 insertions(+), 12 deletions(-) diff --git a/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_29rho.py b/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_29rho.py index 33960dba8..257614f2c 100644 --- a/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_29rho.py +++ b/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_29rho.py @@ -50,7 +50,12 @@ def _evaluate( def latex(self) -> LatexFormula: """Returns LatexFormula object for formula 6.29rho.""" - _equation: str = r"\max\left(0, \left( \frac{2 \cdot V_{Ed}}{V_{pl,Rd}} - 1 \right) \right)^2" + _equation: str = ( + r"\begin{cases} " + r"0 & \text{if } V_{Ed} \leq 0.5 \cdot V_{pl,Rd} \\ " + r"\left( \frac{2 \cdot V_{Ed}}{V_{pl,Rd}} - 1 \right)^2 & \text{if } V_{Ed} > 0.5 \cdot V_{pl,Rd} " + r"\end{cases}" + ) _numeric_equation: str = latex_replace_symbols( _equation, { @@ -65,7 +70,7 @@ def latex(self) -> LatexFormula: r"V_{Ed}": rf"{self.v_ed:.3f} \ N", r"V_{pl,Rd}": rf"{self.v_pl_rd:.3f} \ N", }, - True, + False, ) return LatexFormula( return_symbol=r"\rho", @@ -121,7 +126,12 @@ def _evaluate( def latex(self) -> LatexFormula: """Returns LatexFormula object for formula 6.29rho with torsion.""" - _equation: str = r"\max\left(0, \left( \frac{2 \cdot V_{Ed}}{V_{pl,T,Rd}} - 1 \right) \right)^2" + _equation: str = ( + r"\begin{cases} " + r"0 & \text{if } V_{Ed} \leq 0.5 \cdot V_{pl,T,Rd} \\ " + r"\left( \frac{2 \cdot V_{Ed}}{V_{pl,T,Rd}} - 1 \right)^2 & \text{if } V_{Ed} > 0.5 \cdot V_{pl,T,Rd} " + r"\end{cases}" + ) _numeric_equation: str = latex_replace_symbols( _equation, { @@ -136,7 +146,7 @@ def latex(self) -> LatexFormula: r"V_{Ed}": rf"{self.v_ed:.3f} \ N", r"V_{pl,T,Rd}": rf"{self.v_pl_t_rd:.3f} \ N", }, - True, + False, ) return LatexFormula( return_symbol=r"\rho", diff --git a/tests/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/test_formula_6_29rho.py b/tests/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/test_formula_6_29rho.py index 018d580dd..2b5921099 100644 --- a/tests/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/test_formula_6_29rho.py +++ b/tests/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/test_formula_6_29rho.py @@ -68,13 +68,23 @@ def test_raise_error_when_less_or_equal_to_zero_values_are_given(self, v_ed: flo [ ( "complete", - r"\rho = \max\left(0, \left( \frac{2 \cdot V_{Ed}}{V_{pl,Rd}} - 1 \right) \right)^2 = " - r"\max\left(0, \left( \frac{2 \cdot 300.000}{500.000} - 1 \right) \right)^2 = 0.040 \ -", + r"\rho = \begin{cases} " + r"0 & \text{if } V_{Ed} \leq 0.5 \cdot V_{pl,Rd} \\ " + r"\left( \frac{2 \cdot V_{Ed}}{V_{pl,Rd}} - 1 \right)^2 & \text{if } V_{Ed} > 0.5 \cdot V_{pl,Rd} " + r"\end{cases} = \begin{cases} " + r"0 & \text{if } 300.000 \leq 0.5 \cdot 500.000 \\ " + r"\left( \frac{2 \cdot 300.000}{500.000} - 1 \right)^2 & \text{if } 300.000 > 0.5 \cdot 500.000 " + r"\end{cases} = 0.040 \ -", ), ( "complete_with_units", - r"\rho = \max\left(0, \left( \frac{2 \cdot V_{Ed}}{V_{pl,Rd}} - 1 \right) \right)^2 = " - r"\max\left(0, \left( \frac{2 \cdot 300.000 \ N}{500.000 \ N} - 1 \right) \right)^2 = 0.040 \ -", + r"\rho = \begin{cases} " + r"0 & \text{if } V_{Ed} \leq 0.5 \cdot V_{pl,Rd} \\ " + r"\left( \frac{2 \cdot V_{Ed}}{V_{pl,Rd}} - 1 \right)^2 & \text{if } V_{Ed} > 0.5 \cdot V_{pl,Rd} " + r"\end{cases} = \begin{cases} " + r"0 & \text{if } 300.000 \ N \leq 0.5 \cdot 500.000 \ N \\ " + r"\left( \frac{2 \cdot 300.000 \ N}{500.000 \ N} - 1 \right)^2 & \text{if } 300.000 \ N > 0.5 \cdot 500.000 \ N " + r"\end{cases} = 0.040 \ -", ), ("short", r"\rho = 0.040 \ -"), ], @@ -156,13 +166,23 @@ def test_raise_error_when_less_or_equal_to_zero_values_are_given(self, v_ed: flo [ ( "complete", - r"\rho = \max\left(0, \left( \frac{2 \cdot V_{Ed}}{V_{pl,T,Rd}} - 1 \right) \right)^2 = " - r"\max\left(0, \left( \frac{2 \cdot 600.000}{1000.000} - 1 \right) \right)^2 = 0.040 \ -", + r"\rho = \begin{cases} " + r"0 & \text{if } V_{Ed} \leq 0.5 \cdot V_{pl,T,Rd} \\ " + r"\left( \frac{2 \cdot V_{Ed}}{V_{pl,T,Rd}} - 1 \right)^2 & \text{if } V_{Ed} > 0.5 \cdot V_{pl,T,Rd} " + r"\end{cases} = \begin{cases} " + r"0 & \text{if } 600.000 \leq 0.5 \cdot 1000.000 \\ " + r"\left( \frac{2 \cdot 600.000}{1000.000} - 1 \right)^2 & \text{if } 600.000 > 0.5 \cdot 1000.000 " + r"\end{cases} = 0.040 \ -", ), ( "complete_with_units", - r"\rho = \max\left(0, \left( \frac{2 \cdot V_{Ed}}{V_{pl,T,Rd}} - 1 \right) \right)^2 = " - r"\max\left(0, \left( \frac{2 \cdot 600.000 \ N}{1000.000 \ N} - 1 \right) \right)^2 = 0.040 \ -", + r"\rho = \begin{cases} " + r"0 & \text{if } V_{Ed} \leq 0.5 \cdot V_{pl,T,Rd} \\ " + r"\left( \frac{2 \cdot V_{Ed}}{V_{pl,T,Rd}} - 1 \right)^2 & \text{if } V_{Ed} > 0.5 \cdot V_{pl,T,Rd} " + r"\end{cases} = \begin{cases} " + r"0 & \text{if } 600.000 \ N \leq 0.5 \cdot 1000.000 \ N \\ " + r"\left( \frac{2 \cdot 600.000 \ N}{1000.000 \ N} - 1 \right)^2 & \text{if } 600.000 \ N > 0.5 \cdot 1000.000 \ N " + r"\end{cases} = 0.040 \ -", ), ("short", r"\rho = 0.040 \ -"), ], From 03203bf133d59d796765d939dc3eff032b0f853f Mon Sep 17 00:00:00 2001 From: GerjanDorgelo Date: Fri, 2 May 2025 10:42:31 +0200 Subject: [PATCH 5/9] Update implementation status for formulas 6.29 and 6.30 to reflect completion --- .../objects_overview/eurocode/ec3_1993_1_1_2016/formulas.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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 bfebe075a..a4afbb3ae 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 @@ -53,9 +53,9 @@ Total of 108 formulas present. | 6.26 | :x: | | | | 6.27 | :x: | | | | 6.28 | :x: | | | -| 6.29 | :x: | | Form6Dot29ReducedYieldStrength | -| 6.29 (rho) | :x: | | Form6Dot29Rho and Form6Dot29RhoWithTorsion | -| 6.30 | :x: | | Form6Dot30ReducedPlasticResistanceMoment | +| 6.29 | :heavy_check_mark: | | Form6Dot29ReducedYieldStrength | +| 6.29 (rho) | :heavy_check_mark: | | Form6Dot29Rho and Form6Dot29RhoWithTorsion | +| 6.30 | :heavy_check_mark: | | Form6Dot30ReducedPlasticResistanceMoment | | 6.31 | :x: | | | | 6.32 | :x: | | | | 6.33 | :x: | | | From fcd6603f011fe1482be09ecb0bb3adf3ec38880b Mon Sep 17 00:00:00 2001 From: GerjanDorgelo Date: Wed, 11 Jun 2025 09:25:41 +0200 Subject: [PATCH 6/9] Apply suggestions from code review Co-authored-by: rick <145433945+viktor-rick@users.noreply.github.com> --- .../chapter_6_ultimate_limit_state/formula_6_29.py | 2 +- .../chapter_6_ultimate_limit_state/formula_6_30.py | 8 ++++---- .../chapter_6_ultimate_limit_state/test_formula_6_30.py | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_29.py b/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_29.py index 2c0f14fc1..505f00c53 100644 --- a/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_29.py +++ b/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_29.py @@ -25,7 +25,7 @@ def __init__( Parameters ---------- rho : DIMENSIONLESS - [$\rho$] Reduction factor for shear force, see 6.2.8(3) (dimensionless). + [$\rho$] Reduction factor for shear force, see equation 6.29rho (dimensionless). f_y : MPA [$f_y$] Yield strength of the material [$MPa$]. """ diff --git a/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_30.py b/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_30.py index af1909c59..202843d11 100644 --- a/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_30.py +++ b/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_30.py @@ -8,7 +8,7 @@ class Form6Dot30ReducedPlasticResistanceMoment(Formula): - r"""Class representing formula 6.30 for the calculation of [$M_{y,v,Rd}$].""" + r"""Class representing formula 6.30 for the calculation of [$M_{y,V,Rd}$].""" label = "6.30" source_document = NEN_EN_1993_1_1_C2_A1_2016 @@ -23,7 +23,7 @@ def __init__( gamma_m0: DIMENSIONLESS, m_y_c_rd: NMM, ) -> None: - r"""[$M_{y,v,Rd}$] Reduced design plastic resistance moment [$Nmm$]. + r"""[$M_{y,V,Rd}$] Reduced design plastic resistance moment [$Nmm$]. NEN-EN 1993-1-1+A1:2016 art.6.2.8(5) - Formula (6.30) @@ -32,7 +32,7 @@ def __init__( w_pl_y : MM3 [$W_{pl,y}$] Plastic section modulus about the y axis [$mm^3$]. rho : DIMENSIONLESS - [$\rho$] Shear force ratio (see 6.2.8 (3) or (4)) [-]. + [$\rho$] Shear force ratio (see 6.2.8 (3) or equation 6.29 (rho)) [-]. h_w : MM [$h_w$] Web height [$mm$]. t_w : MM @@ -103,7 +103,7 @@ def latex(self) -> LatexFormula: False, ) return LatexFormula( - return_symbol=r"M_{y,v,Rd}", + return_symbol=r"M_{y,V,Rd}", result=f"{self:.3f}", equation=_equation, numeric_equation=_numeric_equation, diff --git a/tests/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/test_formula_6_30.py b/tests/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/test_formula_6_30.py index 1e3294e2c..c2568aa0c 100644 --- a/tests/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/test_formula_6_30.py +++ b/tests/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/test_formula_6_30.py @@ -97,14 +97,14 @@ def test_raise_error_when_negative_values_are_given( [ ( "complete", - r"M_{y,v,Rd} = \min\left(\frac{\left[W_{pl,y} - \frac{\rho \cdot (h_w \cdot t_w)^2}" + r"M_{y,V,Rd} = \min\left(\frac{\left[W_{pl,y} - \frac{\rho \cdot (h_w \cdot t_w)^2}" r"{4 \cdot t_w}\right] \cdot f_y}{\gamma_{M0}}, M_{y,c,Rd}\right) = " r"\min\left(\frac{\left[500000.000 - \frac{0.500 \cdot (300.000 \cdot 10.000)^2}" r"{4 \cdot 10.000}\right] \cdot 355.000}{1.000}, 10000000000.000\right) = 137562500.000 \ Nmm", ), ( "complete_with_units", - r"M_{y,v,Rd} = \min\left(\frac{\left[W_{pl,y} - \frac{\rho \cdot (h_w \cdot t_w)^2}{4 \cdot t_w}\right] " + r"M_{y,V,Rd} = \min\left(\frac{\left[W_{pl,y} - \frac{\rho \cdot (h_w \cdot t_w)^2}{4 \cdot t_w}\right] " r"\cdot f_y}{\gamma_{M0}}, M_{y,c,Rd}\right) = " r"\min\left(\frac{\left[500000.000 \ mm^3 - \frac{0.500 \cdot (300.000 \ mm \cdot 10.000 \ mm)^2}" r"{4 \cdot 10.000 \ mm}\right] \cdot 355.000 \ MPa}{1.000}, 10000000000.000 \ Nmm\right) = 137562500.000 \ Nmm", From d15c4215ebebdb15c0d6401cb4c32197592aa2e5 Mon Sep 17 00:00:00 2001 From: Gerjan Dorgelo Date: Wed, 11 Jun 2025 09:33:22 +0200 Subject: [PATCH 7/9] Update docstrings for Form6Dot29Rho to clarify torsion context --- .../chapter_6_ultimate_limit_state/formula_6_29rho.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_29rho.py b/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_29rho.py index 257614f2c..97fad1216 100644 --- a/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_29rho.py +++ b/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_29rho.py @@ -8,7 +8,7 @@ class Form6Dot29Rho(Formula): - r"""Class representing formula 6.29rho for the calculation of [$\rho$].""" + r"""Class representing formula 6.29rho for the calculation of [$\rho$], where no torsion is present.""" label = "6.29rho" source_document = NEN_EN_1993_1_1_C2_A1_2016 @@ -18,7 +18,7 @@ def __init__( v_ed: N, v_pl_rd: N, ) -> None: - r"""[$\rho$] Calculation of the reduction factor [$\text{dimensionless}$]. + r"""[$\rho$] Calculation of the reduction factor, where no torsion is present [$\text{dimensionless}$]. NEN-EN 1993-1-1+C2+A1:2016 art.6.2.10(3) - Formula (6.29rho) From c38275780942975f8e7f5dde59136225929f881e Mon Sep 17 00:00:00 2001 From: Gerjan Dorgelo Date: Wed, 11 Jun 2025 09:40:17 +0200 Subject: [PATCH 8/9] Fix case sensitivity in LaTeX output for short representation in test_formula_6_30 --- .../chapter_6_ultimate_limit_state/test_formula_6_30.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/test_formula_6_30.py b/tests/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/test_formula_6_30.py index c2568aa0c..ffb4ea45e 100644 --- a/tests/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/test_formula_6_30.py +++ b/tests/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/test_formula_6_30.py @@ -109,7 +109,7 @@ def test_raise_error_when_negative_values_are_given( r"\min\left(\frac{\left[500000.000 \ mm^3 - \frac{0.500 \cdot (300.000 \ mm \cdot 10.000 \ mm)^2}" r"{4 \cdot 10.000 \ mm}\right] \cdot 355.000 \ MPa}{1.000}, 10000000000.000 \ Nmm\right) = 137562500.000 \ Nmm", ), - ("short", r"M_{y,v,Rd} = 137562500.000 \ Nmm"), + ("short", r"M_{y,V,Rd} = 137562500.000 \ Nmm"), ], ) def test_latex(self, representation: str, expected: str) -> None: From 606fb269979a0e651eda9632596bf05b7c7c49af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Enrique=20Garc=C3=ADa?= Date: Wed, 11 Jun 2025 10:33:37 +0200 Subject: [PATCH 9/9] fix: correct hyphenation in docstring for plastic section modulus in formula 6.30 --- .../chapter_6_ultimate_limit_state/formula_6_30.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_30.py b/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_30.py index 202843d11..9161b7027 100644 --- a/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_30.py +++ b/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_6_ultimate_limit_state/formula_6_30.py @@ -30,7 +30,7 @@ def __init__( Parameters ---------- w_pl_y : MM3 - [$W_{pl,y}$] Plastic section modulus about the y axis [$mm^3$]. + [$W_{pl,y}$] Plastic section modulus about the y-axis [$mm^3$]. rho : DIMENSIONLESS [$\rho$] Shear force ratio (see 6.2.8 (3) or equation 6.29 (rho)) [-]. h_w : MM