Skip to content

Commit

Permalink
Merge pull request #122 from Blueprints-org/121-feature-request-add-l…
Browse files Browse the repository at this point in the history
…atex-representation-to-formulas-from-chapter-8-of-nen-en-1992-1-1+c2

(#121) Add latex representation to formulas from chapter 8 of NEN-EN 1992-1-1+C2:2011
  • Loading branch information
egarciamendez authored Mar 28, 2024
2 parents 6537a4b + 73e2671 commit c401cf4
Show file tree
Hide file tree
Showing 18 changed files with 417 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from blueprints.codes.eurocode.nen_en_1992_1_1_c2_2011 import NEN_EN_1992_1_1_C2_2011
from blueprints.codes.formula import Formula
from blueprints.codes.latex_formula import LatexFormula, latex_max_curly_brackets, latex_min_curly_brackets
from blueprints.type_alias import DIMENSIONLESS, MM
from blueprints.validations import raise_if_negative

Expand Down Expand Up @@ -124,6 +125,20 @@ def _evaluate(
)
return max(alpha_1 * alpha_2 * alpha_3 * alpha_5 * alpha_6 * l_b_rqd, l_0_min)

def latex(self) -> LatexFormula:
"""Returns a LatexFormula representation of the formula."""
return LatexFormula(
return_symbol=r"l_{0}",
result=f"{self:.2f}",
equation=latex_max_curly_brackets(r"\alpha_1 \cdot \alpha_2 \cdot \alpha_3 \cdot \alpha_5 \cdot \alpha_6 \cdot l_{b,rqd}", r"l_{0,min}"),
numeric_equation=latex_max_curly_brackets(
rf"{self.alpha_1:.2f} \cdot {self.alpha_2:.2f} \cdot {self.alpha_3:.2f} \cdot "
rf"{self.alpha_5:.2f} \cdot {self.alpha_6:.2f} \cdot {self.l_b_rqd:.2f}",
f"{self.l_0_min:.2f}",
),
comparison_operator_label="=",
)


class SubForm8Dot10Alpha6(Formula):
"""Class representing the formula for the calculation of the coefficient :math:`α_{6}`."""
Expand Down Expand Up @@ -151,3 +166,15 @@ def _evaluate(rho_1: DIMENSIONLESS) -> DIMENSIONLESS:
raise_if_negative(rho_l=rho_1)
value_max_1_5 = min((rho_1 / 25) ** 0.5, 1.5)
return max(value_max_1_5, 1)

def latex(self) -> LatexFormula:
"""Returns a LatexFormula representation of the formula."""
argument_1_formula = r"\left(\frac{\rho_1}{25}\right)^{0.5}"
numerical_argument_1 = rf"\left(\frac{{{self.rho_1:.2f}}}{{25}}\right)^{{0.5}}"
return LatexFormula(
return_symbol=r"\alpha_6",
result=f"{self:.2f}",
equation=f'{latex_max_curly_brackets(latex_min_curly_brackets(argument_1_formula, "1.5"), "1")}',
numeric_equation=f'{latex_max_curly_brackets(latex_min_curly_brackets(numerical_argument_1, "1.5"), "1")}',
comparison_operator_label="=",
)
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from blueprints.codes.eurocode.nen_en_1992_1_1_c2_2011 import NEN_EN_1992_1_1_C2_2011
from blueprints.codes.formula import Formula
from blueprints.codes.latex_formula import LatexFormula, latex_max_curly_brackets
from blueprints.type_alias import DIMENSIONLESS, MM
from blueprints.validations import raise_if_negative

Expand Down Expand Up @@ -59,3 +60,21 @@ def _evaluate(
diameter=diameter,
)
return max(0.3 * alpha_6 * l_b_rqd, 15 * diameter, 200)

def latex(self) -> LatexFormula:
"""Returns a representation of the formula in LaTeX format."""
arg_1_equation = r"0.3 \cdot \alpha_6 \cdot l_{b,rqd}"
arg_2_equation = r"15 \cdot Ø"
arg_3_equation = r"200 \ \text{mm}"

arg_1_numerical_equation = rf"0.3 \cdot {self.alpha_6:.2f} \cdot {self.l_b_rqd:.2f}"
arg_2_numerical_equation = rf"15 \cdot {self.diameter}"
arg_3_numerical_equation = r"200"

return LatexFormula(
return_symbol=r"l_{0,min}",
result=f"{self:.2f}",
equation=f"{latex_max_curly_brackets(arg_1_equation, arg_2_equation, arg_3_equation)}",
numeric_equation=f"{latex_max_curly_brackets(arg_1_numerical_equation, arg_2_numerical_equation, arg_3_numerical_equation)}",
comparison_operator_label="=",
)
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from blueprints.codes.eurocode.nen_en_1992_1_1_c2_2011 import NEN_EN_1992_1_1_C2_2011
from blueprints.codes.formula import Formula
from blueprints.codes.latex_formula import LatexFormula
from blueprints.type_alias import DIMENSIONLESS, MM, MPA
from blueprints.validations import raise_if_negative

Expand All @@ -18,26 +19,27 @@ def __init__(
eta_2: DIMENSIONLESS,
f_ctd: MPA,
) -> None:
"""[fbd] The design value of the ultimate bond stress for ribbed bars [-].
r"""[:math:`f_{bd}`] The design value of the ultimate bond stress for ribbed bars [-].
NEN-EN 1992-1-1+C2:2011 art.8.4.2(2) - Formula (8.2)
Parameters
----------
eta_1 : DIMENSIONLESS
[η1] coefficient related to the quality of the bond condition and the position of the bar during concreting (see Figure 8.2) [-].
= 1 when ‘good’ conditions are obtained;
= 0.7 other cases and for bars in structural elements built with slip-forms, unless it can be shown that ‘good’ bond conditions exist;
[:math:`η_1`] coefficient related to the quality of the bond condition and the position of the bar during concreting (see Figure 8.2) [-].
= :math:`1` when ‘good’ conditions are obtained;
= :math:`1` other cases and for bars in structural elements built with slip-forms, unless it can be shown that ‘good’ bond conditions
exist;
Use your own implementation of this formula or use the SubForm8Dot2CoefficientQualityOfBond class.
eta_2 : DIMENSIONLESS
[η2] A factor related to the bar diameter [-].
= 1 for bars with a diameter ≤ 32 mm;
= (132 - Ø) / 100 for bars with a diameter > 32 mm.
[:math:`η_2`] A factor related to the bar diameter [-].
= :math:`1` for bars with a diameter ≤ :math:`32 \text{mm}`;
= :math:`(132 - Ø) / 100` for bars with a diameter > :math:`32 \text{mm}`.
Use your own implementation of this value or use the SubForm8Dot2CoefficientBarDiameter class.
f_ctd : MPA
[fctd] Design tensile strength of concrete according to art.3.1.6(2) [MPa].
Due to the increasing brittleness of higher strength concrete, fctk,0,05 should be limited here to the value for C60/75, unless it can be
verified that the average bond strength increases above this limit.
[:math:`f_{ctd}`] Design tensile strength of concrete according to art.3.1.6(2) [MPa].
Due to the increasing brittleness of higher strength concrete, :math:`f_{ctk,0,05}` should be limited here to the value for C60/75, unless
it can be verified that the average bond strength increases above this limit.
"""
super().__init__()
self.eta_1 = eta_1
Expand All @@ -54,6 +56,16 @@ def _evaluate(
raise_if_negative(eta_1=eta_1, eta_2=eta_2, f_ctd=f_ctd)
return 2.25 * eta_1 * eta_2 * f_ctd

def latex(self) -> LatexFormula:
"""Returns a representation of the formula in LaTeX format."""
return LatexFormula(
return_symbol=r"f_{bd}",
result=f"{self:.2f}",
equation=r"2.25 \cdot \eta_1 \cdot \eta_2 \cdot f_{ctd}",
numeric_equation=rf"2.25 \cdot {self.eta_1:.2f} \cdot {self.eta_2:.2f} \cdot {self.f_ctd:.2f}",
comparison_operator_label="=",
)


class SubForm8Dot2CoefficientQualityOfBond(Formula):
"""Class representing sub-formula for formula 8.2, which calculates the coefficient 'η1' which is dependent on the quality of the bond."""
Expand Down Expand Up @@ -96,14 +108,14 @@ class SubForm8Dot2CoefficientBarDiameter(Formula):
label = "8.2"

def __init__(self, diameter: MM) -> None:
"""[η2] Coefficient that depends on the bar diameter [-].
"""[:math:`η_2`] Coefficient that depends on the bar diameter [-].
NEN-EN 1992-1-1+C2:2011 art.8.4.2(2) - η2
NEN-EN 1992-1-1+C2:2011 art.8.4.2(2) - :math:`η_2`
Parameters
----------
diameter : MM
[Ø] Diameter of the bar [mm].
[:math:`Ø`] Diameter of the bar [mm].
"""
super().__init__()
self.diameter = diameter
Expand All @@ -115,3 +127,15 @@ def _evaluate(diameter: MM) -> DIMENSIONLESS:
if diameter <= 32:
return 1
return (132 - diameter) / 100

def latex(self) -> LatexFormula:
"""Returns a LatexFormula object for this formula."""
numerical_equation = "1.00" if self.diameter <= 32 else f"(132 - {self.diameter}) / 100"

return LatexFormula(
return_symbol=r"\eta_2",
result=f"{self:.2f}",
equation=r"\begin{matrix} 1.0 & \text{for }Ø ≤ 32 \\ (132 - Ø) / 100 & \text{for }Ø > 32 \end{matrix}",
numeric_equation=numerical_equation,
comparison_operator_label="=",
)
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@

from blueprints.codes.eurocode.nen_en_1992_1_1_c2_2011 import NEN_EN_1992_1_1_C2_2011
from blueprints.codes.formula import Formula
from blueprints.codes.latex_formula import LatexFormula, latex_fraction
from blueprints.type_alias import MM, MPA
from blueprints.validations import raise_if_less_or_equal_to_zero, raise_if_negative


class Form8Dot3RequiredAnchorageLength(Formula):
"""Class representing formula 8.3 for the calculation of the basic required anchorage length, assuming constant bond stress fbd."""
"""Class representing formula 8.3 for the calculation of the basic required anchorage length, assuming constant bond stress :math:`f_{bd}`."""

label = "8.3"
source_document = NEN_EN_1992_1_1_C2_2011
Expand All @@ -18,18 +19,19 @@ def __init__(
sigma_sd: MPA,
f_bd: MPA,
) -> None:
"""[lb,rqd] Basic required anchorage length, for anchoring the force As*σsd in a straight bar assuming constant bond stress fbd. [mm].
r"""[:math:`l_{b,rqd}`] Basic required anchorage length, for anchoring the force :math:`A_{s} \\cdot σ_{sd}` in a straight bar assuming
constant bond stress :math:`f_{bd}`. [mm].
NEN-EN 1992-1-1+C2:2011 art.8.4.3(2) - Formula (8.3)
Parameters
----------
diameter: MM
[Ø] Diameter of the bar [mm].
[:math:`Ø`] Diameter of the bar [mm].
sigma_sd: MPA
[σsd] design stress of the bar at the position from where the anchorage is measured from [MPa].
[:math:`σ_{sd}`] design stress of the bar at the position from where the anchorage is measured from [MPa].
f_bd: MPA
[fbd] Design value ultimate bond stress [MPa].
[:math:`f_{bd}`] Design value ultimate bond stress [MPa].
Use your own implementation for this value or use the Form8Dot2UltimateBondStress class.
"""
super().__init__()
Expand All @@ -47,3 +49,16 @@ def _evaluate(
raise_if_negative(diameter=diameter, sigma_sd=sigma_sd)
raise_if_less_or_equal_to_zero(f_bd=f_bd)
return (diameter / 4) * (sigma_sd / f_bd)

def latex(self) -> LatexFormula:
"""Returns a LatexFormula object for this formula."""
latex_diameter = r"Ø"
latex_sigma_sd = r"\sigma_{sd}"
latex_f_bd = r"f_{bd}"
return LatexFormula(
return_symbol=r"l_{b,rqd}",
result=f"{self:.2f}",
equation=rf"{latex_fraction(latex_diameter, 4)} \cdot {latex_fraction(latex_sigma_sd, latex_f_bd)}",
numeric_equation=rf"{latex_fraction(self.diameter, 4)} \cdot {latex_fraction(self.sigma_sd, self.f_bd)}",
comparison_operator_label="=",
)
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@

from blueprints.codes.eurocode.nen_en_1992_1_1_c2_2011 import NEN_EN_1992_1_1_C2_2011
from blueprints.codes.formula import Formula
from blueprints.codes.latex_formula import LatexFormula, latex_max_curly_brackets
from blueprints.type_alias import DIMENSIONLESS, MM
from blueprints.validations import raise_if_negative


class Form8Dot4DesignAnchorageLength(Formula):
"""Class representing formula 8.4 for the calculation of the design anchorage length :math:`l_{bd}` [:math:`mm`]."""
"""Class representing formula 8.4 for the calculation of the design anchorage length :math:`l_{bd}` [mm]."""

label = "8.4"
source_document = NEN_EN_1992_1_1_C2_2011
Expand Down Expand Up @@ -68,7 +69,7 @@ def __init__(
[:math:`α_{4}`] Coefficient for the influence of one or more welded transverse bars :math:`(Ø_{t} > 0,6 Ø)` along the design anchorage
length :math:`l_{bd}` (see 8.6) [-].
= 0.7 for all types, position and size as specified in figure 8.6 (e) in both tension and compression.
:math:`= 0.7` for all types, position and size as specified in figure 8.6 (e) in both tension and compression.
alpha_5 : DIMENSIONLESS
[:math:`α_{5}`] Coefficient for the effect of the pressure transverse to the plane of splitting
Expand Down Expand Up @@ -125,3 +126,16 @@ def _evaluate(
l_b_min=l_b_min,
)
return max(alpha_1 * alpha_2 * alpha_3 * alpha_4 * alpha_5 * l_b_rqd, l_b_min)

def latex(self) -> LatexFormula:
"""Returns a LatexFormula representation of the formula."""
return LatexFormula(
return_symbol=r"l_{bd}",
result=f"{self:.2f}",
equation=latex_max_curly_brackets(r"\alpha_1 \cdot \alpha_2 \cdot \alpha_3 \cdot \alpha_4 \cdot \alpha_5 \cdot l_{b,rqd}", r"l_{b,min}"),
numeric_equation=latex_max_curly_brackets(
rf"{self.alpha_1} \cdot {self.alpha_2} \cdot {self.alpha_3} \cdot {self.alpha_4} \cdot {self.alpha_5} \cdot {self.l_b_rqd:.2f}",
self.l_b_min,
),
comparison_operator_label="=",
)
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from blueprints.codes.eurocode.nen_en_1992_1_1_c2_2011 import NEN_EN_1992_1_1_C2_2011
from blueprints.codes.formula import Formula
from blueprints.codes.latex_formula import LatexFormula, latex_max_curly_brackets
from blueprints.type_alias import MM
from blueprints.validations import raise_if_negative

Expand Down Expand Up @@ -41,3 +42,17 @@ def _evaluate(l_b_rqd: MM, diameter: MM) -> MM:
"""Evaluates the formula, for more information see the __init__ method."""
raise_if_negative(diameter=diameter, l_b_rqd=l_b_rqd)
return max(0.3 * l_b_rqd, 10 * diameter, 100)

def latex(self) -> LatexFormula:
"""Returns a LatexFormula object for this formula."""
return LatexFormula(
return_symbol=r"l_{b,min}",
result=f"{self:.2f}",
equation=latex_max_curly_brackets(r"0.3 \cdot l_{b,rqd}", r"10 \cdot Ø", r"100 \ \text{mm}"),
numeric_equation=latex_max_curly_brackets(
rf"0.3 \cdot {self.l_b_rqd:.2f}",
rf"10 \cdot {self.diameter}",
r"100",
),
comparison_operator_label="=",
)
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from blueprints.codes.eurocode.nen_en_1992_1_1_c2_2011 import NEN_EN_1992_1_1_C2_2011
from blueprints.codes.formula import Formula
from blueprints.codes.latex_formula import LatexFormula, latex_max_curly_brackets
from blueprints.type_alias import MM
from blueprints.validations import raise_if_negative

Expand Down Expand Up @@ -41,3 +42,17 @@ def _evaluate(l_b_rqd: MM, diameter: MM) -> MM:
"""Evaluates the formula, for more information see the __init__ method."""
raise_if_negative(diameter=diameter, l_b_rqd=l_b_rqd)
return max(0.6 * l_b_rqd, 10 * diameter, 100)

def latex(self) -> LatexFormula:
"""Returns a LatexFormula object for this formula."""
return LatexFormula(
return_symbol=r"l_{b,min}",
result=f"{self:.2f}",
equation=latex_max_curly_brackets(r"0.6 \cdot l_{b,rqd}", r"10 \cdot Ø", r"100 \ \text{mm}"),
numeric_equation=latex_max_curly_brackets(
rf"0.6 \cdot {self.l_b_rqd:.2f}",
rf"10 \cdot {self.diameter}",
r"100",
),
comparison_operator_label="=",
)
7 changes: 6 additions & 1 deletion blueprints/codes/latex_formula.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,12 @@ def complete(self) -> str:
Return symbol = equation = numeric_equation = result
"""
all_sub_equations = [self.return_symbol, self.equation, self.numeric_equation, self.result]
all_sub_equations = [
self.return_symbol,
self.equation,
self.numeric_equation,
self.result,
]
return f" {self.comparison_operator_label} ".join([eq for eq in all_sub_equations if eq != ""])

@property
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -309,3 +309,41 @@ def test_integration_with_form_8_11(self) -> None:
manually_calculated_result = 240 # mm

assert form_8_10 == pytest.approx(expected=manually_calculated_result, rel=1e-4)

@pytest.mark.parametrize(
("representation", "expected_result"),
[
(
"complete",
r"l_{0} = \max \left\{\alpha_1 \cdot \alpha_2 \cdot \alpha_3 \cdot \alpha_5 \cdot \alpha_6 \cdot l_{b,rqd};"
r" l_{0,min}\right\} = \max \left\{1.00 \cdot 1.00 \cdot 1.00 \cdot 1.00 \cdot 1.00 \cdot 200.00; 400.00\right\} = 400.00",
),
("short", "l_{0} = 400.00"),
],
)
def test_latex(self, representation: str, expected_result: str) -> None:
"""Test latex representation of the formula."""
alpha_1 = 1 # [-]
alpha_2 = 1 # [-]
alpha_3 = 1 # [-]
alpha_5 = 1 # [-]
alpha_6 = 1 # [-]
l_b_rqd = 200 # mm
l_0_min = 400 # mm

latex = Form8Dot10DesignLapLength(
alpha_1=alpha_1,
alpha_2=alpha_2,
alpha_3=alpha_3,
alpha_5=alpha_5,
alpha_6=alpha_6,
l_b_rqd=l_b_rqd,
l_0_min=l_0_min,
).latex()

actual = {
"complete": latex.complete,
"short": latex.short,
}

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

0 comments on commit c401cf4

Please sign in to comment.