midas-civil 0.0.9__py3-none-any.whl → 0.1.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of midas-civil might be problematic. Click here for more details.
- midas_civil/__init__.py +6 -4
- midas_civil/_boundary.py +8 -2
- midas_civil/_construction.py +385 -381
- midas_civil/_construction_backup.py +415 -0
- midas_civil/_element.py +43 -14
- midas_civil/_group.py +22 -1
- midas_civil/_load.py +325 -2
- midas_civil/_material.py +10 -10
- midas_civil/_model.py +38 -0
- midas_civil/_result copy.py +488 -0
- midas_civil/_result.py +30 -363
- midas_civil/_result_extract.py +115 -25
- midas_civil/_temperature.py +353 -0
- midas_civil/_tendon.py +204 -0
- midas_civil/_view.py +26 -0
- {midas_civil-0.0.9.dist-info → midas_civil-0.1.1.dist-info}/METADATA +1 -1
- midas_civil-0.1.1.dist-info/RECORD +25 -0
- midas_civil-0.0.9.dist-info/RECORD +0 -20
- {midas_civil-0.0.9.dist-info → midas_civil-0.1.1.dist-info}/WHEEL +0 -0
- {midas_civil-0.0.9.dist-info → midas_civil-0.1.1.dist-info}/licenses/LICENSE +0 -0
- {midas_civil-0.0.9.dist-info → midas_civil-0.1.1.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,415 @@
|
|
|
1
|
+
from ._mapi import *
|
|
2
|
+
|
|
3
|
+
class CS:
|
|
4
|
+
|
|
5
|
+
CSA = []
|
|
6
|
+
|
|
7
|
+
def __init__(self,
|
|
8
|
+
name: str,
|
|
9
|
+
duration: float = 0,
|
|
10
|
+
s_group: str = None,
|
|
11
|
+
s_age: float = None,
|
|
12
|
+
s_type: str= None,
|
|
13
|
+
b_group: str = None,
|
|
14
|
+
b_pos: str = None,
|
|
15
|
+
b_type: str = None,
|
|
16
|
+
l_group: str = None,
|
|
17
|
+
l_day: str = None,
|
|
18
|
+
l_type: str = None,
|
|
19
|
+
id: int = None,
|
|
20
|
+
sr_stage: bool = True,
|
|
21
|
+
ad_stage: bool = False,
|
|
22
|
+
load_in: bool = False,
|
|
23
|
+
nl: int = 5,
|
|
24
|
+
addstp: list = None):
|
|
25
|
+
"""
|
|
26
|
+
Construction Stage define.
|
|
27
|
+
|
|
28
|
+
Parameters:
|
|
29
|
+
name: Name of Construction Stage
|
|
30
|
+
duration: Duration of Construction Stage in days (default 0)
|
|
31
|
+
s_group: Structure group name or list of group names (default None)
|
|
32
|
+
s_age: Age of structure group in days and Redistribution value(%) win case of Deactivation (default 0)
|
|
33
|
+
s_type: Structure activation type - "A" to activate, "D" to deactivate(default A)
|
|
34
|
+
b_group: Boundary group name or list of group names (default None)
|
|
35
|
+
b_pos: Boundary position type - "ORIGINAL" or "DEFORMED", or list (default DEFORMED)
|
|
36
|
+
b_type: Boundary activation type - "A" to activate, "D" to deactivate (default A)
|
|
37
|
+
l_group: Load group name or list of group names (default None)
|
|
38
|
+
l_day: Load activation day - "FIRST" or "LAST" (default "FIRST")
|
|
39
|
+
l_type: Load activation type - "A" to activate, "D" to deactivate (default A)
|
|
40
|
+
id: The construction stage ID (optional)
|
|
41
|
+
sr_stage: Save results of this stage (default True)
|
|
42
|
+
ad_stage: Add additional step results (default False)
|
|
43
|
+
load_in: Load incremental steps for material nonlinear analysis (default False)
|
|
44
|
+
nl: Number of load incremental steps (default 5)
|
|
45
|
+
addstp: List of additional steps (default None)
|
|
46
|
+
|
|
47
|
+
Examples:
|
|
48
|
+
```python
|
|
49
|
+
# Single group activation
|
|
50
|
+
CS("CS1", 7, "S1", 7, "A", "B1", "DEFORMED", "A", "L1", "FIRST", "A")
|
|
51
|
+
|
|
52
|
+
# Multiple group activation
|
|
53
|
+
CS("CS1", 7, ["S1", "S2"], [7, 10], ["A", "A"], ["B1", "B2"],
|
|
54
|
+
["DEFORMED", "DEFORMED"], ["A", "A"], ["L1", "L2"], ["FIRST", "FIRST"], ["A", "A"])
|
|
55
|
+
|
|
56
|
+
# Mixed activation and deactivation
|
|
57
|
+
CS("CS1", 7, ["S1", "S2"], [7, 10], ["A", "D"], ["B1", "B2"],
|
|
58
|
+
["DEFORMED", "DEFORMED"], ["A", "D"], "L1", "FIRST", "A")
|
|
59
|
+
|
|
60
|
+
# With additional options
|
|
61
|
+
CS("CS1", 7, "S1", 7, "A", "B1", "DEFORMED", "A", "L1", "FIRST", "A",
|
|
62
|
+
sr_stage=True, ad_stage=True, load_in=True, nl=6, addstp=[1, 2, 3])
|
|
63
|
+
```
|
|
64
|
+
"""
|
|
65
|
+
|
|
66
|
+
self.NAME = name
|
|
67
|
+
self.DURATION = duration
|
|
68
|
+
self.SR_stage = sr_stage
|
|
69
|
+
self.Ad_stage = ad_stage
|
|
70
|
+
self.Load_IN = load_in
|
|
71
|
+
self.NL = nl
|
|
72
|
+
self.addstp = [] if addstp is None else addstp
|
|
73
|
+
|
|
74
|
+
# Initialize group containers
|
|
75
|
+
self.act_structure_groups = []
|
|
76
|
+
self.deact_structure_groups = []
|
|
77
|
+
self.act_boundary_groups = []
|
|
78
|
+
self.deact_boundary_groups = []
|
|
79
|
+
self.act_load_groups = []
|
|
80
|
+
self.deact_load_groups = []
|
|
81
|
+
|
|
82
|
+
# Set ID
|
|
83
|
+
if id is None:
|
|
84
|
+
self.ID = len(CS.CSA) + 1
|
|
85
|
+
else:
|
|
86
|
+
self.ID = id
|
|
87
|
+
|
|
88
|
+
# Process structure groups
|
|
89
|
+
if s_group:
|
|
90
|
+
# Convert single values to lists for uniform processing
|
|
91
|
+
if not isinstance(s_group, list):
|
|
92
|
+
s_group = [s_group]
|
|
93
|
+
s_age = [s_age if s_age is not None else 0]
|
|
94
|
+
s_type = [s_type if s_type is not None else "A"]
|
|
95
|
+
else:
|
|
96
|
+
# Ensure other parameters are lists too
|
|
97
|
+
if s_age is None:
|
|
98
|
+
s_age = [0] * len(s_group)
|
|
99
|
+
elif not isinstance(s_age, list):
|
|
100
|
+
s_age = [s_age] * len(s_group)
|
|
101
|
+
|
|
102
|
+
if s_type is None:
|
|
103
|
+
s_type = ["A"] * len(s_group)
|
|
104
|
+
elif not isinstance(s_type, list):
|
|
105
|
+
s_type = [s_type] * len(s_group)
|
|
106
|
+
|
|
107
|
+
# Process each structure group
|
|
108
|
+
for i, group in enumerate(s_group):
|
|
109
|
+
if i < len(s_type) and s_type[i] == "A":
|
|
110
|
+
# Activation: Check if already activated in previous stages
|
|
111
|
+
for stage in CS.CSA:
|
|
112
|
+
for existing_group in stage.act_structure_groups:
|
|
113
|
+
if existing_group["name"] == group:
|
|
114
|
+
raise ValueError(f"Structure group '{group}' has already been activated in stage '{stage.NAME}' (ID: {stage.ID})")
|
|
115
|
+
|
|
116
|
+
age = s_age[i] if i < len(s_age) else 0
|
|
117
|
+
self.act_structure_groups.append({"name": group, "age": age})
|
|
118
|
+
else:
|
|
119
|
+
# Deactivation: Check if activated in previous stages
|
|
120
|
+
activated = False
|
|
121
|
+
for stage in CS.CSA:
|
|
122
|
+
for existing_group in stage.act_structure_groups:
|
|
123
|
+
if existing_group["name"] == group:
|
|
124
|
+
activated = True
|
|
125
|
+
break
|
|
126
|
+
if activated:
|
|
127
|
+
break
|
|
128
|
+
|
|
129
|
+
if not activated:
|
|
130
|
+
raise ValueError(f"Structure group '{group}' cannot be deactivated as it has not been activated in any previous stage")
|
|
131
|
+
|
|
132
|
+
# For deactivation, s_age value is used as redist percentage
|
|
133
|
+
redist = s_age[i] if i < len(s_age) else 100
|
|
134
|
+
self.deact_structure_groups.append({"name": group, "redist": redist})
|
|
135
|
+
|
|
136
|
+
# Process boundary groups
|
|
137
|
+
if b_group:
|
|
138
|
+
# Convert single values to lists for uniform processing
|
|
139
|
+
if not isinstance(b_group, list):
|
|
140
|
+
b_group = [b_group]
|
|
141
|
+
b_pos = [b_pos if b_pos is not None else "DEFORMED"]
|
|
142
|
+
b_type = [b_type if b_type is not None else "A"]
|
|
143
|
+
else:
|
|
144
|
+
# Ensure other parameters are lists too
|
|
145
|
+
if b_pos is None:
|
|
146
|
+
b_pos = ["DEFORMED"] * len(b_group)
|
|
147
|
+
elif not isinstance(b_pos, list):
|
|
148
|
+
b_pos = [b_pos] * len(b_group)
|
|
149
|
+
|
|
150
|
+
if b_type is None:
|
|
151
|
+
b_type = ["A"] * len(b_group)
|
|
152
|
+
elif not isinstance(b_type, list):
|
|
153
|
+
b_type = [b_type] * len(b_group)
|
|
154
|
+
|
|
155
|
+
# Process each boundary group
|
|
156
|
+
for i, group in enumerate(b_group):
|
|
157
|
+
if i < len(b_type) and b_type[i] == "A":
|
|
158
|
+
# Activation: Check if already activated in previous stages
|
|
159
|
+
for stage in CS.CSA:
|
|
160
|
+
for existing_group in stage.act_boundary_groups:
|
|
161
|
+
if existing_group["name"] == group:
|
|
162
|
+
raise ValueError(f"Boundary group '{group}' has already been activated in stage '{stage.NAME}' (ID: {stage.ID})")
|
|
163
|
+
|
|
164
|
+
pos = b_pos[i] if i < len(b_pos) else "DEFORMED"
|
|
165
|
+
self.act_boundary_groups.append({"name": group, "pos": pos})
|
|
166
|
+
else:
|
|
167
|
+
# Deactivation: Check if activated in previous stages
|
|
168
|
+
activated = False
|
|
169
|
+
for stage in CS.CSA:
|
|
170
|
+
for existing_group in stage.act_boundary_groups:
|
|
171
|
+
if existing_group["name"] == group:
|
|
172
|
+
activated = True
|
|
173
|
+
break
|
|
174
|
+
if activated:
|
|
175
|
+
break
|
|
176
|
+
|
|
177
|
+
if not activated:
|
|
178
|
+
raise ValueError(f"Boundary group '{group}' cannot be deactivated as it has not been activated in any previous stage")
|
|
179
|
+
|
|
180
|
+
self.deact_boundary_groups.append(group)
|
|
181
|
+
|
|
182
|
+
# Process load groups
|
|
183
|
+
if l_group:
|
|
184
|
+
# Convert single values to lists for uniform processing
|
|
185
|
+
if not isinstance(l_group, list):
|
|
186
|
+
l_group = [l_group]
|
|
187
|
+
l_day = [l_day if l_day is not None else "FIRST"]
|
|
188
|
+
l_type = [l_type if l_type is not None else "A"]
|
|
189
|
+
else:
|
|
190
|
+
# Ensure other parameters are lists too
|
|
191
|
+
if l_day is None:
|
|
192
|
+
l_day = ["FIRST"] * len(l_group)
|
|
193
|
+
elif not isinstance(l_day, list):
|
|
194
|
+
l_day = [l_day] * len(l_group)
|
|
195
|
+
|
|
196
|
+
if l_type is None:
|
|
197
|
+
l_type = ["A"] * len(l_group)
|
|
198
|
+
elif not isinstance(l_type, list):
|
|
199
|
+
l_type = [l_type] * len(l_group)
|
|
200
|
+
|
|
201
|
+
# Process each load group
|
|
202
|
+
for i, group in enumerate(l_group):
|
|
203
|
+
if i < len(l_type) and l_type[i] == "A":
|
|
204
|
+
# Activation: Check if already activated in previous stages
|
|
205
|
+
for stage in CS.CSA:
|
|
206
|
+
for existing_group in stage.act_load_groups:
|
|
207
|
+
if existing_group["name"] == group:
|
|
208
|
+
raise ValueError(f"Load group '{group}' has already been activated in stage '{stage.NAME}' (ID: {stage.ID})")
|
|
209
|
+
|
|
210
|
+
day = l_day[i] if i < len(l_day) else "FIRST"
|
|
211
|
+
self.act_load_groups.append({"name": group, "day": day})
|
|
212
|
+
else:
|
|
213
|
+
# Deactivation: Check if activated in previous stages
|
|
214
|
+
activated = False
|
|
215
|
+
for stage in CS.CSA:
|
|
216
|
+
for existing_group in stage.act_load_groups:
|
|
217
|
+
if existing_group["name"] == group:
|
|
218
|
+
activated = True
|
|
219
|
+
break
|
|
220
|
+
if activated:
|
|
221
|
+
break
|
|
222
|
+
|
|
223
|
+
if not activated:
|
|
224
|
+
raise ValueError(f"Load group '{group}' cannot be deactivated as it has not been activated in any previous stage")
|
|
225
|
+
|
|
226
|
+
day = l_day[i] if i < len(l_day) else "FIRST"
|
|
227
|
+
self.deact_load_groups.append({"name": group, "day": day})
|
|
228
|
+
|
|
229
|
+
CS.CSA.append(self)
|
|
230
|
+
|
|
231
|
+
@classmethod
|
|
232
|
+
def json(cls):
|
|
233
|
+
"""
|
|
234
|
+
Converts Construction Stage data to JSON format
|
|
235
|
+
Example:
|
|
236
|
+
# Get the JSON data for all construction stages
|
|
237
|
+
json_data = CS.json()
|
|
238
|
+
print(json_data)
|
|
239
|
+
"""
|
|
240
|
+
json = {"Assign": {}}
|
|
241
|
+
|
|
242
|
+
for csa in cls.CSA:
|
|
243
|
+
stage_data = {
|
|
244
|
+
"NAME": csa.NAME,
|
|
245
|
+
"DURATION": csa.DURATION,
|
|
246
|
+
"bSV_RSLT": csa.SR_stage,
|
|
247
|
+
"bSV_STEP": csa.Ad_stage,
|
|
248
|
+
"bLOAD_STEP": csa.Load_IN
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
# Add incremental steps if load step is enabled
|
|
252
|
+
if csa.Load_IN:
|
|
253
|
+
stage_data["INCRE_STEP"] = csa.NL
|
|
254
|
+
|
|
255
|
+
# Add additional steps if specified
|
|
256
|
+
if csa.addstp:
|
|
257
|
+
stage_data["ADD_STEP"] = csa.addstp
|
|
258
|
+
else:
|
|
259
|
+
stage_data["ADD_STEP"] = []
|
|
260
|
+
|
|
261
|
+
# Handle structure group activation
|
|
262
|
+
if csa.act_structure_groups:
|
|
263
|
+
stage_data["ACT_ELEM"] = []
|
|
264
|
+
for group in csa.act_structure_groups:
|
|
265
|
+
stage_data["ACT_ELEM"].append({
|
|
266
|
+
"GRUP_NAME": group["name"],
|
|
267
|
+
"AGE": group["age"]
|
|
268
|
+
})
|
|
269
|
+
|
|
270
|
+
# Handle structure group deactivation
|
|
271
|
+
if csa.deact_structure_groups:
|
|
272
|
+
stage_data["DACT_ELEM"] = []
|
|
273
|
+
for group in csa.deact_structure_groups:
|
|
274
|
+
stage_data["DACT_ELEM"].append({
|
|
275
|
+
"GRUP_NAME": group["name"],
|
|
276
|
+
"REDIST": group["redist"]
|
|
277
|
+
})
|
|
278
|
+
|
|
279
|
+
# Handle boundary group activation
|
|
280
|
+
if csa.act_boundary_groups:
|
|
281
|
+
stage_data["ACT_BNGR"] = []
|
|
282
|
+
for group in csa.act_boundary_groups:
|
|
283
|
+
stage_data["ACT_BNGR"].append({
|
|
284
|
+
"BNGR_NAME": group["name"],
|
|
285
|
+
"POS": group["pos"]
|
|
286
|
+
})
|
|
287
|
+
|
|
288
|
+
# Handle boundary group deactivation
|
|
289
|
+
if csa.deact_boundary_groups:
|
|
290
|
+
stage_data["DACT_BNGR"] = []
|
|
291
|
+
for group_name in csa.deact_boundary_groups:
|
|
292
|
+
stage_data["DACT_BNGR"].append(group_name)
|
|
293
|
+
|
|
294
|
+
# Handle load group activation
|
|
295
|
+
if csa.act_load_groups:
|
|
296
|
+
stage_data["ACT_LOAD"] = []
|
|
297
|
+
for group in csa.act_load_groups:
|
|
298
|
+
stage_data["ACT_LOAD"].append({
|
|
299
|
+
"LOAD_NAME": group["name"],
|
|
300
|
+
"DAY": group["day"]
|
|
301
|
+
})
|
|
302
|
+
|
|
303
|
+
# Handle load group deactivation
|
|
304
|
+
if csa.deact_load_groups:
|
|
305
|
+
stage_data["DACT_LOAD"] = []
|
|
306
|
+
for group in csa.deact_load_groups:
|
|
307
|
+
stage_data["DACT_LOAD"].append({
|
|
308
|
+
"LOAD_NAME": group["name"],
|
|
309
|
+
"DAY": group["day"]
|
|
310
|
+
})
|
|
311
|
+
|
|
312
|
+
json["Assign"][str(csa.ID)] = stage_data
|
|
313
|
+
|
|
314
|
+
return json
|
|
315
|
+
|
|
316
|
+
@classmethod
|
|
317
|
+
def create(cls):
|
|
318
|
+
"""Creates construction stages in the database"""
|
|
319
|
+
MidasAPI("PUT", "/db/stag", CS.json())
|
|
320
|
+
|
|
321
|
+
@classmethod
|
|
322
|
+
def get(cls):
|
|
323
|
+
"""Gets construction stage data from the database"""
|
|
324
|
+
return MidasAPI("GET", "/db/stag")
|
|
325
|
+
|
|
326
|
+
@classmethod
|
|
327
|
+
def sync(cls):
|
|
328
|
+
"""Updates the CS class with data from the database"""
|
|
329
|
+
cls.CSA = []
|
|
330
|
+
a = CS.get()
|
|
331
|
+
if a != {'message': ''}:
|
|
332
|
+
if "STAG" in a:
|
|
333
|
+
stag_data_dict = a["STAG"]
|
|
334
|
+
else:
|
|
335
|
+
return
|
|
336
|
+
|
|
337
|
+
for stag_id, stag_data in stag_data_dict.items():
|
|
338
|
+
# Basic stage data
|
|
339
|
+
name = stag_data.get("NAME")
|
|
340
|
+
duration = stag_data.get("DURATION")
|
|
341
|
+
sr_stage = stag_data.get("bSV_RSLT")
|
|
342
|
+
ad_stage = stag_data.get("bSV_STEP")
|
|
343
|
+
load_in = stag_data.get("bLOAD_STEP")
|
|
344
|
+
nl = stag_data.get("INCRE_STEP")
|
|
345
|
+
addstp = stag_data.get("ADD_STEP")
|
|
346
|
+
|
|
347
|
+
# Create a new CS object with basic properties
|
|
348
|
+
new_cs = CS(
|
|
349
|
+
name=name,
|
|
350
|
+
duration=duration,
|
|
351
|
+
id=int(stag_id),
|
|
352
|
+
sr_stage=sr_stage,
|
|
353
|
+
ad_stage=ad_stage,
|
|
354
|
+
load_in=load_in,
|
|
355
|
+
nl=nl,
|
|
356
|
+
addstp=addstp
|
|
357
|
+
)
|
|
358
|
+
|
|
359
|
+
CS.CSA.pop()
|
|
360
|
+
|
|
361
|
+
# Process activation elements
|
|
362
|
+
if "ACT_ELEM" in stag_data and stag_data["ACT_ELEM"]:
|
|
363
|
+
for elem in stag_data["ACT_ELEM"]:
|
|
364
|
+
group_name = elem.get("GRUP_NAME")
|
|
365
|
+
age = elem.get("AGE")
|
|
366
|
+
new_cs.act_structure_groups.append({"name": group_name, "age": age})
|
|
367
|
+
|
|
368
|
+
# Process deactivation elements
|
|
369
|
+
if "DACT_ELEM" in stag_data and stag_data["DACT_ELEM"]:
|
|
370
|
+
for elem in stag_data["DACT_ELEM"]:
|
|
371
|
+
if isinstance(elem, dict):
|
|
372
|
+
group_name = elem.get("GRUP_NAME")
|
|
373
|
+
redist = elem.get("REDIST")
|
|
374
|
+
else:
|
|
375
|
+
group_name = elem
|
|
376
|
+
redist = 0
|
|
377
|
+
new_cs.deact_structure_groups.append({"name": group_name, "redist": redist})
|
|
378
|
+
|
|
379
|
+
# Process activation boundary groups
|
|
380
|
+
if "ACT_BNGR" in stag_data and stag_data["ACT_BNGR"]:
|
|
381
|
+
for bngr in stag_data["ACT_BNGR"]:
|
|
382
|
+
group_name = bngr.get("BNGR_NAME")
|
|
383
|
+
pos = bngr.get("POS")
|
|
384
|
+
new_cs.act_boundary_groups.append({"name": group_name, "pos": pos})
|
|
385
|
+
|
|
386
|
+
# Process deactivation boundary groups
|
|
387
|
+
if "DACT_BNGR" in stag_data and stag_data["DACT_BNGR"]:
|
|
388
|
+
for bngr in stag_data["DACT_BNGR"]:
|
|
389
|
+
new_cs.deact_boundary_groups.append(bngr)
|
|
390
|
+
|
|
391
|
+
# Process activation loads
|
|
392
|
+
if "ACT_LOAD" in stag_data and stag_data["ACT_LOAD"]:
|
|
393
|
+
for load in stag_data["ACT_LOAD"]:
|
|
394
|
+
group_name = load.get("LOAD_NAME")
|
|
395
|
+
day = load.get("DAY")
|
|
396
|
+
new_cs.act_load_groups.append({"name": group_name, "day": day})
|
|
397
|
+
|
|
398
|
+
# Process deactivation loads
|
|
399
|
+
if "DACT_LOAD" in stag_data and stag_data["DACT_LOAD"]:
|
|
400
|
+
for load in stag_data["DACT_LOAD"]:
|
|
401
|
+
if isinstance(load, dict):
|
|
402
|
+
group_name = load.get("LOAD_NAME")
|
|
403
|
+
day = load.get("DAY")
|
|
404
|
+
else:
|
|
405
|
+
group_name = load
|
|
406
|
+
day = "FIRST"
|
|
407
|
+
new_cs.deact_load_groups.append({"name": group_name, "day": day})
|
|
408
|
+
|
|
409
|
+
CS.CSA.append(new_cs)
|
|
410
|
+
|
|
411
|
+
@classmethod
|
|
412
|
+
def delete(cls):
|
|
413
|
+
"""Deletes all construction stages from the database and resets the class"""
|
|
414
|
+
cls.CSA = []
|
|
415
|
+
return MidasAPI("DELETE", "/db/stag")
|
midas_civil/_element.py
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from ._mapi import *
|
|
2
2
|
from ._node import *
|
|
3
|
+
from ._group import _add_elem_2_stGroup
|
|
3
4
|
|
|
4
5
|
import numpy as np
|
|
5
6
|
|
|
@@ -8,6 +9,8 @@ def _ADD(self):
|
|
|
8
9
|
Adds an element to the main list. If the ID is 0, it auto-increments.
|
|
9
10
|
If the ID already exists, it replaces the existing element.
|
|
10
11
|
"""
|
|
12
|
+
|
|
13
|
+
# ------------ ID assignment -----------------------
|
|
11
14
|
id = int(self.ID)
|
|
12
15
|
if not Element.ids:
|
|
13
16
|
count = 1
|
|
@@ -27,6 +30,20 @@ def _ADD(self):
|
|
|
27
30
|
self.ID = id
|
|
28
31
|
Element.elements.append(self)
|
|
29
32
|
Element.ids.append(int(self.ID))
|
|
33
|
+
|
|
34
|
+
# ------------ Group assignment -----------------------
|
|
35
|
+
if self._GROUP == '' :
|
|
36
|
+
pass
|
|
37
|
+
elif isinstance(self._GROUP, list):
|
|
38
|
+
for gpName in self._GROUP:
|
|
39
|
+
_add_elem_2_stGroup(self.ID,gpName)
|
|
40
|
+
elif isinstance(self._GROUP, str):
|
|
41
|
+
_add_elem_2_stGroup(self.ID,self._GROUP)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
|
|
30
47
|
|
|
31
48
|
def _updateElem(self):
|
|
32
49
|
"""Sends a PUT request to update a single element in Midas."""
|
|
@@ -166,7 +183,7 @@ class Element:
|
|
|
166
183
|
|
|
167
184
|
class Beam(_common):
|
|
168
185
|
|
|
169
|
-
def __init__(self, i: int, j: int, mat: int = 1, sect: int = 1, angle: float = 0, id: int = 0):
|
|
186
|
+
def __init__(self, i: int, j: int, mat: int = 1, sect: int = 1, angle: float = 0, group = "" , id: int = 0):
|
|
170
187
|
"""
|
|
171
188
|
Creates a BEAM element for frame analysis.
|
|
172
189
|
|
|
@@ -176,6 +193,7 @@ class Element:
|
|
|
176
193
|
mat: Material property number (default 1)
|
|
177
194
|
sect: Section property number (default 1)
|
|
178
195
|
angle: Beta angle for section orientation in degrees (default 0.0)
|
|
196
|
+
group: Structure group of the element (str or list; 'SG1' or ['SG1','SG2'])
|
|
179
197
|
id: Element ID (default 0 for auto-increment)
|
|
180
198
|
|
|
181
199
|
Examples:
|
|
@@ -199,10 +217,11 @@ class Element:
|
|
|
199
217
|
self.SECT = sect
|
|
200
218
|
self.NODE = [i, j]
|
|
201
219
|
self.ANGLE = angle
|
|
220
|
+
self._GROUP = group
|
|
202
221
|
_ADD(self)
|
|
203
222
|
|
|
204
223
|
@staticmethod
|
|
205
|
-
def SDL(s_loc:list,dir:list,l:float,n:int=1,mat:int=1,sect:int=1,angle:float=0,id:int=0): #CHANGE TO TUPLE
|
|
224
|
+
def SDL(s_loc:list,dir:list,l:float,n:int=1,mat:int=1,sect:int=1,angle:float=0, group = "" , id: int = 0): #CHANGE TO TUPLE
|
|
206
225
|
beam_nodes =[]
|
|
207
226
|
beam_obj = []
|
|
208
227
|
s_locc = np.array(s_loc)
|
|
@@ -216,13 +235,13 @@ class Element:
|
|
|
216
235
|
for i in range(n):
|
|
217
236
|
if id == 0 : id_new = 0
|
|
218
237
|
else: id_new = id+i
|
|
219
|
-
beam_obj.append(Element.Beam(beam_nodes[i],beam_nodes[i+1],mat,sect,angle,id_new))
|
|
238
|
+
beam_obj.append(Element.Beam(beam_nodes[i],beam_nodes[i+1],mat,sect,angle,group,id_new))
|
|
220
239
|
|
|
221
240
|
return beam_obj
|
|
222
241
|
|
|
223
242
|
|
|
224
243
|
@staticmethod
|
|
225
|
-
def SE(s_loc:list,e_loc:list,n:int=1,mat:int=1,sect:int=1,angle:float=0,id:int=0):
|
|
244
|
+
def SE(s_loc:list,e_loc:list,n:int=1,mat:int=1,sect:int=1,angle:float=0, group = "" , id: int = 0):
|
|
226
245
|
beam_nodes =[]
|
|
227
246
|
beam_obj = []
|
|
228
247
|
i_loc = np.linspace(s_loc,e_loc,n+1)
|
|
@@ -233,12 +252,12 @@ class Element:
|
|
|
233
252
|
for i in range(n):
|
|
234
253
|
if id == 0 : id_new = 0
|
|
235
254
|
else: id_new = id+i
|
|
236
|
-
beam_obj.append(Element.Beam(beam_nodes[i],beam_nodes[i+1],mat,sect,angle,id_new))
|
|
255
|
+
beam_obj.append(Element.Beam(beam_nodes[i],beam_nodes[i+1],mat,sect,angle,group,id_new))
|
|
237
256
|
|
|
238
257
|
return beam_obj
|
|
239
258
|
|
|
240
259
|
class Truss(_common):
|
|
241
|
-
def __init__(self, i: int, j: int, mat: int = 1, sect: int = 1, angle: float = 0, id: int = 0):
|
|
260
|
+
def __init__(self, i: int, j: int, mat: int = 1, sect: int = 1, angle: float = 0, group = "" , id: int = 0):
|
|
242
261
|
"""
|
|
243
262
|
Creates a TRUSS element
|
|
244
263
|
|
|
@@ -248,6 +267,7 @@ class Element:
|
|
|
248
267
|
mat: Material property number (default 1)
|
|
249
268
|
sect: Section property number (default 1)
|
|
250
269
|
angle: Beta angle for section orientation in degrees (default 0.0)
|
|
270
|
+
group: Structure group of the element (str or list; 'SG1' or ['SG1','SG2'])
|
|
251
271
|
id: Element ID (default 0 for auto-increment)
|
|
252
272
|
|
|
253
273
|
Examples:
|
|
@@ -268,10 +288,11 @@ class Element:
|
|
|
268
288
|
self.SECT = sect
|
|
269
289
|
self.NODE = [i, j]
|
|
270
290
|
self.ANGLE = angle
|
|
291
|
+
self._GROUP = group
|
|
271
292
|
_ADD(self)
|
|
272
293
|
|
|
273
294
|
@staticmethod
|
|
274
|
-
def SDL(s_loc:list,dir:list,l:float,n:int=1,mat:int=1,sect:int=1,angle:float=0,id:int=0):
|
|
295
|
+
def SDL(s_loc:list,dir:list,l:float,n:int=1,mat:int=1,sect:int=1,angle:float=0, group = "" , id: int = 0):
|
|
275
296
|
beam_nodes =[]
|
|
276
297
|
beam_obj =[]
|
|
277
298
|
s_locc = np.array(s_loc)
|
|
@@ -285,13 +306,13 @@ class Element:
|
|
|
285
306
|
for i in range(n):
|
|
286
307
|
if id == 0 : id_new = 0
|
|
287
308
|
else: id_new = id+i
|
|
288
|
-
beam_obj.append(Element.Truss(beam_nodes[i],beam_nodes[i+1],mat,sect,angle,id_new))
|
|
309
|
+
beam_obj.append(Element.Truss(beam_nodes[i],beam_nodes[i+1],mat,sect,angle,group,id_new))
|
|
289
310
|
|
|
290
311
|
return beam_obj
|
|
291
312
|
|
|
292
313
|
|
|
293
314
|
@staticmethod
|
|
294
|
-
def SE(s_loc:list,e_loc:list,n:int=1,mat:int=1,sect:int=1,angle:float=0,id:int=0):
|
|
315
|
+
def SE(s_loc:list,e_loc:list,n:int=1,mat:int=1,sect:int=1,angle:float=0, group = "" , id: int = 0):
|
|
295
316
|
beam_nodes =[]
|
|
296
317
|
beam_obj = []
|
|
297
318
|
i_loc = np.linspace(s_loc,e_loc,n+1)
|
|
@@ -302,12 +323,12 @@ class Element:
|
|
|
302
323
|
for i in range(n):
|
|
303
324
|
if id == 0 : id_new = 0
|
|
304
325
|
else: id_new = id+i
|
|
305
|
-
beam_obj.append(Element.Truss(beam_nodes[i],beam_nodes[i+1],mat,sect,angle,id_new))
|
|
326
|
+
beam_obj.append(Element.Truss(beam_nodes[i],beam_nodes[i+1],mat,sect,angle,group,id_new))
|
|
306
327
|
|
|
307
328
|
return beam_obj
|
|
308
329
|
|
|
309
330
|
class Plate(_common):
|
|
310
|
-
def __init__(self, nodes: list, stype: int = 1, mat: int = 1, sect: int = 1, angle: float = 0, id: int = 0):
|
|
331
|
+
def __init__(self, nodes: list, stype: int = 1, mat: int = 1, sect: int = 1, angle: float = 0, group = "" , id: int = 0):
|
|
311
332
|
"""
|
|
312
333
|
Creates a PLATE element.
|
|
313
334
|
|
|
@@ -317,6 +338,7 @@ class Element:
|
|
|
317
338
|
mat: Material property number (default 1)
|
|
318
339
|
sect: Section (thickness) property number (default 1)
|
|
319
340
|
angle: Material angle for orthotropic materials in degrees (default 0.0)
|
|
341
|
+
group: Structure group of the element (str or list; 'SG1' or ['SG1','SG2'])
|
|
320
342
|
id: Element ID (default 0 for auto-increment)
|
|
321
343
|
|
|
322
344
|
Examples:
|
|
@@ -338,10 +360,11 @@ class Element:
|
|
|
338
360
|
self.NODE = nodes
|
|
339
361
|
self.ANGLE = angle
|
|
340
362
|
self.STYPE = stype
|
|
363
|
+
self._GROUP = group
|
|
341
364
|
_ADD(self)
|
|
342
365
|
|
|
343
366
|
class Tension(_common):
|
|
344
|
-
def __init__(self, i: int, j: int, stype: int, mat: int = 1, sect: int = 1, angle: float = 0, id: int = 0, non_len: float = None, cable_type: int = None, tens: float = None, t_limit: float = None):
|
|
367
|
+
def __init__(self, i: int, j: int, stype: int, mat: int = 1, sect: int = 1, angle: float = 0, group = "" , id: int = 0, non_len: float = None, cable_type: int = None, tens: float = None, t_limit: float = None):
|
|
345
368
|
"""
|
|
346
369
|
Creates a TENSTR (Tension-only) element.
|
|
347
370
|
|
|
@@ -352,6 +375,7 @@ class Element:
|
|
|
352
375
|
mat: Material property number (default 1)
|
|
353
376
|
sect: Section property number (default 1)
|
|
354
377
|
angle: Beta angle for section orientation in degrees (default 0.0)
|
|
378
|
+
group: Structure group of the element (str or list; 'SG1' or ['SG1','SG2'])
|
|
355
379
|
id: Element ID (default 0 for auto-increment)
|
|
356
380
|
non_len: Non-linear length parameter for Hook/Cable (default None)
|
|
357
381
|
cable_type: Cable type for stype=3 (1=Pretension, 2=Horizontal, 3=Lu) (default None)
|
|
@@ -380,6 +404,7 @@ class Element:
|
|
|
380
404
|
self.NODE = [i, j]
|
|
381
405
|
self.ANGLE = angle
|
|
382
406
|
self.STYPE = stype
|
|
407
|
+
self._GROUP = group
|
|
383
408
|
|
|
384
409
|
# Handle subtype-specific parameters
|
|
385
410
|
if stype == 1: # Tension-only specific
|
|
@@ -403,7 +428,7 @@ class Element:
|
|
|
403
428
|
_ADD(self)
|
|
404
429
|
|
|
405
430
|
class Compression(_common):
|
|
406
|
-
def __init__(self, i: int, j: int, stype: int, mat: int = 1, sect: int = 1, angle: float = 0, id: int = 0, tens: float = None, t_limit: float = None, non_len: float = None):
|
|
431
|
+
def __init__(self, i: int, j: int, stype: int, mat: int = 1, sect: int = 1, angle: float = 0, group = "" , id: int = 0, tens: float = None, t_limit: float = None, non_len: float = None):
|
|
407
432
|
"""
|
|
408
433
|
Creates a COMPTR (Compression-only) element.
|
|
409
434
|
|
|
@@ -414,6 +439,7 @@ class Element:
|
|
|
414
439
|
mat: Material property number (default 1)
|
|
415
440
|
sect: Section property number (default 1)
|
|
416
441
|
angle: Beta angle for section orientation in degrees (default 0.0)
|
|
442
|
+
group: Structure group of the element (str or list; 'SG1' or ['SG1','SG2'])
|
|
417
443
|
id: Element ID (default 0 for auto-increment)
|
|
418
444
|
tens: Allowable tension or initial compression force (default None)
|
|
419
445
|
t_limit: Compression limit value. If provided, the compression limit flag is set to True. (default None)
|
|
@@ -438,6 +464,7 @@ class Element:
|
|
|
438
464
|
self.NODE = [i, j]
|
|
439
465
|
self.ANGLE = angle
|
|
440
466
|
self.STYPE = stype
|
|
467
|
+
self._GROUP = group
|
|
441
468
|
|
|
442
469
|
# Handle subtype-specific parameters
|
|
443
470
|
if stype == 1: # Compression-only specific
|
|
@@ -453,7 +480,7 @@ class Element:
|
|
|
453
480
|
_ADD(self)
|
|
454
481
|
|
|
455
482
|
class Solid(_common):
|
|
456
|
-
def __init__(self, nodes: list, mat: int = 1, sect: int = 0, id: int = 0):
|
|
483
|
+
def __init__(self, nodes: list, mat: int = 1, sect: int = 0, group = "" , id: int = 0):
|
|
457
484
|
"""
|
|
458
485
|
Creates a SOLID element for 3D analysis.
|
|
459
486
|
|
|
@@ -463,6 +490,7 @@ class Element:
|
|
|
463
490
|
- 6 nodes: Pentahedral element
|
|
464
491
|
- 8 nodes: Hexahedral element
|
|
465
492
|
mat: Material property number (default 1)
|
|
493
|
+
group: Structure group of the element (str or list; 'SG1' or ['SG1','SG2'])
|
|
466
494
|
id: Element ID (default 0 for auto-increment)
|
|
467
495
|
|
|
468
496
|
Examples:
|
|
@@ -484,6 +512,7 @@ class Element:
|
|
|
484
512
|
self.MATL = mat
|
|
485
513
|
self.SECT = sect # Solid elements don't use section properties
|
|
486
514
|
self.NODE = nodes
|
|
515
|
+
self._GROUP = group
|
|
487
516
|
_ADD(self)
|
|
488
517
|
|
|
489
518
|
|