Skip to content

Commit

Permalink
Merge branch 'main' into 109-feature-request-add-a-latex-to-formula-91n
Browse files Browse the repository at this point in the history
  • Loading branch information
egarciamendez authored Mar 27, 2024
2 parents 5511faa + f7ffd1d commit 2fb3fe5
Show file tree
Hide file tree
Showing 4 changed files with 294 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
"""Formula 5.10 from NEN-EN 1993-5:2008 Chapter 5 - Ultimate limit state."""

from blueprints.codes.eurocode.nen_en_1993_5_2008 import NEN_EN_1993_5_2008
from blueprints.codes.formula import Formula
from blueprints.codes.latex_formula import LatexFormula
from blueprints.type_alias import DIMENSIONLESS, KN
from blueprints.validations import raise_if_less_or_equal_to_zero


class Form5Dot10ReductionFactorShearArea(Formula):
"""Class representing formula 5.10 for reduction factor for shear area."""

label = "5.10"
source_document = NEN_EN_1993_5_2008

def __init__(
self,
v_ed: KN,
v_pl_rd: KN,
) -> None:
"""[:math:`ρ`] Calculate the reduction factor for shear area of the cross-section [-].
NEN-EN 1993-5:2008(E) art.5.2.2(9) - Formula (5.10)
Parameters
----------
v_ed : KN
[:math:`V_{Ed}`] Design shear force in [:math:`kN`].
v_pl_rd : KN
[:math:`V_{pl,rd}`] Plastic shear resistance in [:math:`kN`].
"""
super().__init__()
self.v_ed: float = v_ed
self.v_pl_rd: float = v_pl_rd

@staticmethod
def _evaluate(
v_ed: KN,
v_pl_rd: KN,
) -> DIMENSIONLESS:
"""Evaluates the formula for reduction factor for shear area."""
raise_if_less_or_equal_to_zero(v_ed=v_ed, v_pl_rd=v_pl_rd)
return (2 * v_ed / v_pl_rd - 1) ** 2

