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

"""This module provides the base class for representing columns
within the BDIM layer.
"""
# Imports from installed packages
from abc import ABC, abstractmethod
from dataclasses import dataclass
from math import ceil
import numpy as np
from typing import Literal, List, Dict

# Imports from bdim base library
from .materials import SteelBase, ConcreteBase

# Imports from geometry library
from ...geometry.base import Point, Line

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


[docs] @dataclass class ColumnForces: """Data class for storing element forces. Attributes ---------- N1 : float Axial force at 1st gauss point (start-section). Mx1 : float Moment around local-x at 1st gauss point (start-section). Vy1 : float Shear in local-y at 1st gauss point (start-section). My1 : float Moment around local-y at 1st gauss point (start-section). Vx1 : float Shear in local-x at 1st gauss point (start-section). N9 : float Axial force at 9th gauss point (end-section). Mx9 : float Moment around local-x at 9th gauss point (end-section). Vy9 : float Shear in local-y at 9th gauss point (end-section). My9 : float Moment around local-y at 9th gauss point (end-section). Vx9 : float Shear in local-x at 9th gauss point (end-section). case : Literal['gravity', 'seismic', None], optional Type of load combination if forces are computed for a combo, otherwise None. By default None. """ N1: float Mx1: float Vy1: float My1: float Vx1: float N9: float Mx9: float Vy9: float My9: float Vx9: float case: Literal['gravity', 'seismic', None] = None def __add__(self, other: 'ColumnForces') -> 'ColumnForces': """The addition operator “+” (object is left operand). Parameters ---------- other : ColumnForces Other ColumnForces object. Returns ------- ColumnForces Addition of the other two `ColumnForces` objects. Raises ------ TypeError Unsupported operand type. """ if isinstance(other, ColumnForces): return ColumnForces( self.N1 + other.N1, self.Mx1 + other.Mx1, self.Vy1 + other.Vy1, self.My1 + other.My1, self.Vx1 + other.Vx1, self.N9 + other.N9, self.Mx9 + other.Mx9, self.Vy9 + other.Vy9, self.My9 + other.My9, self.Vx9 + other.Vx9 ) else: raise TypeError("Unsupported operand type(s) for +: ", "'{}' and '{}'".format(type(self), type(other))) def __sub__(self, other: 'ColumnForces') -> 'ColumnForces': """The subtraction operator “-” (object is left operand). Parameters ---------- other : ColumnForces Other `ColumnForces` object. Returns ------- ColumnForces Subtraction of the other two `ColumnForces` objects. Raises ------ TypeError Unsupported operand type. """ if isinstance(other, ColumnForces): return ColumnForces( self.N1 - other.N1, self.Mx1 - other.Mx1, self.Vy1 - other.Vy1, self.My1 - other.My1, self.Vx1 - other.Vx1, self.N9 - other.N9, self.Mx9 - other.Mx9, self.Vy9 - other.Vy9, self.My9 - other.My9, self.Vx9 - other.Vx9 ) else: raise TypeError("Unsupported operand type(s) for -: ", "'{}' and '{}'".format(type(self), type(other))) def __mul__(self, factor: float | int) -> 'ColumnForces': """The multiplication operator “*” (object is left operand). Parameters ---------- factor : float | int Factor used for multiplying the force quantities. Returns ------- ColumnForces Product of factor and ColumnForces object. """ return ColumnForces( self.N1 * factor, self.Mx1 * factor, self.Vy1 * factor, self.My1 * factor, self.Vx1 * factor, self.N9 * factor, self.Mx9 * factor, self.Vy9 * factor, self.My9 * factor, self.Vx9 * factor ) def __rmul__(self, factor: float | int) -> 'ColumnForces': """The multiplication operator “*” (object is right operand). Parameters ---------- factor : float | int Factor used for multiplying the force quantities. Returns ------- ColumnForces Product of factor and ColumnForces object. """ return self.__mul__(factor) def __truediv__(self, factor: float | int) -> 'ColumnForces': """The division operator “/” (object is left operand). Parameters ---------- factor : float | int Factor used for dividing the force quantities. Returns ------- ColumnForces Quotient of division operation: ColumnForces/factor. """ return ColumnForces( self.N1 / factor, self.Mx1 / factor, self.Vy1 / factor, self.My1 / factor, self.Vx1 / factor, self.N9 / factor, self.Mx9 / factor, self.Vy9 / factor, self.My9 / factor, self.Vx9 / factor )
[docs] @dataclass class ColumnEnvelopeForces: """Data class for storing element envelope forces. Attributes ---------- N1_neg : float Negative axial force envelope (maximum compression force) at 1st gauss point (start-section). N1_pos : float Positive axial force envelope (maximum tension force) at 1st gauss point (start-section). Mx1_neg : float Negative moment envelope around local-x at 1st gauss point (start-section). Mx1_pos : float Positive moment envelope around local-x at 1st gauss point (start-section). Vy1 : float Shear force envelope in local-y at 1st gauss point (start-section). My1_neg : float Negative moment envelope around local-y at 1st gauss point (start-section). My1_pos : float Positive moment envelope around local-y at 1st gauss point (start-section). Vx1 : float Shear force envelope in local-x at 1st gauss point (start-section). N9_neg : float Negative axial force envelope (maximum compression force) at 9th gauss point (end-section). N9_pos : float Positive axial force envelope (maximum tension force) at 9th gauss point (end-section). Mx9_neg : float Negative moment envelope around local-x at 9th gauss point (end-section). Mx9_pos : float Positive moment envelope around local-x at 9th gauss point (end-section). Vy9 : float Shear force envelope in local-y at 9th gauss point (end-section). My9_neg : float Negative moment envelope around local-y at 9th gauss point (end-section). My9_pos : float Positive moment envelope around local-y at 9th gauss point (end-section). Vx9 : float Shear force envelope in local-x at 9th gauss point (end-section). """ N1_neg: float N1_pos: float Mx1_neg: float Mx1_pos: float Vy1: float My1_neg: float My1_pos: float Vx1: float N9_neg: float N9_pos: float Mx9_neg: float Mx9_pos: float Vy9: float My9_neg: float My9_pos: float Vx9: float
[docs] class ColumnBase(ABC): """Abstract base class for columns. Must be inherited by design-class-specific columns. Attributes ---------- steel : SteelBase Steel material. concrete : ConcreteBase Concrete material. bx : float Breadth (width) along global X. by : float Breadth (width) along global Y. section : Literal[1, 2] Column cross-section type: 1: square solid section. 2: rectangular solid section. line : ~simdesign.rcmrf.geometry.base.Line Line representation of column (tag and points). gamma_rc : float Reinforced concrete unit weight. pre_Nq_pos : float Expected axial force due to variable loads (factored for position). pre_Ng_pos : float Expected axial force due to permanent loads (factored for position). pre_Nq : float Expected axial force due to variable loads (unfactored). pre_Ng : float Expected axial force due to permanent loads (unfactored). pre_Nd : float Expected preliminary design axial force. orient : Literal['x', 'y', None] Direction of greater dimension in global axis. ok_x : bool Flag to check section adequacy in x direction. ok_y : bool Flag to check section adequacy in y direction. pre_bx : float Preliminary design breadth (width) along global X. pre_by : float Preliminary design breadth (width) along global Y. cover : float Concrete cover. Aslx_req : float Required longitudinal reinforcement area at bottom or top side of the section. In other words, required area of bars distributed along -x on one side. Asly_req : float Required longitudinal reinforcement area at left or right side of the section. In other words, required area of bars distributed along -y on one side. Ashx_sbh_req : float Required ratio of transverse reinforcement area along -x axis (i.e., parallel to -x axis) to the bar spacing. Ashy_sbh_req : float Required ratio of transverse reinforcement area along -y axis (i.e., parallel to -y axis) to the bar spacing. dbl_cor : float Diameter of corner longitudinal bars (reinforcement). dbl_int : float Diameter of internal longitudinal bars (reinforcement). nblx_int : int Number of internal longitudinal bars at bottom or top side of the section. In other words, half of the total number of internal bars distributed along X (on one side). nbly_int : int Number of internal longitudinal bars at left or right side of the section. In other words, half of the total number of internal bars distributed along Y (on one side). dbh : float Diameter of horizontal bars (transverse reinforcement). sbh : float Spacing of horizontal bars (transverse reinforcement). nbh_x : float Number of horizontal bars (stirrup legs) along -x axis. nbh_y : float Number of horizontal bars (stirrup legs) along -y axis. MAX_B_SQUARE : float The default maximum square column dimension. MAX_B_RECTANGLE : float The default maximum rectangular column dimension. MIN_B_SQUARE : float The default minimum square column dimension. MIN_B_RECTANGLE : float The default minimum rectangular column dimension. BX_INCR : float Controls amount of ``bx`` increase in design iterations. BY_INCR : float Controls amount of ``by`` increase in design iterations. forces : Dict[str, ColumnForces] Dictionary containing forces obtained from unique load cases (in load combos), e.g., 'G', 'Q', 'E+X', 'E-X', 'E+Y', 'E-Y'. design_forces : List[ColumnForces] List of forces obtained each load combination (design forces). fc_q : float In-situ (quality adjusted) concrete compressive strength. fsyl_q : float In-situ (quality adjusted) longitudinal reinforcement yield strength. fsyh_q : float In-situ (quality adjusted) transverse reinforcement yield strength. sbh_q : float In-situ (quality adjusted) spacing of transverse bars. dbh_q : float In-situ (quality adjusted) diameter of transverse bars. nbh_x_q : float In-situ (quality adjusted) number of horizontal bars (stirrup legs) along -x axis. nbh_y_q : float In-situ (quality adjusted) number of horizontal bars (stirrup legs) along -y axis. cover_q : float In-situ (quality adjusted) concrete cover. dbl_cor_q : float In-situ (quality adjusted) diameter of corner longitudinal bars. dbl_int_q : float In-situ (quality adjusted) diameter of internal longitudinal bars. nblx_int_q : int In-situ (quality adjusted) number of internal longitudinal bars at bottom or top side of the section. nbly_int_q : int In-situ (quality adjusted) number of internal longitudinal bars at left or right side of the section. position_factor : float Position factor considered to account for the column axial force increase during seismic loading. hinge_Nq : float Expected axial force due to variable loads in nonlinear model (used in hinge calculations). hinge_Ng : float Expected axial force due to permanent loads in nonlinear model (used in hinge calculations). Notes ----- Section view: .. code-block:: text Y (2) |__X (1) -------------- ---- | y | | | | | | | +--x | by | | | | | | -------------- ---- |---- bx ----| """ steel: SteelBase concrete: ConcreteBase bx: float by: float section: Literal[1, 2] line: Line gamma_rc: float pre_Nq_pos: float pre_Ng_pos: float pre_Nq: float pre_Ng: float pre_Nd: float orient: Literal['x', 'y', None] ok_x: bool ok_y: bool pre_bx: float pre_by: float cover: float Aslx_req: float Asly_req: float Ashx_sbh_req: float Ashy_sbh_req: float dbl_cor: float dbl_int: float nblx_int: int nbly_int: int dbh: float sbh: float nbh_x: float nbh_y: float MAX_B_SQUARE: float = 0.80 * m MAX_B_RECTANGLE: float = 1.30 * m MIN_B_SQUARE: float = 0.25 * m MIN_B_RECTANGLE: float = 0.25 * m BX_INCR: float = 0.05 * m BY_INCR: float = 0.05 * m __bx: float __by: float forces: Dict[str, ColumnForces] design_forces: List[ColumnForces] fc_q: float fsyl_q: float fsyh_q: float sbh_q: float dbh_q: float nbh_x_q: float nbh_y_q: float cover_q: float dbl_cor_q: float dbl_int_q: float nblx_int_q: int nbly_int_q: int position_factor: float hinge_Nq: float hinge_Ng: float def __init__( self, line: Line, section: Literal[1, 2], gamma_rc: float ) -> None: """Initialize a new instance of ColumnBase. Parameters ---------- line : ~simdesign.rcmrf.geometry.base.Line Geometric mesh representation of column. section : Literal[1, 2] Column cross-section type 1: square solid section. 2: rectangular solid section. gamma_rc : float Reinforced concrete unit weight. """ # Save inputs self.line = line self.section = section self.gamma_rc = gamma_rc # Initialize some parameters self.bx = self.min_b self.by = self.min_b self.ok_x = True self.ok_y = True self.orient = None self.forces = {} def __str__(self) -> str: """Return string representation of the column object. Returns ------- str String representation of the column object. """ column_rep = self.line.__str__() column_rep = column_rep.replace('Line', 'Column') column_rep = column_rep.replace('Point', 'Node-') return column_rep @property def fck(self) -> float: """Characteristic concrete compressive strength (in base units). Returns ------- float Characteristic concrete compressive strength (in base units). """ return self.concrete.fck * MPa @property def fsyk(self) -> float: """Characteristic steel yield strength (in base units). Returns ------- float Characteristic steel yield strength (in base units). """ return self.steel.fsyk * MPa @property def fsym(self) -> float: """Mean steel yield strength (in base units). Returns ------- float Mean steel yield strength (in base units). """ return self.steel.fsym * MPa @property def fcd(self) -> float: """Design value of concrete compressive strength (in base units). Returns ------- float Design value of concrete compressive strength (in base units). """ return self.concrete.fcd * MPa @property def fcm(self) -> float: """Mean value of concrete compressive strength (in base units). Returns ------- float Mean value of concrete compressive strength (in base units). """ return self.concrete.fcm * MPa @property def fsyd(self) -> float: """Design value of steel yield strength (in base units). Returns ------- float Design value of steel yield strength (in base units). """ return self.steel.fsyd * MPa @property def Ecm(self) -> float: """Mean elastic Young's modulus of concrete (in base units). Returns ------- float Mean elastic Young's modulus of concrete (in base units). """ return self.concrete.Ecm @property def Ecd(self) -> float: """Design elastic Young's modulus of concrete (in base units). Returns ------- float Design elastic Young's modulus of concrete (in base units). """ return self.concrete.Ecd @property def Gcm(self) -> float: """Mean value of elastic shear modulus of concrete (in base units). Returns ------- float Mean value of elastic shear modulus of concrete (in base units). """ return self.concrete.Gcm @property def Gcd(self) -> float: """Design value of elastic shear modulus of concrete (in base units). Returns ------- float Design value of elastic shear modulus of concrete (in base units). """ return self.concrete.Gcd @property def Es(self) -> float: """Elastic Young's modulus of steel (in base units). Returns ------- float Elastic Young's modulus of steel (in base units). """ return self.steel.Es @property def Ag(self) -> float: """Gross area of the column cross-section. Returns ------- float Gross area of the column cross-section. """ return self.bx * self.by @property def Ix(self) -> float: """Column moment of inertia around x-axis. Returns ------- float Column moment of inertia around x-axis. """ return (self.bx * self.by**3) / 12 @property def Iy(self) -> float: """Column moment of inertia around y-axis. Returns ------- float Column moment of inertia around y-axis. """ return (self.by * self.bx**3) / 12 @property def Ix_eff(self) -> float: """Effective (cracked) column moment of inertia around x-axis. Returns ------- float Effective (cracked) column moment of inertia around x-axis. """ return self.Ix @property def Iy_eff(self) -> float: """Effective (cracked) column moment of inertia around y-axis. Returns ------- float Effective (cracked) column moment of inertia around y-axis. """ return self.Iy @property def H(self) -> float: """Column height. Returns ------- float Column height. """ return self.line.length @property def J(self) -> float: """Column second polar moment of area. Returns ------- float Column second polar moment of area. """ hmin = np.minimum(self.bx, self.by) hmax = np.maximum(self.bx, self.by) return (hmax * hmin**3) * ( 1 / 3 - 0.21 * (hmin / hmax) * (1 - (hmin**4 / (12 * hmax**4))) ) @property def self_wg(self) -> float: """Column unit weight per length. Returns ------- float Column unit weight per length. """ return self.gamma_rc * self.Ag @property def elastic_nodes(self) -> List[Point]: """Column element nodes (points) in elastic model. Returns ------- List[Point] Column element nodes (points) in elastic model. """ return self.line.points @property def max_b(self) -> float: """Computed maximum allowed column dimension. Returns ------- float Computed maximum allowed column dimension. """ if self.section == 1: # Square columns return self.MAX_B_SQUARE elif self.section == 2: # Rectangular columns return self.MAX_B_RECTANGLE @property def min_b(self) -> float: """Computed minimum allowed column dimension. Returns ------- float Computed minimum allowed column dimension. """ if self.section == 1: # Square columns return self.MIN_B_SQUARE elif self.section == 2: # Rectangular columns return self.MIN_B_RECTANGLE @property def rhol_max(self) -> float: """Maximum allowed longitudinal reinforcement ratio. Returns ------- float Maximum allowed longitudinal reinforcement ratio. """ return 1.0 @property def rhol_min(self) -> float: """Minimum longitudinal reinforcement ratio. Returns ------- float Minimum longitudinal reinforcement ratio. """ return 0.0 @property def rhol(self) -> float: """Longitudinal reinforcement area ratio. Returns ------- float Longitudinal reinforcement area ratio. """ Abl_cor = (np.pi * self.dbl_cor**2) / 4 Abl_int = (np.pi * self.dbl_int**2) / 4 nbl_int = 2 * (self.nbly_int + self.nblx_int) nbl_cor = 4 return (nbl_cor * Abl_cor + nbl_int * Abl_int) / self.Ag @property def rhoh_x(self) -> float: """Transverse reinforcement area (in x) ratio. Returns ------- float Transverse reinforcement area (in x) ratio. """ Abh_x = self.nbh_x * (np.pi * self.dbh**2) / 4 return Abh_x / (self.sbh * self.by) @property def rhoh_y(self) -> float: """Transverse reinforcement area (in y) ratio. Returns ------- float Transverse reinforcement area (in y) ratio. """ Abh_y = self.nbh_y * (np.pi * self.dbh**2) / 4 return Abh_y / (self.sbh * self.bx) @property def envelope_forces(self) -> ColumnEnvelopeForces: """Envelope forces computed from ``design_forces``. Returns ------- ColumnEnvelopeForces Envelope forces computed from ``design_forces``. """ # Get a list of all attributes attributes = ['N1', 'Mx1', 'Vy1', 'My1', 'Vx1', 'N9', 'Mx9', 'Vy9', 'My9', 'Vx9'] # Find minimum and maximum for each attribute min_values = [min(getattr(force, attr) for force in self.design_forces) for attr in attributes] max_values = [max(getattr(force, attr) for force in self.design_forces) for attr in attributes] return ColumnEnvelopeForces( N1_neg=min(min_values[0], 0.0), N1_pos=max(max_values[0], 0.0), Mx1_neg=min(min_values[1], 0.0), Mx1_pos=min(max_values[1], 0.0), Vy1=max(max_values[2], abs(min_values[2])), My1_neg=min(min_values[3], 0.0), My1_pos=min(max_values[3], 0.0), Vx1=max(max_values[4], abs(min_values[4])), N9_neg=min(min_values[5], 0.0), N9_pos=max(max_values[5], 0.0), Mx9_neg=min(min_values[6], 0.0), Mx9_pos=min(max_values[6], 0.0), Vy9=max(max_values[7], abs(min_values[7])), My9_neg=min(min_values[8], 0.0), My9_pos=min(max_values[8], 0.0), Vx9=max(max_values[9], abs(min_values[9])) )
[docs] def restore_dimensions(self) -> None: """Restore column dimension attributes. `bx, by` """ self.bx = self.__bx self.by = self.__by
[docs] def set_restore_point(self) -> None: """Set the restore point for specific column attributes. `bx, by, steel, concrete` """ self.__bx = self.bx self.__by = self.by
[docs] def increase_dimensions(self) -> None: """Method used for increasing dimensions of inadequate sections. Used in design iterations. Can be overwritten for each design class. """ # Modify dimension in global X if not self.ok_x: self.bx = ceil(20 * (self.bx + self.BX_INCR)) / 20 # Modify dimension in global Y if not self.ok_y: self.by = ceil(20 * (self.by + self.BY_INCR)) / 20 # Make dimensions compatible with the section type (square, rect) self.apply_section_compatibility()
[docs] def apply_section_compatibility(self) -> None: """Modifies the section dimensions for compatibility with section type. i.e., square (1), rectangle (2). Used in design iterations. Can be overwritten for each design class. """ if self.section == 1: # Square section # Make both dimensions equal to their maximum self.bx = ceil(20 * max(self.bx, self.by)) / 20 self.by = ceil(20 * max(self.bx, self.by)) / 20 elif self.section == 2: # Rectangular section # Shorter dimension should be at least half of the longer dimension if self.orient == "x": # Longer dimension is bx self.by = ceil(20 * max(self.by, 0.5 * self.bx)) / 20 self.by = ceil(20 * self.by) / 20 elif self.orient == "y": # Longer dimension is by self.bx = ceil(20 * max(self.bx, 0.5 * self.by)) / 20 self.bx = ceil(20 * self.bx) / 20
[docs] def predesign_section_dimensions(self) -> None: """Make an initial guess for column section dimensions. Notes ----- It can be overwritten for specific design classes. """ # Initial guess for column concrete area min_area = self.pre_Nd / self.fcd # Determine initial dimensions if self.section == 1: # Square section self.bx = min_area**0.5 self.by = min_area**0.5 elif self.section == 2: # Rectangular section if self.orient == "x": # Longer dimension is bx self.bx = (2 * min_area) ** 0.5 self.by = 0.5 * self.bx elif self.orient == "y": # Longer dimension is by self.by = (2 * min_area) ** 0.5 self.bx = 0.5 * self.by # Check against minimum dimensions self.bx = max(ceil(20 * self.bx) / 20, self.min_b) self.by = max(ceil(20 * self.by) / 20, self.min_b)
[docs] def validate_section_dimensions(self) -> None: """Method for validating section dimensions against maximum. """ if self.bx > self.max_b: self.ok_x = False if self.by > self.max_b: self.ok_y = False
[docs] def validate_longitudinal_reinforcement(self) -> None: """Method for validating longitudinal reinforcement against maximum. This method is intended to run after determining column rebars. """ # Adequacy check for maximum longitudinal reinforcement if self.rhol > self.rhol_max: self.ok_x = False self.ok_y = False
[docs] def validate_transverse_reinforcement(self) -> None: """Method for validating transverse reinforcement. This method is intended to run after determining column rebars. """ pass
[docs] def get_mrdx(self, **kwargs) -> float: """Computes the design value of moment of resistance around local x. This method can be overwritten for specific design class. Parameters ---------- Ned : float Mean axial force on column. Returns ------- float Design value of moment of resistance around local x. """ # Make compression force positive return self._get_mrd(-1.0 * kwargs['Ned'], 'x')
[docs] def get_mrdy(self, **kwargs) -> float: """Computes the design value of moment of resistance around local y. This method can be overwritten for specific design class. Parameters ---------- Ned : float Mean axial force on column. Returns ------- float Design value of moment of resistance around local y. """ # Make compression force positive return self._get_mrd(-1.0 * kwargs["Ned"], "y")
def _get_mrd(self, Ned: float, axis=Literal['x', 'y']) -> float: """Computes the design value of moment of resistance around specified local axis. Parameters ---------- Ned : float Mean axial force on column (compressive force has positive sign). Returns ------- float Design value of moment of resistance around specified local axis. References ---------- 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. """ # Stress block coefficients for different axial load ratio (REBAP 1983) BETA_FC_VECTOR = [1.00, 0.93, 0.88, 0.88, 0.93] # Axial load ratio corresponding to each stress block coefficient NIU_VECTOR = [0.40, 0.50, 0.60, 0.70, 0.85] # Axis dependent section properties if axis == 'x': # Around local x-axis h = self.by b = self.bx nbl_int = self.nblx_int elif axis == 'y': # Around local y-axis h = self.bx b = self.by nbl_int = self.nbly_int # Total steel area, ignoring the intermediate steel Asl = 2 * np.pi * 0.25 * ( 2 * self.dbl_cor**2 + nbl_int * self.dbl_int**2) # Dimensionless omega (similar to reinf. ratio) omega = (Asl / self.Ag) * (self.fsyd / self.fcd) # Axial load ratio niu = Ned / (self.Ag * self.fcd) # Axial load ratio - 0.85 niu_c = niu - 0.85 # Stress block coefficient for given axial load ratio beta_c = np.interp(niu, NIU_VECTOR, BETA_FC_VECTOR) # Dimensionless lambda lambda_ = 0.5 - self.cover / h # Dimensionless mu if niu < 0.0: # Axial force is tensile mu = (omega + niu) * (lambda_ * beta_c) elif niu <= 0.85: # Axial force is compressive and lower than 0.85 mu = (omega * lambda_ * beta_c) - (0.55 * niu * niu_c) else: # Axial force is compressive and greater than 0.85 mu = (omega - niu_c) * (lambda_ * beta_c) # Design moment of resistance Mrd = mu * b * (h**2) * self.fcd # Return return Mrd
[docs] @abstractmethod def verify_section_adequacy(self) -> None: """Abstract method for verifying adequacy of section dimensions. """
[docs] @abstractmethod def compute_required_longitudinal_reinforcement(self) -> None: """Abstract method for computing required longitudinal reinforcement. Final solution is determined after finding rebar solution to meet the detailing requirements. """
[docs] @abstractmethod def compute_required_transverse_reinforcement(self) -> None: """Abstract method for computing required transverse reinforcement. Final solution is determined after finding rebar solution to meet the detailing requirements. """