Skip to content

Commit

Permalink
feat: add reinforcement material (#83)
Browse files Browse the repository at this point in the history
* Add draft base class for reinforcement material

* Add draft implementation of code specific reinforcement

* Add Youngs modulus to reinforcement base class

* Add factory function for reinforcement

* Add fyd function for ec2_2004 and mc2010

* Add default gamma_s for ec2_2023

* Add fyd property for all reinforcement classes

* Add youngs modulus in reinforcement factory

* Correct internal attr in base reinforcement

* Add tests for reinforcement materials

* Add functions for getting reinf duct props

* Add ftk and epsuk to reinforcement classes
  • Loading branch information
mortenengen authored May 14, 2024
1 parent 90dd941 commit cd6bb81
Show file tree
Hide file tree
Showing 17 changed files with 762 additions and 2 deletions.
6 changes: 6 additions & 0 deletions structuralcodes/codes/ec2_2004/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

import typing as t

from ._reinforcement_material_properties import (
fyd,
reinforcement_duct_props,
)
from ._section_7_3_crack_control import (
As_min,
As_min_2,
Expand Down Expand Up @@ -46,6 +50,7 @@
'kc_tension',
'kt',
'phi_eq',
'reinforcement_duct_props',
'rho_p_eff',
'sr_max_close',
'sr_max_far',
Expand All @@ -54,6 +59,7 @@
'w_spacing',
'wk',
'xi1',
'fyd',
]

__title__: str = 'EUROCODE 2 1992-1-1:2004'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
"""Material properties for reinforcement steel."""

import typing as t

DUCTILITY_CLASSES = {
'A': {
'epsuk': 2.5e-2,
'k': 1.05,
},
'B': {
'epsuk': 5.0e-2,
'k': 1.08,
},
'C': {
'epsuk': 7.5e-2,
'k': 1.15,
},
}


def fyd(fyk: float, gamma_s: float = 1.15) -> float:
"""Calculate the design value of the reinforcement yield strength.
EUROCODE 2 1992-1-1:2004, Fig. 3.8
Args:
fyk (float): The characteristic yield strength in MPa.
gamma_s (float): The partial factor.
Returns:
float: The design yield strength in MPa.
Raises:
ValueError: if fyk is less than 0
ValueError: if gamma_s is less than or equal to 0
"""
if fyk < 0:
raise ValueError(f'fyk={fyk} cannot be less than 0')
if gamma_s <= 0:
raise ValueError(f'gamma_s={gamma_s} must be larger than 0')
return fyk / gamma_s


def reinforcement_duct_props(
fyk: float,
ductility_class: t.Literal['A', 'B', 'C'],
) -> t.Dict[str, float]:
"""Return a dict with the minimum characteristic ductility properties for
reinforcement ductility class.
EUROCODE 2 1992-1-1:2004, Tab. C.1
Args:
fyk (float): The characteristic yield strength.
ductility_class (Literal['A', 'B', 'C']): The reinforcement ductility
class designation.
Returns:
Dict[str, float]: A dict with the characteristik strain value at the
ultimate stress level (epsuk), and the characteristic ultimate stress
(ftk).
"""
duct_props = DUCTILITY_CLASSES.get(ductility_class.upper(), None)
if duct_props is None:
raise ValueError(
'The no properties was found for the provided ductility class '
f'({ductility_class}).'
)
return {
'epsuk': duct_props['epsuk'],
'ftk': duct_props['k'] * fyk,
}
2 changes: 2 additions & 0 deletions structuralcodes/codes/ec2_2023/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
phi_50y_t0,
phi_correction_factor,
r_steel_stress_strain_params,
reinforcement_duct_props,
sigma_c,
sigma_p,
sigma_s,
Expand Down Expand Up @@ -74,6 +75,7 @@
'phi_50y_t0',
'phi_correction_factor',
'r_steel_stress_strain_params',
'reinforcement_duct_props',
'sigma_c',
'sigma_p',
'sigma_s',
Expand Down
48 changes: 47 additions & 1 deletion structuralcodes/codes/ec2_2023/_section5_materials.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,21 @@

VALID_STRENGTH_DEV_CLASSES = ('CS', 'CN', 'CR', 'SLOW', 'NORMAL', 'RAPID')

DUCTILITY_CLASSES = {
'A': {
'epsuk': 2.5e-2,
'k': 1.05,
},
'B': {
'epsuk': 5.0e-2,
'k': 1.08,
},
'C': {
'epsuk': 7.5e-2,
'k': 1.15,
},
}


def fcm(fck: float, delta_f: float = 8.0) -> float:
"""Determines the mean strength of concrete from its characteristic value.
Expand Down Expand Up @@ -858,7 +873,7 @@ def weight_s() -> float:
return 78.5


def fyd(fyk: float, gamma_S: float) -> float:
def fyd(fyk: float, gamma_S: float = 1.15) -> float:
"""Design value for the yielding stress for welding reinforcing steel.
EN 1992-1-1:2023, Eq (5.11)
Expand Down Expand Up @@ -1109,3 +1124,34 @@ def sigma_p(
# If plastic
m = (fpu - fpy) / (eps_u - eps_y)
return fpy + m * (eps - eps_y)


def reinforcement_duct_props(
fyk: float,
ductility_class: t.Literal['A', 'B', 'C'],
) -> t.Dict[str, float]:
"""Return a dict with the minimum characteristic ductility properties for
reinforcement ductility class.
EUROCODE 2 1992-1-1:2023, Tab. 5.5
Args:
fyk (float): The characteristic yield strength.
ductility_class (Literal['A', 'B', 'C']): The reinforcement ductility
class designation.
Returns:
Dict[str, float]: A dict with the characteristik strain value at the
ultimate stress level (epsuk), and the characteristic ultimate stress
(ftk).
"""
duct_props = DUCTILITY_CLASSES.get(ductility_class.upper(), None)
if duct_props is None:
raise ValueError(
'The no properties was found for the provided ductility class '
f'({ductility_class}).'
)
return {
'epsuk': duct_props['epsuk'],
'ftk': duct_props['k'] * fyk,
}
3 changes: 3 additions & 0 deletions structuralcodes/codes/mc2010/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,16 @@
import typing as t

from ._concrete_material_properties import Gf, fcm, fctkmax, fctkmin, fctm
from ._reinforcement_material_properties import fyd, reinforcement_duct_props

__all__ = [
'fcm',
'fctm',
'fctkmin',
'fctkmax',
'Gf',
'fyd',
'reinforcement_duct_props',
]

__title__: str = 'fib Model Code 2010'
Expand Down
76 changes: 76 additions & 0 deletions structuralcodes/codes/mc2010/_reinforcement_material_properties.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
"""Material properties for reinforcement steel."""

import typing as t

DUCTILITY_CLASSES = {
'A': {
'epsuk': 2.5e-2,
'k': 1.05,
},
'B': {
'epsuk': 5.0e-2,
'k': 1.08,
},
'C': {
'epsuk': 7.5e-2,
'k': 1.15,
},
'D': {
'epsuk': 8.0e-2,
'k': 1.25,
},
}


def fyd(fyk: float, gamma_s: float = 1.15) -> float:
"""Calculate the design value of the reinforcement yield strength.
fib Model Code 2010, Sec. 4.5.2.2.3
Args:
fyk (float): The characteristic yield strength in MPa.
gamma_s (float): The partial factor.
Returns:
float: The design yield strength in MPa.
Raises:
ValueError: if fyk is less than 0
ValueError: if gamma_s is less than or equal to 0
"""
if fyk < 0:
raise ValueError(f'fyk={fyk} cannot be less than 0')
if gamma_s <= 0:
raise ValueError(f'gamma_s={gamma_s} must be larger than 0')
return fyk / gamma_s


def reinforcement_duct_props(
fyk: float,
ductility_class: t.Literal['A', 'B', 'C', 'D'],
) -> t.Dict[str, float]:
"""Return a dict with the minimum characteristic ductility properties for
reinforcement ductility class.
fib Model Code 2010, Sec. 5.2.5.4
Args:
fyk (float): The characteristic yield strength.
ductility_class (Literal['A', 'B', 'C', 'D']): The reinforcement
ductility class designation.
Returns:
Dict[str, float]: A dict with the characteristik strain value at the
ultimate stress level (epsuk), and the characteristic ultimate stress
(ftk).
"""
duct_props = DUCTILITY_CLASSES.get(ductility_class.upper(), None)
if duct_props is None:
raise ValueError(
'The no properties was found for the provided ductility class '
f'({ductility_class}).'
)
return {
'epsuk': duct_props['epsuk'],
'ftk': duct_props['k'] * fyk,
}
3 changes: 2 additions & 1 deletion structuralcodes/materials/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
"""Main entry point for materials."""

from . import concrete
from . import concrete, reinforcement

__all__ = [
'concrete',
'reinforcement',
]
81 changes: 81 additions & 0 deletions structuralcodes/materials/reinforcement/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
"""Reinforcement material."""

import typing as t

from structuralcodes.codes import _use_design_code

from ._reinforcement import Reinforcement
from ._reinforcementEC2_2004 import ReinforcementEC2_2004
from ._reinforcementEC2_2023 import ReinforcementEC2_2023
from ._reinforcementMC2010 import ReinforcementMC2010

__all__ = [
'create_reinforcement',
'Reinforcement',
'ReinforcementMC2010',
'ReinforcementEC2_2004',
'ReinforcementEC2_2023',
]

REINFORCEMENTS: t.Dict[str, Reinforcement] = {
'fib Model Code 2010': ReinforcementMC2010,
'EUROCODE 2 1992-1-1:2004': ReinforcementEC2_2004,
'EUROCODE 2 1992-1-1:2023': ReinforcementEC2_2023,
}


def create_reinforcement(
fyk: float,
Es: float,
ftk: float,
epsuk: float,
name: t.Optional[str] = None,
density: float = 7850,
design_code: t.Optional[str] = None,
) -> t.Optional[Reinforcement]:
"""A factory function to create the correct type of reinforcement based on
the desired design code.
Args:
fyk (float): Characteristic yield strength in MPa.
Es (float): The Young's modulus in MPa.
ftk (float): Characteristic ultimate strength in MPa.
epsuk (float): The characteristik strain at the ultimate stress level.
Keyword Args:
density (float): Density of the material in kg/m3 (default: 7850)
design_code (str): Optional string (default: None) indicating the
desired standard. If None (default) the globally used design
standard will be adopted. Otherwise the design standard specified
will be used for the instance of the material.
Raises:
ValueError: if the design code is not valid or does not cover
reinforcement as a material.
"""
# Get the code from the global variable
_code = _use_design_code(design_code)

# Check if the code is a proper code for reinforcement
code = None
if _code is not None and 'reinforcement' in _code.__materials__:
code = _code
if code is None:
raise ValueError(
'The design code is not set, either use '
'structuralcodes.code.set_designcode, or provide a valid '
'string in the function.'
)

# Create the proper reinforcement object
current_reinforcement = REINFORCEMENTS.get(code.__title__, None)
if current_reinforcement is not None:
return current_reinforcement(
fyk=fyk,
Es=Es,
name=name,
density=density,
ftk=ftk,
epsuk=epsuk,
)
return None
Loading

0 comments on commit cd6bb81

Please sign in to comment.