"""This module provides the column class implementation for the ``CP02`` model
in the BNSM layer.
"""
# Imports from installed packages
import numpy as np
from typing import Literal, List
# Imports from bnsm base library
from ..cp01.column import Column as ColumnCP01
# Imports from utils library
from ....utils.units import MPa
from ....utils.misc import round_list
[docs]
class Column(ColumnCP01):
"""Column implementation for the ``CP02`` model.
This class directly uses the behaviour defined in ``ColumnCP01``,
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.column.Column`
CP01 column model definition extended by this class.
"""
def _get_yield_rotation(self, axis: Literal['x', 'y']) -> float:
"""Gets the yield rotation of the flexural plastic hinge.
Parameters
----------
axis : Literal['x', 'y']
The local axis considered for the calculations.
Returns
-------
float
Yield rotation ``My·Ls/(3·EIy)`` around `axis`, with the
effective stiffness ratio of Hasanoglu and O'Reilly. It is used
also to define the drift limits of the shear failure curve.
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.
"""
if axis == 'x':
h = self.design.by # Section height, along y
EI_gross = self.Ecm_q * self.design.Ix
elif axis == 'y':
h = self.design.bx # Section height, along x
EI_gross = self.Ecm_q * self.design.Iy
# Axial load ratio, compressive axial load (+)
Nu = max(-self.axial_force, 0)
niu = Nu / (self.design.Ag * self.design.fc_q)
# Shear span to effective depth ratio
dd = (h - self.design.cover_q - self.design.dbh_q
- 0.5 * self.design.dbl_cor_q)
Ls = self.clear_length / 2
rSsD = Ls / dd
# Yield moment
My = self._get_rot_hinge_props(axis)[1]
# Effective flexural rigidity at yield
EI_ratio = np.clip(0.08 * (1.25 ** (10*niu)) * (1.2 ** rSsD), 0.2, 0.8)
EIy = EI_gross * EI_ratio
return My * Ls / (3 * EIy)
def _get_rot_hinge_mat_inputs(self, axis: Literal['x', 'y']
) -> List[int | float | str]:
"""Gets the plastic hinge material inputs for given axis.
Parameters
----------
axis : Literal['x', 'y']
The local axis considered for the calculations.
Returns
-------
rot_mat_inputs : List[int | float | str]
HystereticSM material model inputs for the plastic hinge describing
behaviour in flexure around `axis`.
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.
"""
if axis == 'x':
# The integer tag for the material describing flexure behaviour
# around local -x (corresponds to z in ops)
flex_mat_tag = self.mz_mat_tag
# Section height
h = self.design.by # along y
# Transverse reinforcement ratio
rhoh = self.rhoh_y_q # Stirrups are along -y axis
elif axis == 'y':
# The integer tag for the material describing flexure behaviour
# around local -y axis (corresponds to y in ops)
flex_mat_tag = self.my_mat_tag
# Section height
h = self.design.bx # along x
# Transverse reinforcement ratio
rhoh = self.rhoh_x_q # Stirrups are along -x axis
# Concrete compressive strength in base units
fc = self.design.fc_q
# Concrete compressive strength in MPa
fc_mpa = self.design.fc_q / MPa # convert to MPa
# Longitudinal steel yield strength in MPa
fsyl_mpa = self.design.fsyl_q / MPa # convert to MPa
# Concrete cover
cover = self.design.cover_q
# Diameter of corner reinforcement
dbl_cor = self.design.dbl_cor_q
# Horizontal (stirrup) reinforcement diameter
dbh = self.design.dbh_q
# Longitudinal reinforcement ratio
rhol = self.rhol_q
# Compressive axial load (+)
Nu = max(-self.axial_force, 0)
# Axial load ratio
niu = Nu / (self.design.Ag * fc)
# Distance from top fiber to bottom rebars
dd = h - cover - dbh - 0.5 * dbl_cor
# Clear length of column, without the rigid joint offsets
Ln = self.clear_length
# Shear span, assuming equal to 50% of the free length of the element
Ls = Ln / 2
# Shear span to effective depth ratio
rSsD = Ls / dd
# Yield moment
My = self._get_rot_hinge_props(axis)[1]
# Capping moment capacity
Mc_My = (1.08 ** niu) * (1.38 ** (10*rhol)) * (1.14 ** (0.1*rSsD))
Mc = Mc_My * My
# Ultimate moment capacity
Mu_Mc = (0.91 ** (0.01*fc_mpa)) * (0.8 ** (0.1*rSsD))
Mu = Mu_Mc * Mc
# Yield rotation capacity
theta_y = self._get_yield_rotation(axis)
# Plastic rotation capacity
theta_cap_pl = 0.009 * (0.25 ** (0.01*fc_mpa)) * (0.23 ** niu) * \
(2.17 ** (100*rhol))
# Post-capping rotation capacity
theta_pc = 0.01 * (0.07 ** niu) * (1.78 ** (100*rhoh)) * \
(1.18 ** (0.01*fsyl_mpa))
# Post-ultimate rotation capacity
theta_pu = 0.0023 * (1.96 ** (0.1*fc_mpa)) * (2.74 ** (100*rhoh))
theta_pu = np.minimum(theta_pu, 4*theta_pc)
# Cyclic backbone (HystereticSM material)
moment_1 = My
moment_2 = Mc
moment_3 = Mu
moment_4 = 0.1 * Mu
theta_1 = theta_y
theta_2 = theta_1 + theta_cap_pl
theta_3 = theta_2 + theta_pc
theta_4 = theta_3 + theta_pu
# 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.5
# Material inputs other than tag and type
rot_mat_inputs = [
'HystereticSM',
flex_mat_tag,
moment_1, theta_1,
moment_2, theta_2,
moment_3, theta_3,
moment_4, theta_4,
-moment_1, -theta_1,
-moment_2, -theta_2,
-moment_3, -theta_3,
-moment_4, -theta_4,
pinchx, pinchy, damage1, damage2, beta
]
# Rounding to precision
rot_mat_inputs = round_list(rot_mat_inputs)
return rot_mat_inputs