Skip to content

Commit 82d5a24

Browse files
Merge pull request #402 from Blueprints-org/401-feature-request-add-formulas-from-chapter-589-from-nen_en_1992_1_1
401 feature request add formulas from chapter 589 from nen en 1992 1 1
2 parents e55791f + 0506933 commit 82d5a24

File tree

7 files changed

+429
-3
lines changed

7 files changed

+429
-3
lines changed
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
"""Formula 5.38a from NEN-EN 1992-1-1+C2:2011: Chapter 5 - Structural Analysis."""
2+
3+
from blueprints.codes.eurocode.nen_en_1992_1_1_c2_2011 import NEN_EN_1992_1_1_C2_2011
4+
from blueprints.codes.formula import Formula
5+
from blueprints.codes.latex_formula import LatexFormula
6+
from blueprints.type_alias import DIMENSIONLESS
7+
from blueprints.validations import raise_if_less_or_equal_to_zero
8+
9+
10+
class Form5Dot38aCheckRelativeSlendernessRatio(Formula):
11+
r"""Class representing formula 5.38a for check of relative slenderness ratio."""
12+
13+
label = "5.38a"
14+
source_document = NEN_EN_1992_1_1_C2_2011
15+
16+
def __init__(
17+
self,
18+
lambda_y: DIMENSIONLESS,
19+
lambda_z: DIMENSIONLESS,
20+
) -> None:
21+
r"""Check the ratio of the slenderness in y-direction and z-direction.
22+
23+
NEN-EN 1992-1-1+C2:2011 art.5.8.9(3) - Formula (5.38a)
24+
25+
Parameters
26+
----------
27+
lambda_y : DIMENSIONLESS
28+
[:math:`\lambda_{y}`] Slenderness ratio in y-direction [-].
29+
lambda_z : DIMENSIONLESS
30+
[:math:`\lambda_{z}`] Slenderness ratio in z-direction [-].
31+
"""
32+
super().__init__()
33+
self.lambda_y = lambda_y
34+
self.lambda_z = lambda_z
35+
36+
@staticmethod
37+
def _evaluate(
38+
lambda_y: float,
39+
lambda_z: float,
40+
) -> bool:
41+
"""Evaluates the formula, for more information see the __init__ method."""
42+
raise_if_less_or_equal_to_zero(lambda_y=lambda_y, lambda_z=lambda_z)
43+
44+
return (lambda_y / lambda_z <= 2) and (lambda_z / lambda_y <= 2)
45+
46+
def latex(self) -> LatexFormula:
47+
"""Returns LatexFormula object for formula 5.38a."""
48+
return LatexFormula(
49+
return_symbol=r"CHECK",
50+
result="OK" if self.__bool__() else "\\text{Not OK}",
51+
equation=r"\left( \frac{\lambda_{y}}{\lambda_{z}} \leq 2 \text{ and } \frac{\lambda_{z}}{\lambda_{y}} \leq 2 \right)",
52+
numeric_equation=rf"\left( \frac{{{self.lambda_y:.3f}}}{{{self.lambda_z:.3f}}} \leq 2 \text{{ and }} "
53+
rf"\frac{{{self.lambda_z:.3f}}}{{{self.lambda_y:.3f}}} \leq 2 \right)",
54+
comparison_operator_label="\\to",
55+
unit="",
56+
)
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
"""Formula 5.38b from NEN-EN 1992-1-1+C2:2011: Chapter 5 - Structural Analysis."""
2+
3+
from blueprints.codes.eurocode.nen_en_1992_1_1_c2_2011 import NEN_EN_1992_1_1_C2_2011
4+
from blueprints.codes.formula import Formula
5+
from blueprints.codes.latex_formula import LatexFormula
6+
from blueprints.type_alias import MM
7+
from blueprints.validations import raise_if_less_or_equal_to_zero, raise_if_negative
8+
9+
10+
class Form5Dot38bCheckRelativeEccentricityRatio(Formula):
11+
r"""Class representing formula 5.38b for check of relative eccentricity ratio."""
12+
13+
label = "5.38b"
14+
source_document = NEN_EN_1992_1_1_C2_2011
15+
16+
def __init__(
17+
self,
18+
e_y: MM,
19+
e_z: MM,
20+
b_eq: MM,
21+
h_eq: MM,
22+
) -> None:
23+
r"""Check the excentricity of the loads in x and y direction.
24+
25+
NEN-EN 1992-1-1+C2:2011 art.5.8.9(3) - Formula (5.38b)
26+
27+
Parameters
28+
----------
29+
e_y : DIMENSIONLESS
30+
[:math:`e_{y}`] Eccentricity along y-axis [mm].
31+
e_z : DIMENSIONLESS
32+
[:math:`e_{z}`] Eccentricity along z-axis [mm].
33+
b_eq : DIMENSIONLESS
34+
[:math:`b_{eq}`] Equivalent width [mm].
35+
h_eq : DIMENSIONLESS
36+
[:math:`h_{eq}`] Equivalent depth [mm].
37+
"""
38+
super().__init__()
39+
self.e_y = e_y
40+
self.e_z = e_z
41+
self.b_eq = b_eq
42+
self.h_eq = h_eq
43+
44+
@staticmethod
45+
def _evaluate(
46+
e_y: float,
47+
e_z: float,
48+
b_eq: float,
49+
h_eq: float,
50+
) -> bool:
51+
"""Evaluates the formula, for more information see the __init__ method."""
52+
raise_if_negative(e_y=e_y, e_z=e_z)
53+
raise_if_less_or_equal_to_zero(b_eq=b_eq, h_eq=h_eq)
54+
55+
# The formula is simplified to avoid division by zero.
56+
if e_y == 0 or e_z == 0:
57+
return True
58+
59+
return (e_y / h_eq) / (e_z / b_eq) <= 0.2 or (e_z / b_eq) / (e_y / h_eq) <= 0.2
60+
61+
def latex(self) -> LatexFormula:
62+
"""Returns LatexFormula object for formula 5.38b."""
63+
return LatexFormula(
64+
return_symbol=r"CHECK",
65+
result="OK" if self.__bool__() else "\\text{Not OK}",
66+
equation=r"\left(\frac{e_{y}/h_{eq}}{e_{z}/b_{eq}} \leq 0.2 \text{ or } \frac{e_{z}/b_{eq}}{e_{y}/h_{eq}} \leq 0.2 \right)",
67+
numeric_equation=rf"\left(\frac{{{self.e_y:.3f}/{self.h_eq:.3f}}}{{{self.e_z:.3f}/{self.b_eq:.3f}}} "
68+
rf"\leq 0.2 \text{{ or }} \frac{{{self.e_z:.3f}/{self.b_eq:.3f}}}{{{self.e_y:.3f}/{self.h_eq:.3f}}} \leq 0.2 \right)",
69+
comparison_operator_label="\\to",
70+
unit="",
71+
)
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
"""Formula 5.39 from NEN-EN 1992-1-1+C2:2011: Chapter 5 - Structural Analysis."""
2+
3+
from blueprints.codes.eurocode.nen_en_1992_1_1_c2_2011 import NEN_EN_1992_1_1_C2_2011
4+
from blueprints.codes.formula import Formula
5+
from blueprints.codes.latex_formula import LatexFormula
6+
from blueprints.type_alias import DIMENSIONLESS, KNM
7+
from blueprints.validations import raise_if_less_or_equal_to_zero, raise_if_negative
8+
9+
10+
class Form5Dot39SimplifiedCriterionBiaxialBending(Formula):
11+
r"""Class representing formula 5.39 for simplified criterion for biaxial bending."""
12+
13+
label = "5.39"
14+
source_document = NEN_EN_1992_1_1_C2_2011
15+
16+
def __init__(
17+
self,
18+
m_edz: KNM,
19+
m_rdz: KNM,
20+
m_edy: KNM,
21+
m_rdy: KNM,
22+
a: DIMENSIONLESS,
23+
) -> None:
24+
r"""Simplified criterion for biaxial bending.
25+
26+
NEN-EN 1992-1-1+C2:2011 art.5.8.9(4) - Formula (5.39)
27+
28+
Parameters
29+
----------
30+
m_edz : KNM
31+
[:math:`M_{Edz}`] Design moment including second order moment in z-direction [:math:`kNm`].
32+
m_rdz : KNM
33+
[:math:`M_{Rdz}`] Design moment resistance in z-direction [:math:`kNm`].
34+
m_edy : KNM
35+
[:math:`M_{Edy}`] Design moment including second order moment in y-direction [:math:`kNm`].
36+
m_rdy : KNM
37+
[:math:`M_{Rdy}`] Design moment resistance in y-direction [:math:`kNm`].
38+
a : DIMENSIONLESS
39+
[:math:`a`] Exponent for the interaction formula, for circular and elliptical cross sections: a = 2, for rectengular see table [-].
40+
"""
41+
super().__init__()
42+
self.m_edz = m_edz
43+
self.m_rdz = m_rdz
44+
self.m_edy = m_edy
45+
self.m_rdy = m_rdy
46+
self.a = a
47+
48+
@staticmethod
49+
def _evaluate(
50+
m_edz: KNM,
51+
m_rdz: KNM,
52+
m_edy: KNM,
53+
m_rdy: KNM,
54+
a: DIMENSIONLESS,
55+
) -> bool:
56+
"""Evaluates the formula, for more information see the __init__ method."""
57+
raise_if_negative(m_edz=m_edz, m_edy=m_edy)
58+
raise_if_less_or_equal_to_zero(m_rdz=m_rdz, m_rdy=m_rdy, a=a)
59+
60+
return (m_edz / m_rdz) ** a + (m_edy / m_rdy) ** a <= 1
61+
62+
def latex(self) -> LatexFormula:
63+
"""Returns LatexFormula object for formula 5.39."""
64+
return LatexFormula(
65+
return_symbol=r"CHECK",
66+
result="OK" if self.__bool__() else "\\text{Not OK}",
67+
equation=r"\left( \frac{M_{Edz}}{M_{Rdz}} \right)^{a} + \left( \frac{M_{Edy}}{M_{Rdy}} \right)^{a} \leq 1",
68+
numeric_equation=rf"\left( \frac{{{self.m_edz:.3f}}}{{{self.m_rdz:.3f}}} \right)^{{{self.a:.3f}}} + "
69+
rf"\left( \frac{{{self.m_edy:.3f}}}{{{self.m_rdy:.3f}}} \right)^{{{self.a:.3f}}} \leq 1",
70+
comparison_operator_label="\\to",
71+
unit="",
72+
)

