Objects to Design and Exclude#
|
This example demonstrates how to read and modify the two input tables which every design add-on uses to narrow down what is designed:
Keywords:
objects to design objects to exclude design add-on steel design load combination design situation |
Note
Both tables are common to all design add-ons - the add-on is selected with the
addon argument of get_objects_to_design() / get_objects_to_exclude().
Add-ons which design whole model objects (Steel Joints, Component Design, Craneway
Design, Concrete Foundations) have no Objects to Design table; there the selection
is an attribute of the object itself (SteelJoint.to_design, Craneway.to_design, …).
The add-on has to be active in the base data, otherwise both methods report that it is not active.
from dlubal.api import rfem, common
from math import inf
import pandas
# -------------------------------------------------------
# This example demonstrates how to read and modify the two
# input tables of a design add-on:
# Objects to Design - which objects the add-on designs,
# one row per object type and role
# Objects to Exclude - which objects are excluded from the
# design of a design situation or a
# load combination, one row per case object
#
# Add-ons which design whole model objects (Steel Joints,
# Component Design, Craneway Design, Concrete Foundations) have no
# Objects to Design table - there the selection is an attribute of
# the object itself (SteelJoint.to_design, Craneway.to_design, ...).
#
# The model is a two-span beam (members 1 and 2) loaded in two load
# combinations (CO1 and CO2), so all four member/combination pairs could
# be designed. Both tables narrow this down step by step:
# Objects to Design - member 2 is removed from the design
# Objects to Exclude - member 1 is excluded from CO2
# After the calculation only member 1 in CO1 has design results.
# -------------------------------------------------------
ADDON = rfem.DesignAddons.STEEL_DESIGN
DISTRIBUTED_LOAD = 10000.0 # N/m
def define_structure_objects() -> list:
# Two-span beam, 2 x 5 m: pinned at the left end, rollers at the middle
# support and at the right end.
return [
rfem.structure_core.Material(no=1, name="S235 | EN 1993-1-1:2005-05"),
rfem.structure_core.CrossSection(no=1, name="IPE 200", material=1),
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=5.0, coordinate_2=0.0, coordinate_3=0.0),
rfem.structure_core.Node(no=3, coordinate_1=10.0, coordinate_2=0.0, coordinate_3=0.0),
rfem.structure_core.Line(no=1, definition_nodes=[1, 2]),
rfem.structure_core.Line(no=2, definition_nodes=[2, 3]),
rfem.structure_core.Member(no=1, line=1, cross_section_start=1),
rfem.structure_core.Member(no=2, line=2, cross_section_start=1),
rfem.types_for_nodes.NodalSupport(
no=1,
nodes=[1],
spring=common.Vector3d(x=inf, y=inf, z=inf),
rotational_restraint=common.Vector3d(x=inf, y=0.0, z=0.0),
),
rfem.types_for_nodes.NodalSupport(
no=2,
nodes=[2, 3],
spring=common.Vector3d(x=0.0, y=inf, z=inf),
rotational_restraint=common.Vector3d(x=inf, y=0.0, z=0.0),
),
]
def define_loading_objects() -> list:
# One load case with a uniform load on both spans, evaluated in two load
# combinations. CO2 is the governing one - unless the member is excluded
# from it further below.
return [
rfem.loading.StaticAnalysisSettings(no=1),
rfem.loading.LoadCase(
no=1,
name="LC1",
static_analysis_settings=1,
self_weight_active=False,
),
rfem.loading.DesignSituation(
no=1,
user_defined_name_enabled=True,
name="ULS - Permanent and transient",
design_situation_type=rfem.loading.DesignSituation.DESIGN_SITUATION_TYPE_STR_PERMANENT_AND_TRANSIENT_6_10,
),
rfem.loading.LoadCombination(no=1, design_situation=1, name="CO1",
static_analysis_settings=1, combination_rule_str="LC1"),
rfem.loading.LoadCombination(no=2, design_situation=1, name="CO2",
static_analysis_settings=1, combination_rule_str="1.35*LC1"),
rfem.loads.MemberLoad(
no=1,
members=[1, 2],
load_case=1,
magnitude=DISTRIBUTED_LOAD,
),
]
def define_steel_design_objects() -> list:
# delete_all_objects() removes the default configurations as well, so the
# add-on needs at least the ULS configuration to design anything.
return [
rfem.steel_design_objects.SteelDesignUlsConfiguration(
no=1,
assigned_to_all_members=True,
),
]
# Connect to the RFEM application
with rfem.Application() as rfem_app:
rfem_app.close_all_models(save_changes=False)
rfem_app.create_model(name="objects_to_design_and_exclude")
# Activate the add-on, otherwise both methods report that it is not active
base_data = rfem_app.get_base_data()
base_data.addons.steel_design_active = True
rfem_app.set_base_data(base_data=base_data)
rfem_app.delete_all_objects()
rfem_app.create_object_list(
objs=
define_structure_objects() +
define_loading_objects() +
define_steel_design_objects()
)
# --- Objects to Design ---
objects_to_design = rfem_app.get_objects_to_design(addon=ADDON)
print(f"\nOBJECTS TO DESIGN:\n{objects_to_design}")
# A row is addressed by its key: the object type and the role. The table has a row only for
# object types which exist in the model, and Timber/Glass Design have two rows of the same
# object type distinguished by the role.
rfem_app.set_objects_to_design(
addon=ADDON,
objects_to_design=rfem.ObjectsToDesignTable(rows=[
rfem.ObjectsToDesignRow(
object_type=rfem.ObjectType.OBJECT_TYPE_MEMBER,
role=rfem.ObjectsToDesignRow.Role.ROLE_DEFAULT,
design_all=False,
selected_objects=[1, 2],
removed_from_design=[2],
comment="set through the API",
),
]),
)
# Only the rows contained in the request are modified. 'to_design' and 'not_valid_deactivated'
# are results of the selection and are read only. Member 2 is selected but removed again,
# so 'to_design' contains member 1 only.
objects_to_design = rfem_app.get_objects_to_design(addon=ADDON)
print(f"\nOBJECTS TO DESIGN AFTER THE CHANGE:\n{objects_to_design}")
# --- Objects to Exclude ---
objects_to_exclude = rfem_app.get_objects_to_exclude(addon=ADDON)
print(f"\nOBJECTS TO EXCLUDE:\n{objects_to_exclude}")
# A row is addressed by its case object - the design situation or the load combination the row
# belongs to. Every object type of the add-on has its own column with the excluded objects.
co2_row = next(
row for row in objects_to_exclude.rows
if row.case_object.object_type == rfem.ObjectType.OBJECT_TYPE_LOAD_COMBINATION
and row.case_object.no == 2
)
rfem_app.set_objects_to_exclude(
addon=ADDON,
objects_to_exclude=rfem.ObjectsToExcludeTable(rows=[
rfem.ObjectsToExcludeRow(
case_object=co2_row.case_object,
members=[1],
comment="excluded through the API",
),
]),
)
objects_to_exclude = rfem_app.get_objects_to_exclude(addon=ADDON)
print(f"\nOBJECTS TO EXCLUDE AFTER THE CHANGE:\n{objects_to_exclude}")
calculation_info = rfem_app.calculate_all(skip_warnings=True)
if not calculation_info.succeeded:
errors_and_warnings = rfem_app.get_result_table(
table=rfem.results.ResultTable.ERRORS_AND_WARNINGS_TABLE,
loading=None,
).data
print(f"\nCALCULATION FAILED:\n{errors_and_warnings}")
else:
pandas.set_option("display.max_columns", None)
pandas.set_option("display.width", 200)
# Member 2 is not designed at all and member 1 is designed for CO1 only,
# so one out of the four member/combination pairs is left in the results.
design_ratios = rfem_app.get_result_table(
table=rfem.results.ResultTable.STEEL_DESIGN_MEMBERS_DESIGN_RATIOS_BY_MEMBER_TABLE,
loading=None,
).data
print(f"\nSTEEL DESIGN | DESIGN RATIOS BY MEMBER:\n{design_ratios}")
using Rfem = Dlubal.Api.Rfem;
using Common = Dlubal.Api.Common;
using Google.Protobuf;
// -------------------------------------------------------
// This example demonstrates how to read and modify the two
// input tables of a design add-on:
// Objects to Design - which objects the add-on designs,
// one row per object type and role
// Objects to Exclude - which objects are excluded from the
// design of a design situation or a
// load combination, one row per case object
//
// Add-ons which design whole model objects (Steel Joints,
// Component Design, Craneway Design, Concrete Foundations) have no
// Objects to Design table - there the selection is an attribute of
// the object itself (SteelJoint.ToDesign, Craneway.ToDesign, ...).
//
// The model is a two-span beam (members 1 and 2) loaded in two load
// combinations (CO1 and CO2), so all four member/combination pairs could
// be designed. Both tables narrow this down step by step:
// Objects to Design - member 2 is removed from the design
// Objects to Exclude - member 1 is excluded from CO2
// After the calculation only member 1 in CO1 has design results.
// -------------------------------------------------------
const Rfem.DesignAddons ADDON = Rfem.DesignAddons.SteelDesign;
const double DISTRIBUTED_LOAD = 10000.0; // N/m
static List<IMessage> DefineStructureObjects()
{
// Two-span beam, 2 x 5 m: pinned at the left end, rollers at the middle
// support and at the right end.
double inf = double.PositiveInfinity;
return new List<IMessage>
{
new Rfem.StructureCore.Material{No=1, Name="S235 | EN 1993-1-1:2005-05"},
new Rfem.StructureCore.CrossSection{No=1, Name="IPE 200", Material=1},
new Rfem.StructureCore.Node{No=1, Coordinate1=0.0, Coordinate2=0.0, Coordinate3=0.0},
new Rfem.StructureCore.Node{No=2, Coordinate1=5.0, Coordinate2=0.0, Coordinate3=0.0},
new Rfem.StructureCore.Node{No=3, Coordinate1=10.0, Coordinate2=0.0, Coordinate3=0.0},
new Rfem.StructureCore.Line{No=1, DefinitionNodes={1, 2}},
new Rfem.StructureCore.Line{No=2, DefinitionNodes={2, 3}},
new Rfem.StructureCore.Member{No=1, Line=1, CrossSectionStart=1},
new Rfem.StructureCore.Member{No=2, Line=2, CrossSectionStart=1},
new Rfem.TypesForNodes.NodalSupport
{
No = 1,
Nodes = { 1 },
Spring = new Common.Vector3d{X=inf, Y=inf, Z=inf},
RotationalRestraint = new Common.Vector3d{X=inf, Y=0.0, Z=0.0},
},
new Rfem.TypesForNodes.NodalSupport
{
No = 2,
Nodes = { 2, 3 },
Spring = new Common.Vector3d{X=0.0, Y=inf, Z=inf},
RotationalRestraint = new Common.Vector3d{X=inf, Y=0.0, Z=0.0},
},
};
}
static List<IMessage> DefineLoadingObjects()
{
// One load case with a uniform load on both spans, evaluated in two load
// combinations. CO2 is the governing one - unless the member is excluded
// from it further below.
return new List<IMessage>
{
new Rfem.Loading.StaticAnalysisSettings{No=1},
new Rfem.Loading.LoadCase
{
No = 1,
Name = "LC1",
StaticAnalysisSettings = 1,
SelfWeightActive = false,
},
new Rfem.Loading.DesignSituation
{
No = 1,
UserDefinedNameEnabled = true,
Name = "ULS - Permanent and transient",
DesignSituationType = Rfem.Loading.DesignSituation.Types.DesignSituationType.StrPermanentAndTransient610,
},
new Rfem.Loading.LoadCombination
{
No = 1, DesignSituation = 1, Name = "CO1",
StaticAnalysisSettings = 1, CombinationRuleStr = "LC1",
},
new Rfem.Loading.LoadCombination
{
No = 2, DesignSituation = 1, Name = "CO2",
StaticAnalysisSettings = 1, CombinationRuleStr = "1.35*LC1",
},
new Rfem.Loads.MemberLoad
{
No = 1,
Members = { 1, 2 },
LoadCase = 1,
Magnitude = DISTRIBUTED_LOAD,
},
};
}
static List<IMessage> DefineSteelDesignObjects()
{
// delete_all_objects() removes the default configurations as well, so the
// add-on needs at least the ULS configuration to design anything.
return new List<IMessage>
{
new Rfem.SteelDesignObjects.SteelDesignUlsConfiguration
{
No = 1,
AssignedToAllMembers = true,
},
};
}
// --- MAIN SCRIPT ---
ApplicationRfem? rfemApp = null;
try
{
// Connect to the RFEM application
rfemApp = new ApplicationRfem();
rfemApp.close_all_models(saveChanges: false);
rfemApp.create_model(name: "objects_to_design_and_exclude");
// Activate the add-on, otherwise both methods report that it is not active
var baseData = rfemApp.get_base_data();
baseData.Addons.SteelDesignActive = true;
rfemApp.set_base_data(baseData: baseData);
rfemApp.delete_all_objects();
var modelObjects = new List<IMessage>();
modelObjects.AddRange(DefineStructureObjects());
modelObjects.AddRange(DefineLoadingObjects());
modelObjects.AddRange(DefineSteelDesignObjects());
rfemApp.create_object_list(objs: modelObjects);
// --- Objects to Design ---
var objectsToDesign = rfemApp.get_objects_to_design(addon: ADDON);
Console.WriteLine($"\nOBJECTS TO DESIGN:\n{objectsToDesign}");
// A row is addressed by its key: the object type and the role. The table has a row only for
// object types which exist in the model, and Timber/Glass Design have two rows of the same
// object type distinguished by the role.
rfemApp.set_objects_to_design(
addon: ADDON,
objectsToDesign: new Rfem.ObjectsToDesignTable
{
Rows =
{
new Rfem.ObjectsToDesignRow
{
ObjectType = Rfem.ObjectType.Member,
Role = Rfem.ObjectsToDesignRow.Types.Role.Default,
DesignAll = false,
SelectedObjects = { 1, 2 },
RemovedFromDesign = { 2 },
Comment = "set through the API",
},
},
}
);
// Only the rows contained in the request are modified. 'to_design' and 'not_valid_deactivated'
// are results of the selection and are read only. Member 2 is selected but removed again,
// so 'to_design' contains member 1 only.
objectsToDesign = rfemApp.get_objects_to_design(addon: ADDON);
Console.WriteLine($"\nOBJECTS TO DESIGN AFTER THE CHANGE:\n{objectsToDesign}");
// --- Objects to Exclude ---
var objectsToExclude = rfemApp.get_objects_to_exclude(addon: ADDON);
Console.WriteLine($"\nOBJECTS TO EXCLUDE:\n{objectsToExclude}");
// A row is addressed by its case object - the design situation or the load combination the row
// belongs to. Every object type of the add-on has its own column with the excluded objects.
var co2Row = objectsToExclude.Rows.First(
row => row.CaseObject.ObjectType == Rfem.ObjectType.LoadCombination
&& row.CaseObject.No == 2
);
rfemApp.set_objects_to_exclude(
addon: ADDON,
objectsToExclude: new Rfem.ObjectsToExcludeTable
{
Rows =
{
new Rfem.ObjectsToExcludeRow
{
CaseObject = co2Row.CaseObject,
Members = { 1 },
Comment = "excluded through the API",
},
},
}
);
objectsToExclude = rfemApp.get_objects_to_exclude(addon: ADDON);
Console.WriteLine($"\nOBJECTS TO EXCLUDE AFTER THE CHANGE:\n{objectsToExclude}");
var calculationInfo = rfemApp.calculate_all(skipWarnings: true);
if (!calculationInfo.Succeeded)
{
var errorsAndWarnings = rfemApp.get_result_table(
table: Rfem.Results.ResultTable.ErrorsAndWarningsTable,
loading: null
);
Console.WriteLine("\nCALCULATION FAILED:");
errorsAndWarnings.Print();
}
else
{
// Member 2 is not designed at all and member 1 is designed for CO1 only,
// so one out of the four member/combination pairs is left in the results.
var designRatios = rfemApp.get_result_table(
table: Rfem.Results.ResultTable.SteelDesignMembersDesignRatiosByMemberTable,
loading: null
);
Console.WriteLine("\nSTEEL DESIGN | DESIGN RATIOS BY MEMBER:");
designRatios.Print();
}
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
}
finally
{
if (rfemApp != null) rfemApp.close_connection();
}