Source code for opstool.pre.load._gravity_load

from typing import Optional

from ...utils import get_opensees_module
from .._model_data import get_node_mass

ops = get_opensees_module()


[docs] def create_gravity_load( exclude_nodes: Optional[list] = None, direction: str = "Z", factor: float = -9.81, ) -> dict[int, list[float]]: """Applying the gravity loads. The mass values are derived from the extracted mass matrix, including the masses from the nodes and elements. See the blog `Do It Your Self-Weight <https://portwooddigital.com/2023/11/05/do-it-your-self-weight/>`_ for more details. .. Note:: * This function is a modification of the method described in the previous blog post, which relaxes the restrictions on imposing constraints. This means you can impose constraints at any position. * This function invokes the OpenSees ``load`` command, which applies the loads to the nodes in the model, and the function does not check if the ``timeSeries`` and ``pattern`` are defined, so make sure to define them before calling this function. * The mass values are derived from the mass matrix, which is obtained from the :func:`opstool.pre.get_node_mass`. The function assumes that the mass matrix is defined and available in the model. Parameters ----------- exclude_nodes: list, default=None Excluded node tags, whose masses will not be used to generate gravity loads. direction: str, default="Z" The gravity load direction. factor: float, default=-9.81 The factor applied to the mass values, it should be the multiplication of gravitational acceleration and directional indicators, e.g., -9.81, where 9.81 is the gravitational acceleration and -1 indicates along the negative Z axis. Of course, it can be multiplied by an additional factor to account for additional constant loads, e.g., 1.05 * (-9.81). Returns -------- node_loads : dict[int, list[float]] A dictionary where keys are node tags and values are the gravity loads applied to those nodes. The loads are in the form of a list, with the load in the specified direction and zeros in other directions. Examples --------- >>> ops.timeSeries("Constant", 1) # Define a constant time series >>> ops.pattern("Plain", 1, 1) # Define a load pattern >>> node_loads = create_gravity_load(direction='Z', factor=-9.81) """ direction = direction.upper() if direction not in ["X", "Y", "Z"]: raise ValueError(f"Invalid direction {direction}. Must be one of 'X', 'Y', or 'Z'.") # noqa: TRY003 elif direction == "X": gravDOF = 0 elif direction == "Y": gravDOF = 1 elif direction == "Z": gravDOF = 2 node_tags = ops.getNodeTags() if exclude_nodes is not None: node_tags = [tag for tag in node_tags if tag not in exclude_nodes] node_mass = get_node_mass() node_loads = {} for ntag in node_tags: if ntag in node_mass: mass = node_mass[ntag] gravload = [0.0] * len(mass) p = factor * mass[gravDOF] if p != 0.0: gravload[gravDOF] = p ops.load(ntag, *gravload) node_loads[ntag] = gravload return node_loads
gen_grav_load = create_gravity_load