diff --git a/.github/prompts/comparison_formula.prompt.md b/.github/prompts/comparison_formula.prompt.md index 46d57b481..0843c763c 100644 --- a/.github/prompts/comparison_formula.prompt.md +++ b/.github/prompts/comparison_formula.prompt.md @@ -4,10 +4,10 @@ - Make sure the script returns a bool. - Keep all formatting and naming conventions such as they are presented in the template. - If variable descriptions are given or found, copy precisely and fully from input or Eurocode. -- Variablenames are always lowercase. +- Variable names are always lowercase in line with PEP8. - In the LaTeX formula, edit the return symbol such that it is the left hand side of the equation - Edit the _equation variable such that it represents the right hand side of the equation -- LaTeX variables should be rounded to 3 decimals. +- LaTeX variables should be rounded to 3 decimals as default, but could be overwritten at usage level. - Import the necessary typehinting with type alias units found in type_alias.py and remove the unused imported type aliases. Forces in N, (Bending) moments in Nmm, distances in mm, areas in mm^2, Stress in MPa, angles in DEG, no unit is DIMENSIONLESS. When dealing with angles, use np.deg2rad. ## Template for service @@ -58,14 +58,14 @@ class Form5Dot38aCheckRelativeSlendernessRatio(Formula): return (lambda_y / lambda_z <= 2) and (lambda_z / lambda_y <= 2) - def latex(self) -> LatexFormula: + def latex(self, n: int = 3) -> LatexFormula: """Returns LatexFormula object for formula 5.38a.""" _equation: str = r"\left( \frac{\lambda_{y}}{\lambda_{z}} \leq 2 \text{ and } \frac{\lambda_{z}}{\lambda_{y}} \leq 2 \right)" _numeric_equation: str = latex_replace_symbols( _equation, { - "lambda_y": f"{self.lambda_y:.3f}", - "lambda_z": f"{self.lambda_z:.3f}", + "lambda_y": f"{self.lambda_y:.{n}f}", + "lambda_z": f"{self.lambda_z:.{n}f}", }, False, ) diff --git a/.gitignore b/.gitignore index e85e0527b..d34d68216 100644 --- a/.gitignore +++ b/.gitignore @@ -165,4 +165,5 @@ cython_debug/ .vscode/ # ENV file -.ENV \ No newline at end of file +.ENV +/local/ diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 5f33cefa4..743ca201a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -17,7 +17,7 @@ repos: - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.9.4 + rev: v0.9.9 hooks: # Run the linter. - id: ruff @@ -26,7 +26,7 @@ repos: - id: ruff-format - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.14.1 + rev: v1.15.0 hooks: - id: mypy language_version: python3.12 diff --git a/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_5_structural_analysis/__init__.py b/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_5_structural_analysis/__init__.py new file mode 100644 index 000000000..1436a5910 --- /dev/null +++ b/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_5_structural_analysis/__init__.py @@ -0,0 +1 @@ +"""Module containing all formulas from 1993-1-1+C2+A1:2016: Chapter 5 - Structural analysis.""" diff --git a/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_5_structural_analysis/formula_5_8.py b/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_5_structural_analysis/formula_5_8.py new file mode 100644 index 000000000..b41492bff --- /dev/null +++ b/blueprints/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_5_structural_analysis/formula_5_8.py @@ -0,0 +1,79 @@ +"""Formula 5.8 from NEN-EN 1993-1-1+C2+A1:2016: Chapter 5 - Structural Analysis.""" + +import numpy as np + +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, MM2, MPA, N +from blueprints.validations import raise_if_less_or_equal_to_zero + + +class Form5Dot8CheckSlenderness(Formula): + r"""Class representing formula 5.8 for check of slenderness.""" + + label = "5.8" + source_document = NEN_EN_1993_1_1_C2_A1_2016 + + def __init__( + self, + lambda_bar: DIMENSIONLESS, + a: MM2, + f_y: MPA, + n_ed: N, + ) -> None: + r"""Check the slenderness ratio. + + NEN-EN 1993-1-1+C2+A1:2016 art.5.3.2(6) - Formula (5.8) + + Parameters + ---------- + lambda_bar : DIMENSIONLESS + [$\lambda_{bar}$] Non-dimensional slenderness [-]. + a : MM2 + [$A$] Cross-sectional area [$mm^2$]. + f_y : MPA + [$f_y$] Yield strength [$MPa$]. + n_ed : N + [$N_{Ed}$] Design value of the compression force [$N$]. + """ + super().__init__() + self.lambda_bar = lambda_bar + self.a = a + self.f_y = f_y + self.n_ed = n_ed + + @staticmethod + def _evaluate( + lambda_bar: DIMENSIONLESS, + a: MM2, + f_y: MPA, + n_ed: N, + ) -> bool: + """Evaluates the formula, for more information see the __init__ method.""" + raise_if_less_or_equal_to_zero(lambda_bar=lambda_bar, A=a, f_y=f_y, N_Ed=n_ed) + + return lambda_bar > 0.5 * np.sqrt(a * f_y / n_ed) + + def latex(self) -> LatexFormula: + """Returns LatexFormula object for formula 5.8.""" + n = 2 + _equation: str = r"\left( \lambda_{bar} > 0.5 \sqrt{\frac{A \cdot f_{y}}{N_{Ed}}} \right)" + _numeric_equation: str = latex_replace_symbols( + _equation, + { + r"\lambda_{bar}": f"{self.lambda_bar:.{n}f}", + "A": f"{self.a:.{n}f}", + "f_{y}": f"{self.f_y:.{n}f}", + "N_{Ed}": f"{self.n_ed:.{n}f}", + }, + False, + ) + return LatexFormula( + return_symbol=r"CHECK", + result="OK" if self.__bool__() else "\\text{Not OK}", + equation=_equation, + numeric_equation=_numeric_equation, + comparison_operator_label="\\to", + unit="", + ) diff --git a/tests/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_5_structural_analysis/__init__.py b/tests/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_5_structural_analysis/__init__.py new file mode 100644 index 000000000..7625734e2 --- /dev/null +++ b/tests/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_5_structural_analysis/__init__.py @@ -0,0 +1 @@ +"""Tests for the module `nen_en_1993_1_1_c2_a1_2016.chapter_5_structural_analysis`.""" diff --git a/tests/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_5_structural_analysis/test_formula_5_8.py b/tests/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_5_structural_analysis/test_formula_5_8.py new file mode 100644 index 000000000..cf5964cfb --- /dev/null +++ b/tests/codes/eurocode/nen_en_1993_1_1_c2_a1_2016/chapter_5_structural_analysis/test_formula_5_8.py @@ -0,0 +1,64 @@ +"""Testing formula 5.8 of NEN-EN 1993-1-1+C2+A1:2016.""" + +import pytest + +from blueprints.codes.eurocode.nen_en_1993_1_1_c2_a1_2016.chapter_5_structural_analysis.formula_5_8 import Form5Dot8CheckSlenderness +from blueprints.validations import LessOrEqualToZeroError + + +class TestForm5Dot8CheckSlenderness: + """Validation for formula 5.8 from NEN-EN 1993-1-1+C2+A1:2016.""" + + def test_evaluation(self) -> None: + """Tests the evaluation of the result.""" + # Example values + lambda_bar = 1.0 + a = 1000.0 + f_y = 355.0 + n_ed = 100000.0 + + # Object to test + formula = Form5Dot8CheckSlenderness(lambda_bar=lambda_bar, a=a, f_y=f_y, n_ed=n_ed) + + # Expected result, manually calculated + expected_result = True + + assert formula == expected_result + + @pytest.mark.parametrize( + ("lambda_bar", "a", "f_y", "n_ed"), + [ + (-1.0, 1000.0, 355.0, 100000.0), # lambda_bar is negative + (1.0, -1000.0, 355.0, 100000.0), # a is negative + (1.0, 1000.0, -355.0, 100000.0), # f_y is negative + (1.0, 1000.0, 355.0, -100000.0), # n_ed is negative + (0.0, 1000.0, 355.0, 100000.0), # lambda_bar is zero + (1.0, 0.0, 355.0, 100000.0), # a is zero + (1.0, 1000.0, 0.0, 100000.0), # f_y is zero + (1.0, 1000.0, 355.0, 0.0), # n_ed is zero + ], + ) + def test_raise_error_when_invalid_values_are_given(self, lambda_bar: float, a: float, f_y: float, n_ed: float) -> None: + """Test invalid values.""" + with pytest.raises(LessOrEqualToZeroError): + Form5Dot8CheckSlenderness(lambda_bar, a, f_y, n_ed) + + def test_latex(self) -> None: + """Test the latex representation of the formula.""" + # Example values + lambda_bar = 1.0 + a = 1000.0 + f_y = 355.0 + n_ed = 100000.0 + + # Object to test + formula = Form5Dot8CheckSlenderness(lambda_bar=lambda_bar, a=a, f_y=f_y, n_ed=n_ed) + latex = formula.latex() + + expected_equation = r"\left( \lambda_{bar} > 0.5 \sqrt{\frac{A \cdot f_{y}}{N_{Ed}}} \right)" + expected_numeric_equation = r"\left( 1.00 > 0.5 \sqrt{\frac{1000.00 \cdot 355.00}{100000.00}} \right)" + expected_result = "OK" + + assert latex.equation == expected_equation + assert latex.numeric_equation == expected_numeric_equation + assert latex.result == expected_result