Plate Buckling#
|
Creating a beam-to-beam steel joint and running its ULS design including the plate buckling check:
Keywords:
steel joint beam to beam member cut stiffener buckling analysis critical load factor design ratios |
from math import inf
from dlubal.api import rfem, common
from dlubal.api.common.packing import wrap_value
# -------------------------------------------------------
# This example creates a beam-to-beam steel joint and runs its ULS design
# including the buckling design check of the joint.
#
# A welded I-section column (member 1) meets an IPE 500 beam (member 2) at
# node 2. The joint connects them with two member cuts and one stiffener. The
# buckling analysis is enabled in the ULS configuration, and both the design
# ratios and the buckling critical load factors are read back.
# -------------------------------------------------------
# Editable parameters (SI units)
BEAM_CROSS_SECTION = "IPE 500"
STEEL_GRADE = "S235"
STIFFENER_THICKNESS = 0.016
# Welded parametric I-section for member 1: h/b/t_w/t_f in metres -> "I 840/250/4/10/0/0/H"
COLUMN_SECTION_H = 0.84
COLUMN_SECTION_B = 0.25
COLUMN_SECTION_TW = 0.004
COLUMN_SECTION_TF = 0.01
def define_structure() -> list:
"""Define the base RFEM model (column + beam) used for the analysis."""
return [
# Materials
rfem.structure_core.Material(
no=1,
name=STEEL_GRADE,
),
# Cross-Sections
rfem.structure_core.CrossSection(
no=1,
material=1,
type=rfem.structure_core.CrossSection.TYPE_PARAMETRIC_THIN_WALLED,
parametrization_type=rfem.structure_core.CrossSection.PARAMETRIZATION_TYPE_PARAMETRIC_THIN_WALLED__I_SECTION__I,
h=COLUMN_SECTION_H,
b=COLUMN_SECTION_B,
t_w=COLUMN_SECTION_TW,
t_f=COLUMN_SECTION_TF,
r_1=0.0,
r_2=0.0,
),
rfem.structure_core.CrossSection(
no=2,
material=1,
name=BEAM_CROSS_SECTION,
),
# Nodes
rfem.structure_core.Node(
no=1,
coordinate_1=0.0,
coordinate_2=0.0,
coordinate_3=0.0,
),
rfem.structure_core.Node(
no=2,
coordinate_1=0.0,
coordinate_2=0.0,
coordinate_3=-1.35,
),
rfem.structure_core.Node(
no=3,
coordinate_1=1.045,
coordinate_2=0.0,
coordinate_3=-1.35,
),
# Lines
rfem.structure_core.Line(
no=1,
definition_nodes=[1, 2],
),
rfem.structure_core.Line(
no=2,
definition_nodes=[2, 3],
),
# Members
rfem.structure_core.Member(
no=1,
line=1,
type=rfem.structure_core.Member.TYPE_BEAM,
cross_section_start=1,
),
rfem.structure_core.Member(
no=2,
line=2,
type=rfem.structure_core.Member.TYPE_BEAM,
cross_section_start=2,
),
# Nodal Supports
rfem.types_for_nodes.NodalSupport(
no=1,
nodes=[1],
spring_x=inf,
spring_y=inf,
spring_z=inf,
rotational_restraint_x=inf,
rotational_restraint_y=inf,
rotational_restraint_z=inf,
),
]
def define_loading() -> list:
"""Define a load case, the ULS design situation and one load combination."""
return [
rfem.loading.StaticAnalysisSettings(
no=1,
),
rfem.loading.LoadCase(
no=1,
name="Moment",
static_analysis_settings=1,
action_category=rfem.loading.LoadCase.ACTION_CATEGORY_PERMANENT_G,
self_weight_active=False,
),
rfem.loading.DesignSituation(
no=1,
name="ULS (STR/GEO) - Permanent and transient - Eq. 6.10",
design_situation_type=rfem.loading.DesignSituation.DESIGN_SITUATION_TYPE_STR_PERMANENT_AND_TRANSIENT_6_10,
active_for_steel_joints=True,
),
rfem.loading.LoadCombination(
no=1,
design_situation=1,
name="Moment",
static_analysis_settings=1,
items=rfem.loading.LoadCombination.ItemsTable(
rows=[
rfem.loading.LoadCombination.ItemsRow(
no=1,
factor=1.0,
load_case=1,
),
]
),
combination_rule_str="LC1",
),
# Bending moment about the global Y axis at the free beam end (node 3)
rfem.loads.NodalLoad(
no=1,
nodes=[3],
load_case=1,
load_type=rfem.loads.NodalLoad.LOAD_TYPE_MOMENT,
moment_magnitude=-239190,
load_direction=rfem.loads.NodalLoad.LOAD_DIRECTION_GLOBAL_Y_OR_USER_DEFINED_V_TRUE_LENGTH,
),
]
def define_joint_members():
"""Define members assigned inside the Steel Joint add-on table."""
return rfem.steel_joints_objects.SteelJoint.MembersTable(
rows=[
rfem.steel_joints_objects.SteelJoint.MembersRow(
no=1,
is_active=True,
members_no=[1],
status="Member 1",
end_type=rfem.steel_joints_objects.SteelJoint.MembersRow.EndType.END_TYPE_MEMBER_ENDED,
supported=True,
),
rfem.steel_joints_objects.SteelJoint.MembersRow(
no=2,
is_active=True,
members_no=[2],
status="Member 2",
end_type=rfem.steel_joints_objects.SteelJoint.MembersRow.EndType.END_TYPE_MEMBER_ENDED,
supported=False,
),
]
)
def define_joint_components():
"""Define top-level Steel Joint components and their RFEM setting keys.
Only the user-defined components are created here (two member cuts that
connect the members plus one stiffener). RFEM auto-generates the derived
plates, plate cuts and welds from these.
"""
joint_components = [
(
rfem.steel_joints_objects.SteelJoint.ComponentsRow.Type.TYPE_MEMBER_CUT,
"Member Cut 1",
[
("member_to_cut", "Member 1"),
("type_of_cut", 0),
("cut_by", "Member 2"),
("cutting_method", 0),
("cutting_plane", 1),
("direction", 0),
("offset", 0.0),
],
),
(
rfem.steel_joints_objects.SteelJoint.ComponentsRow.Type.TYPE_MEMBER_CUT,
"Member Cut 2",
[
("member_to_cut", "Member 2"),
("type_of_cut", 0),
("cut_by", "Member 1"),
("cutting_method", 0),
("cutting_plane", 0),
("direction", 0),
("offset", 0.0),
("weld_is_active_1", True),
("weld_is_active_2", True),
("weld_is_active_3", True),
("weld_type_1", 3),
("weld_type_2", 3),
("weld_type_3", 3),
],
),
(
rfem.steel_joints_objects.SteelJoint.ComponentsRow.Type.TYPE_STIFFENER,
"Stiffener 1",
[
("stiffened_member", "Member 1"),
("reference_member", "Member 2"),
("plate_material", 1),
("plate_thickness", STIFFENER_THICKNESS),
("plate_count", 2),
("position", 2),
("direction", 1),
("location_offset", "0.0000 0.0000"),
("side", 2),
("inclination", 0.0),
("width_offset", 0.0),
("height_offset", 0.0),
("chamfer", 0.0),
("weld_is_active_1", True),
("weld_is_active_2", True),
("weld_is_active_3", True),
("weld_type_1", 3),
("weld_type_2", 3),
("weld_type_3", 3),
],
),
]
joint_component_rows = []
for component_no, joint_component in enumerate(joint_components, start=1):
component_type, component_name, component_settings = joint_component
setting_rows = []
for setting_no, setting in enumerate(component_settings, start=1):
setting_key, setting_value = setting
setting_rows.append(
rfem.steel_joints_objects.SteelJoint.ComponentsRow.SettingsTableRow(
no=setting_no,
key=setting_key,
value=wrap_value(setting_value),
)
)
joint_component_rows.append(
rfem.steel_joints_objects.SteelJoint.ComponentsRow(
no=component_no,
is_active=True,
type=component_type,
name=component_name,
settings=rfem.steel_joints_objects.SteelJoint.ComponentsRow.SettingsTable(
rows=setting_rows,
),
)
)
return rfem.steel_joints_objects.SteelJoint.ComponentsTable(
rows=joint_component_rows,
)
def define_steel_joint() -> list:
"""Define the steel joint and its design configuration."""
return [
rfem.steel_joints_design_addon_objects.JointUlsConfiguration(
no=1,
name="ULS Configuration",
),
rfem.steel_joints_objects.SteelJoint(
no=1,
nodes=[2],
user_defined_name_enabled=True,
name="Nodes : 2 | Created via API",
comment="Created via API",
to_design=True,
ultimate_configuration=1,
members=define_joint_members(),
components=define_joint_components(),
),
]
# -------------------------------------------------------
# MAIN SCRIPT
# -------------------------------------------------------
with rfem.Application() as rfem_app:
# Initialize model
rfem_app.close_all_models(save_changes=False)
rfem_app.create_model(name='steel_joint_buckling_analysis')
# Activate the Steel Joints add-on
base_data = rfem_app.get_base_data()
base_data.addons.steel_joints_active = True
rfem_app.set_base_data(base_data=base_data)
rfem_app.delete_all_objects()
# Create structure, loading and the steel joint
rfem_app.create_object_list(
define_structure() +
define_loading() +
define_steel_joint()
)
# Enable the buckling analysis in the ULS configuration
# (a freshly created configuration has it switched off by default)
settings_tree = rfem_app.get_object(
obj=rfem.steel_joints_design_addon_objects.JointUlsConfiguration(no=1)
).settings_ec3
common.tree_table.set_values_by_key(settings_tree, "perform_buckling_analysis", values=[True])
rfem_app.update_object(
obj=rfem.steel_joints_design_addon_objects.JointUlsConfiguration(
no=1,
settings_ec3=settings_tree,
)
)
# Calculate the ULS design situation
rfem_app.calculate_all(skip_warnings=True)
# --- Steel joint design checks (max ratios) ---
design_ratios_df: common.Table = rfem_app.get_results(
results_type=rfem.results.ResultsType.STEEL_JOINTS_DESIGN_RATIOS,
).data
plate_ratio = design_ratios_df.loc[
design_ratios_df["design_check_type"] == "UL1000.00", "design_ratio"
].dropna().max()
print("Steel joint design check summary (max ratios):")
print(f"Plates (UL1000.00): {plate_ratio:.3f}")
# --- Steel joint buckling analysis (critical load factors) ---
# Only available when perform_buckling_analysis is enabled.
# design_check_type ST2000.00 -> "Buckling analysis"; f = critical load factor.
buckling_df: common.Table = rfem_app.get_results(
results_type=rfem.results.ResultsType.STEEL_JOINTS_BUCKLING_DESIGN_RATIOS,
).data
print("\nSteel joint buckling analysis (critical load factors):")
for row in buckling_df.itertuples():
print(f"Mode {row.mode_shape_no}: f = {row.critical_load_factor:.3f}")
lowest_factor = buckling_df["critical_load_factor"].dropna().min()
print(f"Lowest critical load factor: {lowest_factor:.3f}")