diff --git a/blueprints/codes/eurocode/nen_en_1992_1_1_c2_2011/chapter_7_serviceability_limit_state/formula_7_16_ab.py b/blueprints/codes/eurocode/nen_en_1992_1_1_c2_2011/chapter_7_serviceability_limit_state/formula_7_16_ab.py new file mode 100644 index 000000000..6bf041be2 --- /dev/null +++ b/blueprints/codes/eurocode/nen_en_1992_1_1_c2_2011/chapter_7_serviceability_limit_state/formula_7_16_ab.py @@ -0,0 +1,148 @@ +"""Formula 7.16a/b from NEN-EN 1992-1-1+C2:2011: Chapter 7 - Serviceability limit state.""" + +import numpy as np + +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_replace_symbols +from blueprints.type_alias import DIMENSIONLESS, MPA +from blueprints.validations import raise_if_less_or_equal_to_zero, raise_if_negative + + +class Form7Dot16abSpanDepthRatio(Formula): + r"""Class representing formula 7.16a/b for the calculation of the limit span/depth ratio.""" + + label = "7.16a/b" + source_document = NEN_EN_1992_1_1_C2_2011 + + def __init__( + self, + capital_k: DIMENSIONLESS, + f_ck: MPA, + rho: DIMENSIONLESS, + rho_0: DIMENSIONLESS, + rho_prime: DIMENSIONLESS, + ) -> None: + r"""[$\frac{l}{d}$] Limit span/depth ratio [-]. + + NEN-EN 1992-1-1+C2:2011 art.7.4.2(2) - Formula (7.16a and 7.16b) + + Parameters + ---------- + capital_k : DIMENSIONLESS + [$K$] Factor to take into account the different structural systems [-]. + f_ck : MPA + [$f_{ck}$] Characteristic compressive strength of concrete [$MPa$]. + rho : DIMENSIONLESS + [$\rho$] Required tension reinforcement ratio at mid-span to resist the moment + due to the design loads (at support for cantilevers) [-]. + rho_0 : DIMENSIONLESS + [$\rho_0$] Reference reinforcement ratio [$\sqrt{f_{ck}} \cdot 10^{-3}$] [-]. + rho_prime : DIMENSIONLESS + [$\rho'$] Required compression reinforcement ratio at mid-span to resist the moment + due to design loads (at support for cantilevers) [-]. + """ + super().__init__() + self.capital_k = capital_k + self.f_ck = f_ck + self.rho = rho + self.rho_0 = rho_0 + self.rho_prime = rho_prime + + @staticmethod + def _evaluate( + capital_k: DIMENSIONLESS, + f_ck: MPA, + rho: DIMENSIONLESS, + rho_0: DIMENSIONLESS, + rho_prime: DIMENSIONLESS, + ) -> DIMENSIONLESS: + """Evaluates the formula, for more information see the __init__ method.""" + raise_if_negative(capital_k=capital_k, f_ck=f_ck, rho=rho, rho_0=rho_0, rho_prime=rho_prime) + raise_if_less_or_equal_to_zero(rho=rho) + + if rho <= rho_0: + l_over_d = capital_k * (11 + 1.5 * np.sqrt(f_ck) * rho_0 / rho + 3.2 * np.sqrt(f_ck) * (rho_0 / rho - 1) ** 1.5) + else: + l_over_d = capital_k * (11 + 1.5 * np.sqrt(f_ck) * rho_0 / (rho - rho_prime) + 1 / 12 * np.sqrt(f_ck) * np.sqrt(rho_prime / rho_0)) + + return l_over_d + + def latex(self) -> LatexFormula: + """Returns LatexFormula object for formula 7.16a/b.""" + _equation: str = ( + r"\begin{cases} K \cdot \left[11 + 1.5 \cdot \sqrt{f_{ck}} \cdot \frac{\rho_0}{\rho} + " + r"3.2 \cdot \sqrt{f_{ck}} \cdot \left(\frac{\rho_0}{\rho} - 1\right)^{3/2}\right] & \text{if } \rho \leq \rho_0 \\ " + r"K \cdot \left[11 + 1.5 \cdot \sqrt{f_{ck}} \cdot \frac{\rho_0}{\rho - \rho'} + " + r"\frac{1}{12} \cdot \sqrt{f_{ck}} \cdot \sqrt{\frac{\rho'}{\rho_0}}\right] & \text{if } \rho > \rho_0 \end{cases}" + ) + _numeric_equation: str = latex_replace_symbols( + _equation, + { + r"K": f"{self.capital_k:.3f}", + r"f_{ck}": f"{self.f_ck:.3f}", + r"\rho_0": f"{self.rho_0:.4f}", + r"\rho'": f"{self.rho_prime:.4f}", + r"\rho": f"{self.rho:.4f}", + }, + False, + ) + return LatexFormula( + return_symbol=r"\frac{l}{d}", + result=f"{self:.3f}", + equation=_equation, + numeric_equation=_numeric_equation, + comparison_operator_label="=", + unit="-", + ) + + +class Form7Dot16ReferenceReinforcementRatio(Formula): + r"""Class representing formula 7.16 for the calculation of [$\rho_0$].""" + + label = "7.16_rho_0" + source_document = NEN_EN_1992_1_1_C2_2011 + + def __init__( + self, + f_ck: MPA, + ) -> None: + r"""[$\rho_0$] Reference reinforcement ratio [-]. + + NEN-EN 1992-1-1+C2:2011 art.7.4.2(2) - Formula (7.16) + + Parameters + ---------- + f_ck : MPA + [$f_{ck}$] Characteristic compressive strength of concrete [$MPa$]. + """ + super().__init__() + self.f_ck = f_ck + + @staticmethod + def _evaluate( + f_ck: MPA, + ) -> DIMENSIONLESS: + """Evaluates the formula, for more information see the __init__ method.""" + raise_if_negative(f_ck=f_ck) + + return np.sqrt(f_ck) * 10**-3 + + def latex(self) -> LatexFormula: + """Returns LatexFormula object for formula 7.16_rho_0.""" + _equation: str = r"\sqrt{f_{ck}} \cdot 10^{-3}" + _numeric_equation: str = latex_replace_symbols( + _equation, + { + r"f_{ck}": f"{self.f_ck:.3f}", + }, + False, + ) + return LatexFormula( + return_symbol=r"\rho_0", + result=f"{self:.6f}", + equation=_equation, + numeric_equation=_numeric_equation, + comparison_operator_label="=", + unit="-", + ) diff --git a/blueprints/codes/eurocode/nen_en_1992_1_1_c2_2011/chapter_7_serviceability_limit_state/formula_7_17.py b/blueprints/codes/eurocode/nen_en_1992_1_1_c2_2011/chapter_7_serviceability_limit_state/formula_7_17.py new file mode 100644 index 000000000..243ba2cf4 --- /dev/null +++ b/blueprints/codes/eurocode/nen_en_1992_1_1_c2_2011/chapter_7_serviceability_limit_state/formula_7_17.py @@ -0,0 +1,70 @@ +"""Formula 7.17 from NEN-EN 1992-1-1+C2:2011: Chapter 7 - Serviceability limit state (SLS).""" + +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_replace_symbols +from blueprints.type_alias import DIMENSIONLESS, MM2, N +from blueprints.validations import raise_if_less_or_equal_to_zero + + +class Form7Dot1MultiplicationFactorLimitSlenderness(Formula): + r"""Class representing formula 7.17 for the calculation of the stress multiplication factor for the limit span to depth ratio.""" + + label = "7.17" + source_document = NEN_EN_1992_1_1_C2_2011 + + def __init__( + self, + f_yk: N, + a_s_req: MM2, + a_s_prov: MM2, + ) -> None: + r"""[$\frac{310}{\sigma_s}$] Calculation of the multiplication factor [$-$]. + + NEN-EN 1992-1-1+C2:2011 art.7.4.2(2) - Formula (7.17) + + Parameters + ---------- + f_yk : MPa + [$f_{yk}$] Characteristic yield strength of the steel [$MPa$]. + a_s_req : MM2 + [$A_{s,req}$] Area of steel required at this section for ultimate limit state [$mm^2$]. + a_s_prov : MM2 + [$A_{s,prov}$] Area of steel provided at this section [$mm^2$]. + """ + super().__init__() + self.f_yk = f_yk + self.a_s_req = a_s_req + self.a_s_prov = a_s_prov + + @staticmethod + def _evaluate( + f_yk: N, + a_s_req: MM2, + a_s_prov: MM2, + ) -> DIMENSIONLESS: + """Evaluates the formula, for more information see the __init__ method.""" + raise_if_less_or_equal_to_zero(f_yk=f_yk, a_s_req=a_s_req, a_s_prov=a_s_prov) + + return 500 / (f_yk * a_s_req / a_s_prov) + + def latex(self) -> LatexFormula: + """Returns LatexFormula object for formula 7.17.""" + _equation: str = r"\frac{500}{f_{yk} \cdot \frac{A_{s,req}}{A_{s,prov}}}" + _numeric_equation: str = latex_replace_symbols( + _equation, + { + r"f_{yk}": f"{self.f_yk:.3f}", + r"A_{s,req}": f"{self.a_s_req:.3f}", + r"A_{s,prov}": f"{self.a_s_prov:.3f}", + }, + False, + ) + return LatexFormula( + return_symbol=r"\frac{310}{\sigma_s}", + result=f"{self:.3f}", + equation=_equation, + numeric_equation=_numeric_equation, + comparison_operator_label="=", + unit="-", + ) diff --git a/blueprints/codes/eurocode/nen_en_1992_1_1_c2_2011/chapter_7_serviceability_limit_state/formula_7_18.py b/blueprints/codes/eurocode/nen_en_1992_1_1_c2_2011/chapter_7_serviceability_limit_state/formula_7_18.py new file mode 100644 index 000000000..ef46be1e1 --- /dev/null +++ b/blueprints/codes/eurocode/nen_en_1992_1_1_c2_2011/chapter_7_serviceability_limit_state/formula_7_18.py @@ -0,0 +1,71 @@ +"""Formula 7.18 from NEN-EN 1992-1-1+C2:2011: Chapter 7 - Serviceability Limit State.""" + +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_replace_symbols +from blueprints.type_alias import DIMENSIONLESS +from blueprints.validations import raise_if_negative + + +class Form7Dot18DeformationParameter(Formula): + r"""Class representing formula 7.18 for the calculation of [$\alpha$].""" + + label = "7.18" + source_document = NEN_EN_1992_1_1_C2_2011 + + def __init__( + self, + zeta: DIMENSIONLESS, + alpha_l: DIMENSIONLESS, + alpha_ll: DIMENSIONLESS, + ) -> None: + r"""[$\alpha$] Calculation of the deformation parameter [$\alpha$]. + + NEN-EN 1992-1-1+C2:2011 art.7.4.3(3) - Formula (7.18) + + Parameters + ---------- + zeta : DIMENSIONLESS + [$\zeta$] Distribution coefficient allowing for tension stiffening at a section, calculated with Expression (7.19). + alpha_l : DIMENSIONLESS + [$\alpha_{I}$] Value of the parameter calculated for the uncracked condition + alpha_ll : DIMENSIONLESS + [$\alpha_{II}$] Value of the parameter calculated for the fully cracked condition. + . + """ + super().__init__() + self.zeta = zeta + self.alpha_l = alpha_l + self.alpha_ll = alpha_ll + + @staticmethod + def _evaluate( + zeta: DIMENSIONLESS, + alpha_l: DIMENSIONLESS, + alpha_ll: DIMENSIONLESS, + ) -> DIMENSIONLESS: + """Evaluates the formula, for more information see the __init__ method.""" + raise_if_negative(alpha_ll=alpha_ll, alpha_l=alpha_l, zeta=zeta) + + return zeta * alpha_ll + (1 - zeta) * alpha_l + + def latex(self) -> LatexFormula: + """Returns LatexFormula object for formula 7.18.""" + _equation: str = r"\zeta \cdot \alpha_{II} + (1 - \zeta) \cdot \alpha_{I}" + _numeric_equation: str = latex_replace_symbols( + _equation, + { + r"\zeta": f"{self.zeta:.3f}", + r"\alpha_{II}": f"{self.alpha_ll:.3f}", + r"\alpha_{I}": f"{self.alpha_l:.3f}", + }, + False, + ) + return LatexFormula( + return_symbol=r"\alpha", + result=f"{self:.3f}", + equation=_equation, + numeric_equation=_numeric_equation, + comparison_operator_label="=", + unit="-", + ) diff --git a/blueprints/codes/eurocode/nen_en_1992_1_1_c2_2011/chapter_7_serviceability_limit_state/formula_7_19.py b/blueprints/codes/eurocode/nen_en_1992_1_1_c2_2011/chapter_7_serviceability_limit_state/formula_7_19.py new file mode 100644 index 000000000..01c01ca3a --- /dev/null +++ b/blueprints/codes/eurocode/nen_en_1992_1_1_c2_2011/chapter_7_serviceability_limit_state/formula_7_19.py @@ -0,0 +1,78 @@ +"""Formula 7.19 from NEN-EN 1992-1-1+C2:2011: Chapter 7 - Serviceability Limit State.""" + +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_replace_symbols +from blueprints.type_alias import DIMENSIONLESS, MPA +from blueprints.validations import raise_if_less_or_equal_to_zero, raise_if_negative + + +class Form7Dot19DistributionCoefficient(Formula): + r"""Class representing formula 7.19 for the calculation of [$\zeta$].""" + + label = "7.19" + source_document = NEN_EN_1992_1_1_C2_2011 + + def __init__( + self, + beta: DIMENSIONLESS, + sigma_sr: MPA, + sigma_s: MPA, + ) -> None: + r"""[$\zeta$] Calculation of the distribution coefficient, 0 for uncracked sections [$\zeta$]. + + Note: $\sigma_{sr} / \sigma_{s}$ may be replaced by $M_{cr} / M$ for flexure or $N_{cr} / N$ for pure tension, + where $M_{cr}$ is the cracking moment and $N_{cr}$ is the cracking force. + + NEN-EN 1992-1-1+C2:2011 art.7.4.3(3) - Formula (7.19) + + Parameters + ---------- + beta : DIMENSIONLESS + [$\beta$] Coefficient taking account of the influence of the duration of the loading or of + repeated loading on the average strain. For short-term loading, [$\beta$] = 1.0. For sustained loads or + many cycles of repeated loading [$\beta$] = 0.5 [$-$]. + sigma_sr : MPA + [$\sigma_{sr}$] Stress in the tension reinforcement calculated on the basis of a + cracked section under the loading conditions causing first cracking [$MPa$]. + sigma_s : MPA + [$\sigma_{s}$] Stress in the tension reinforcement calculated on the basis of a cracked section under + loading conditions causing first cracking [$MPa$]. + """ + super().__init__() + self.beta = beta + self.sigma_sr = sigma_sr + self.sigma_s = sigma_s + + @staticmethod + def _evaluate( + beta: DIMENSIONLESS, + sigma_sr: MPA, + sigma_s: MPA, + ) -> DIMENSIONLESS: + """Evaluates the formula, for more information see the __init__ method.""" + raise_if_negative(beta=beta, sigma_sr=sigma_sr, sigma_s=sigma_s) + raise_if_less_or_equal_to_zero(sigma_s=sigma_s) + + return 1 - beta * (sigma_sr / sigma_s) ** 2 + + def latex(self) -> LatexFormula: + """Returns LatexFormula object for formula 7.19.""" + _equation: str = r"1 - \beta \left(\frac{\sigma_{sr}}{\sigma_{s}}\right)^2" + _numeric_equation: str = latex_replace_symbols( + _equation, + { + r"\beta": f"{self.beta:.3f}", + r"\sigma_{sr}": f"{self.sigma_sr:.3f}", + r"\sigma_{s}": f"{self.sigma_s:.3f}", + }, + False, + ) + return LatexFormula( + return_symbol=r"\zeta", + result=f"{self:.3f}", + equation=_equation, + numeric_equation=_numeric_equation, + comparison_operator_label="=", + unit="-", + ) diff --git a/blueprints/codes/eurocode/nen_en_1992_1_1_c2_2011/chapter_7_serviceability_limit_state/formula_7_20.py b/blueprints/codes/eurocode/nen_en_1992_1_1_c2_2011/chapter_7_serviceability_limit_state/formula_7_20.py new file mode 100644 index 000000000..678ab8601 --- /dev/null +++ b/blueprints/codes/eurocode/nen_en_1992_1_1_c2_2011/chapter_7_serviceability_limit_state/formula_7_20.py @@ -0,0 +1,64 @@ +"""Formula 7.20 from NEN-EN 1992-1-1+C2:2011: Chapter 7 - Serviceability Limit State.""" + +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_replace_symbols +from blueprints.type_alias import DIMENSIONLESS, MPA +from blueprints.validations import raise_if_negative + + +class Form7Dot20EffectiveModulusCreep(Formula): + r"""Class representing formula 7.20 for the calculation of [$E_{c,eff}$].""" + + label = "7.20" + source_document = NEN_EN_1992_1_1_C2_2011 + + def __init__( + self, + e_cm: MPA, + phi_inf_t0: DIMENSIONLESS, + ) -> None: + r"""[$E_{c,eff}$] Calculation of the effective modulus of elasticity for concrete including creep. + + NEN-EN 1992-1-1+C2:2011 art.7.4.3(5) - Formula (7.20) + + Parameters + ---------- + e_cm : MPA + [$E_{cm}$] Secant modulus of elasticity of concrete [$MPa$]. + phi_inf_t0 : DIMENSIONLESS + [$\phi(\infty, t_0)$] Creep coefficient relevant for the load and time interval (see 3.1.3) [$-$]. + """ + super().__init__() + self.e_cm = e_cm + self.phi_inf_t0 = phi_inf_t0 + + @staticmethod + def _evaluate( + e_cm: MPA, + phi_inf_t0: DIMENSIONLESS, + ) -> MPA: + """Evaluates the formula, for more information see the __init__ method.""" + raise_if_negative(e_cm=e_cm, phi_inf_t0=phi_inf_t0) + + return e_cm / (1 + phi_inf_t0) + + def latex(self) -> LatexFormula: + """Returns LatexFormula object for formula 7.20.""" + _equation: str = r"\frac{E_{cm}}{1 + \phi(\infty , t_0)}" + _numeric_equation: str = latex_replace_symbols( + _equation, + { + r"E_{cm}": f"{self.e_cm:.3f}", + r"\phi(\infty , t_0)": f"{self.phi_inf_t0:.3f}", + }, + False, + ) + return LatexFormula( + return_symbol=r"E_{c,eff}", + result=f"{self:.3f}", + equation=_equation, + numeric_equation=_numeric_equation, + comparison_operator_label="=", + unit="MPa", + ) diff --git a/blueprints/codes/eurocode/nen_en_1992_1_1_c2_2011/chapter_7_serviceability_limit_state/formula_7_21.py b/blueprints/codes/eurocode/nen_en_1992_1_1_c2_2011/chapter_7_serviceability_limit_state/formula_7_21.py new file mode 100644 index 000000000..efda859a3 --- /dev/null +++ b/blueprints/codes/eurocode/nen_en_1992_1_1_c2_2011/chapter_7_serviceability_limit_state/formula_7_21.py @@ -0,0 +1,85 @@ +"""Formula 7.21 from NEN-EN 1992-1-1+C2:2011: Chapter 7 - Serviceability Limit State.""" + +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_replace_symbols +from blueprints.type_alias import DIMENSIONLESS, MM3, MM4, MPA, ONE_OVER_MM +from blueprints.validations import raise_if_negative + + +class Form7Dot21CurvatureDueToShrinkage(Formula): + r"""Class representing formula 7.21 for the calculation of [$\frac{1}{r_{cs}}$].""" + + label = "7.21" + source_document = NEN_EN_1992_1_1_C2_2011 + + def __init__( + self, + epsilon_cs: DIMENSIONLESS, + es: MPA, + ec_eff: MPA, + capital_s: MM3, + capital_i: MM4, + ) -> None: + r"""[$\frac{1}{r_{cs}}$] Calculation of the curvature due to shrinkage [$mm^{-1}$]. + + NEN-EN 1992-1-1+C2:2011 art.7.4.3(6) - Formula (7.21) + + Parameters + ---------- + epsilon_cs : DIMENSIONLESS + [$\epsilon_{cs}$] Free shrinkage strain, see 3.1.4. + es : MPA + [$E_s$] Modulus of elasticity of the reinforcement [$MPa$]. + ec_eff : MPA + [$E_{c,eff}$] Effective modulus of elasticity of the concrete [$MPa$]. + s : MM3 + [$S$] First moment of area of the reinforcement about the centroid of the section [$mm^3$]. + i : MM4 + [$I$] Second moment of area of the section [$mm^4$]. + + S and i should be calculated for the uncracked condition and the fully cracked condition, the + final curvature being assessed by use of Expression (7.18). + """ + super().__init__() + self.epsilon_cs = epsilon_cs + self.es = es + self.ec_eff = ec_eff + self.capital_s = capital_s + self.capital_i = capital_i + + @staticmethod + def _evaluate( + epsilon_cs: DIMENSIONLESS, + es: MPA, + ec_eff: MPA, + capital_s: MM3, + capital_i: MM4, + ) -> ONE_OVER_MM: + """Evaluates the formula, for more information see the __init__ method.""" + raise_if_negative(epsilon_cs=epsilon_cs, es=es, ec_eff=ec_eff, capital_s=capital_s, capital_i=capital_i) + + return epsilon_cs * es / ec_eff * (capital_s / capital_i) + + def latex(self) -> LatexFormula: + """Returns LatexFormula object for formula 7.21.""" + _equation: str = r"\epsilon_{cs} \cdot \frac{E_s}{E_{c,eff}} \cdot \frac{S}{I}" + _numeric_equation: str = latex_replace_symbols( + _equation, + { + r"\epsilon_{cs}": f"{self.epsilon_cs:.4f}", + r"E_s": f"{self.es:.3f}", + r"E_{c,eff}": f"{self.ec_eff:.3f}", + r"S": f"{self.capital_s:.3f}", + r"I": f"{self.capital_i:.3f}", + }, + False, + ) + return LatexFormula( + return_symbol=r"\frac{1}{r_{cs}}", + result=f"{self:.6f}", + equation=_equation, + numeric_equation=_numeric_equation, + comparison_operator_label="=", + unit="mm^{-1}", + ) diff --git a/docs/objects_overview/eurocode/ec2_1992_1_1_2011/formulas.md b/docs/objects_overview/eurocode/ec2_1992_1_1_2011/formulas.md index 7f4fcb1b4..4beab247f 100644 --- a/docs/objects_overview/eurocode/ec2_1992_1_1_2011/formulas.md +++ b/docs/objects_overview/eurocode/ec2_1992_1_1_2011/formulas.md @@ -199,13 +199,13 @@ Total of 304 formulas present. | 7.13 | :heavy_check_mark: | | Form7Dot13CoefficientK2 | | 7.14 | :heavy_check_mark: | | Form7Dot14MaximumCrackSpacing | | 7.15 | :heavy_check_mark: | | Form7Dot15MaximumCrackSpacing | -| 7.16.a | :x: | | | -| 7.16.b | :x: | | | -| 7.17 | :x: | | | -| 7.18 | :x: | | | -| 7.19 | :x: | | | -| 7.20 | :x: | | | -| 7.21 | :x: | | | +| 7.16.a | :heavy_check_mark: | | Form7Dot16abSpanDepthRatio | +| 7.16.b | :heavy_check_mark: | | Form7Dot16abSpanDepthRatio | +| 7.17 | :heavy_check_mark: | | Form7Dot17MultiplicationFactor | +| 7.18 | :heavy_check_mark: | | Form7Dot18DeformationParameter | +| 7.19 | :heavy_check_mark: | | Form7Dot19DistributionCoefficient | +| 7.20 | :heavy_check_mark: | | Form7Dot20EffectiveModulus | +| 7.21 | :heavy_check_mark: | | Form7Dot21CurvatureDueToShrinkage | 8.1 | :heavy_check_mark: | | Form8Dot1RequiredMinimumMandrelDiameter | | 8.2 | :heavy_check_mark: | | Form8Dot2UltimateBondStress | | 8.3 | :heavy_check_mark: | | Form8Dot3RequiredAnchorageLength | diff --git a/tests/codes/eurocode/nen_en_1992_1_1_c2_2011/chapter_7_serviceability_limit_state/test_formula_7_16_ab.py b/tests/codes/eurocode/nen_en_1992_1_1_c2_2011/chapter_7_serviceability_limit_state/test_formula_7_16_ab.py new file mode 100644 index 000000000..d2d91b672 --- /dev/null +++ b/tests/codes/eurocode/nen_en_1992_1_1_c2_2011/chapter_7_serviceability_limit_state/test_formula_7_16_ab.py @@ -0,0 +1,149 @@ +"""Testing formula 7.16.a and 7.16.b of NEN-EN 1992-1-1+C2:2011.""" + +import pytest + +from blueprints.codes.eurocode.nen_en_1992_1_1_c2_2011.chapter_7_serviceability_limit_state.formula_7_16_ab import ( + Form7Dot16abSpanDepthRatio, + Form7Dot16ReferenceReinforcementRatio, +) +from blueprints.validations import LessOrEqualToZeroError, NegativeValueError + + +class TestForm7Dot16abSpanDepthRatio: + """Validation for formula 7.16a/b from NEN-EN 1992-1-1+C2:2011.""" + + def test_evaluation_rho_less_than_rho_0(self) -> None: + """Tests the evaluation of the result when rho <= rho_0.""" + # Example values + capital_k = 1.0 + f_ck = 30.0 + rho = 0.001 + rho_0 = 0.002 + rho_prime = 0.0005 + + # Object to test + formula = Form7Dot16abSpanDepthRatio(capital_k=capital_k, f_ck=f_ck, rho=rho, rho_0=rho_0, rho_prime=rho_prime) + + # Expected result, manually calculated + manually_calculated_result = 44.9587985653203 + + assert formula == pytest.approx(expected=manually_calculated_result, rel=1e-4) + + def test_evaluation_rho_greater_than_rho_0(self) -> None: + """Tests the evaluation of the result when rho > rho_0.""" + # Example values + capital_k = 1.0 + f_ck = 30.0 + rho = 0.003 + rho_0 = 0.002 + rho_prime = 0.0005 + + # Object to test + formula = Form7Dot16abSpanDepthRatio(capital_k=capital_k, f_ck=f_ck, rho=rho, rho_0=rho_0, rho_prime=rho_prime) + + # Expected result, manually calculated + manually_calculated_result = 17.80088842235581 + + assert formula == pytest.approx(expected=manually_calculated_result, rel=1e-4) + + @pytest.mark.parametrize( + ("capital_k", "f_ck", "rho", "rho_0", "rho_prime"), + [ + (-1.0, 30.0, 0.001, 0.002, 0.0), # capital_k is negative + (1.0, -30.0, 0.001, 0.002, 0.0), # f_ck is negative + (1.0, 30.0, -0.001, 0.002, 0.0), # rho is negative + (1.0, 30.0, 0.001, -0.002, 0.0), # rho_0 is negative + (1.0, 30.0, 0.001, 0.002, -0.001), # rho_prime is negative + (1.0, 30.0, 0.0, 0.002, 0.0), # rho is zero + ], + ) + def test_raise_error_when_invalid_values_are_given(self, capital_k: float, f_ck: float, rho: float, rho_0: float, rho_prime: float) -> None: + """Test invalid values.""" + with pytest.raises((NegativeValueError, LessOrEqualToZeroError)): + Form7Dot16abSpanDepthRatio(capital_k=capital_k, f_ck=f_ck, rho=rho, rho_0=rho_0, rho_prime=rho_prime) + + @pytest.mark.parametrize( + ("representation", "expected"), + [ + ( + "complete", + r"\frac{l}{d} = \begin{cases} K \cdot \left[11 + 1.5 \cdot \sqrt{f_{ck}} \cdot " + r"\frac{\rho_0}{\rho} + 3.2 \cdot \sqrt{f_{ck}} \cdot \left(\frac{\rho_0}{\rho} - 1\right)^{3/2}\right] & " + r"\text{if } \rho \leq \rho_0 \\ K \cdot \left[11 + 1.5 \cdot \sqrt{f_{ck}} \cdot " + r"\frac{\rho_0}{\rho - \rho'} + \frac{1}{12} \cdot \sqrt{f_{ck}} \cdot \sqrt{\frac{\rho'}" + r"{\rho_0}}\right] & \text{if } \rho > \rho_0 \end{cases} = " + r"\begin{cases} 1.000 \cdot \left[11 + 1.5 \cdot \sqrt{30.000} \cdot \frac{0.0020}{0.0010} + " + r"3.2 \cdot \sqrt{30.000} \cdot \left(\frac{0.0020}{0.0010} - 1\right)^{3/2}\right] & " + r"\text{if } 0.0010 \leq 0.0020 \\ 1.000 \cdot \left[11 + 1.5 \cdot \sqrt{30.000} " + r"\cdot \frac{0.0020}{0.0010 - 0.0005} + \frac{1}{12} \cdot \sqrt{30.000} \cdot " + r"\sqrt{\frac{0.0005}{0.0020}}\right] & \text{if } 0.0010 > 0.0020 \end{cases} = 44.959 \ -", + ), + ("short", r"\frac{l}{d} = 44.959 \ -"), + ], + ) + def test_latex(self, representation: str, expected: str) -> None: + """Test the latex representation of the formula.""" + # Example values + capital_k = 1.0 + f_ck = 30.0 + rho = 0.0010 + rho_0 = 0.0020 + rho_prime = 0.0005 + + # Object to test + latex = Form7Dot16abSpanDepthRatio(capital_k=capital_k, f_ck=f_ck, rho=rho, rho_0=rho_0, rho_prime=rho_prime).latex() + + actual = { + "complete": latex.complete, + "short": latex.short, + } + + assert expected == actual[representation], f"{representation} representation failed." + + +class TestForm7Dot16ReferenceReinforcementRatio: + """Validation for reference reinforcement ratio calculation from NEN-EN 1992-1-1+C2:2011.""" + + def test_evaluation(self) -> None: + """Tests the evaluation of the result.""" + f_ck = 30.0 + + formula = Form7Dot16ReferenceReinforcementRatio(f_ck=f_ck) + manually_calculated_result = 0.00547722557 # Example manually calculated result + + assert formula == pytest.approx(expected=manually_calculated_result, rel=1e-4) + + @pytest.mark.parametrize( + "f_ck", + [ + -30.0, # f_ck is negative + ], + ) + def test_raise_error_when_invalid_values_are_given(self, f_ck: float) -> None: + """Test invalid values.""" + with pytest.raises(NegativeValueError): + Form7Dot16ReferenceReinforcementRatio(f_ck=f_ck) + + @pytest.mark.parametrize( + ("representation", "expected"), + [ + ( + "complete", + r"\rho_0 = \sqrt{f_{ck}} \cdot 10^{-3}" + r" = \sqrt{30.000} \cdot 10^{-3} = 0.005477 \ -", + ), + ("short", r"\rho_0 = 0.005477 \ -"), + ], + ) + def test_latex(self, representation: str, expected: str) -> None: + """Test the latex representation of the formula.""" + f_ck = 30.0 + + latex = Form7Dot16ReferenceReinforcementRatio(f_ck=f_ck).latex() + + actual = { + "complete": latex.complete, + "short": latex.short, + } + + assert expected == actual[representation], f"{representation} representation failed." diff --git a/tests/codes/eurocode/nen_en_1992_1_1_c2_2011/chapter_7_serviceability_limit_state/test_formula_7_17.py b/tests/codes/eurocode/nen_en_1992_1_1_c2_2011/chapter_7_serviceability_limit_state/test_formula_7_17.py new file mode 100644 index 000000000..8b749d7f3 --- /dev/null +++ b/tests/codes/eurocode/nen_en_1992_1_1_c2_2011/chapter_7_serviceability_limit_state/test_formula_7_17.py @@ -0,0 +1,71 @@ +"""Testing formula 7.17 of NEN-EN 1992-1-1+C2:2011.""" + +import pytest + +from blueprints.codes.eurocode.nen_en_1992_1_1_c2_2011.chapter_7_serviceability_limit_state.formula_7_17 import ( + Form7Dot1MultiplicationFactorLimitSlenderness, +) +from blueprints.validations import LessOrEqualToZeroError, NegativeValueError + + +class TestForm7Dot1MultiplicationFactorLimitSlenderness: + """Validation for formula 7.17 from NEN-EN 1992-1-1+C2:2011.""" + + def test_evaluation(self) -> None: + """Tests the evaluation of the result.""" + # Example values + f_yk = 500.0 + a_s_req = 200.0 + a_s_prov = 250.0 + + # Object to test + formula = Form7Dot1MultiplicationFactorLimitSlenderness(f_yk=f_yk, a_s_req=a_s_req, a_s_prov=a_s_prov) + + # Expected result, manually calculated + manually_calculated_result = 1.25 # dimensionless + + assert formula == pytest.approx(expected=manually_calculated_result, rel=1e-4) + + @pytest.mark.parametrize( + ("f_yk", "a_s_req", "a_s_prov"), + [ + (-500.0, 200.0, 250.0), # f_yk is negative + (500.0, -200.0, 250.0), # a_s_req is negative + (500.0, 200.0, -250.0), # a_s_prov is negative + (500.0, 0.0, 250.0), # a_s_req is zero + (500.0, 200.0, 0.0), # a_s_prov is zero + (0.0, 200.0, 250.0), # f_yk is zero + ], + ) + def test_raise_error_when_invalid_values_are_given(self, f_yk: float, a_s_req: float, a_s_prov: float) -> None: + """Test invalid values.""" + with pytest.raises((NegativeValueError, LessOrEqualToZeroError)): + Form7Dot1MultiplicationFactorLimitSlenderness(f_yk=f_yk, a_s_req=a_s_req, a_s_prov=a_s_prov) + + @pytest.mark.parametrize( + ("representation", "expected"), + [ + ( + "complete", + r"\frac{310}{\sigma_s} = \frac{500}{f_{yk} \cdot \frac{A_{s,req}}{A_{s,prov}}} = " + r"\frac{500}{500.000 \cdot \frac{200.000}{250.000}} = 1.250 \ -", + ), + ("short", r"\frac{310}{\sigma_s} = 1.250 \ -"), + ], + ) + def test_latex(self, representation: str, expected: str) -> None: + """Test the latex representation of the formula.""" + # Example values + f_yk = 500.0 + a_s_req = 200.0 + a_s_prov = 250.0 + + # Object to test + latex = Form7Dot1MultiplicationFactorLimitSlenderness(f_yk=f_yk, a_s_req=a_s_req, a_s_prov=a_s_prov).latex() + + actual = { + "complete": latex.complete, + "short": latex.short, + } + + assert expected == actual[representation], f"{representation} representation failed." diff --git a/tests/codes/eurocode/nen_en_1992_1_1_c2_2011/chapter_7_serviceability_limit_state/test_formula_7_18.py b/tests/codes/eurocode/nen_en_1992_1_1_c2_2011/chapter_7_serviceability_limit_state/test_formula_7_18.py new file mode 100644 index 000000000..69ec486ee --- /dev/null +++ b/tests/codes/eurocode/nen_en_1992_1_1_c2_2011/chapter_7_serviceability_limit_state/test_formula_7_18.py @@ -0,0 +1,66 @@ +"""Testing formula 7.18 of NEN-EN 1992-1-1+C2:2011.""" + +import pytest + +from blueprints.codes.eurocode.nen_en_1992_1_1_c2_2011.chapter_7_serviceability_limit_state.formula_7_18 import Form7Dot18DeformationParameter +from blueprints.validations import NegativeValueError + + +class TestForm7Dot18DeformationParameter: + """Validation for formula 7.18 from NEN-EN 1992-1-1+C2:2011.""" + + def test_evaluation(self) -> None: + """Tests the evaluation of the result.""" + # Example values + zeta = 1 / 3.0 + alpha_ll = 1.4 + alpha_l = 0.8 + + # Object to test + formula = Form7Dot18DeformationParameter(zeta=zeta, alpha_ll=alpha_ll, alpha_l=alpha_l) + + # Expected result, manually calculated + manually_calculated_result = 1.0 # dimensionless + + assert formula == pytest.approx(expected=manually_calculated_result, rel=1e-4) + + @pytest.mark.parametrize( + ("zeta", "alpha_ll", "alpha_l"), + [ + (-0.5, 1.2, 0.8), # zeta is negative + (0.5, -1.2, 0.8), # alpha_ll is negative + (0.5, 1.2, -0.8), # alpha_l is negative + ], + ) + def test_raise_error_when_invalid_values_are_given(self, zeta: float, alpha_ll: float, alpha_l: float) -> None: + """Test invalid values.""" + with pytest.raises(NegativeValueError): + Form7Dot18DeformationParameter(zeta=zeta, alpha_ll=alpha_ll, alpha_l=alpha_l) + + @pytest.mark.parametrize( + ("representation", "expected"), + [ + ( + "complete", + r"\alpha = \zeta \cdot \alpha_{II} + (1 - \zeta) \cdot \alpha_{I} = " + r"0.500 \cdot 1.200 + (1 - 0.500) \cdot 0.800 = 1.000 \ -", + ), + ("short", r"\alpha = 1.000 \ -"), + ], + ) + def test_latex(self, representation: str, expected: str) -> None: + """Test the latex representation of the formula.""" + # Example values + zeta = 0.5 + alpha_ll = 1.2 + alpha_l = 0.8 + + # Object to test + latex = Form7Dot18DeformationParameter(zeta=zeta, alpha_ll=alpha_ll, alpha_l=alpha_l).latex() + + actual = { + "complete": latex.complete, + "short": latex.short, + } + + assert expected == actual[representation], f"{representation} representation failed." diff --git a/tests/codes/eurocode/nen_en_1992_1_1_c2_2011/chapter_7_serviceability_limit_state/test_formula_7_19.py b/tests/codes/eurocode/nen_en_1992_1_1_c2_2011/chapter_7_serviceability_limit_state/test_formula_7_19.py new file mode 100644 index 000000000..c6be07929 --- /dev/null +++ b/tests/codes/eurocode/nen_en_1992_1_1_c2_2011/chapter_7_serviceability_limit_state/test_formula_7_19.py @@ -0,0 +1,67 @@ +"""Testing formula 7.19 of NEN-EN 1992-1-1+C2:2011.""" + +import pytest + +from blueprints.codes.eurocode.nen_en_1992_1_1_c2_2011.chapter_7_serviceability_limit_state.formula_7_19 import Form7Dot19DistributionCoefficient +from blueprints.validations import LessOrEqualToZeroError, NegativeValueError + + +class TestForm7Dot19DistributionCoefficient: + """Validation for formula 7.19 from NEN-EN 1992-1-1+C2:2011.""" + + def test_evaluation(self) -> None: + """Tests the evaluation of the result.""" + # Example values + beta = 0.5 + sigma_sr = 200.0 + sigma_s = 400.0 + + # Object to test + formula = Form7Dot19DistributionCoefficient(beta=beta, sigma_sr=sigma_sr, sigma_s=sigma_s) + + # Expected result, manually calculated + manually_calculated_result = 0.875 # dimensionless + + assert formula == pytest.approx(expected=manually_calculated_result, rel=1e-4) + + @pytest.mark.parametrize( + ("beta", "sigma_sr", "sigma_s"), + [ + (-0.5, 200.0, 400.0), # beta is negative + (0.5, -200.0, 400.0), # sigma_sr is negative + (0.5, 200.0, -400.0), # sigma_s is negative + (0.5, 200.0, 0.0), # sigma_s is zero + ], + ) + def test_raise_error_when_invalid_values_are_given(self, beta: float, sigma_sr: float, sigma_s: float) -> None: + """Test invalid values.""" + with pytest.raises((NegativeValueError, LessOrEqualToZeroError)): + Form7Dot19DistributionCoefficient(beta=beta, sigma_sr=sigma_sr, sigma_s=sigma_s) + + @pytest.mark.parametrize( + ("representation", "expected"), + [ + ( + "complete", + r"\zeta = 1 - \beta \left(\frac{\sigma_{sr}}{\sigma_{s}}\right)^2 = " + r"1 - 0.500 \left(\frac{200.000}{400.000}\right)^2 = 0.875 \ -", + ), + ("short", r"\zeta = 0.875 \ -"), + ], + ) + def test_latex(self, representation: str, expected: str) -> None: + """Test the latex representation of the formula.""" + # Example values + beta = 0.5 + sigma_sr = 200.0 + sigma_s = 400.0 + + # Object to test + latex = Form7Dot19DistributionCoefficient(beta=beta, sigma_sr=sigma_sr, sigma_s=sigma_s).latex() + + actual = { + "complete": latex.complete, + "short": latex.short, + } + + assert expected == actual[representation], f"{representation} representation failed." diff --git a/tests/codes/eurocode/nen_en_1992_1_1_c2_2011/chapter_7_serviceability_limit_state/test_formula_7_20.py b/tests/codes/eurocode/nen_en_1992_1_1_c2_2011/chapter_7_serviceability_limit_state/test_formula_7_20.py new file mode 100644 index 000000000..dc3e3ef0e --- /dev/null +++ b/tests/codes/eurocode/nen_en_1992_1_1_c2_2011/chapter_7_serviceability_limit_state/test_formula_7_20.py @@ -0,0 +1,62 @@ +"""Testing formula 7.20 of NEN-EN 1992-1-1+C2:2011.""" + +import pytest + +from blueprints.codes.eurocode.nen_en_1992_1_1_c2_2011.chapter_7_serviceability_limit_state.formula_7_20 import Form7Dot20EffectiveModulusCreep +from blueprints.validations import NegativeValueError + + +class TestForm7Dot20EffectiveModulusCreep: + """Validation for formula 7.20 from NEN-EN 1992-1-1+C2:2011.""" + + def test_evaluation(self) -> None: + """Tests the evaluation of the result.""" + # Example values + e_cm = 30000.0 # MPa + phi_inf_t0 = 2.0 # dimensionless + + # Object to test + formula = Form7Dot20EffectiveModulusCreep(e_cm=e_cm, phi_inf_t0=phi_inf_t0) + + # Expected result, manually calculated + manually_calculated_result = 10000.0 # MPa + + assert formula == pytest.approx(manually_calculated_result, rel=1e-4) + + @pytest.mark.parametrize( + ("e_cm", "phi_inf_t0"), + [ + (-30000.0, 2.0), # e_cm is negative + (30000.0, -2.0), # phi_inf_t0 is negative + ], + ) + def test_raise_error_when_invalid_values_are_given(self, e_cm: float, phi_inf_t0: float) -> None: + """Test invalid values.""" + with pytest.raises(NegativeValueError): + Form7Dot20EffectiveModulusCreep(e_cm=e_cm, phi_inf_t0=phi_inf_t0) + + @pytest.mark.parametrize( + ("representation", "expected"), + [ + ( + "complete", + r"E_{c,eff} = \frac{E_{cm}}{1 + \phi(\infty , t_0)} = \frac{30000.000}{1 + 2.000} = 10000.000 \ MPa", + ), + ("short", r"E_{c,eff} = 10000.000 \ MPa"), + ], + ) + def test_latex(self, representation: str, expected: str) -> None: + """Test the latex representation of the formula.""" + # Example values + e_cm = 30000.0 # MPa + phi_inf_t0 = 2.0 # dimensionless + + # Object to test + latex = Form7Dot20EffectiveModulusCreep(e_cm=e_cm, phi_inf_t0=phi_inf_t0).latex() + + actual = { + "complete": latex.complete, + "short": latex.short, + } + + assert expected == actual[representation], f"{representation} representation failed." diff --git a/tests/codes/eurocode/nen_en_1992_1_1_c2_2011/chapter_7_serviceability_limit_state/test_formula_7_21.py b/tests/codes/eurocode/nen_en_1992_1_1_c2_2011/chapter_7_serviceability_limit_state/test_formula_7_21.py new file mode 100644 index 000000000..6dc29eaef --- /dev/null +++ b/tests/codes/eurocode/nen_en_1992_1_1_c2_2011/chapter_7_serviceability_limit_state/test_formula_7_21.py @@ -0,0 +1,72 @@ +"""Testing formula 7.21 of NEN-EN 1992-1-1+C2:2011.""" + +import pytest + +from blueprints.codes.eurocode.nen_en_1992_1_1_c2_2011.chapter_7_serviceability_limit_state.formula_7_21 import Form7Dot21CurvatureDueToShrinkage +from blueprints.validations import NegativeValueError + + +class TestForm7Dot21CurvatureDueToShrinkage: + """Validation for formula 7.21 from NEN-EN 1992-1-1+C2:2011.""" + + def test_evaluation(self) -> None: + """Tests the evaluation of the result.""" + # Example values + epsilon_cs = 0.0003 # dimensionless + es = 200000.0 # MPa + ec_eff = 30000.0 # MPa + capital_s = 50000.0 # mm^3 + capital_i = 200000.0 # mm^4 + + # Object to test + formula = Form7Dot21CurvatureDueToShrinkage(epsilon_cs=epsilon_cs, es=es, ec_eff=ec_eff, capital_s=capital_s, capital_i=capital_i) + + # Expected result, manually calculated + manually_calculated_result = 0.0005 # dimensionless + + assert formula == pytest.approx(manually_calculated_result, rel=1e-4) + + @pytest.mark.parametrize( + ("epsilon_cs", "es", "ec_eff", "capital_s", "capital_i"), + [ + (-0.0003, 200000.0, 30000.0, 50000.0, 200000.0), # epsilon_cs is negative + (0.0003, -200000.0, 30000.0, 50000.0, 200000.0), # es is negative + (0.0003, 200000.0, -30000.0, 50000.0, 200000.0), # ec_eff is negative + (0.0003, 200000.0, 30000.0, -50000.0, 200000.0), # capital_s is negative + (0.0003, 200000.0, 30000.0, 50000.0, -200000.0), # capital_i is negative + ], + ) + def test_raise_error_when_invalid_values_are_given(self, epsilon_cs: float, es: float, ec_eff: float, capital_s: float, capital_i: float) -> None: + """Test invalid values.""" + with pytest.raises(NegativeValueError): + Form7Dot21CurvatureDueToShrinkage(epsilon_cs=epsilon_cs, es=es, ec_eff=ec_eff, capital_s=capital_s, capital_i=capital_i) + + @pytest.mark.parametrize( + ("representation", "expected"), + [ + ( + "complete", + r"\frac{1}{r_{cs}} = \epsilon_{cs} \cdot \frac{E_s}{E_{c,eff}} \cdot \frac{S}{I} = " + r"0.0003 \cdot \frac{200000.000}{30000.000} \cdot \frac{50000.000}{200000.000} = 0.000500 \ mm^{-1}", + ), + ("short", r"\frac{1}{r_{cs}} = 0.000500 \ mm^{-1}"), + ], + ) + def test_latex(self, representation: str, expected: str) -> None: + """Test the latex representation of the formula.""" + # Example values + epsilon_cs = 0.0003 # dimensionless + es = 200000.0 # MPa + ec_eff = 30000.0 # MPa + capital_s = 50000.0 # mm^3 + capital_i = 200000.0 # mm^4 + + # Object to test + latex = Form7Dot21CurvatureDueToShrinkage(epsilon_cs=epsilon_cs, es=es, ec_eff=ec_eff, capital_s=capital_s, capital_i=capital_i).latex() + + actual = { + "complete": latex.complete, + "short": latex.short, + } + + assert expected == actual[representation], f"{representation} representation failed."