Source code for simdesign.rcmrf.bdim.eu_cdm.column

"""This module provides the column class implementation for the ``eu_cdm``
design class in the BDIM layer.
"""
# Imports from installed packages
import numpy as np
from typing import Tuple

# Imports from the design class (eu_cdm) library
from .materials import Steel, Concrete

# Imports from bdim base library
from ..baselib.column import ColumnBase

# Imports from units library
from ....utils.units import MPa, m

ECONOMIC_MU: float = 0.25
"""Maximum mu value considered for the economic column design."""
MAX_NIU = 1.0
"""Maximum allowed value of axial load ratio."""
TAU_C_VECT = np.array([0.5, 0.6, 0.65, 0.75, 0.85, 0.90, 1.00, 1.10, 1.15]
                      ) * MPa
"""Vector of allowable shear stresses that carried by the concrete or
vector of the design shear strength values of concrete."""
TAU_MAX_VECT = np.array([2.4, 3.2, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0]) * MPa
"""Vector of allowable shear stresses that can be carried by
the column section."""
FCK_VECT = np.array([12, 16, 20, 25, 30, 35, 40, 45, 50]) * MPa
"""Vector of characteristic concrete compressive strength values."""
MODULAR_RATIO = 15
"""Assumed steel to concrete elastic modular ratio for reinf. computation."""
BETA_FC_VECTOR = [1.00, 0.93, 0.88, 0.88, 0.93]
"""Stress block coefficients for different axial load ratio (in REBAP 1983)."""
NIU_VECTOR = [0.40, 0.50, 0.60, 0.70, 0.85]
"""Axial load ratio corresponding to each stress block coefficient."""


