"""This module provides the beam class implementation for the ``CP02`` model in
the BNSM layer.
"""
# Imports from installed packages
import numpy as np
from typing import Tuple, List
# Imports from bnsm base library
from ..cp01.beam import Beam as BeamCP01
# Imports from utils library
from ....utils.units import MPa
from ....utils.misc import round_list
[docs]
class Beam(BeamCP01):
"""Beam implementation for the ``CP02`` model.
This class directly uses the behaviour defined in ``BeamCP01``,
but overrides the plastic hinge material definition for rotational
degrees of freedoms based on the PhD Thesis of Serkan Hasanoglu.
See Also
--------
:class:`~simdesign.rcmrf.bnsm.cp01.beam.Beam`
CP01 beam model definition extended by this class.
"""
def _get_mz_mat_inputs(self) -> Tuple[List[str | float | int],
List[str | float | int]]:
"""Retrieves the material inputs defining the flexural behaviour
around local-z for the plastic hinge.
Returns
-------
mat_inputs_i : List[str | float | int]
HystereticSM material model inputs for hinge at the start section.
mat_inputs_j : List[str | float | int]
HystereticSM material model inputs for hinge at the end section.
References
---------
Hasanoglu, S. and O'Reilly G. J. (2027). Calibration of cyclic
backbone parameters for numerical modelling and hysteretic energy
capacity of ductile reinforced concrete members.
"""
h = self.design.h
ln = self.clear_length # Clear length, without the joint offsets
fc_mpa = self.design.fc_q / MPa
fsyl_mpa = self.design.fsyl_q / MPa
dbh = self.design.dbh_q
dbl = self.design.dbl_b1_q
cover = self.design.cover_q
rhol = self.rhol_q
rhoh = self.rhoh_y_q
ls = ln / 2 # Shear span length
niu = 0.0 # Axial load ratio, assuming beams do not have any
dd = h - cover - dbh - 0.5 * dbl
rSsD = ls / dd # shear span to effective depth ratio
# Compute yield moments in positive and negative directions at both
# end sections of the beam (i and j) - Panagiotakos and Fardis (2001)
My_pos, _, _ = self._get_my_phiy('positive')
My_neg, _, _ = self._get_my_phiy('negative')
# Capping moment capacities in positive and negative directions
Mc_My = (1.08 ** niu) * (1.38 ** (10*rhol)) * (1.14 ** (0.1*rSsD))
Mc_pos = Mc_My * My_pos
Mc_neg = Mc_My * My_neg
# Ultimate moment capacities in positive and negative directions
Mu_Mc = (0.91 ** (0.01*fc_mpa)) * (0.8 ** (0.1*rSsD))
Mu_pos = Mu_Mc * Mc_pos
Mu_neg = Mu_Mc * Mc_neg
# Zero moment values in positive and negative directions
M0_pos = 0.1 * Mu_pos
M0_neg = 0.1 * Mu_neg
# Yield rotation capacities in positive and negative directions
EI_ratio = np.clip(0.08 * (1.25 ** (10*niu)) * (1.2 ** rSsD), 0.2, 0.8)
EI_gross = self.Ecm_q * self.design.Iz
EIy = EI_gross * EI_ratio
theta_y_pos = My_pos * ls / (3 * EIy)
theta_y_neg = My_neg * ls / (3 * EIy)
# Plastic rotation capacities before capping
theta_cap_pl_sym = 0.009 * (0.25 ** (0.01*fc_mpa)) * (0.23 ** niu) * \
(2.17 ** (100*rhol))
# Non-symmetric beam section - Haselton et al. 2016 - Equation 7
# (max(0.01, w_compression) / max(0.01, w_tension)) ** 0.225
w_top = np.maximum(0.01, fsyl_mpa * self.rhol_top_q / fc_mpa)
w_bot = np.maximum(0.01, fsyl_mpa * self.rhol_bot_q / fc_mpa)
# Negative: top rebar in tension, bottom rebar in compression
theta_cap_pl_neg = ((w_bot / w_top) ** 0.225) * theta_cap_pl_sym
# Positive: bottom rebar in tension, top rebar in compression
theta_cap_pl_pos = ((w_top / w_bot) ** 0.225) * theta_cap_pl_sym
# Post-capping rotation capacity
theta_pc_pos: np.ndarray = 0.01 * (0.07 ** niu) * \
(1.78 ** (100*rhoh)) * (1.18 ** (0.01*fsyl_mpa))
theta_pc_neg = theta_pc_pos.copy()
# Post-ultimate rotation capacity
theta_pu_pos = 0.0023 * (1.96 ** (0.1*fc_mpa)) * (2.74 ** (100*rhoh))
theta_pu_pos = np.minimum(theta_pu_pos, 4*theta_pc_pos)
theta_pu_neg = theta_pu_pos.copy()
# Positive backbone (HystereticSM material)
moment_1_pos = My_pos
moment_2_pos = Mc_pos
moment_3_pos = Mu_pos
moment_4_pos = M0_pos
theta_1_pos = theta_y_pos
theta_2_pos = theta_1_pos + theta_cap_pl_pos
theta_3_pos = theta_2_pos + theta_pc_pos
theta_4_pos = theta_3_pos + theta_pu_pos
# Negative backbone (HystereticSM material)
moment_1_neg = My_neg
moment_2_neg = Mc_neg
moment_3_neg = Mu_neg
moment_4_neg = M0_neg
theta_1_neg = theta_y_neg
theta_2_neg = theta_1_neg + theta_cap_pl_neg
theta_3_neg = theta_2_neg + theta_pc_neg
theta_4_neg = theta_3_neg + theta_pu_neg
# Pinching factor for strain (or deformation) during reloading
pinchx = 1.0
# Pinching factor for stress (or force) during reloading
pinchy = 0.95
# Damage due to ductility: D1(mu-1)
damage1 = 0.0
# Damage due to energy: D2(Eii/Eult)
damage2 = 0.0
# Power used to determine the degraded unloading stiffness
beta = 0.2
# The negative ones are based on top (compression) reinforcement
# The positive ones are based on bottom (tension) renforcement
hinge_i_mat_inputs = [
'HystereticSM', self.mz_i_mat_tag,
moment_1_pos[0], theta_1_pos[0],
moment_2_pos[0], theta_2_pos[0],
moment_3_pos[0], theta_3_pos[0],
moment_4_pos[0], theta_4_pos[0],
-moment_1_neg[0], -theta_1_neg[0],
-moment_2_neg[0], -theta_2_neg[0],
-moment_3_neg[0], -theta_3_neg[0],
-moment_4_neg[0], -theta_4_neg[0],
pinchx, pinchy, damage1, damage2, beta
]
hinge_j_mat_inputs = [
'HystereticSM', self.mz_j_mat_tag,
moment_1_pos[-1], theta_1_pos[-1],
moment_2_pos[-1], theta_2_pos[-1],
moment_3_pos[-1], theta_3_pos[-1],
moment_4_pos[-1], theta_4_pos[-1],
-moment_1_neg[-1], -theta_1_neg[-1],
-moment_2_neg[-1], -theta_2_neg[-1],
-moment_3_neg[-1], -theta_3_neg[-1],
-moment_4_neg[-1], -theta_4_neg[-1],
pinchx, pinchy, damage1, damage2, beta
]
# Rounding to precision
hinge_i_mat_inputs = round_list(hinge_i_mat_inputs)
hinge_j_mat_inputs = round_list(hinge_j_mat_inputs)
return hinge_i_mat_inputs, hinge_j_mat_inputs