FEMA_SAC_SteelFrame
FEMA_SAC_SteelFrame
FEMA_SAC_SteelFrame(name_prefix: str = 'FEMA_SAC_Frame', x_bays: Optional[List[float]] = None, y_bays: Optional[List[float]] = None, story_heights: Optional[List[float]] = None, section_map: Optional[Dict[str, List[Union[str, Tuple]]]] = None, defaults: Optional[Dict[str, str]] = None, n_ele_col: int = 1, n_ele_beam: int = 1, length_unit_system: str = 'm', origin: Tuple[float, float, float] = (0.0, 0.0, 0.0), floor_masses: Optional[List[float]] = None)
Bases: Building
Represents a FEMA/SAC Steel Frame benchmark building.
Defaults to the SAC 9-Story (LA9) configuration if no geometry is provided, but can be initialized with custom bays, stories, and sections.
Attributes
defaults
instance-attribute
Methods:
_is_valid_beam
Validates if a beam exists at this location based on FEMA/SAC pinwheel logic.
get_coordinates
Returns the X, Y, and Z coordinates of the building grid intersections.
_initialize_sections
Populate the section grids based on defaults and section_map.
view_story
Visualize the layout and sections for a specific story.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
story
|
int
|
1-based story index. |
required |
mode
|
str
|
'text' for ASCII output, 'plot' for matplotlib window. |
'text'
|
_load_sac_9_story_defaults
Internal helper to load the specific LA9 benchmark sections.
build
Generate the steel frame geometry and return as a CompositeMesh.
create_rigid_diaphragms
Creates rigid diaphragm constraints for each floor.
This method identifies the Center-of-Mass (CoM) node at each floor and connects it to all column endpoint nodes on that floor. It ensures that intermediate beam nodes (from subdivided beams) are excluded.
Must be called AFTER model.assembler.assemble().
create_gravity_pattern
Build a plain gravity load pattern for the assembled frame.
For each elevated floor (z levels from the building grid), the
translational mass stored in floor_masses for that story is multiplied
by g to obtain a total vertical force, which is applied in equal parts
at every structural grid node on that level (num_x_grid * num_y_grid
nodes). Ghost center-of-mass nodes are not loaded.
Prerequisites: :meth:build and mesh assembly on model must be
completed so nodal coordinates and tags are available.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
Femora model instance ( |
required | |
g
|
float
|
Acceleration magnitude; must combine with |
required |
Returns:
| Type | Description |
|---|---|
Pattern
|
A |
Pattern
|
six-DOF nodal loads in global Z) ready to attach to a process or export. |
get_modes
get_modes(num_modes: int, *, material: Optional[Union[Dict[str, object], Callable]] = None, material_density: Optional[float] = None, opensees_exe: Optional[str] = None, print_results: bool = False, plot: bool = False, plot_scale: Optional[float] = None) -> Dict[str, np.ndarray]
Return modal frequencies, periods, and eigenvectors.
The method builds a copy of this frame in a separate Model instance,
applies the same gravity and diaphragm setup used by the example modal
script, runs OpenSees in a temporary directory, and parses frequencies,
periods, and nodal eigenvectors from OpenSees stdout.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
num_modes
|
int
|
Number of eigen modes to request from OpenSees. |
required |
material
|
Optional[Union[Dict[str, object], Callable]]
|
Material definition for the isolated modal model. Use
|
None
|
material_density
|
Optional[float]
|
Density used by |
None
|
opensees_exe
|
Optional[str]
|
Optional OpenSees executable path. If omitted, the
|
None
|
print_results
|
bool
|
If |
False
|
plot
|
bool
|
If |
False
|
plot_scale
|
Optional[float]
|
Optional deformation scale for plotting. If omitted, a scale is estimated from the mesh size and eigenvector magnitudes. |
None
|
Returns:
| Type | Description |
|---|---|
Dict[str, ndarray]
|
Dictionary with |
Dict[str, ndarray]
|
|
Dict[str, ndarray]
|
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
RuntimeError
|
If OpenSees is not configured, fails to run, or does not return the expected modal data. |
Material ownership
get_modes() builds a separate temporary Model() so modal
analysis cannot accidentally mutate the user's active model. For
that reason, do not pass a Material object from another model.
Use a material dictionary or a callable factory so the material is
created inside the temporary modal model with the correct managers
and tags.
Examples:
Default A992 steel:
Custom elastic isotropic material from a dictionary:
result = frame.get_modes(
num_modes=6,
material={
"name": "CustomSteel",
"E": 2.0e8,
"nu": 0.3,
"rho": 7.85,
},
opensees_exe=opensees_path,
)
Advanced material factory:
get_recorders
get_recorders(model, *, file_name: Optional[str] = None, delta_t: Optional[float] = None, element_responses: List[str] = ['force'], node_responses: List[str] = ['displacement', 'acceleration'])
Returns an MPCO recorder for the building's elements.
This method must be called after build() has been called to ensure
the building region is created.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
Active Femora model (Model instance). |
required | |
file_name
|
Optional[str]
|
Output file name with .mpco extension. Defaults to {name_prefix}.mpco. |
None
|
delta_t
|
Optional[float]
|
Optional recorder time interval (-T dt). |
None
|
element_responses
|
List[str]
|
List of element responses to record (-E). Defaults to ["force"]. |
['force']
|
node_responses
|
List[str]
|
List of element responses to record (-N). Defaults to ["displacement", "acceleration"]. |
['displacement', 'acceleration']
|
Returns:
| Type | Description |
|---|---|
|
List containing the MPCORecorder instance. |