Skip to content

Commit

Permalink
Merge pull request #16 from Blueprints-org/9-feature-request-add-form…
Browse files Browse the repository at this point in the history
…ula-3_1-3_2

Add formulas 3.1 and 3.2 from 1992-1-1+C2:2011, thanks Luuk
  • Loading branch information
egarciamendez authored Nov 29, 2023
2 parents c9eb69c + c8163c7 commit bc2d08f
Show file tree
Hide file tree
Showing 6 changed files with 240 additions and 5 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
"""Module including all formulas from chapter 3 - Materials of NEN-EN 1992-1-1+C2:2011."""
# pylint: disable=arguments-differ
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.type_alias import MPA


class Form3Dot1EstimationConcreteCompressiveStrength(Formula):
"""Class representing formula 3.1 for the estimation of the concrete compressive strength, fcm(t), after t days
with an average temperature of 20 degrees Celsius [MPa]."""

label = "3.1"
source_document = NEN_EN_1992_1_1_C2_2011

def __init__(
self,
beta_cc_t: float,
f_cm: MPA,
) -> None:
"""[fcm(t)] The estimated concrete compressive strength [MPa].
NEN-EN 1992-1-1+C2:2011 art.3.1.2(6) - Formula (3.1)
Parameters
----------
beta_cc_t : float
[βcc(t)] Coefficient dependent of the age of concrete [-].
f_cm : MPA
[fcm] Average concrete compressive strength on day 28 based on table 3.1 [MPa].
"""
super().__init__()
self.beta_cc_t = beta_cc_t
self.f_cm = f_cm

@staticmethod
def _evaluate(
beta_cc_t: float,
f_cm: MPA,
) -> MPA:
"""Evaluates the formula, for more information see the __init__ method"""
if beta_cc_t < 0:
raise ValueError(f"Negative beta_cc_t: {beta_cc_t}. beta_cc_t cannot be negative")
if f_cm < 0:
raise ValueError(f"Negative f_cm: {f_cm}. f_cm cannot be negative")
return beta_cc_t * f_cm


class Form3Dot2CoefficientDependentOfConcreteAge(Formula):
"""Class representing formula 3.2 for the coefficient βcc(t) which is dependent of the age of concrete [-]."""

label = "3.2"
source_document = NEN_EN_1992_1_1_C2_2011

def __init__(
self,
s: float,
t: int,
) -> None:
"""Calculates beta_cc(t) coefficient which is dependent of the age of concrete in days [-].
NEN-EN 1992-1-1+C2:2011 art.3.1.2(6) - Formula (3.2)
Parameters
----------
s : float
[s] Coefficient dependent on the kind of cement [-].
= 0.20 for cement of strength classes CEM 42.5 R, CEM 52.5 N, and CEM 52.5 R (class R);
= 0.25 for cement of strength classes CEM 32.5 R, CEM 42.5 N (class N);
= 0.38 for cement of strength class CEM 32.5 N (class S).
Use your own implementation of this formula or use the SubForm3Dot2CoefficientTypeOfCementS class.
t : int
[t] Age of concrete in days [days].
"""
super().__init__()
self.s = s
self.t = t

@staticmethod
def _evaluate(
s: float,
t: int,
) -> float:
"""Evaluates the formula, for more information see the __init__ method"""
if s < 0:
raise ValueError(f"Invalid s: {s}. s cannot be negative")
if t <= 0:
raise ValueError(f"Invalid t: {t}. t cannot be negative or zero")
return np.exp(s * (1 - (28 / t) ** (1 / 2)))


class SubForm3Dot2CoefficientTypeOfCementS(Formula):
"""Class representing sub-formula for formula 3.2, which calculates the coefficient s which is dependent on the cement class"""

source_document = NEN_EN_1992_1_1_C2_2011
label = "3.2"

def __init__(
self,
cement_class: str,
) -> None:
"""[s] Coefficient that depends on the type of cement [-].
NEN-EN 1992-1-1+C2:2011 art.3.1.2(6) - s
Parameters
----------
cement_class : str
[cement_class] Class of the cement.
= 'R' for cement of strength classes CEM 42.5 R, CEM 52.5 N, and CEM 52.5 R (class R);
= 'N' for cement of strength classes CEM 32.5 R, CEM 42.5 N (class N);
= 'S' for cement of strength class CEM 32.5 N (class S).
"""
super().__init__()
self.cement_class = cement_class

@staticmethod
def _evaluate(
cement_class: str,
) -> float:
"""Evaluates the formula, for more information see the __init__ method"""
match cement_class.lower():
case "r":
return 0.20
case "n":
return 0.25
case "s":
return 0.38
case _:
raise ValueError(f"Invalid cement class: {cement_class}. Options: R, N or S")
7 changes: 2 additions & 5 deletions blueprints/codes/formula.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@