[docs] class Column(ColumnBase): """Column implementation for design class ``eu_cdm``. This class extends ``ColumnBase`` by narrowing the attribute types and overriding design methods per REBAP (1983). Attributes ---------- steel : ~simdesign.rcmrf.bdim.eu_cdm.materials.Steel Steel material assigned to the column. concrete : ~simdesign.rcmrf.bdim.eu_cdm.materials.Concrete Concrete material assigned to the column. See Also -------- :class:`~bdim.baselib.column.ColumnBase` Base class defining the core behaviour and configuration. References ---------- REBAP (1983). Regulamento de Estruturas de Betão Armado e Pré-Esforçado. Decreto-Lei N.° 349-C/83, Lisbon, Portugal. d'Arga e Lima, J., Monteiro, V., Mun, M. (2005). Betão armado: esforços normais e de flexão: REBAP-83. Laboratório Nacional de Engenharia Civil, Lisboa. """ steel: Steel concrete: Concrete @property def rhol_max(self) -> float: """ Returns ------- float Maximum longitudinal reinforcement ratio. """ # Art 90.2 in REBAP (1983) return 0.04 @property def rhol_min(self) -> float: """ Returns ------- float Minimum longitudinal reinforcement ratio. """ return 0.01
[docs] def verify_section_adequacy(self) -> None: """Verify the adequacy of section dimensions for design forces. Notes ----- The original code does not enforce checks for axial load ratio. """ # Distance of long. bars in tens. to extreme conc. fibers in compr. dx = 0.9 * self.bx dy = 0.9 * self.by # Maximum axial load ratio max_niu = max( self.envelope_forces.N1_pos, self.envelope_forces.N9_pos, abs(self.envelope_forces.N1_neg), abs(self.envelope_forces.N9_neg), ) / (self.Ag * self.fcd) # Max. normalised moment max_mu_x = max( self.envelope_forces.Mx1_pos, self.envelope_forces.Mx9_pos, abs(self.envelope_forces.Mx1_neg), abs(self.envelope_forces.Mx9_neg), ) / ((self.bx * self.by**2) * self.fcd) max_mu_y = max( self.envelope_forces.My1_pos, self.envelope_forces.My9_pos, abs(self.envelope_forces.My1_neg), abs(self.envelope_forces.My9_neg), ) / ((self.by * self.bx**2) * self.fcd) # Max. shear stress max_tau_x = max( self.envelope_forces.Vx1, self.envelope_forces.Vx9 ) / (self.by * dx) max_tau_y = max( self.envelope_forces.Vy1, self.envelope_forces.Vy9 ) / (self.bx * dy) # Allowable shear stress that can be carried by the beam tau_max = np.interp(self.concrete.fck_cube, FCK_VECT, TAU_MAX_VECT) # Verify the adequacy of the section dimensions if max_mu_y > ECONOMIC_MU or max_tau_x > tau_max: # Need to increase dimension parallel to global-x self.ok_x = False else: self.ok_x = True if max_mu_x > ECONOMIC_MU or max_tau_y > tau_max: # Need to increase dimension parallel to global-y self.ok_y = False else: self.ok_y = True if max_niu > MAX_NIU and self.ok_x and self.ok_y: # May increase both dimensions or only one of them self.ok_x = False self.ok_y = False
[docs] def compute_required_longitudinal_reinforcement(self) -> None: """Compute the required longitudinal reinforcement for design forces. """ # Initial longitudinal reinforcement area Aslx_req = 0.000226195 * m**2 # 2 bars with diam of 12mm Asly_req = 0.000226195 * m**2 # 2 bars with diam of 12mm for force in self.design_forces: # Dimensionless design force quantities niu_1 = (-force.N1) / (self.Ag * self.fcd) niu_9 = (-force.N9) / (self.Ag * self.fcd) mu_x1 = abs(force.Mx1) / ((self.bx * self.by**2) * self.fcd) mu_y1 = abs(force.My1) / ((self.by * self.bx**2) * self.fcd) mu_x9 = abs(force.Mx9) / ((self.bx * self.by**2) * self.fcd) mu_y9 = abs(force.My9) / ((self.by * self.bx**2) * self.fcd) # Determine the required longitudinal reinforcement ratio beta1 = np.interp(niu_1, NIU_VECTOR, BETA_FC_VECTOR) beta9 = np.interp(niu_9, NIU_VECTOR, BETA_FC_VECTOR) # Should we use cover here or assume ratio as 0.1? lambda_x = 0.5 - self.cover / self.bx lambda_y = 0.5 - self.cover / self.by niuc_1 = niu_1 - 0.85 niuc_9 = niu_9 - 0.85 # Start section if niu_1 < 0.0: # Axial force is tensile # REBAP (1983), pp. 48, eqn. 22 omega_x1 = mu_x1 / (lambda_y * beta1) - niu_1 omega_y1 = mu_y1 / (lambda_x * beta1) - niu_1 elif niu_1 <= 0.85: omega_x1 = (mu_x1 + 0.55 * niu_1 * niuc_1) / (lambda_y * beta1) omega_y1 = (mu_y1 + 0.55 * niu_1 * niuc_1) / (lambda_x * beta1) else: omega_x1 = mu_x1 / (lambda_y * beta1) + niuc_1 omega_y1 = mu_y1 / (lambda_x * beta1) + niuc_1 # End section if niu_9 < 0.0: # Axial force is tensile # REBAP (1983), pp. 48, eqn. 22 omega_x9 = mu_x9 / (lambda_y * beta9) - niu_9 omega_y9 = mu_y9 / (lambda_x * beta9) - niu_9 elif niu_9 <= 0.85: omega_x9 = (mu_x9 + 0.55 * niu_9 * niuc_9) / (lambda_y * beta9) omega_y9 = (mu_y9 + 0.55 * niu_9 * niuc_9) / (lambda_x * beta9) else: omega_x9 = mu_x9 / (lambda_y * beta9) + niuc_9 omega_y9 = mu_y9 / (lambda_x * beta9) + niuc_9 # Compute required reinforcement area on two sides omega_x = max(omega_x1, omega_x9) omega_y = max(omega_y1, omega_y9) Aslx = (0.5 * omega_x * self.Ag * self.fcd / self.fsyd) Asly = (0.5 * omega_y * self.Ag * self.fcd / self.fsyd) # Update the required reinforcement area Aslx_req = max(Aslx_req, Aslx) Asly_req = max(Asly_req, Asly) # Save the required longitudinal reinforcement area self.Aslx_req = Aslx_req self.Asly_req = Asly_req
[docs] def compute_required_transverse_reinforcement(self) -> None: """Compute the required transverse reinforcement for design forces. """ # Allowable shear stress that can be carried by the beam tau_c = np.interp(self.concrete.fck, FCK_VECT, TAU_C_VECT) # Initial transverse reinforcement area to spacing ratio Ashx_sh_req, Ashy_sh_req = self.__get_min_transv_reinf() for force in self.design_forces: # Distance of long. bars in tens. to extreme conc. fibers in compr. dx = 0.9 * self.bx dy = 0.9 * self.by # lever arm, i.e., distance between comp. and tens. forces zx = 0.9 * dx zy = 0.9 * dy # Design forces Vy1 = abs(force.Vy1) Vx1 = abs(force.Vx1) Vy9 = abs(force.Vy9) Vx9 = abs(force.Vx9) # Determine loading eccentricty ecc_x1 = force.My1 / force.N1 ecc_x9 = force.My9 / force.N9 ecc_y1 = force.Mx1 / force.N1 ecc_y9 = force.Mx9 / force.N9 # TO define big and small ecc. section for tensile force and # to discard concrete contribution for small eccentricity. et_x1 = ecc_x1 / dx et_x9 = ecc_x9 / dx et_y1 = ecc_y1 / dy et_y9 = ecc_y9 / dy # Allowable shear force in concrete, assuming vertical stirrups Vcd_x = tau_c * self.by * dx # REBAP-83, 53.3, 53.2 c) Vcd_y = tau_c * self.bx * dy # REBAP-83, 53.3, 53.2 c) # Start section -X direction if force.N1 > 0 and abs(et_x1) < 0.5: # REBAP-83, 53.3 # Tensile force with small ecc. (cracked concrete) Ash_sh_x1 = Vx1 / (zx * self.fsyd) elif Vx1 > Vcd_x: Ash_sh_x1 = (Vx1 - Vcd_x) / (zx * self.fsyd) else: Ash_sh_x1 = 0.0 # Start section -Y direction if force.N1 > 0 and abs(et_y1) < 0.5: # Tensile force with small ecc. (cracked concrete) Ash_sh_y1 = Vy1 / (zy * self.fsyd) elif Vy1 > Vcd_y: Ash_sh_y1 = (Vy1 - Vcd_y) / (zy * self.fsyd) else: Ash_sh_y1 = 0.0 # End section -X direction if force.N9 > 0 and abs(et_x9) < 0.5: # Tensile force with small ecc. (cracked concrete) Ash_sh_x9 = Vx9 / (zx * self.fsyd) elif Vx9 > Vcd_x: Ash_sh_x9 = (Vx9 - Vcd_x) / (zx * self.fsyd) else: Ash_sh_x9 = 0.0 # End section -Y direction if force.N9 > 0 and abs(et_y9) < 0.5: # Tensile force with small ecc. (cracked concrete) Ash_sh_y9 = Vy9 / (zy * self.fsyd) elif Vy9 > Vcd_y: Ash_sh_y9 = (Vy9 - Vcd_y) / (zy * self.fsyd) else: Ash_sh_y9 = 0.0 Ash_sh_x1 = Vx1 / (zx * self.fsyd) Ash_sh_y1 = Vy1 / (zy * self.fsyd) Ash_sh_x9 = Vx9 / (zx * self.fsyd) Ash_sh_y9 = Vy9 / (zy * self.fsyd) # Update the required reinforcement Ashx_sh_req = max(Ashx_sh_req, Ash_sh_x1, Ash_sh_x9) Ashy_sh_req = max(Ashy_sh_req, Ash_sh_y1, Ash_sh_y9) # Save the required transverse reinforcement area to spacing ratio self.Ashx_sbh_req = Ashx_sh_req self.Ashy_sbh_req = Ashy_sh_req
def __get_min_transv_reinf(self) -> Tuple[float]: """Get minimum transverse reinforcement area to spacing ratio. Returns ------- Tuple[float] Transverse reinforcement area (along x and y axes) to spacing ratio. """ if self.fsyd < 230 * MPa: Ashx_sh_min = 0.16 * self.bx / 100 Ashy_sh_min = 0.16 * self.by / 100 elif self.fsyd < 400 * MPa: Ashx_sh_min = 0.10 * self.bx / 100 Ashy_sh_min = 0.10 * self.by / 100 else: Ashx_sh_min = 0.08 * self.bx / 100 Ashy_sh_min = 0.08 * self.by / 100 return Ashx_sh_min, Ashy_sh_min