Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
2e70179
Draft initial structure for the concrete class
mortenengen Dec 13, 2022
b8f67bb
Update docstring of base material
mortenengen Dec 13, 2022
c299dcc
minimum reinforcement areas functions
DanielGMorenaFhecor Dec 15, 2022
59a04f5
raise ValueError test functions for min area
DanielGMorenaFhecor Dec 27, 2022
b7167aa
crack_min_steel_without_direct_calculation
DanielGMorenaFhecor Jan 12, 2023
7189d31
Commit
DanielGMorenaFhecor Jan 12, 2023
4a0fcfb
crack without direct calculation tests
DanielGMorenaFhecor Jan 12, 2023
84c0140
adjusted bond strength
DanielGMorenaFhecor Jan 12, 2023
e0f1baa
hc_eff_concrete_tension formulation and testing
DanielGMorenaFhecor Jan 12, 2023
f2cbb49
requiremets.txt updated
DanielGMorenaFhecor Jan 12, 2023
333dcbe
rho_p_eff
DanielGMorenaFhecor Jan 12, 2023
59f1198
kt load duration
DanielGMorenaFhecor Jan 12, 2023
34d85d2
strain diff formula
DanielGMorenaFhecor Jan 12, 2023
a8ab129
chapter completed
DanielGMorenaFhecor Jan 13, 2023
ce4e432
imports and renamed functions
DanielGMorenaFhecor Jan 13, 2023
938c0f5
removed duplicate file
DanielGMorenaFhecor Jan 13, 2023
6ba6dc9
removed testing file
DanielGMorenaFhecor Jan 13, 2023
a9c9263
test renaming and docstring corrections
DanielGMorenaFhecor Jan 16, 2023
50c65b7
pull from upstream
DanielGMorenaFhecor Feb 8, 2023
ea3552b
Merge branch 'dev' of https://github.com/fib-international/structural…
DanielGMorenaFhecor Mar 9, 2023
4fd8b7e
230309 requested changes applied
DanielGMorenaFhecor Mar 9, 2023
1cffa61
small lint fixes
DanielGMorenaFhecor Mar 9, 2023
b483d40
vscode config updated
DanielGMorenaFhecor Mar 9, 2023
e9d953d
Merge branch 'dev' of https://github.com/fib-international/structural…
DanielGMorenaFhecor May 26, 2023
182e538
Merge branch 'dev' of https://github.com/fib-international/structural…
DanielGMorenaFhecor Dec 18, 2023
e509fb9
Merge branch 'dev' of https://github.com/fib-international/structural…
DanielGMorenaFhecor Mar 4, 2024
d57f945
Merge branch 'dev' of https://github.com/fib-international/structural…
DanielGMorenaFhecor Apr 4, 2024
bc049e4
Merge branch 'dev' of https://github.com/DanielGMorenaFhecor/structur…
DanielGMorenaFhecor Jul 30, 2024
17cdf47
Merge branch 'dev' of https://github.com/fib-international/structural…
DanielGMorenaFhecor Aug 20, 2024
33ec3ee
Merge branch 'dev' of https://github.com/fib-international/structural…
Sep 25, 2024
3bdaed3
Merge remote-tracking branch 'upstream/dev' into dev
Dec 2, 2024
57d3a77
Merge branch 'dev' of https://github.com/fib-international/structural…
MestreCarlos Feb 4, 2025
a50b943
Merge branch 'dev' of https://github.com/fib-international/structural…
MestreCarlos May 22, 2025
b2f8b03
additional methods for control of cracking
MestreCarlos May 22, 2025
eeea6c2
fix linting
MestreCarlos May 22, 2025
217df64
fix linting
MestreCarlos May 22, 2025
a577284
fix checks
MestreCarlos May 22, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
225 changes: 224 additions & 1 deletion structuralcodes/codes/ec2_2023/_section9_sls.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def As_min_y(
fyk (float): Characteristic yield strength of steel in MPa.

Returns:
tuple(float, float): The minimum tensile reinforcement to avoid
Tuple(float, float): The minimum tensile reinforcement to avoid
yielding of steel on the most tensioned fibre of the rectangle
(As_min_y1) in cm2, and the minimum tensile reinforcement to avoid
yielding of steel on the most tensioned fibre of the rectangle
Expand Down Expand Up @@ -323,3 +323,226 @@ def delta_simpl(
kS = 455 * rho_l**2 - 35 * rho_l + 1.6
kI = zeta * Ig_Icr + (1 - zeta)
return kI * (delta_loads + kS * delta_shr)


def rho_p_eff(As: float, xi1: float, Ap: float, Ac_eff: float) -> float:
"""Effective bond ratio between areas.

EN 1992-1-1:2023, Eq. (9.12).

Args:
As (float): Steel area in mm2.
xi1 (float): The adjusted ratio of bond according to expression (9.6).
Ap (float): The area in mm2 of post-tensioned tendons in ac_eff.
Ac_eff (float): Effective area of concrete in tension surrounding the
reinforcement or prestressing tendons of depth hc_eff.

Returns:
float: With the retio between areas.

Raises:
ValueError: If any of As, xi1, Ap or Ac_eff is less than 0.
"""
if As < 0:
raise ValueError(f'As={As} cannot be less than 0')
if xi1 < 0:
raise ValueError(f'xi1={xi1} cannot be less than 0')
if Ap < 0:
raise ValueError(f'Ap={Ap} cannot be less than 0')
if Ac_eff < 0:
raise ValueError(f'Ac_eff={Ac_eff} cannot be less than 0')

return (As + xi1**2 * Ap) / Ac_eff


def xi1(xi: float, phi_p: float, phi_s: float) -> float:
"""Computes the adjusted ratio of bond strength taking into account
the different diameters of prestressing and reinforcing steel.

EN 1992-1-1:2023, Eq. (9.6).

Args:
xi (float): ratio of bond strength of prestressing and reinforcing
steel, according to Table 10.1 in 10.3(2)
phi_p (float): largest bar diameter in mm of reinforcing steel.
Equal to 0 if only reinforced steel is used in control cracking.
phi_s (float): equivalent diameter in mm of tendon acoording
to 9.19.

Returns:
float: With the value of the ratio.

Raises:
ValueError: If diameters phi_s or phi_p are lower than 0. If ratio of
bond strength xi is less than 0.15 or larger than 0.8.
"""
if phi_p == 0:
return 0
if phi_p < 0:
raise ValueError(f'phi_p={phi_p} cannot be less than 0')
if phi_s < 0:
raise ValueError(f'phi_s={phi_s} cannot be less than 0')
if xi < 0.15:
raise ValueError(f'The minimum value for xi={xi} is 0.15')
if xi > 0.8:
raise ValueError(f'The maximum value for xi={xi} is 0.8')

return ((xi * phi_s / phi_p) ** 0.5) if phi_s > 0 else xi**0.5


def _lower_circular_segment_area(d, x):
"""Calculates the area of the lower circular segment cut by a horizontal
line at a height `x` from the top of the circle.

Args:
d (float): Diameter of the circle. Must be greater than 0.
x (float): Vertical distance from the top edge of the circle to the
horizontal chord. Must satisfy 0 < x < d.

Returns:
float: Area of the circular segment below the chord.

Raises:
ValueError: If `x` is not in the range (0, d).
"""
if x < 0 or x > d:
raise ValueError(
'x must be between 0 and d (the diameter of the circle).'
)

r = d / 2
y = r - x # vertical distance from the center to the chord
theta = math.acos(y / r) # central angle in radians
upper_area = r**2 * theta - y * math.sqrt(r**2 - y**2)
return r**2 * math.pi - upper_area # lower area


def Ac_eff( # noqa: PLR0912, PLR0915
x: float,
ay,
phi,
h: float = None,
b: float = None,
diameter: float = None,
n: int = 1,
sy: float = None,
loading_type: str = 'bending',
section_type: str = 'rectangular',
bar_spacing: float = None,
ax: float = None,
) -> Tuple[float, float]:
"""Returns the effective area of concrete in tension surrounding the
reinforcement or prestressing tendons.

EN 1992-1-1:2023, Figure 9.3 (a to f).

Args:
x (float): distance in mm to the zero tensile stress line.
ay (float): distance from extreme fibre of concrete to centroid of
reinforcement bars in mm.
phi (float): diameter of the tensioned bars in mm.
h (float): total heigth of the rectangular section in mm.
b (float): total width of the rectangular section in mm.
diameter (float): diameter of the circular section in mm.
n (int): Number of layers. Default is 1.
sy (float): Spacing of the layers in mm. Default is None.
loading_type (str): Type of loading. Default is 'bending'. Can be
bending' or 'tension'.
section_type (str): Type of section. Default is 'rectangular'.
Can be 'rectangular' or 'circular'.
bar_spacing (float): Spacing of the bars in mm. Default is less than 10
times phi.
ax (float): distance from extreme fibre of concrete to centroid of
reinforcement bars in mm (Figure 9.3 f).

Returns:
Tuple: (Ac_eff, hc_eff)
Ac_eff (float): The effective area in mm2.
hc_eff (float): The effective height in mm.

Raises:
ValueError: If any of h, ay or x is lower than zero.
ValueError: If x is greater than h.
ValueError: If ay is greater than h.
ValueError: If phi is lower than zero.
ValueError: If n is lower than 1.
ValueError: If sy is None and n > 1.
ValueError: If loading_type is not 'bending' or 'tension'.
ValueError: If section_type is not 'rectangular' or 'circular'.
ValueError: If missing a parameter gor rectangular or circular section.
"""
if section_type not in ['rectangular', 'circular']:
raise ValueError(
(
f'section_type={section_type} not implemented. '
'It should be "rectangular" or "circular for this method"'
)
)
if section_type == 'rectangular':
if b is None:
raise ValueError('b must be provided for rectangular sections')
if h is None:
raise ValueError('h must be provided for rectangular sections')
if h < 0:
raise ValueError(f'h={h} cannot be less than 0')
if b < 0:
raise ValueError(f'b={b} cannot be less than 0')
if ay > h:
raise ValueError(f'ay={ay} cannot be larger than h={h}')
if x > h:
raise ValueError(f'x={x} cannot be larger than h={h}')
bc_eff = (
b if bar_spacing is None else min(b, 10 * phi / bar_spacing * b)
)
if section_type == 'circular':
if diameter is None:
raise ValueError('diameter must be provided for circular sections')
if diameter < 0:
raise ValueError(f'diameter={diameter} cannot be less than 0')
if ay > diameter:
raise ValueError(f'ay={ay} cannot be larger than D={diameter}')
if x > diameter:
raise ValueError(f'x={x} cannot be larger than D={diameter}')

if ay < 0:
raise ValueError(f'ay={ay} cannot be less than 0')
if x < 0:
raise ValueError(f'x={x} cannot be less than zero')
if phi < 0:
raise ValueError(f'phi={phi} cannot be less than 0')
if n < 1:
raise ValueError(f'n={n} cannot be less than 1')
if sy is None and n > 1:
raise ValueError(f'sy cannot be None if n={n} > 1')
if loading_type not in ['bending', 'tension']:
raise ValueError(
f'loading_type={loading_type} is not valid. It should be "bending"'
'or "tension"'
)

if section_type == 'rectangular' and loading_type == 'bending':
if n == 1:
hc_eff = min(ay + 5 * phi, 10 * phi, 3.5 * ay, h - x, h / 2)
else:
hc_eff = min(
min(ay + 5 * phi, 10 * phi, 3.5 * ay) + (n - 1) * sy,
h - x,
h / 2,
)
Ac_eff = bc_eff * hc_eff
if section_type == 'circular' and loading_type == 'bending':
hc_eff = min(ay + 5 * phi, 10 * phi, 3.5 * ay)
Ac_eff = _lower_circular_segment_area(
diameter, x
) - _lower_circular_segment_area(
diameter - hc_eff * 2, max(0, x - hc_eff)
)
if section_type == 'rectangular' and loading_type == 'tension': # d,e,f
hc_eff = min(ay + 5 * phi, 10 * phi, 3.5 * ay, h / 2)
if ax is not None: # f
bc_eff = min(ax + 5 * phi, 10 * phi, 3.5 * ax, b / 2)
Ac_eff = h * b - (b - 2 * bc_eff) * (h - 2 * hc_eff)
else: # d,e
Ac_eff = bc_eff * hc_eff

return (Ac_eff, hc_eff)
110 changes: 110 additions & 0 deletions tests/test_ec2_2023/test_ec2_2023_section9_sls.py
Original file line number Diff line number Diff line change
Expand Up @@ -469,3 +469,113 @@ def test_delta_simpl(
expected,
rel_tol=0.01,
)


@pytest.mark.parametrize(
'As, xi1, Ap, Ac_eff, expected',
[
(495.9, 0, 0, 126000, 0.00394),
(319.2, 0, 319.2, 126000, 0.00253),
(493.9, 0.89, 493.9, 126000, 0.00702),
(205.1, 0.489, 205.1, 126000, 0.00202),
(806.2, 0.707, 0, 126000, 0.0064),
],
)
def test_rho_p_eff(As, xi1, Ap, Ac_eff, expected):
"""Test for rho_p_eff."""
result = _section9_sls.rho_p_eff(As, xi1, Ap, Ac_eff)
assert math.isclose(result, expected, rel_tol=0.01)


@pytest.mark.parametrize(
'xi, phi_p, phi_s, expected',
[
(0.8, 20, 0, 0.894427),
(0.6, 25, 10, 0.489898),
(0.5, 10, 10, 0.707107),
(0.5, 10, 10, 0.707107),
(0.5, 10, 10, 0.707107),
],
)
def test_xi1(xi, phi_p, phi_s, expected):
"""Test for xi1."""
result = _section9_sls.xi1(xi, phi_p, phi_s)
assert math.isclose(result, expected, rel_tol=0.01)


@pytest.mark.parametrize(
'd, x, expected', [(500, 100, 168394), (114, 0, 10207), (300, 300, 0)]
)
def test__lower_circular_segment_area(d, x, expected):
"""Test for _lower_circular_segment_area."""
result = _section9_sls._lower_circular_segment_area(d, x)
assert math.isclose(result, expected, rel_tol=0.01)


@pytest.mark.parametrize(
'x, ay, phi, h, b, diameter, n, sy, loading_type, section_type,'
'bar_spacing, ax, expected',
[
(
100,
68,
25,
400,
400,
None,
1,
None,
'bending',
'rectangular',
None,
None,
77200,
),
(
100,
68,
25,
None,
None,
500,
1,
None,
'bending',
'circular',
None,
None,
158187,
),
],
)
def test_Ac_eff(
x,
ay,
phi,
h,
b,
diameter,
n,
sy,
loading_type,
section_type,
bar_spacing,
ax,
expected,
):
"""Test for Ac_eff."""
result = _section9_sls.Ac_eff(
x,
ay,
phi,
h,
b,
diameter,
n,
sy,
loading_type,
section_type,
bar_spacing,
ax,
)
assert math.isclose(result[0], expected, rel_tol=0.01)