class Formula(float, ABC):
"""
Abstract base class for formulas used in the codes.
"""
"""Abstract base class for formulas used in the codes."""

def __new__(cls, *args, **kwargs) -> "Formula":
"""Method for creating a new instance of the class."""
Expand All @@ -19,8 +17,7 @@ def __init__(self, *args, **kwargs):
self._initialized = True

def __setattr__(self, name, value):
"""
Override the __setattr__ method to prevent modifications after initialization.
"""Override the __setattr__ method to prevent modifications after initialization.
Parameters
----------
Expand Down
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
"""Testing formula 3.1 of NEN-EN 1992-1-1+C2:2011."""
# pylint: disable=arguments-differ
import pytest

from blueprints.codes.eurocode.nen_en_1992_1_1_c2_2011.chapter_3_materials import Form3Dot1EstimationConcreteCompressiveStrength


class TestForm3Dot1EstimationConcreteCompressiveStrength:
"""Validation for formula 3.1 from NEN-EN 1992-1-1+C2:2011."""

def test_evaluation(self) -> None:
"""Test the evaluation of the result."""
# Example values
beta_cc_t = 1 # -
f_cm = 10 # MPa
form_3_1 = Form3Dot1EstimationConcreteCompressiveStrength(beta_cc_t=beta_cc_t, f_cm=f_cm)

# Expected result, manually calculated
manually_calculated_result = 10

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

def test_raise_error_when_negative_beta_is_given(self) -> None:
"""Test the evaluation of the result."""
# Example values
beta_cc_t = -1 # -
f_cm = 10 # MPa

with pytest.raises(ValueError):
Form3Dot1EstimationConcreteCompressiveStrength(beta_cc_t=beta_cc_t, f_cm=f_cm)

def test_raise_error_when_negative_f_cm_is_given(self) -> None:
"""Test the evaluation of the result."""
# Example values
beta_cc_t = 1 # -
f_cm = -10 # MPa

with pytest.raises(ValueError):
Form3Dot1EstimationConcreteCompressiveStrength(beta_cc_t=beta_cc_t, f_cm=f_cm)
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
"""Testing formula 3.2 of NEN-EN 1992-1-1+C2:2011."""
# pylint: disable=arguments-differ
import pytest

from blueprints.codes.eurocode.nen_en_1992_1_1_c2_2011.chapter_3_materials import Form3Dot2CoefficientDependentOfConcreteAge


class TestForm3Dot2CoefficientDependentOfConcreteAge:
"""Validation for formula 3.2 from NEN-EN 1992-1-1+C2:2011."""

def test_evaluation(self) -> None:
"""Test the evaluation of the result."""
# Example values
s = 0.25 # -
t = 10 # days
form_3_2 = Form3Dot2CoefficientDependentOfConcreteAge(s=s, t=t)

# Expected result, manually calculated
manually_calculated_result = 0.84507490

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

def test_raise_error_when_negative_t_is_given(self) -> None:
"""Test the evaluation of the result."""
# Example values
s = 0.25 # -
t = -10 # days

with pytest.raises(ValueError):
Form3Dot2CoefficientDependentOfConcreteAge(s=s, t=t)

def test_raise_error_when_negative_s_is_given(self) -> None:
"""Test the evaluation of the result."""
# Example values
s = -0.9 # -
t = 10 # days

with pytest.raises(ValueError):
Form3Dot2CoefficientDependentOfConcreteAge(s=s, t=t)
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
"""Testing sub-formula for 3.2 of NEN-EN 1992-1-1+C2:2011."""
# pylint: disable=arguments-differ
import pytest

from blueprints.codes.eurocode.nen_en_1992_1_1_c2_2011.chapter_3_materials import SubForm3Dot2CoefficientTypeOfCementS


class TestSubForm3Dot2CoefficientTypeOfCementS:
"""Validation for formula 3.2 from NEN-EN 1992-1-1+C2:2011."""

def test_evaluation(self) -> None:
"""Test the evaluation of the result."""
# Example values
cement_class = "R" # str
sub_form_3_2 = SubForm3Dot2CoefficientTypeOfCementS(cement_class=cement_class)

# Expected result, manually calculated
manually_result = 0.20

assert sub_form_3_2 == pytest.approx(expected=manually_result, rel=1e-4)

def test_raise_error_when_invalid_cement_class_is_given(self) -> None:
"""Test the evaluation of the result."""
# Example values
cement_class = "V" # str

with pytest.raises(ValueError):
SubForm3Dot2CoefficientTypeOfCementS(cement_class=cement_class)

0 comments on commit bc2d08f

Please sign in to comment.