Response Spectrum by Standard#
|
Defining a response spectrum according to standard, adjusting the peak ground acceleration, and reading spectral member forces:
Keywords:
spectral analysis response spectrum standard peak ground acceleration member internal forces |
from math import inf
from dlubal.api import rfem, common
# -------------------------------------------------------
# This example demonstrates response spectrum analysis with a response spectrum defined according to standard.
# It defines the same fixed-column model, modal mass import,
# spectral analysis settings, and result retrieval workflow.
# -------------------------------------------------------
def define_structure() -> list:
"""Define a single fixed column (IPE 550)."""
return [
# Material
rfem.structure_core.Material(
no=1,
name='S235',
),
# CrossSection
rfem.structure_core.CrossSection(
no=1,
name='IPE 550',
material=1,
),
# Nodes
rfem.structure_core.Node(
no=1,
coordinate_2=-2,
),
rfem.structure_core.Node(
no=2,
coordinate_2=-2,
coordinate_3=-4,
),
# Line
rfem.structure_core.Line(
no=1,
definition_nodes=[1, 2],
),
# Member
rfem.structure_core.Member(
no=1,
line=1,
cross_section_start=1,
),
# Support
rfem.types_for_nodes.NodalSupport(
no=1,
user_defined_name_enabled=True,
name="Fixed",
nodes=[1],
spring=common.Vector3d(x=inf, y=inf, z=inf),
rotational_restraint=common.Vector3d(x=inf, y=inf, z=inf),
)
]
def define_loading() -> list:
"""Define load cases, static analysis settings, and seismic mass combinations."""
return [
# Load Case | LC1
rfem.loading.LoadCase(
no=1,
name="Static | Self-weight",
static_analysis_settings=1,
),
# Nodal Loads | LC1
rfem.loads.NodalLoad( # Force
no=1,
nodes=[2],
force_magnitude=1000,
load_direction=rfem.loads.NodalLoad.LOAD_DIRECTION_GLOBAL_Z_OR_USER_DEFINED_W_TRUE_LENGTH,
load_case=1,
),
rfem.loads.NodalLoad( # Mass
no=2,
load_type=rfem.loads.NodalLoad.LOAD_TYPE_MASS,
nodes=[2],
individual_mass_components=True,
mass=common.Vector3d(x=100, y=100, z=100),
mass_moment_of_inertia=common.Vector3d(x=100, y=100, z=100),
load_case=1,
),
# Static Analysis Settings
rfem.loading.StaticAnalysisSettings(
no=1,
analysis_type=rfem.loading.StaticAnalysisSettings.ANALYSIS_TYPE_GEOMETRICALLY_LINEAR,
mass_conversion_enabled=True,
),
rfem.loading.StaticAnalysisSettings(
no=2,
analysis_type=rfem.loading.StaticAnalysisSettings.ANALYSIS_TYPE_SECOND_ORDER_P_DELTA,
mass_conversion_enabled=True,
consider_favorable_effect_due_to_tension_in_members=True,
),
# --- Combinatoric for Seismic Mass ---
# Combination Wizard
rfem.loading.CombinationWizard(
no=1,
generate_combinations=rfem.loading.CombinationWizard.GENERATE_COMBINATIONS_LOAD_COMBINATIONS,
consider_imperfection_case=True,
static_analysis_settings=2,
),
rfem.loading.CombinationWizard(
no=2,
generate_combinations=rfem.loading.CombinationWizard.GENERATE_COMBINATIONS_RESULT_COMBINATIONS,
),
# Design Situations
rfem.loading.DesignSituation(
no=1,
name="Seismic/Mass Combination - psi-E,i",
design_situation_type=rfem.loading.DesignSituation.DesignSituationType.DESIGN_SITUATION_TYPE_SEISMIC_MASS,
combination_wizard=1,
),
rfem.loading.DesignSituation(
no=2,
name="ULS (EQU) - Seismic",
design_situation_type= rfem.loading.DesignSituation.DesignSituationType.DESIGN_SITUATION_TYPE_EQU_SEISMIC,
combination_wizard=2,
),
]
def define_response_spectra() -> list:
"""Define response spectrum input data for this example."""
return [
rfem.dynamic_loads.ResponseSpectrum(
no=1,
definition_type=rfem.dynamic_loads.ResponseSpectrum.DEFINITION_TYPE_ACCORDING_TO_STANDARD,
user_defined_response_spectrum_step_enabled=False,
is_g_factor_mode=False,
),
]
def define_modal_analysis_settings() -> list:
"""Modal analysis settings and the corresponding modal load case."""
return [
# Modal Analysis Settings
rfem.loading.ModalAnalysisSettings(
no=1,
name='User-defined | Modes=10',
user_defined_name_enabled=True,
acting_masses_about_axis_x_enabled=True,
acting_masses_about_axis_y_enabled=True,
acting_masses_about_axis_z_enabled=True,
acting_masses_in_direction_z_enabled=True,
activate_minimum_initial_prestress=False,
solution_method=rfem.loading.ModalAnalysisSettings.SOLUTION_METHOD_LANCZOS,
number_of_modes=10,
minimum_initial_strain=0.00001,
),
# Modal Load Cases
rfem.loading.LoadCase(
no=2,
analysis_type=rfem.loading.LoadCase.ANALYSIS_TYPE_MODAL_ANALYSIS,
name="Modal Analysis ALL 10",
modal_analysis_settings=1,
),
]
def define_spectral_analysis_settings() -> list:
"""Spectral analysis settings (SRSS + Scaled Sum 30%) and the RSA load case."""
return [
# Spectral Analysis Settings
rfem.loading.SpectralAnalysisSettings(
no=1,
user_defined_name_enabled=True,
name='SRSS | Scaled Sum 30.00 %',
assigned_to='LC 3',
combination_rule_for_periodic_responses=rfem.loading.SpectralAnalysisSettings.COMBINATION_RULE_FOR_DIRECTIONAL_COMPONENTS_SRSS,
use_equivalent_linear_combination=False,
combination_rule_for_directional_components=rfem.loading.SpectralAnalysisSettings.COMBINATION_RULE_FOR_DIRECTIONAL_COMPONENTS_SCALED_SUM,
combination_rule_for_directional_components_value=0.3,
),
# Spectral Load Cases
rfem.loading.LoadCase(
no=3,
analysis_type=rfem.loading.LoadCase.ANALYSIS_TYPE_RESPONSE_SPECTRUM_ANALYSIS,
name="RSA Direction X",
spectral_analysis_settings=1,
response_spectrum_is_enabled_in_direction_x=True,
response_spectrum_in_direction_x=1,
response_spectrum_and_equivalent_load_consider_accidental_torsion=True,
response_spectrum_and_equivalent_load_eccentricity_for_y_direction_relative=0.01,
import_modal_analysis_from=2,
response_spectrum_save_results_of_all_selected_modes=True,
),
]
# -------------------------------------------------------
# MAIN SCRIPT
# -------------------------------------------------------
with rfem.Application() as rfem_app:
rfem_app.close_all_models(save_changes=False)
rfem_app.create_model(name='Response Spectrum by Standard')
# Set global model settings:
base_data: rfem.BaseData = rfem_app.get_base_data()
# Activate add-ons
base_data.addons.modal_analysis_active = True
base_data.addons.response_spectrum_analysis_active = True
base_data.combinations_settings.combination_wizard_active = True
base_data.combinations_settings.result_combinations_active = True
base_data.combinations_settings.result_combinations_parentheses_active = True
base_data.combinations_settings.result_combinations_consider_sub_results = True
# Set standard
base_data.standards.combination_wizard_standard = rfem.BaseData.Standards.COMBINATION_WIZARD_NATIONAL_ANNEX_AND_EDITION_EN_1990_DIN_2012_08_STANDARD
base_data.standards.load_wizard_standard = rfem.BaseData.Standards.LOAD_WIZARD_NATIONAL_ANNEX_AND_EDITION_EN_1991_DIN_2019_04_STANDARD
base_data.standards.dynamic_analysis_standard = rfem.BaseData.Standards.DYNAMIC_ANALYSIS_NATIONAL_ANNEX_AND_EDITION_EN_1998_1_DIN_2023_11_STANDARD
# Adjust general settings
base_data.general_settings.gravitational_acceleration = 9.81
rfem_app.set_base_data(base_data=base_data)
rfem_app.delete_all_objects()
# Build model structure and loading
rfem_app.create_object_list(
define_structure() +
define_loading()
)
# Define analysis settings
rfem_app.create_object_list(
define_modal_analysis_settings() +
define_spectral_analysis_settings()
)
# Import masses from combinations to modal load cases
rfem_app.generate_combinations()
lc_list = rfem_app.get_object_list(
objs=[rfem.loading.LoadCase()]
)
for lc in lc_list:
if lc.analysis_type is rfem.loading.LoadCase.ANALYSIS_TYPE_MODAL_ANALYSIS:
lc.import_masses_from.no = 1
lc.import_masses_from.object_type = rfem.ObjectType.OBJECT_TYPE_LOAD_COMBINATION
rfem_app.update_object_list(lc_list)
# Create response spectrum data
rfem_app.create_object_list(
objs=define_response_spectra()
)
# Modify response spectrum by standard (peak ground acceleration)
spectrum_by_standard = rfem_app.get_object(
rfem.dynamic_loads.ResponseSpectrum(no=1)
)
common.set_values_by_key(
tree=spectrum_by_standard.standard_parameters,
key='a_gr',
values=[0.459]
)
rfem_app.update_object(spectrum_by_standard)
# Retrieve results
rfem_app.calculate_all(skip_warnings=True)
results = rfem_app.get_results(
results_type=rfem.results.ResultsType.SPECTRAL_ANALYSIS_MEMBERS_INTERNAL_FORCES
)
print(f"\nSpectral Analysis | Members Internal Forces:\n{results.data}")
using Google.Protobuf;
using Common = Dlubal.Api.Common;
using Rfem = Dlubal.Api.Rfem;
static List<IMessage> DefineStructureAndLoading()
{
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 550 | DIN 1025-5:1994-03 | Ferona", Material = 1 },
new Rfem.StructureCore.Node { No = 1, Coordinate2 = -2 },
new Rfem.StructureCore.Node { No = 2, Coordinate2 = -2, Coordinate3 = -4 },
new Rfem.StructureCore.Line { No = 1, DefinitionNodes = { 1, 2 } },
new Rfem.StructureCore.Member { No = 1, Line = 1, CrossSectionStart = 1 },
new Rfem.TypesForNodes.NodalSupport { No = 1, Nodes = { 1 }, Spring = new Common.Vector3d { X = double.PositiveInfinity, Y = double.PositiveInfinity, Z = double.PositiveInfinity }, RotationalRestraint = new Common.Vector3d { X = double.PositiveInfinity, Y = double.PositiveInfinity, Z = double.PositiveInfinity } },
new Rfem.Loading.StaticAnalysisSettings { No = 1, AnalysisType = Rfem.Loading.StaticAnalysisSettings.Types.AnalysisType.GeometricallyLinear, MassConversionEnabled = true },
new Rfem.Loading.StaticAnalysisSettings { No = 2, AnalysisType = Rfem.Loading.StaticAnalysisSettings.Types.AnalysisType.SecondOrderPDelta, MassConversionEnabled = true, ConsiderFavorableEffectDueToTensionInMembers = true },
new Rfem.Loading.LoadCase { No = 1, Name = "Static | Self-weight", StaticAnalysisSettings = 1 },
new Rfem.Loads.NodalLoad { No = 1, Nodes = { 2 }, ForceMagnitude = 1000, LoadCase = 1, LoadDirection = Rfem.Loads.NodalLoad.Types.LoadDirection.GlobalZOrUserDefinedWTrueLength },
new Rfem.Loads.NodalLoad { No = 2, Nodes = { 2 }, LoadCase = 1, LoadType = Rfem.Loads.NodalLoad.Types.LoadType.Mass, IndividualMassComponents = true, Mass = new Common.Vector3d { X = 100, Y = 100, Z = 100 }, MassMomentOfInertia = new Common.Vector3d { X = 100, Y = 100, Z = 100 } },
new Rfem.Loading.CombinationWizard { No = 1, GenerateCombinations = Rfem.Loading.CombinationWizard.Types.GenerateCombinations.LoadCombinations, ConsiderImperfectionCase = true, StaticAnalysisSettings = 2 },
new Rfem.Loading.CombinationWizard { No = 2, GenerateCombinations = Rfem.Loading.CombinationWizard.Types.GenerateCombinations.ResultCombinations },
new Rfem.Loading.DesignSituation { No = 1, Name = "Seismic/Mass Combination - psi-E,i", DesignSituationType = Rfem.Loading.DesignSituation.Types.DesignSituationType.SeismicMass, CombinationWizard = 1 },
new Rfem.Loading.DesignSituation { No = 2, Name = "ULS (EQU) - Seismic", DesignSituationType = Rfem.Loading.DesignSituation.Types.DesignSituationType.EquSeismic, CombinationWizard = 2 },
new Rfem.Loading.ModalAnalysisSettings { No = 1, Name = "User-defined | Modes=10", UserDefinedNameEnabled = true, ActingMassesAboutAxisXEnabled = true, ActingMassesAboutAxisYEnabled = true, ActingMassesAboutAxisZEnabled = true, ActingMassesInDirectionZEnabled = true, SolutionMethod = Rfem.Loading.ModalAnalysisSettings.Types.SolutionMethod.Lanczos, NumberOfModes = 10, MinimumInitialStrain = 0.00001 },
new Rfem.Loading.LoadCase { No = 2, AnalysisType = Rfem.Loading.LoadCase.Types.AnalysisType.ModalAnalysis, Name = "Modal Analysis ALL 10", ModalAnalysisSettings = 1 },
new Rfem.Loading.SpectralAnalysisSettings { No = 1, UserDefinedNameEnabled = true, Name = "SRSS | Scaled Sum 30.00 %", AssignedTo = "LC 3", CombinationRuleForPeriodicResponses = Rfem.Loading.SpectralAnalysisSettings.Types.CombinationRuleForPeriodicResponses.Srss, UseEquivalentLinearCombination = false, CombinationRuleForDirectionalComponents = Rfem.Loading.SpectralAnalysisSettings.Types.CombinationRuleForDirectionalComponents.ScaledSum, CombinationRuleForDirectionalComponentsValue = 0.3 },
new Rfem.Loading.LoadCase { No = 3, AnalysisType = Rfem.Loading.LoadCase.Types.AnalysisType.ResponseSpectrumAnalysis, Name = "RSA Direction X", SpectralAnalysisSettings = 1, ResponseSpectrumIsEnabledInDirectionX = true, ResponseSpectrumInDirectionX = 1, ResponseSpectrumAndEquivalentLoadConsiderAccidentalTorsion = true, ResponseSpectrumAndEquivalentLoadEccentricityForYDirectionRelative = 0.01, ImportModalAnalysisFrom = 2, ResponseSpectrumSaveResultsOfAllSelectedModes = true },
};
}
static List<IMessage> DefineResponseSpectrumData()
{
return new List<IMessage>
{
new Rfem.DynamicLoads.ResponseSpectrum
{
No = 1,
DefinitionType = Rfem.DynamicLoads.ResponseSpectrum.Types.DefinitionType.AccordingToStandard,
UserDefinedResponseSpectrumStepEnabled = false,
IsGFactorMode = false,
},
};
}
ApplicationRfem? rfemApp = null;
try
{
rfemApp = new ApplicationRfem();
rfemApp.close_all_models(saveChanges: false);
rfemApp.create_model(name: "Response Spectrum by Standard");
var baseData = rfemApp.get_base_data();
baseData.Addons.ModalAnalysisActive = true;
baseData.Addons.ResponseSpectrumAnalysisActive = true;
baseData.CombinationsSettings.CombinationWizardActive = true;
baseData.CombinationsSettings.ResultCombinationsActive = true;
baseData.CombinationsSettings.ResultCombinationsParenthesesActive = true;
baseData.CombinationsSettings.ResultCombinationsConsiderSubResults = true;
baseData.Standards.CombinationWizardStandard = Rfem.BaseData.Types.Standards.Types.CombinationWizardStandard.CombinationWizardNationalAnnexAndEditionEn1990Din201208Standard;
baseData.Standards.LoadWizardStandard = Rfem.BaseData.Types.Standards.Types.LoadWizardStandard.LoadWizardNationalAnnexAndEditionEn1991Din201904Standard;
baseData.Standards.DynamicAnalysisStandard = Rfem.BaseData.Types.Standards.Types.DynamicAnalysisStandard.DynamicAnalysisNationalAnnexAndEditionEn19981Din202311Standard;
baseData.GeneralSettings.GravitationalAcceleration = 9.81;
rfemApp.set_base_data(baseData: baseData);
rfemApp.delete_all_objects();
rfemApp.create_object_list(DefineStructureAndLoading());
rfemApp.generate_combinations();
var loadCases = rfemApp.get_object_list(new List<IMessage> { new Rfem.Loading.LoadCase() });
foreach (var obj in loadCases)
{
if (obj is Rfem.Loading.LoadCase lc && lc.AnalysisType == Rfem.Loading.LoadCase.Types.AnalysisType.ModalAnalysis)
{
lc.ImportMassesFrom = new Rfem.ObjectId { No = 1, ObjectType = Rfem.ObjectType.LoadCombination };
}
}
rfemApp.update_object_list(loadCases);
rfemApp.create_object_list(DefineResponseSpectrumData());
var spectrumByStandard = rfemApp.get_object<Rfem.DynamicLoads.ResponseSpectrum>(new Rfem.DynamicLoads.ResponseSpectrum { No = 1 });
if (spectrumByStandard != null)
{
Common.TreeTable.SetValuesByKey(tree: spectrumByStandard.StandardParameters, key: "a_gr", values: new List<object> { 0.459 });
rfemApp.update_object(spectrumByStandard);
}
rfemApp.calculate_all(skipWarnings: true);
var results = rfemApp.get_results(resultsType: Rfem.Results.ResultsType.SpectralAnalysisMembersInternalForces);
Console.WriteLine($"\nSpectral Analysis | Members Internal Forces:\n{results.Data}");
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
}
finally
{
if (rfemApp != null) rfemApp.close_connection();
}