Source code for simdesign.rcmrf.bnsm.baselib.floor

"""This module provides a base class for representing floor diaphragms
within the BNSM layer and for building and exporting their OpenSees
representations.
"""
# Imports from installed packages
from abc import ABC
import numpy as np
import openseespy.opensees as ops
from typing import List, Type

# Imports from bnsm library
from .node import Node

# Imports from utils library
from ....utils.misc import PRECISION


[docs] class FloorDiaphragmBase(ABC): """Abstract Base Class for floor diaphragm implementations in BNSM layer. It provides methods to define a floor diaphragm in the OpenSees domain and to export equivalent Python and Tcl commands. The diaphragm is represented through a retained node (placed at the floor center of mass) and rigid diaphragm multi-point constraints that connect the retained node to the constrained floor nodes. In the case of flexible diaphragms, the base class needs to be extended. Attributes ---------- cnodes : List[Node] Constrained floor nodes. rnode : Node Retained floor node. floor : int Floor id (e.g., storey no). masses: List[float] Total joint masses used for defining retained node location. """ cnodes: List[Node] rnode: Node floor: int masses: List[float] NodeClass: Type[Node] = Node def __init__(self, cnodes: List[Node], floor: int, masses: List[float] ) -> None: """"Initialize FloorDiaphragm object. Parameters ---------- cnodes : List[Node] Constrained floor nodes. floor : int Floor id (e.g., storey no). masses : List[float] Total joint masses used for defining retained node location. """ # Save the inputs self.cnodes = cnodes self.floor = floor self.masses = masses # Set the retained node self._set_retained_node() def _set_retained_node(self): """Compute the diaphragm center of mass and create the retained node. """ # Compute center of mass sum_mass = 0 # summation of the masses sum_mass_moment = 0 # summation of the mass moments for i, node in enumerate(self.cnodes): mass = np.array(3 * self.masses[i]) coords = np.array(node.coordinates) sum_mass += mass sum_mass_moment += mass * coords # Center of mass cm = np.round(sum_mass_moment / sum_mass, PRECISION) # Initialize the retained node for floor diaphragms tag = 90000 + self.floor * 1000 self.rnode = self.NodeClass(tag, cm)
[docs] def add_to_ops(self) -> None: """Adds all of the floor diaphragm objects into the OpenSees domain (i.e, retained floor node at center of mass and floor diaphragm). """ # Rigid floor diaphragm - Multi-point (mp) constraints self.rnode.add_to_ops() # Retained floor node perp_dir = 3 rnode_tag = self.rnode.tag cnode_tags = [node.tag for node in self.cnodes] ops.rigidDiaphragm(perp_dir, rnode_tag, *cnode_tags) ops.fix(rnode_tag, 0, 0, 1, 1, 1, 0)
[docs] def to_py(self) -> List[str]: """Gets the Python commands to define floor diaphragm objects in the OpenSees domain (i.e, retained floor node at center of mass and floor diaphragm). Returns ------- List[str] List of Python commands for constructing the components of floor diaphragm in OpenSees. """ content = [f"# Floor no. {self.floor}"] # Rigid floor diaphragm - Multi-point (mp) constraints content.append("# Retained floor node") content.append(self.rnode.to_py()) # Retained floor node perp_dir = 3 rnode_tag = self.rnode.tag cnode_tags = ', '.join([f"{node.tag}" for node in self.cnodes]) content.append("# Rigid floor diaphragm - multi-point constraints") content.append( f"ops.rigidDiaphragm({perp_dir}, {rnode_tag}, {cnode_tags})") content.append("# Fix the floating dofs of the retained node") content.append(f"ops.fix({rnode_tag}, 0, 0, 1, 1, 1, 0)") return content
[docs] def to_tcl(self) -> List[str]: """Gets the Tcl commands to define floor diaphragm objects in the OpenSees domain (i.e, retained floor node at center of mass and floor diaphragm). Returns ------- List[str] List of Tcl commands for constructing the components of floor diaphragm in OpenSees. """ content = [f"# Floor no. {self.floor}"] # Rigid floor diaphragm - Multi-point (mp) constraints content.append("# Retained floor node") content.append(self.rnode.to_tcl()) # Retained floor node perp_dir = 3 rnode_tag = self.rnode.tag cnode_tags = ' '.join([f"{node.tag}" for node in self.cnodes]) content.append("# Rigid floor diaphragm - multi-point constraints") content.append( f"rigidDiaphragm {perp_dir} {rnode_tag} {cnode_tags}") content.append("# Fix the floating dofs of the retained node") content.append(f"fix {rnode_tag} 0 0 1 1 1 0") return content