docs/source/codes/eurocode/ec2_1992_1_1_2011/formulas.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,9 +86,9 @@ Total of 304 formulas present.
8686
| 5.35 | :heavy_check_mark: | | Form5Dot35EffectiveDepth |
8787
| 5.36 | :heavy_check_mark: | | Form5Dot36RelativeAxialForce |
8888
| 5.37 | :heavy_check_mark: | | Form5Dot37CreepFactor |
89-
| 5.38a | :x: | | |
90-
| 5.38b | :x: | | |
91-
| 5.39 | :x: | | |
89+
| 5.38a | :heavy_check_mark: | | Form5Dot38aCheckRelativeSlendernessRatio |
90+
| 5.38b | :heavy_check_mark: | | Form5Dot38bCheckRelativeEccentricityRatio |
91+
| 5.39 | :heavy_check_mark: | | Form5Dot39SimplifiedCriterionBiaxialBending |
9292
| 5.40a | :x: | | |
9393
| 5.40b | :x: | | |
9494
| 5.41 | :x: | | |
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
"""Testing formula 5.38a of NEN-EN 1992-1-1+C2:2011."""
2+
3+
import pytest
4+
5+
from blueprints.codes.eurocode.nen_en_1992_1_1_c2_2011.chapter_5_structural_analysis.formula_5_38a import Form5Dot38aCheckRelativeSlendernessRatio
6+
from blueprints.validations import LessOrEqualToZeroError, NegativeValueError
7+
8+
9+
class TestForm5Dot38aCheckRelativeSlendernessRatio:
10+
"""Validation for formula 5.38a from NEN-EN 1992-1-1+C2:2011."""
11+
12+
def test_evaluation(self) -> None:
13+
"""Tests the evaluation of the result."""
14+
# Example values
15+
lambda_y = 1.0
16+
lambda_z = 1.5
17+
18+
# Object to test
19+
formula = Form5Dot38aCheckRelativeSlendernessRatio(lambda_y=lambda_y, lambda_z=lambda_z)
20+
21+
# Expected result, manually calculated
22+
expected_result = True
23+
24+
assert formula == expected_result
25+
26+
@pytest.mark.parametrize(
27+
("lambda_y", "lambda_z"),
28+
[
29+
(-1.0, 1.5), # lambda_y is negative
30+
(1.0, -1.5), # lambda_z is negative
31+
(0.0, 1.5), # lambda_y is zero
32+
(1.0, 0.0), # lambda_z is zero
33+
],
34+
)
35+
def test_raise_error_when_invalid_values_are_given(self, lambda_y: float, lambda_z: float) -> None:
36+
"""Test invalid values."""
37+
with pytest.raises((NegativeValueError, LessOrEqualToZeroError)):
38+
Form5Dot38aCheckRelativeSlendernessRatio(lambda_y=lambda_y, lambda_z=lambda_z)
39+
40+
@pytest.mark.parametrize(
41+
("representation", "expected"),
42+
[
43+
(
44+
"complete",
45+
r"CHECK \to \left( \frac{\lambda_{y}}{\lambda_{z}} \leq 2 \text{ and } \frac{\lambda_{z}}{\lambda_{y}} \leq 2 \right) \to "
46+
r"\left( \frac{1.000}{1.500} \leq 2 \text{ and } \frac{1.500}{1.000} \leq 2 \right) \to OK",
47+
),
48+
("short", r"CHECK \to OK"),
49+
],
50+
)
51+
def test_latex(self, representation: str, expected: str) -> None:
52+
"""Test the latex representation of the formula."""
53+
# Example values
54+
lambda_y = 1.0
55+
lambda_z = 1.5
56+
57+
# Object to test
58+
latex = Form5Dot38aCheckRelativeSlendernessRatio(lambda_y=lambda_y, lambda_z=lambda_z).latex()
59+
60+
actual = {
61+
"complete": latex.complete,
62+
"short": latex.short,
63+
}
64+
65+
assert expected == actual[representation], f"{representation} representation failed."
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
"""Testing formula 5.38b of NEN-EN 1992-1-1+C2:2011."""
2+
3+
import pytest
4+
5+
from blueprints.codes.eurocode.nen_en_1992_1_1_c2_2011.chapter_5_structural_analysis.formula_5_38b import Form5Dot38bCheckRelativeEccentricityRatio
6+
from blueprints.validations import LessOrEqualToZeroError, NegativeValueError
7+
8+
9+
class TestForm5Dot38bCheckRelativeEccentricityRatio:
10+
"""Validation for formula 5.38b from NEN-EN 1992-1-1+C2:2011."""
11+
12+
def test_evaluation(self) -> None:
13+
"""Tests the evaluation of the result."""
14+
# Example values
15+
e_y = 30.0
16+
e_z = 4.0
17+
b_eq = 100.0
18+
h_eq = 101.0
19+
20+
# Object to test
21+
formula = Form5Dot38bCheckRelativeEccentricityRatio(e_y=e_y, e_z=e_z, b_eq=b_eq, h_eq=h_eq)
22+
23+
# Expected result, manually calculated
24+
expected_result = True
25+
26+
assert formula == expected_result
27+
28+
def test_evaluation_excentricity_zero(self) -> None:
29+
"""Tests the evaluation of the result with e=0."""
30+
# Example values
31+
e_y = 30.0
32+
e_z = 0.0
33+
b_eq = 100.0
34+
h_eq = 101.0
35+
36+
# Object to test
37+
formula = Form5Dot38bCheckRelativeEccentricityRatio(e_y=e_y, e_z=e_z, b_eq=b_eq, h_eq=h_eq)
38+
39+
# Expected result, manually calculated
40+
expected_result = True
41+
42+
assert formula == expected_result
43+
44+
@pytest.mark.parametrize(
45+
("e_y", "e_z", "b_eq", "h_eq"),
46+
[
47+
(-30.0, 4.0, 100.0, 101.0), # e_y is negative
48+
(30.0, -4.0, 100.0, 101.0), # e_z is negative
49+
(30.0, 4.0, -100.0, 101.0), # b_eq is negative
50+
(30.0, 4.0, 100.0, -101.0), # h_eq is negative
51+
(30.0, 4.0, 0.0, 101.0), # b_eq is zero
52+
(30.0, 4.0, 100.0, 0.0), # h_eq is zero
53+
],
54+
)
55+
def test_raise_error_when_invalid_values_are_given(self, e_y: float, e_z: float, b_eq: float, h_eq: float) -> None:
56+
"""Test invalid values."""
57+
with pytest.raises((NegativeValueError, LessOrEqualToZeroError)):
58+
Form5Dot38bCheckRelativeEccentricityRatio(e_y=e_y, e_z=e_z, b_eq=b_eq, h_eq=h_eq)
59+
60+
@pytest.mark.parametrize(
61+
("representation", "expected"),
62+
[
63+
(
64+
"complete",
65+
r"CHECK \to \left(\frac{e_{y}/h_{eq}}{e_{z}/b_{eq}} \leq 0.2 \text{ or } \frac{e_{z}/b_{eq}}{e_{y}/h_{eq}} \leq 0.2 \right) \to"
66+
r" \left(\frac{30.000/101.000}{4.000/100.000} \leq 0.2 \text{ or } \frac{4.000/100.000}{30.000/101.000} \leq 0.2 \right) \to OK",
67+
),
68+
("short", r"CHECK \to OK"),
69+
],
70+
)
71+
def test_latex(self, representation: str, expected: str) -> None:
72+
"""Test the latex representation of the formula."""
73+
# Example values
74+
e_y = 30.0
75+
e_z = 4.0
76+
b_eq = 100.0
77+
h_eq = 101.0
78+
79+
# Object to test
80+
latex = Form5Dot38bCheckRelativeEccentricityRatio(e_y=e_y, e_z=e_z, b_eq=b_eq, h_eq=h_eq).latex()
81+
82+
actual = {
83+
"complete": latex.complete,
84+
"short": latex.short,
85+
}
86+
87+
assert expected == actual[representation], f"{representation} representation failed."

0 commit comments

Comments
 (0)