Skip to content

Commit c0dd8d5

Browse files
authored
Merge pull request #363 from Dlubal-Software/heet-memberSpring
Heet member spring
2 parents 07ce677 + f56141a commit c0dd8d5

5 files changed

Lines changed: 299 additions & 5 deletions

File tree

RFEM/BasicObjects/member.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1727,6 +1727,63 @@ def CouplingHingeHinge(
17271727
# Add Member to client model
17281728
model.clientModel.service.set_member(clientObject)
17291729

1730+
@staticmethod
1731+
def Spring(no: int = 1,
1732+
start_node_no: int = 1,
1733+
end_node_no: int = 2,
1734+
line: int = None,
1735+
spring_type: int = None,
1736+
comment: str = '',
1737+
params: dict = None,
1738+
model = Model):
1739+
"""
1740+
Args:
1741+
no (int): Member Tag
1742+
start_node_no (int): Tag of Start Node
1743+
end_node_no (int): Tag of End Node
1744+
line (int, optional): Assigned Line
1745+
spring_type (int, optional): Assign Member Spring Type
1746+
comment (str, optional): Comment
1747+
params (dict, optional): Any WS Parameter relevant to the object and its value in form of a dictionary
1748+
model (RFEM Class, optional): Model to be edited
1749+
"""
1750+
1751+
# Client model | Member
1752+
clientObject = model.clientModel.factory.create('ns0:member')
1753+
1754+
# Clears object atributes | Sets all atributes to None
1755+
clearAttributes(clientObject)
1756+
1757+
# Member No.
1758+
clientObject.no = no
1759+
1760+
# Member Type
1761+
clientObject.type = MemberType.TYPE_SPRING.name
1762+
1763+
# Assigned Line number or Node numbers
1764+
if line is None:
1765+
clientObject.node_start = start_node_no
1766+
clientObject.node_end = end_node_no
1767+
else:
1768+
clientObject.line = line
1769+
1770+
# Spring Type
1771+
clientObject.member_type_spring = spring_type
1772+
1773+
# Comment
1774+
clientObject.comment = comment
1775+
1776+
# Adding optional parameters via dictionary
1777+
if params:
1778+
for key in params:
1779+
clientObject[key] = params[key]
1780+
1781+
# Delete None attributes for improved performance
1782+
deleteEmptyAttributes(clientObject)
1783+
1784+
# Add Member to client model
1785+
model.clientModel.service.set_member(clientObject)
1786+
17301787
@staticmethod
17311788
def DeleteMember(members_no: str = '1 2', model = Model):
17321789

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
from RFEM.initModel import Model, clearAttributes, deleteEmptyAttributes,ConvertToDlString
2+
from RFEM.enums import MemberSpringType, PartialActivityAlongType, MemberSpringSelfWeightDefinition
3+
4+
class MemberSpring():
5+
6+
def __init__(self,
7+
no: int = 1,
8+
member: str = "",
9+
definition_type = MemberSpringType.PARTIAL_ACTIVITY,
10+
parameters: list = [[PartialActivityAlongType.PARTIAL_ACTIVITY_TYPE_COMPLETE, 0.0], [PartialActivityAlongType.PARTIAL_ACTIVITY_TYPE_COMPLETE, 0.0]],
11+
axial_stiffness: float = 0.0,
12+
self_weight: list = [MemberSpringSelfWeightDefinition.MASS_PER_LENGTH, 1],
13+
name: str = None,
14+
comment: str = '',
15+
params: dict = None,
16+
model = Model):
17+
18+
'''
19+
Args:
20+
no (int): Member Spring Tag
21+
members (str): Assigned Members
22+
definition_type (enum): Member Spring Type Enumeration
23+
parameters (list of lists): List of Parameters for Spring Nonlinearity
24+
for definition_type == 'PARTIAL_ACTIVITY':
25+
parameters = [negative zone, positive zone]
26+
for negative/positive zone[0] == PartialActivityAlongType.PARTIAL_ACTIVITY_TYPE_COMPLETE:
27+
negative/positive zone = [negative/positive zone type (enum), slippage (float)]
28+
for negative/positive zone[0] == PartialActivityAlongType.PARTIAL_ACTIVITY_TYPE_FIXED:
29+
negative/positive zone = [negative/positive zone type (enum), slippage (float), displacement (float)] (Note: Displacement must be greater than slippage)
30+
for negative/positive zone[0] == PartialActivityAlongType.PARTIAL_ACTIVITY_TYPE_FAILURE_FROM_FORCE/PARTIAL_ACTIVITY_TYPE_YIELDING_FROM_FORCE:
31+
negative/positive zone = [negative/positive zone type (enum), slippage (float), force (float)]
32+
for definition_type == 'DIAGRAM':
33+
parameters = [[symmetric(bool), LineReleaseDiagram Enumeration(start), LineReleaseDiagram Enumeration(end)], [[displacement, force],...]]
34+
axial_stiffness (float): Axial Stiffness
35+
self_weight (list): Self Weight Parameters List
36+
for self_weight[0] == 'MASS':
37+
self_weight = [MemberSpringSelfWeightDefinition.MASS, mass (float)]
38+
for self_weight[0] == 'MASS_PER_LENGTH':
39+
self_weight = [MemberSpringSelfWeightDefinition.MASS_PER_LENGTH, mass_per_length (float)]
40+
for self_weight[0] == 'SPECIFIC_WEIGHT':
41+
self_weight = [MemberSpringSelfWeightDefinition.SPECIFIC_WEIGHT, specific_weight (float), section_area (float)]
42+
name (str, option): User Defined Design Support Name
43+
comment (str, optional): Comment
44+
params (dict, optional): Any WS Parameter relevant to the object and its value in form of a dictionary
45+
model (RFEM Class, optional): Model to be edited
46+
'''
47+
48+
# Client model | Member Hinge
49+
clientObject = model.clientModel.factory.create('ns0:member_spring')
50+
51+
# Clears object atributes | Sets all atributes to None
52+
clearAttributes(clientObject)
53+
54+
# Member Spring No.
55+
clientObject.no = no
56+
57+
# Assigned Member
58+
clientObject.assigned_to = ConvertToDlString(member)
59+
60+
# Member Spring Type
61+
clientObject.definition_type = definition_type.name
62+
63+
# Spring Nonlinearity
64+
if definition_type.name == 'PARTIAL_ACTIVITY':
65+
66+
# Negative Zone
67+
clientObject.partial_activity_along_x_negative_type = parameters[0][0].name
68+
69+
if parameters[0][0].name == "PARTIAL_ACTIVITY_TYPE_COMPLETE":
70+
clientObject.partial_activity_along_x_negative_slippage = parameters[0][1]
71+
72+
elif parameters[0][0].name == "PARTIAL_ACTIVITY_TYPE_FIXED":
73+
clientObject.partial_activity_along_x_negative_slippage = parameters[0][1]
74+
clientObject.partial_activity_along_x_negative_displacement = parameters[0][2]
75+
76+
elif parameters[0][0].name == ("PARTIAL_ACTIVITY_TYPE_FAILURE_FROM_FORCE" or "PARTIAL_ACTIVITY_TYPE_YIELDING_FROM_FORCE"):
77+
clientObject.partial_activity_along_x_negative_slippage = parameters[0][1]
78+
clientObject.partial_activity_along_x_negative_force = parameters[0][2]
79+
80+
# Positive Zone
81+
clientObject.partial_activity_along_x_positive_type = parameters[1][0].name
82+
83+
if parameters[1][0].name == "PARTIAL_ACTIVITY_TYPE_COMPLETE":
84+
clientObject.partial_activity_along_x_positive_slippage = parameters[1][1]
85+
86+
elif parameters[1][0].name == "PARTIAL_ACTIVITY_TYPE_FIXED":
87+
clientObject.partial_activity_along_x_positive_slippage = parameters[1][1]
88+
clientObject.partial_activity_along_x_positive_displacement = parameters[1][1]
89+
90+
elif parameters[1][0].name == ("PARTIAL_ACTIVITY_TYPE_FAILURE_FROM_FORCE" or "PARTIAL_ACTIVITY_TYPE_YIELDING_FROM_FORCE"):
91+
clientObject.partial_activity_along_x_positive_slippage = parameters[1][1]
92+
clientObject.partial_activity_along_x_positive_force = parameters[1][2]
93+
94+
elif definition_type.name == 'DIAGRAM':
95+
96+
clientObject.diagram_along_x_symmetric = parameters[0][0]
97+
clientObject.diagram_along_x_is_sorted = True
98+
99+
if parameters[0][0]:
100+
clientObject.diagram_along_x_start = parameters[0][1].name
101+
clientObject.diagram_along_x_end = parameters[0][1].name
102+
103+
else:
104+
clientObject.diagram_along_x_start = parameters[0][1].name
105+
clientObject.diagram_along_x_end = parameters[0][2].name
106+
107+
clientObject.diagram_along_x_table = Model.clientModel.factory.create('ns0:member_spring.diagram_along_x_table')
108+
109+
for i,j in enumerate(parameters[1]):
110+
msdx = Model.clientModel.factory.create('ns0:member_spring_diagram_along_x_table_row')
111+
msdx.no = i+1
112+
msdx.row = Model.clientModel.factory.create('ns0:member_spring_diagram_along_x_table')
113+
clearAttributes(msdx.row)
114+
msdx.row.displacement = parameters[1][i][0]
115+
msdx.row.force = parameters[1][i][1]
116+
117+
clientObject.diagram_along_x_table.member_spring_diagram_along_x_table.append(msdx)
118+
119+
# Axial Stiffness
120+
clientObject.axial_stiffness = axial_stiffness
121+
122+
# Self Weight
123+
clientObject.self_weight_definition = self_weight[0].name
124+
125+
if self_weight[0].name == 'MASS':
126+
clientObject.mass = self_weight[1]
127+
128+
elif self_weight[0].name == 'MASS_PER_LENGTH':
129+
clientObject.mass_per_length = self_weight[1]
130+
131+
elif self_weight[0].name == 'SPECIFIC_WEIGHT':
132+
clientObject.specific_weight = self_weight[1]
133+
clientObject.section_area = self_weight[2]
134+
135+
# User Defined Name
136+
if name:
137+
clientObject.user_defined_name_enabled = True
138+
clientObject.name = name
139+
140+
# Comment
141+
clientObject.comment = comment
142+
143+
# Adding optional parameters via dictionary
144+
if params:
145+
for key in params:
146+
clientObject[key] = params[key]
147+
148+
# Delete None attributes for improved performance
149+
deleteEmptyAttributes(clientObject)
150+
151+
# Add Member Spring to client model
152+
model.clientModel.service.set_member_spring(clientObject)
153+

RFEM/enums.py

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ class MemberType(Enum):
66
Member Type
77
'''
88
TYPE_BEAM, TYPE_BUCKLING, TYPE_CABLE, TYPE_COMPRESSION, TYPE_COUPLING_HINGE_HINGE,\
9-
TYPE_COUPLING_HINGE_RIGID, TYPE_COUPLING_RIGID_HINGE, TYPE_COUPLING_RIGID_RIGID,\
10-
TYPE_DEFINABLE_STIFFNESS, TYPE_RIB, TYPE_RIGID, TYPE_TENSION, TYPE_TRUSS, TYPE_TRUSS_ONLY_N, TYPE_RESULT_BEAM = range(15)
9+
TYPE_COUPLING_HINGE_RIGID, TYPE_COUPLING_RIGID_HINGE, TYPE_COUPLING_RIGID_RIGID, TYPE_SPRING,\
10+
TYPE_DEFINABLE_STIFFNESS, TYPE_RIB, TYPE_RIGID, TYPE_TENSION, TYPE_TRUSS, TYPE_TRUSS_ONLY_N, TYPE_RESULT_BEAM = range(16)
1111

1212

1313
class NodalSupportType(Enum):
@@ -2626,18 +2626,36 @@ class MaterialStiffnessModificationType(Enum):
26262626

26272627
class PoissonRatioEditableGroupType(Enum):
26282628
'''
2629-
Poisson Ratio Editable Group Type
2629+
Poisson Ratio Editable Group Type Enumeration
26302630
'''
26312631
POISSON_RATIOS_GROUP_MAJOR_2D, POISSON_RATIOS_GROUP_MAJOR_3D, POISSON_RATIOS_GROUP_MINOR_2D, POISSON_RATIOS_GROUP_MINOR_3D = range(4)
26322632

26332633
class DesignSupportOrientationZType(Enum):
26342634
'''
2635-
Design Support Orientation Z Type
2635+
Design Support Orientation Z Type Enumeration
26362636
'''
26372637
DESIGN_SUPPORT_ORIENTATION_ZAXIS_BOTH, DESIGN_SUPPORT_ORIENTATION_ZAXIS_NEGATIVE, DESIGN_SUPPORT_ORIENTATION_ZAXIS_POSITIVE = range(3)
26382638

26392639
class DesignSupportOrientationYType(Enum):
26402640
'''
2641-
Design Support Orientation Y Type
2641+
Design Support Orientation Y Type Enumeration
26422642
'''
26432643
DESIGN_SUPPORT_ORIENTATION_YAXIS_BOTH, DESIGN_SUPPORT_ORIENTATION_YAXIS_NEGATIVE, DESIGN_SUPPORT_ORIENTATION_YAXIS_POSITIVE = range(3)
2644+
2645+
class MemberSpringType(Enum):
2646+
'''
2647+
Member Spring Type Enumeration
2648+
'''
2649+
PARTIAL_ACTIVITY, DIAGRAM = range(2)
2650+
2651+
class MemberSpringDiagramType(Enum):
2652+
'''
2653+
Member Spring Diagram Type Enumeration
2654+
'''
2655+
DIAGRAM_ENDING_TYPE_CONTINUOUS, DIAGRAM_ENDING_TYPE_STOP, DIAGRAM_ENDING_TYPE_FAILURE, DIAGRAM_ENDING_TYPE_YIELDING = range(4)
2656+
2657+
class MemberSpringSelfWeightDefinition(Enum):
2658+
'''
2659+
Member Spring Self Weight Definition Enumeration
2660+
'''
2661+
MASS, MASS_PER_LENGTH, SPECIFIC_WEIGHT = range(3)

UnitTests/test_member.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,3 +338,23 @@ def test_member_couplingHingeHinge():
338338

339339
assert round(member.analytical_length, 5) == 5.19615
340340
assert member.type == "TYPE_COUPLING_HINGE_HINGE"
341+
342+
def test_member_spring():
343+
344+
Model.clientModel.service.delete_all()
345+
Model.clientModel.service.begin_modification()
346+
347+
Material(1, 'S235')
348+
Section(1, 'IPE 300', 1)
349+
350+
Node(1, 0, 0, 0)
351+
Node(2, 3, 3, 3)
352+
353+
Member.Spring(1, 1, 2)
354+
355+
Model.clientModel.service.finish_modification()
356+
357+
member = Model.clientModel.service.get_member(1)
358+
359+
assert round(member.analytical_length, 5) == 5.19615
360+
assert member.type == "TYPE_SPRING"

UnitTests/test_memberSpring.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import sys
2+
import os
3+
PROJECT_ROOT = os.path.abspath(os.path.join(
4+
os.path.dirname(__file__),
5+
os.pardir)
6+
)
7+
sys.path.append(PROJECT_ROOT)
8+
from RFEM.enums import MemberSpringType, PartialActivityAlongType, MemberSpringSelfWeightDefinition, MemberSpringDiagramType
9+
from RFEM.initModel import Model
10+
from RFEM.BasicObjects.material import Material
11+
from RFEM.BasicObjects.node import Node
12+
from RFEM.BasicObjects.member import Member
13+
from RFEM.TypesForMembers.memberSpring import MemberSpring
14+
15+
if Model.clientModel is None:
16+
Model()
17+
18+
def test_MemberSpring():
19+
20+
Model.clientModel.service.delete_all()
21+
Model.clientModel.service.begin_modification()
22+
23+
Material(1, 'S235')
24+
25+
Node(1, 0, 0, 0)
26+
Node(2, 10, 0, 0)
27+
Node(3, 20, 0, 0)
28+
29+
Member.Spring(1, 1, 2)
30+
31+
MemberSpring(1, '1', MemberSpringType.PARTIAL_ACTIVITY, [[PartialActivityAlongType.PARTIAL_ACTIVITY_TYPE_COMPLETE, 0.1], \
32+
[PartialActivityAlongType.PARTIAL_ACTIVITY_TYPE_FIXED, 0.15, 0.25]], 110, [MemberSpringSelfWeightDefinition.MASS_PER_LENGTH, 5], 'Spring 1')
33+
MemberSpring(2, '', MemberSpringType.DIAGRAM, [[True, MemberSpringDiagramType.DIAGRAM_ENDING_TYPE_FAILURE], \
34+
[[0.01, 1000], [0.02, 1100], [0.035, 500]]], 20, [MemberSpringSelfWeightDefinition.SPECIFIC_WEIGHT, 1500, 0.012], 'Spring 2')
35+
36+
Member.Spring(2, 2, 3, spring_type=2)
37+
38+
Model.clientModel.service.finish_modification()
39+
40+
ms1 = Model.clientModel.service.get_member_spring(1)
41+
assert ms1.assigned_to == '1'
42+
assert ms1.mass_per_length == 5
43+
44+
ms2 = Model.clientModel.service.get_member_spring(2)
45+
assert ms2.name == 'Spring 2'
46+
assert ms2.axial_stiffness == 20

0 commit comments

Comments
 (0)