diff --git a/blueprints/codes/cur/cur_228/__init__.py b/blueprints/codes/cur/cur_228/__init__.py new file mode 100644 index 00000000..8ca265e2 --- /dev/null +++ b/blueprints/codes/cur/cur_228/__init__.py @@ -0,0 +1,3 @@ +"""CUR-228 package.""" + +CUR_228 = "CUR 228" diff --git a/blueprints/codes/cur/cur_228/formula_2_21.py b/blueprints/codes/cur/cur_228/formula_2_21.py new file mode 100644 index 00000000..6c5d7e60 --- /dev/null +++ b/blueprints/codes/cur/cur_228/formula_2_21.py @@ -0,0 +1,93 @@ +"""Contains formula 2.21 from CUR 228.""" + +from blueprints.codes.cur.cur_228 import CUR_228 +from blueprints.codes.formula import Formula +from blueprints.codes.latex_formula import LatexFormula +from blueprints.type_alias import KN_M3, KPA, M +from blueprints.validations import raise_if_negative + + +class Form2Dot21MenardStiffness(Formula): + """Representation of equation 2.21 CUR 228.""" + + source_document = CUR_228 + label = "2.21" + r_0: M = 0.3 + + def __init__(self, r: M, e_p: KPA, alpha: float) -> None: + """Calculates the Menard stiffness (k_h) for r >= 0.3 m. + + Parameters + ---------- + r: M + The radius of a foundation pile [m]: + r >= 0.3 m + e_p: KPA + Elastic modulus of Ménard [kPa]: + e_p ≈ beta * q_c + beta: float + Dependent on soil type [-]: + q_c: float + Cone resistance [kPa] + alpha: float + Factor dependent on soil type [-]: + """ + super().__init__() + self.r = float(r) + self.e_p = float(e_p) + self.alpha = float(alpha) + + @staticmethod + def _evaluate(r: M, e_p: KPA, alpha: float) -> KN_M3: + """Evaluates the formula, for more information see the __init__ method.""" + r_0 = Form2Dot21MenardStiffness.r_0 + raise_if_negative(r=r, e_p=e_p, alpha=alpha) + + if r >= r_0: + return 3 * e_p / (1.3 * r_0 * (2.65 * r / r_0) ** alpha + alpha * r) + msg = "Radius is smaller than 0.3m, use: Eq2Dot21MenardStiffness" + raise ValueError(msg) + + @property + def result(self) -> KN_M3: + """Return the Menard stiffness k_h when r >= 0.3 m [kN/m3]. + + Returns + ------- + KN_M3 + The Menard stiffness k_h [kN/m3] + """ + if self.r >= self.r_0: + return 3 * self.e_p / (1.3 * self.r_0 * (2.65 * self.r / self.r_0) ** self.alpha + self.alpha * self.r) + msg = "Radius is smaller than 0.3m, use: Eq2Dot21MenardStiffness" + raise ValueError(msg) + + def latex(self, n_decimals: int = 2) -> LatexFormula: + """Latex representation of the full equation including result. + + Parameters + ---------- + n_decimals: int + Number of decimals to round the result to + + Returns + ------- + LatexFormula + Latex representation of the equation + + """ + n = n_decimals + + return LatexFormula( + return_symbol="k_{h}", + equation=r"\frac{1}{3 \cdot E_{p}} \cdot " + r"\left[1.3 \cdot R_{0} " + r"\left( 2.65 \frac{R}{R_0}\right)^\alpha" + r" + \alpha \cdot R \right]", + numeric_equation=rf"\frac{{1}}{{3 \cdot {self.e_p :.{n}}}} \cdot" + rf"\left[1.3 \cdot {self.r_0 :.{n}} " + rf"\left( 2.65 \cdot \frac{{{self.r :.{n}}}}{{{self.r_0 :.{n}}}}\right)^{{{self.alpha :.{n}f}}}" + rf"+ {self.alpha :.{n}} \cdot {self.r :.{n}}\right]", + result=f"{self.result :.{n_decimals}f}", + unit="kN/m^3", + ) diff --git a/blueprints/codes/cur/cur_228/formula_2_22.py b/blueprints/codes/cur/cur_228/formula_2_22.py new file mode 100644 index 00000000..19319267 --- /dev/null +++ b/blueprints/codes/cur/cur_228/formula_2_22.py @@ -0,0 +1,68 @@ +"""Contains formula 2.22 from CUR 228.""" + +from blueprints.codes.cur.cur_228 import CUR_228 +from blueprints.codes.formula import Formula +from blueprints.codes.latex_formula import LatexFormula +from blueprints.type_alias import KN_M3, KPA, M + + +class Form2Dot22MenardStiffness(Formula): + """Representation of equation 2.22 CUR 228.""" + + source_document = CUR_228 + label = "2.22" + + def __init__(self, r: M, e_p: KPA, alpha: float) -> None: + """Calculates the Menard stiffness (k_h) for r < 0.3 m. + + Parameters + ---------- + r: M + The radius of a foundation pile [m]: + r >= 0.3 m + e_p: KPA + Elastic modulus of Ménard [kPa]: + e_p ≈ beta * q_c + beta: float + Dependent on soil type [-]: + q_c: KPA + Cone resistance [kPa] + alpha: float + Factor dependent on soil type [-]: + """ + super().__init__() + self.r = r + self.e_p = e_p + self.alpha = alpha + + @staticmethod + def _evaluate(r: M, e_p: KPA, alpha: float) -> KN_M3: + """Return the Menard stiffness k_h when r >= 0.3 m [kN/m3].""" + if r < 0.3: + return e_p / 2 / r / ((4 * 2.65**alpha + 3 * alpha) / 18) + msg = "Radius is equal to- or larger than 0.3m, use: Eq2Dot21MenardStiffness" + raise ValueError(msg) + + def latex(self, n_decimals: int = 2) -> LatexFormula: + """Latex representation of the full equation including result. + + Parameters + ---------- + n_decimals: int + Number of decimals to round the result to + + Returns + ------- + LatexFormula + Latex representation of the equation + + """ + n = n_decimals + return LatexFormula( + return_symbol=r"k_{h}", + result=f"{self:.{n}f} kN/m3", + equation=r"\frac{2 \cdot R}{E_{p}} \cdot \frac{4 \cdot 2.65^{\alpha} + 3 \alpha}{18}", + numeric_equation=rf"\frac{{2 \cdot {self.r :.{n}f}}}{{{self.e_p :.{n}f}}} \cdot \frac{{4 \cdot 2.65^{{{self.alpha :.{n}f}}} + 3 \cdot " + rf"{self.alpha :.{n}f}}}{{18}}", + unit="kN/m^3", + ) diff --git a/blueprints/type_alias.py b/blueprints/type_alias.py index cc317f4d..dbf9ec5f 100644 --- a/blueprints/type_alias.py +++ b/blueprints/type_alias.py @@ -59,6 +59,7 @@ # N_M2 = float KN_M2 = float +KN_M3 = float # # diff --git a/docs/source/codes/cur/cur_228/formulas.md b/docs/source/codes/cur/cur_228/formulas.md new file mode 100644 index 00000000..9ddd3071 --- /dev/null +++ b/docs/source/codes/cur/cur_228/formulas.md @@ -0,0 +1,12 @@ +**CUR 228 - 2010 +Design guideline for soil laterally loaded piles** + +The table presents a list of formulas from the CUR 228 guideline, tracking their implementation status +( :x: or :heavy_check_mark: ) and any pertinent remarks. The 'Object Name' column references the corresponding Python entities inside of Blueprints. + +Total of 2 formulas present. + +| Formula number | Done | Remarks | Object name | +|:---------------|:------------------:|:--------|:--------------------------| +| 2.21 | :heavy_check_mark: | | Form2Dot21MenardStiffness | +| 2.22 | :heavy_check_mark: | | Form2Dot22MenardStiffness | diff --git a/tests/codes/cur/__init__.py b/tests/codes/cur/__init__.py new file mode 100644 index 00000000..6871e3fb --- /dev/null +++ b/tests/codes/cur/__init__.py @@ -0,0 +1 @@ +"""Tests for the CUR guidelines.""" diff --git a/tests/codes/cur/cur_228/__init__.py b/tests/codes/cur/cur_228/__init__.py new file mode 100644 index 00000000..10a2474c --- /dev/null +++ b/tests/codes/cur/cur_228/__init__.py @@ -0,0 +1 @@ +"""Tests for the CUR 228.""" diff --git a/tests/codes/cur/cur_228/test_formula_2_21.py b/tests/codes/cur/cur_228/test_formula_2_21.py new file mode 100644 index 00000000..96fd8024 --- /dev/null +++ b/tests/codes/cur/cur_228/test_formula_2_21.py @@ -0,0 +1,42 @@ +"""Test for formula 2.21 from CUR 228.""" + +import pytest + +from blueprints.codes.cur.cur_228.formula_2_21 import Form2Dot21MenardStiffness + + +class TestForm2Dot21MenardStiffness: + """Validation for formula 2.21 from CUR 228.""" + + def test_evaluation(self) -> None: + """Test the evaluation of the result.""" + # Example values + r = 0.5 # m + e_p = 2.47 # kN/m² + alpha = 1 / 3 # - + form_2_21 = Form2Dot21MenardStiffness(r=r, e_p=e_p, alpha=alpha) + + # Expected result, manually calculated + manually_calculated_result = 9.187357198 + + assert form_2_21 == pytest.approx(expected=manually_calculated_result, rel=1e-4) + + def test_raise_error_when_r_is_lower_then_0_3(self) -> None: + """Tests if an ValueError is raised when r < 0.3.""" + # Example values + r = 0.2 # m + e_p = 2.47 # kN/m² + alpha = 1 / 3 # - + + with pytest.raises(ValueError): + Form2Dot21MenardStiffness(r=r, e_p=e_p, alpha=alpha) + + def test_latex_method(self) -> None: + """Test the latex method.""" + r = 0.5 # m + e_p = 2.47 # kN/m² + alpha = 1 / 3 # - + form_2_21 = Form2Dot21MenardStiffness(r=r, e_p=e_p, alpha=alpha) + + # Test the full LaTeX representation + assert isinstance(form_2_21.latex(2).complete, str) diff --git a/tests/codes/cur/cur_228/test_formula_2_22.py b/tests/codes/cur/cur_228/test_formula_2_22.py new file mode 100644 index 00000000..ddd79d36 --- /dev/null +++ b/tests/codes/cur/cur_228/test_formula_2_22.py @@ -0,0 +1,42 @@ +"""Test for formula 2.22 from CUR 228.""" + +import pytest + +from blueprints.codes.cur.cur_228.formula_2_22 import Form2Dot22MenardStiffness + + +class TestForm2Dot22MenardStiffness: + """Validation for formula 2.22 from CUR 228.""" + + def test_evaluation(self) -> None: + """Test the evaluation of the result.""" + # Example values + r = 0.2 # m + e_p = 2.47 # kN/m² + alpha = 1 / 3 # - + form_2_22 = Form2Dot22MenardStiffness(r=r, e_p=e_p, alpha=alpha) + + # Expected result, manually calculated + manually_calculated_result = 17.00760939 + + assert form_2_22 == pytest.approx(expected=manually_calculated_result, rel=1e-4) + + def test_raise_error_when_r_is_higher_then_0_3(self) -> None: + """Tests if an ValueError is raised when r > 0.3.""" + # Example values + r = 0.5 # m + e_p = 2.47 # kN/m² + alpha = 1 / 3 # - + + with pytest.raises(ValueError): + Form2Dot22MenardStiffness(r=r, e_p=e_p, alpha=alpha) + + def test_latex_method(self) -> None: + """Test the latex method.""" + r = 0.2 # m + e_p = 2.47 # kN/m² + alpha = 1 / 3 # - + form_2_22 = Form2Dot22MenardStiffness(r=r, e_p=e_p, alpha=alpha) + + # Test the full LaTeX representation + assert isinstance(form_2_22.latex(2).complete, str)