def latex(self) -> LatexFormula:
"""Returns LatexFormula object for formula 5.10."""
return LatexFormula(
return_symbol=r"\rho",
result=str(self),
equation=r"\left(2 \cdot \frac{V_{Ed}}{V_{pl,Rd}} - 1\right)^2",
numeric_equation=rf"\left(2 \cdot \frac{{{self.v_ed}}}{{{self.v_pl_rd}}} - 1\right)^2",
comparison_operator_label="=",
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
"""Formula 5.7 from NEN-EN 1993-5:2008 Chapter 5 - Ultimate limit state."""

from blueprints.codes.eurocode.nen_en_1993_5_2008 import NEN_EN_1993_5_2008
from blueprints.codes.formula import Formula
from blueprints.codes.latex_formula import LatexFormula, latex_fraction
from blueprints.type_alias import DIMENSIONLESS, KN, MM, MPA
from blueprints.unit_conversion import N_TO_KN
from blueprints.validations import raise_if_less_or_equal_to_zero


class Form5Dot7ShearBucklingResistance(Formula):
"""Class representing formula 5.7 for shear buckling resistance."""

label = "5.7"
source_document = NEN_EN_1993_5_2008

def __init__(
self,
h: MM,
t_f: MM,
t_w: MM,
f_bv: MPA,
gamma_m_0: DIMENSIONLESS,
) -> None:
"""[:math:`V_{b,Rd}`] Calculate the shear buckling resistance [:math:`kN`].
NEN-EN 1993-5:2008(E) art.5.2.2(7) - Formula (5.7)
Parameters
----------
h : MM
[:math:`h`] Height of the web in [:math:`mm`].
t_f : MM
[:math:`t_{f}`] Thickness of the flange in [:math:`mm`].
t_w : MM
[:math:`t_{w}`] Thickness of the web in [:math:`mm`].
f_bv : MPA
[:math:`f_{bv}`] Shear buckling strength according to Table 6-1 of EN 1993-1-3 for a web without stiffening
at the support and for a relative web slenderness [:math:`MPa`]
gamma_m_0 : float
[:math:`γ_{M0}`] Partial factor for material properties [-].
"""
super().__init__()
self.h: float = h
self.t_f: float = t_f
self.t_w: float = t_w
self.f_bv: float = f_bv
self.gamma_m_0: float = gamma_m_0

@staticmethod
def _evaluate(
h: MM,
t_f: MM,
t_w: MM,
f_bv: MPA,
gamma_m_0: float,
) -> KN:
"""Evaluates the formula for shear buckling resistance."""
raise_if_less_or_equal_to_zero(
h=h,
t_f=t_f,
t_w=t_w,
f_bv=f_bv,
gamma_m_0=gamma_m_0,
)
if t_f >= h:
raise ValueError("The thickness of the flange should be less than the height of the web.")
return ((h - t_f) * t_w * f_bv / gamma_m_0) * N_TO_KN

def latex(self) -> LatexFormula:
"""Returns LatexFormula object for formula 5.7."""
return LatexFormula(
return_symbol=r"V_{b,Rd}",
result=f"{self:.3f}",
equation=latex_fraction(numerator=r"\left(h - t_f \right) t_w f_{bv}", denominator=r"\gamma_{M0}"),
numeric_equation=latex_fraction(
numerator=rf"({self.h:.2f} - {self.t_f:.2f}) \cdot {self.t_w} \cdot {self.f_bv:.3f}",
denominator=self.gamma_m_0,
),
comparison_operator_label="=",
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
"""Testing formula 5.10 of NEN-EN 1993-5:2008."""

import pytest

from blueprints.codes.eurocode.nen_en_1993_5_2008.chapter_5_ultimate_limit_states.formula_5_10 import Form5Dot10ReductionFactorShearArea
from blueprints.validations import LessOrEqualToZeroError


class TestForm5Dot10ReductionFactorShearArea:
"""Validation for formula 5.10 from NEN-EN 1993-5:2008."""

def test_evaluation(self) -> None:
"""Test the evaluation of the result."""
# Example values
v_ed = 100 # kN
v_pl_rd = 400 # kN

form = Form5Dot10ReductionFactorShearArea(v_ed=v_ed, v_pl_rd=v_pl_rd)

# Expected result, manually calculated
expected = 0.25

assert form == pytest.approx(expected)

@pytest.mark.parametrize(
("v_ed", "v_pl_rd"),
[
(0, 200), # v_ed is zero
(-100, 200), # v_ed is negative
(100, 0), # v_pl_rd is zero
(100, -200), # v_pl_rd is negative
],
)
def test_raise_error_when_negative_or_zero_values_are_given(self, v_ed: float, v_pl_rd: float) -> None:
"""Test a zero and negative value for parameters v_ed and v_pl_rd."""
with pytest.raises(LessOrEqualToZeroError):
Form5Dot10ReductionFactorShearArea(v_ed=v_ed, v_pl_rd=v_pl_rd)

@pytest.mark.parametrize(
("representation", "expected"),
[
(
"complete",
r"\rho = \left(2 \cdot \frac{V_{Ed}}{V_{pl,Rd}} - 1\right)^2 = \left(2 \cdot \frac{100}{400} - 1\right)^2 = 0.25",
),
("short", r"\rho = 0.25"),
(
"string",
r"\rho = \left(2 \cdot \frac{V_{Ed}}{V_{pl,Rd}} - 1\right)^2 = \left(2 \cdot \frac{100}{400} - 1\right)^2 = 0.25",
),
],
)
def test_latex_output(self, representation: str, expected: str) -> None:
"""Test the latex implementation."""
# Example values
v_ed = 100 # kN
v_pl_rd = 400 # kN

form = Form5Dot10ReductionFactorShearArea(v_ed=v_ed, v_pl_rd=v_pl_rd).latex()

actual = {
"complete": form.complete,
"short": form.short,
"string": str(form),
}

assert actual[representation] == expected, f"{representation} representation failed."
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
"""Testing formula 5.7 of NEN-EN 1993-5:2008."""

import pytest

from blueprints.codes.eurocode.nen_en_1993_5_2008.chapter_5_ultimate_limit_states.formula_5_7 import Form5Dot7ShearBucklingResistance
from blueprints.validations import LessOrEqualToZeroError


class TestForm5Dot7ShearBucklingResistance:
"""Validation for formula 5.7 from NEN-EN 1993-5:2008."""

def test_evaluation(self) -> None:
"""Test the evaluation of the result."""
# Example values
h = 500 # MM
t_f = 20 # MM
t_w = 10 # MM
f_bv = 300 # MPA
gamma_m_0 = 1.1

form = Form5Dot7ShearBucklingResistance(
h=h,
t_f=t_f,
t_w=t_w,
f_bv=f_bv,
gamma_m_0=gamma_m_0,
)

# Expected result, manually calculated
expected = 1309.09

assert form == pytest.approx(expected)

@pytest.mark.parametrize(
("h", "t_f", "t_w", "f_bv", "gamma_m_0"),
[
(0, 20, 10, 300, 1.1), # h is zero
(-500, 20, 10, 300, 1.1), # h is negative
(500, -20, 10, 300, 1.1), # t_f is negative
(500, 0, 10, 300, 1.1), # t_f is zero
(500, 20, -10, 300, 1.1), # t_w is negative
(500, 20, 0, 300, 1.1), # t_w is zero
(500, 20, 10, 300, 0), # gamma_m_0 is zero
(500, 20, 10, 300, -1), # gamma_m_0 is negative
],
)
def test_raise_error_when_negative_or_zero_values_are_given(self, h: float, t_f: float, t_w: float, f_bv: float, gamma_m_0: float) -> None:
"""Test a zero and negative value for parameters h, t_f, t_w, f_bv, and gamma_m_0."""
with pytest.raises(LessOrEqualToZeroError):
Form5Dot7ShearBucklingResistance(h=h, t_f=t_f, t_w=t_w, f_bv=f_bv, gamma_m_0=gamma_m_0)

def test_t_f_not_greater_than_h(self) -> None:
"""Test if the thickness of the flange is not greater than the height of the web."""
with pytest.raises(ValueError):
Form5Dot7ShearBucklingResistance(h=500, t_f=600, t_w=10, f_bv=300, gamma_m_0=1.1)

@pytest.mark.parametrize(
("representation", "expected"),
[
(
"complete",
r"V_{b,Rd} = \frac{\left(h - t_f \right) t_w f_{bv}}{\gamma_{M0}} = \frac{(500.00 - 20.00) \cdot 10 \cdot 300.000}{1.1} = 1309.091",
),
("short", r"V_{b,Rd} = 1309.091"),
(
"string",
r"V_{b,Rd} = \frac{\left(h - t_f \right) t_w f_{bv}}{\gamma_{M0}} = \frac{(500.00 - 20.00) \cdot 10 \cdot 300.000}{1.1} = 1309.091",
),
],
)
def test_latex_output(self, representation: str, expected: str) -> None:
"""Test the latex implementation."""
h = 500 # MM
t_f = 20 # MM
t_w = 10 # MM
f_bv = 300 # MPA
gamma_m_0 = 1.1

form = Form5Dot7ShearBucklingResistance(
h=h,
t_f=t_f,
t_w=t_w,
f_bv=f_bv,
gamma_m_0=gamma_m_0,
).latex()

actual = {
"complete": form.complete,
"short": form.short,
"string": str(form),
}

assert actual[representation] == expected, f"{representation} representation failed."

0 comments on commit 2fb3fe5

Please sign in to comment.