midas-civil 1.4.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.
- midas_civil/_BoundaryChangeAssignment.py +278 -0
- midas_civil/__init__.py +51 -0
- midas_civil/_analysiscontrol.py +585 -0
- midas_civil/_boundary.py +888 -0
- midas_civil/_construction.py +1004 -0
- midas_civil/_element.py +1346 -0
- midas_civil/_group.py +337 -0
- midas_civil/_load.py +967 -0
- midas_civil/_loadcomb.py +159 -0
- midas_civil/_mapi.py +249 -0
- midas_civil/_material.py +1692 -0
- midas_civil/_model.py +522 -0
- midas_civil/_movingload.py +1479 -0
- midas_civil/_node.py +532 -0
- midas_civil/_result_table.py +929 -0
- midas_civil/_result_test.py +5455 -0
- midas_civil/_section/_TapdbSecSS.py +175 -0
- midas_civil/_section/__init__.py +413 -0
- midas_civil/_section/_compositeSS.py +283 -0
- midas_civil/_section/_dbSecSS.py +164 -0
- midas_civil/_section/_offsetSS.py +53 -0
- midas_civil/_section/_pscSS copy.py +455 -0
- midas_civil/_section/_pscSS.py +822 -0
- midas_civil/_section/_tapPSC12CellSS.py +565 -0
- midas_civil/_section/_unSupp.py +58 -0
- midas_civil/_settlement.py +161 -0
- midas_civil/_temperature.py +677 -0
- midas_civil/_tendon.py +1016 -0
- midas_civil/_thickness.py +147 -0
- midas_civil/_utils.py +529 -0
- midas_civil/_utilsFunc/__init__.py +0 -0
- midas_civil/_utilsFunc/_line2plate.py +636 -0
- midas_civil/_view.py +891 -0
- midas_civil/_view_trial.py +430 -0
- midas_civil/_visualise.py +347 -0
- midas_civil-1.4.1.dist-info/METADATA +74 -0
- midas_civil-1.4.1.dist-info/RECORD +40 -0
- midas_civil-1.4.1.dist-info/WHEEL +5 -0
- midas_civil-1.4.1.dist-info/licenses/LICENSE +21 -0
- midas_civil-1.4.1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,1004 @@
|
|
|
1
|
+
from ._mapi import MidasAPI
|
|
2
|
+
|
|
3
|
+
class CS:
|
|
4
|
+
|
|
5
|
+
@staticmethod
|
|
6
|
+
def create():
|
|
7
|
+
if CS.STAGE.stages!=[]: CS.STAGE.create()
|
|
8
|
+
if CS.CompSec.compsecs!=[] : CS.CompSec.create()
|
|
9
|
+
if CS.TimeLoad.timeloads!=[] : CS.TimeLoad.create()
|
|
10
|
+
if CS.CreepCoeff.creepcoeffs!=[] : CS.CreepCoeff.create()
|
|
11
|
+
if CS.Camber.cambers!=[] : CS.Camber.create()
|
|
12
|
+
|
|
13
|
+
class STAGE:
|
|
14
|
+
stages = []
|
|
15
|
+
_maxID_ = 0
|
|
16
|
+
_maxNO_ = 0
|
|
17
|
+
_isSync_ = False
|
|
18
|
+
|
|
19
|
+
def __init__(self,
|
|
20
|
+
name: str,
|
|
21
|
+
duration: float = 0,
|
|
22
|
+
s_group: str = None,
|
|
23
|
+
s_age: float = None,
|
|
24
|
+
s_type: str= None,
|
|
25
|
+
b_group: str = None,
|
|
26
|
+
b_pos: str = None,
|
|
27
|
+
b_type: str = None,
|
|
28
|
+
l_group: str = None,
|
|
29
|
+
l_day: str = None,
|
|
30
|
+
l_type: str = None,
|
|
31
|
+
id: int = None,
|
|
32
|
+
sv_result: bool = True,
|
|
33
|
+
sv_step: bool = False,
|
|
34
|
+
load_in: bool = False,
|
|
35
|
+
nl: int = 5,
|
|
36
|
+
addstp: list = None):
|
|
37
|
+
"""
|
|
38
|
+
Construction Stage define.
|
|
39
|
+
|
|
40
|
+
Parameters:
|
|
41
|
+
name: Name of Construction Stage
|
|
42
|
+
duration: Duration of Construction Stage in days (default 0)
|
|
43
|
+
s_group: Structure group name or list of group names (default None)
|
|
44
|
+
s_age: Age of structure group in days and Redistribution value(%) win case of Deactivation (default 0)
|
|
45
|
+
s_type: Structure activation type - "A" to activate, "D" to deactivate(default A)
|
|
46
|
+
b_group: Boundary group name or list of group names (default None)
|
|
47
|
+
b_pos: Boundary position type - "ORIGINAL" or "DEFORMED", or list (default DEFORMED)
|
|
48
|
+
b_type: Boundary activation type - "A" to activate, "D" to deactivate (default A)
|
|
49
|
+
l_group: Load group name or list of group names (default None)
|
|
50
|
+
l_day: Load activation day - "FIRST" or "LAST" (default "FIRST")
|
|
51
|
+
l_type: Load activation type - "A" to activate, "D" to deactivate (default A)
|
|
52
|
+
id: The construction stage ID (optional)
|
|
53
|
+
sv_result: Save results of this stage (default True)
|
|
54
|
+
sv_step: Add additional step results (default False)
|
|
55
|
+
load_in: Load incremental steps for material nonlinear analysis (default False)
|
|
56
|
+
nl: Number of load incremental steps (default 5)
|
|
57
|
+
addstp: List of additional steps (default None)
|
|
58
|
+
|
|
59
|
+
Examples:
|
|
60
|
+
```python
|
|
61
|
+
# Single group activation
|
|
62
|
+
CS("CS1", 7, "S1", 7, "A", "B1", "DEFORMED", "A", "L1", "FIRST", "A")
|
|
63
|
+
|
|
64
|
+
# Multiple group activation
|
|
65
|
+
CS("CS1", 7, ["S1", "S2"], [7, 10], ["A", "A"], ["B1", "B2"],
|
|
66
|
+
["DEFORMED", "DEFORMED"], ["A", "A"], ["L1", "L2"], ["FIRST", "FIRST"], ["A", "A"])
|
|
67
|
+
|
|
68
|
+
# Mixed activation and deactivation
|
|
69
|
+
CS("CS1", 7, ["S1", "S2"], [7, 10], ["A", "D"], ["B1", "B2"],
|
|
70
|
+
["DEFORMED", "DEFORMED"], ["A", "D"], "L1", "FIRST", "A")
|
|
71
|
+
|
|
72
|
+
# With additional options
|
|
73
|
+
CS("CS1", 7, "S1", 7, "A", "B1", "DEFORMED", "A", "L1", "FIRST", "A",
|
|
74
|
+
sv_result=True, sv_step=True, load_in=True, nl=6, addstp=[1, 2, 3])
|
|
75
|
+
```
|
|
76
|
+
"""
|
|
77
|
+
|
|
78
|
+
self.NAME = name
|
|
79
|
+
self.DURATION = duration
|
|
80
|
+
self.SV_Result = sv_result
|
|
81
|
+
self.SV_Step = sv_step
|
|
82
|
+
self.Load_IN = load_in
|
|
83
|
+
self.NL = nl
|
|
84
|
+
self.addstp = [] if addstp is None else addstp
|
|
85
|
+
|
|
86
|
+
# Initialize group containers
|
|
87
|
+
self.act_structure_groups = []
|
|
88
|
+
self.deact_structure_groups = []
|
|
89
|
+
self.act_boundary_groups = []
|
|
90
|
+
self.deact_boundary_groups = []
|
|
91
|
+
self.act_load_groups = []
|
|
92
|
+
self.deact_load_groups = []
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
# Set ID
|
|
96
|
+
if id is None:
|
|
97
|
+
self.ID = CS.STAGE._maxID_ + 1
|
|
98
|
+
self.NO = CS.STAGE._maxNO_ + 1
|
|
99
|
+
else:
|
|
100
|
+
self.ID = id
|
|
101
|
+
self.NO = id
|
|
102
|
+
CS.STAGE._maxNO_ = max(CS.STAGE._maxNO_ ,self.NO)
|
|
103
|
+
CS.STAGE._maxID_ = max(CS.STAGE._maxID_ ,self.ID)
|
|
104
|
+
|
|
105
|
+
# Process structure groups
|
|
106
|
+
if s_group:
|
|
107
|
+
# Convert single values to lists for uniform processing
|
|
108
|
+
if not isinstance(s_group, list):
|
|
109
|
+
s_group = [s_group]
|
|
110
|
+
s_age = [s_age if s_age is not None else 0]
|
|
111
|
+
s_type = [s_type if s_type is not None else "A"]
|
|
112
|
+
else:
|
|
113
|
+
# Ensure other parameters are lists too
|
|
114
|
+
if s_age is None:
|
|
115
|
+
s_age = [0] * len(s_group)
|
|
116
|
+
elif not isinstance(s_age, list):
|
|
117
|
+
s_age = [s_age] * len(s_group)
|
|
118
|
+
|
|
119
|
+
if s_type is None:
|
|
120
|
+
s_type = ["A"] * len(s_group)
|
|
121
|
+
elif not isinstance(s_type, list):
|
|
122
|
+
s_type = [s_type] * len(s_group)
|
|
123
|
+
|
|
124
|
+
# Process each structure group
|
|
125
|
+
for i, group in enumerate(s_group):
|
|
126
|
+
if i < len(s_type) and s_type[i] == "A":
|
|
127
|
+
# Activation: Check if already activated in previous stages
|
|
128
|
+
for stage in CS.STAGE.stages:
|
|
129
|
+
for existing_group in stage.act_structure_groups:
|
|
130
|
+
if existing_group["name"] == group:
|
|
131
|
+
raise ValueError(f"Structure group '{group}' has already been activated in stage '{stage.NAME}' (ID: {stage.ID})")
|
|
132
|
+
|
|
133
|
+
age = s_age[i] if i < len(s_age) else 0
|
|
134
|
+
self.act_structure_groups.append({"name": group, "age": age})
|
|
135
|
+
else:
|
|
136
|
+
# Deactivation: Check if activated in previous stages
|
|
137
|
+
activated = False
|
|
138
|
+
for stage in CS.STAGE.stages:
|
|
139
|
+
for existing_group in stage.act_structure_groups:
|
|
140
|
+
if existing_group["name"] == group:
|
|
141
|
+
activated = True
|
|
142
|
+
break
|
|
143
|
+
if activated:
|
|
144
|
+
break
|
|
145
|
+
|
|
146
|
+
if not activated:
|
|
147
|
+
raise ValueError(f"Structure group '{group}' cannot be deactivated as it has not been activated in any previous stage")
|
|
148
|
+
|
|
149
|
+
# For deactivation, s_age value is used as redist percentage
|
|
150
|
+
redist = s_age[i] if i < len(s_age) else 100
|
|
151
|
+
self.deact_structure_groups.append({"name": group, "redist": redist})
|
|
152
|
+
|
|
153
|
+
# Process boundary groups
|
|
154
|
+
if b_group:
|
|
155
|
+
# Convert single values to lists for uniform processing
|
|
156
|
+
if not isinstance(b_group, list):
|
|
157
|
+
b_group = [b_group]
|
|
158
|
+
b_pos = [b_pos if b_pos is not None else "DEFORMED"]
|
|
159
|
+
b_type = [b_type if b_type is not None else "A"]
|
|
160
|
+
else:
|
|
161
|
+
# Ensure other parameters are lists too
|
|
162
|
+
if b_pos is None:
|
|
163
|
+
b_pos = ["DEFORMED"] * len(b_group)
|
|
164
|
+
elif not isinstance(b_pos, list):
|
|
165
|
+
b_pos = [b_pos] * len(b_group)
|
|
166
|
+
|
|
167
|
+
if b_type is None:
|
|
168
|
+
b_type = ["A"] * len(b_group)
|
|
169
|
+
elif not isinstance(b_type, list):
|
|
170
|
+
b_type = [b_type] * len(b_group)
|
|
171
|
+
|
|
172
|
+
# Process each boundary group
|
|
173
|
+
for i, group in enumerate(b_group):
|
|
174
|
+
if i < len(b_type) and b_type[i] == "A":
|
|
175
|
+
# Activation: Check if already activated in previous stages
|
|
176
|
+
for stage in CS.STAGE.stages:
|
|
177
|
+
for existing_group in stage.act_boundary_groups:
|
|
178
|
+
if existing_group["name"] == group:
|
|
179
|
+
raise ValueError(f"Boundary group '{group}' has already been activated in stage '{stage.NAME}' (ID: {stage.ID})")
|
|
180
|
+
|
|
181
|
+
pos = b_pos[i] if i < len(b_pos) else "DEFORMED"
|
|
182
|
+
self.act_boundary_groups.append({"name": group, "pos": pos})
|
|
183
|
+
else:
|
|
184
|
+
# Deactivation: Check if activated in previous stages
|
|
185
|
+
activated = False
|
|
186
|
+
for stage in CS.STAGE.stages:
|
|
187
|
+
for existing_group in stage.act_boundary_groups:
|
|
188
|
+
if existing_group["name"] == group:
|
|
189
|
+
activated = True
|
|
190
|
+
break
|
|
191
|
+
if activated:
|
|
192
|
+
break
|
|
193
|
+
|
|
194
|
+
if not activated:
|
|
195
|
+
raise ValueError(f"Boundary group '{group}' cannot be deactivated as it has not been activated in any previous stage")
|
|
196
|
+
|
|
197
|
+
self.deact_boundary_groups.append(group)
|
|
198
|
+
|
|
199
|
+
# Process load groups
|
|
200
|
+
if l_group:
|
|
201
|
+
# Convert single values to lists for uniform processing
|
|
202
|
+
if not isinstance(l_group, list):
|
|
203
|
+
l_group = [l_group]
|
|
204
|
+
l_day = [l_day if l_day is not None else "FIRST"]
|
|
205
|
+
l_type = [l_type if l_type is not None else "A"]
|
|
206
|
+
else:
|
|
207
|
+
# Ensure other parameters are lists too
|
|
208
|
+
if l_day is None:
|
|
209
|
+
l_day = ["FIRST"] * len(l_group)
|
|
210
|
+
elif not isinstance(l_day, list):
|
|
211
|
+
l_day = [l_day] * len(l_group)
|
|
212
|
+
|
|
213
|
+
if l_type is None:
|
|
214
|
+
l_type = ["A"] * len(l_group)
|
|
215
|
+
elif not isinstance(l_type, list):
|
|
216
|
+
l_type = [l_type] * len(l_group)
|
|
217
|
+
|
|
218
|
+
# Process each load group
|
|
219
|
+
for i, group in enumerate(l_group):
|
|
220
|
+
if i < len(l_type) and l_type[i] == "A":
|
|
221
|
+
# Activation: Check if already activated in previous stages
|
|
222
|
+
for stage in CS.STAGE.stages:
|
|
223
|
+
for existing_group in stage.act_load_groups:
|
|
224
|
+
if existing_group["name"] == group:
|
|
225
|
+
raise ValueError(f"Load group '{group}' has already been activated in stage '{stage.NAME}' (ID: {stage.ID})")
|
|
226
|
+
|
|
227
|
+
day = l_day[i] if i < len(l_day) else "FIRST"
|
|
228
|
+
self.act_load_groups.append({"name": group, "day": day})
|
|
229
|
+
else:
|
|
230
|
+
# Deactivation: Check if activated in previous stages
|
|
231
|
+
activated = False
|
|
232
|
+
for stage in CS.STAGE.stages:
|
|
233
|
+
for existing_group in stage.act_load_groups:
|
|
234
|
+
if existing_group["name"] == group:
|
|
235
|
+
activated = True
|
|
236
|
+
break
|
|
237
|
+
if activated:
|
|
238
|
+
break
|
|
239
|
+
|
|
240
|
+
if not activated:
|
|
241
|
+
raise ValueError(f"Load group '{group}' cannot be deactivated as it has not been activated in any previous stage")
|
|
242
|
+
|
|
243
|
+
day = l_day[i] if i < len(l_day) else "FIRST"
|
|
244
|
+
self.deact_load_groups.append({"name": group, "day": day})
|
|
245
|
+
|
|
246
|
+
CS.STAGE.stages.append(self)
|
|
247
|
+
|
|
248
|
+
@classmethod
|
|
249
|
+
def json(cls):
|
|
250
|
+
"""
|
|
251
|
+
Converts Construction Stage data to JSON format
|
|
252
|
+
Example:
|
|
253
|
+
# Get the JSON data for all construction stages
|
|
254
|
+
json_data = CS.json()
|
|
255
|
+
print(json_data)
|
|
256
|
+
"""
|
|
257
|
+
json = {"Assign": {}}
|
|
258
|
+
|
|
259
|
+
for csa in cls.stages:
|
|
260
|
+
stage_data = {
|
|
261
|
+
"NAME": csa.NAME,
|
|
262
|
+
"DURATION": csa.DURATION,
|
|
263
|
+
"bSV_RSLT": csa.SV_Result,
|
|
264
|
+
"bSV_STEP": csa.SV_Step,
|
|
265
|
+
"bLOAD_STEP": csa.Load_IN,
|
|
266
|
+
"NO" : csa.NO
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
# Add incremental steps if load step is enabled
|
|
270
|
+
if csa.Load_IN:
|
|
271
|
+
stage_data["INCRE_STEP"] = csa.NL
|
|
272
|
+
|
|
273
|
+
# Add additional steps if specified
|
|
274
|
+
if csa.addstp:
|
|
275
|
+
stage_data["ADD_STEP"] = csa.addstp
|
|
276
|
+
else:
|
|
277
|
+
stage_data["ADD_STEP"] = []
|
|
278
|
+
|
|
279
|
+
# Handle structure group activation
|
|
280
|
+
if csa.act_structure_groups:
|
|
281
|
+
stage_data["ACT_ELEM"] = []
|
|
282
|
+
for group in csa.act_structure_groups:
|
|
283
|
+
stage_data["ACT_ELEM"].append({
|
|
284
|
+
"GRUP_NAME": group["name"],
|
|
285
|
+
"AGE": group["age"]
|
|
286
|
+
})
|
|
287
|
+
|
|
288
|
+
# Handle structure group deactivation
|
|
289
|
+
if csa.deact_structure_groups:
|
|
290
|
+
stage_data["DACT_ELEM"] = []
|
|
291
|
+
for group in csa.deact_structure_groups:
|
|
292
|
+
stage_data["DACT_ELEM"].append({
|
|
293
|
+
"GRUP_NAME": group["name"],
|
|
294
|
+
"REDIST": group["redist"]
|
|
295
|
+
})
|
|
296
|
+
|
|
297
|
+
# Handle boundary group activation
|
|
298
|
+
if csa.act_boundary_groups:
|
|
299
|
+
stage_data["ACT_BNGR"] = []
|
|
300
|
+
for group in csa.act_boundary_groups:
|
|
301
|
+
stage_data["ACT_BNGR"].append({
|
|
302
|
+
"BNGR_NAME": group["name"],
|
|
303
|
+
"POS": group["pos"]
|
|
304
|
+
})
|
|
305
|
+
|
|
306
|
+
# Handle boundary group deactivation
|
|
307
|
+
if csa.deact_boundary_groups:
|
|
308
|
+
stage_data["DACT_BNGR"] = []
|
|
309
|
+
for group_name in csa.deact_boundary_groups:
|
|
310
|
+
stage_data["DACT_BNGR"].append(group_name)
|
|
311
|
+
|
|
312
|
+
# Handle load group activation
|
|
313
|
+
if csa.act_load_groups:
|
|
314
|
+
stage_data["ACT_LOAD"] = []
|
|
315
|
+
for group in csa.act_load_groups:
|
|
316
|
+
stage_data["ACT_LOAD"].append({
|
|
317
|
+
"LOAD_NAME": group["name"],
|
|
318
|
+
"DAY": group["day"]
|
|
319
|
+
})
|
|
320
|
+
|
|
321
|
+
# Handle load group deactivation
|
|
322
|
+
if csa.deact_load_groups:
|
|
323
|
+
stage_data["DACT_LOAD"] = []
|
|
324
|
+
for group in csa.deact_load_groups:
|
|
325
|
+
stage_data["DACT_LOAD"].append({
|
|
326
|
+
"LOAD_NAME": group["name"],
|
|
327
|
+
"DAY": group["day"]
|
|
328
|
+
})
|
|
329
|
+
|
|
330
|
+
json["Assign"][str(csa.ID)] = stage_data
|
|
331
|
+
|
|
332
|
+
return json
|
|
333
|
+
|
|
334
|
+
@classmethod
|
|
335
|
+
def create(cls):
|
|
336
|
+
"""Creates construction stages in the database"""
|
|
337
|
+
if CS.STAGE._isSync_:
|
|
338
|
+
MidasAPI("DELETE", "/db/stag")
|
|
339
|
+
MidasAPI("PUT", "/db/stag", cls.json())
|
|
340
|
+
|
|
341
|
+
@classmethod
|
|
342
|
+
def get(cls):
|
|
343
|
+
"""Gets construction stage data from the database"""
|
|
344
|
+
return MidasAPI("GET", "/db/stag")
|
|
345
|
+
|
|
346
|
+
@classmethod
|
|
347
|
+
def sync(cls):
|
|
348
|
+
"""Updates the CS class with data from the database"""
|
|
349
|
+
cls.stages = []
|
|
350
|
+
a = cls.get()
|
|
351
|
+
if a != {'message': ''}:
|
|
352
|
+
if "STAG" in a:
|
|
353
|
+
stag_data_dict = a["STAG"]
|
|
354
|
+
else:
|
|
355
|
+
return
|
|
356
|
+
|
|
357
|
+
for stag_id, stag_data in stag_data_dict.items():
|
|
358
|
+
# Basic stage data
|
|
359
|
+
name = stag_data.get("NAME")
|
|
360
|
+
duration = stag_data.get("DURATION")
|
|
361
|
+
sv_result = stag_data.get("bSV_RSLT")
|
|
362
|
+
sv_step = stag_data.get("bSV_STEP")
|
|
363
|
+
load_in = stag_data.get("bLOAD_STEP")
|
|
364
|
+
nl = stag_data.get("INCRE_STEP")
|
|
365
|
+
addstp = stag_data.get("ADD_STEP")
|
|
366
|
+
stagNo = stag_data.get("NO")
|
|
367
|
+
|
|
368
|
+
# Create a new CS object with basic properties
|
|
369
|
+
new_cs = CS.STAGE(
|
|
370
|
+
name=name,
|
|
371
|
+
duration=duration,
|
|
372
|
+
id=int(stagNo),
|
|
373
|
+
sv_result=sv_result,
|
|
374
|
+
sv_step=sv_step,
|
|
375
|
+
load_in=load_in,
|
|
376
|
+
nl=nl,
|
|
377
|
+
addstp=addstp
|
|
378
|
+
)
|
|
379
|
+
new_cs.NO = stagNo
|
|
380
|
+
CS.STAGE.stages.pop()
|
|
381
|
+
|
|
382
|
+
# Process activation elements
|
|
383
|
+
if "ACT_ELEM" in stag_data and stag_data["ACT_ELEM"]:
|
|
384
|
+
for elem in stag_data["ACT_ELEM"]:
|
|
385
|
+
group_name = elem.get("GRUP_NAME")
|
|
386
|
+
age = elem.get("AGE")
|
|
387
|
+
new_cs.act_structure_groups.append({"name": group_name, "age": age})
|
|
388
|
+
|
|
389
|
+
# Process deactivation elements
|
|
390
|
+
if "DACT_ELEM" in stag_data and stag_data["DACT_ELEM"]:
|
|
391
|
+
for elem in stag_data["DACT_ELEM"]:
|
|
392
|
+
if isinstance(elem, dict):
|
|
393
|
+
group_name = elem.get("GRUP_NAME")
|
|
394
|
+
redist = elem.get("REDIST")
|
|
395
|
+
else:
|
|
396
|
+
group_name = elem
|
|
397
|
+
redist = 0
|
|
398
|
+
new_cs.deact_structure_groups.append({"name": group_name, "redist": redist})
|
|
399
|
+
|
|
400
|
+
# Process activation boundary groups
|
|
401
|
+
if "ACT_BNGR" in stag_data and stag_data["ACT_BNGR"]:
|
|
402
|
+
for bngr in stag_data["ACT_BNGR"]:
|
|
403
|
+
group_name = bngr.get("BNGR_NAME")
|
|
404
|
+
pos = bngr.get("POS")
|
|
405
|
+
new_cs.act_boundary_groups.append({"name": group_name, "pos": pos})
|
|
406
|
+
|
|
407
|
+
# Process deactivation boundary groups
|
|
408
|
+
if "DACT_BNGR" in stag_data and stag_data["DACT_BNGR"]:
|
|
409
|
+
for bngr in stag_data["DACT_BNGR"]:
|
|
410
|
+
new_cs.deact_boundary_groups.append(bngr)
|
|
411
|
+
|
|
412
|
+
# Process activation loads
|
|
413
|
+
if "ACT_LOAD" in stag_data and stag_data["ACT_LOAD"]:
|
|
414
|
+
for load in stag_data["ACT_LOAD"]:
|
|
415
|
+
group_name = load.get("LOAD_NAME")
|
|
416
|
+
day = load.get("DAY")
|
|
417
|
+
new_cs.act_load_groups.append({"name": group_name, "day": day})
|
|
418
|
+
|
|
419
|
+
# Process deactivation loads
|
|
420
|
+
if "DACT_LOAD" in stag_data and stag_data["DACT_LOAD"]:
|
|
421
|
+
for load in stag_data["DACT_LOAD"]:
|
|
422
|
+
if isinstance(load, dict):
|
|
423
|
+
group_name = load.get("LOAD_NAME")
|
|
424
|
+
day = load.get("DAY")
|
|
425
|
+
else:
|
|
426
|
+
group_name = load
|
|
427
|
+
day = "FIRST"
|
|
428
|
+
new_cs.deact_load_groups.append({"name": group_name, "day": day})
|
|
429
|
+
|
|
430
|
+
CS.STAGE.stages.append(new_cs)
|
|
431
|
+
|
|
432
|
+
sorted_stgs = sorted(CS.STAGE.stages,key=lambda x : x.NO)
|
|
433
|
+
CS.STAGE.stages = sorted_stgs
|
|
434
|
+
CS.STAGE._isSync_ = True
|
|
435
|
+
|
|
436
|
+
@classmethod
|
|
437
|
+
def delete(cls):
|
|
438
|
+
"""Deletes all construction stages from the database and resets the class"""
|
|
439
|
+
cls.stages = []
|
|
440
|
+
return MidasAPI("DELETE", "/db/stag")
|
|
441
|
+
|
|
442
|
+
#-----------------------------------------------------------Comp Section for CS--------------------------------------------------------------
|
|
443
|
+
|
|
444
|
+
class CompSec:
|
|
445
|
+
compsecs = []
|
|
446
|
+
|
|
447
|
+
def __init__(self,
|
|
448
|
+
activation_stage: str,
|
|
449
|
+
section_id: int,
|
|
450
|
+
comp_type: str = "GENERAL",
|
|
451
|
+
tapered_type: bool = False,
|
|
452
|
+
partinfo: list = None,
|
|
453
|
+
id: int = None):
|
|
454
|
+
"""
|
|
455
|
+
Parameters:
|
|
456
|
+
activation_stage: Active Stage name (required)
|
|
457
|
+
section_id: Section ID (required)
|
|
458
|
+
comp_type: Composite Type - "GENERAL" or "USER" (default "GENERAL")
|
|
459
|
+
tapered_type: Tapered Type - True or False (default False)
|
|
460
|
+
partinfo: List of part information lists (required)
|
|
461
|
+
id: The composite section ID (optional)
|
|
462
|
+
|
|
463
|
+
Part Info Format:
|
|
464
|
+
Each part should be a list with elements in order:
|
|
465
|
+
[part_number, material_type, material_id, composite_stage, age,
|
|
466
|
+
height, volume_surface_ratio, module_exposed_surface, area,
|
|
467
|
+
asy, asz, ixx, iyy, izz, warea, iw]
|
|
468
|
+
|
|
469
|
+
- part_number: Integer (required)
|
|
470
|
+
- material_type: "ELEM" or "MATL" (required)
|
|
471
|
+
- material_id: String (optional, blank for ELEM)
|
|
472
|
+
- composite_stage: String (optional, blank for active stage)
|
|
473
|
+
- age: Number (default 0)
|
|
474
|
+
- height: Number (default AUTO)
|
|
475
|
+
- volume_surface_ratio: Number (default 0)
|
|
476
|
+
- module_exposed_surface: Number (default 0)
|
|
477
|
+
- area: Number (default 1)
|
|
478
|
+
- asy: Number (default 1)
|
|
479
|
+
- asz: Number (default 1)
|
|
480
|
+
- ixx: Number (default 1)
|
|
481
|
+
- iyy: Number (default 1)
|
|
482
|
+
- izz: Number (default 1)
|
|
483
|
+
- warea: Number (default 1)
|
|
484
|
+
- iw: Number (default 1)
|
|
485
|
+
|
|
486
|
+
Examples:
|
|
487
|
+
```python
|
|
488
|
+
# Basic composite section
|
|
489
|
+
CompSec("CS1", 1, "GENERAL", False, [
|
|
490
|
+
[1, "ELEM", "", "", 2, 1.5, 1.5, 1, 1, 1, 1, 1, 1, 1, 1, 1],
|
|
491
|
+
[2, "MATL", "3", "CS2", 5, 0.245, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1]
|
|
492
|
+
])
|
|
493
|
+
|
|
494
|
+
# With minimal part info (using defaults)
|
|
495
|
+
CompSec("CS1", 2, "GENERAL", False, [
|
|
496
|
+
[1, "ELEM"],
|
|
497
|
+
[2, "MATL", "2","CS2"]
|
|
498
|
+
])
|
|
499
|
+
```
|
|
500
|
+
"""
|
|
501
|
+
|
|
502
|
+
self.ASTAGE = activation_stage
|
|
503
|
+
self.SEC = section_id
|
|
504
|
+
self.TYPE = comp_type
|
|
505
|
+
self.bTAP = tapered_type
|
|
506
|
+
|
|
507
|
+
# Set ID
|
|
508
|
+
if id is None:
|
|
509
|
+
self.ID = len(CS.CompSec.compsecs) + 1
|
|
510
|
+
else:
|
|
511
|
+
self.ID = id
|
|
512
|
+
|
|
513
|
+
# Process part information
|
|
514
|
+
self.vPARTINFO = []
|
|
515
|
+
|
|
516
|
+
if partinfo is None:
|
|
517
|
+
raise ValueError("Part information is required")
|
|
518
|
+
|
|
519
|
+
if not isinstance(partinfo, list):
|
|
520
|
+
raise ValueError("Part information must be a list of lists")
|
|
521
|
+
|
|
522
|
+
for part_data in partinfo:
|
|
523
|
+
if not isinstance(part_data, list) or len(part_data) < 2:
|
|
524
|
+
raise ValueError("Each part must be a list with at least part number and material type")
|
|
525
|
+
|
|
526
|
+
# Default values for part info
|
|
527
|
+
defaults = [
|
|
528
|
+
None, # PART (required)
|
|
529
|
+
None, # MTYPE (required)
|
|
530
|
+
"", # MAT
|
|
531
|
+
"", # CSTAGE
|
|
532
|
+
0, # AGE
|
|
533
|
+
"AUTO", # PARTINFO_H
|
|
534
|
+
0, # PARTINFO_VS
|
|
535
|
+
0, # PARTINFO_M
|
|
536
|
+
1, # AREA
|
|
537
|
+
1, # ASY
|
|
538
|
+
1, # ASZ
|
|
539
|
+
1, # IXX
|
|
540
|
+
1, # IYY
|
|
541
|
+
1, # IZZ
|
|
542
|
+
1, # WAREA
|
|
543
|
+
1 # IW
|
|
544
|
+
]
|
|
545
|
+
|
|
546
|
+
# Fill in provided values
|
|
547
|
+
for i, value in enumerate(part_data):
|
|
548
|
+
if i < len(defaults):
|
|
549
|
+
defaults[i] = value
|
|
550
|
+
|
|
551
|
+
# Validate required fields
|
|
552
|
+
if defaults[0] is None:
|
|
553
|
+
raise ValueError("Part number is required")
|
|
554
|
+
if defaults[1] is None:
|
|
555
|
+
raise ValueError("Material type is required")
|
|
556
|
+
if defaults[1] not in ["ELEM", "MATL"]:
|
|
557
|
+
raise ValueError("Material type must be 'ELEM' or 'MATL'")
|
|
558
|
+
|
|
559
|
+
# Create part info dictionary
|
|
560
|
+
part_info = {
|
|
561
|
+
"PART": defaults[0],
|
|
562
|
+
"MTYPE": defaults[1],
|
|
563
|
+
"MAT": defaults[2],
|
|
564
|
+
"CSTAGE": defaults[3],
|
|
565
|
+
"AGE": defaults[4],
|
|
566
|
+
"PARTINFO_H": defaults[5],
|
|
567
|
+
"PARTINFO_VS": defaults[6],
|
|
568
|
+
"PARTINFO_M": defaults[7],
|
|
569
|
+
"AREA": defaults[8],
|
|
570
|
+
"ASY": defaults[9],
|
|
571
|
+
"ASZ": defaults[10],
|
|
572
|
+
"IXX": defaults[11],
|
|
573
|
+
"IYY": defaults[12],
|
|
574
|
+
"IZZ": defaults[13],
|
|
575
|
+
"WAREA": defaults[14],
|
|
576
|
+
"IW": defaults[15]
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
self.vPARTINFO.append(part_info)
|
|
580
|
+
|
|
581
|
+
CS.CompSec.compsecs.append(self)
|
|
582
|
+
|
|
583
|
+
@classmethod
|
|
584
|
+
def json(cls):
|
|
585
|
+
"""
|
|
586
|
+
Converts Composite Section data to JSON format
|
|
587
|
+
Example:
|
|
588
|
+
# Get the JSON data for all composite sections
|
|
589
|
+
json_data = CS.CompSec.json()
|
|
590
|
+
print(json_data)
|
|
591
|
+
"""
|
|
592
|
+
json_data = {"Assign": {}}
|
|
593
|
+
|
|
594
|
+
for compsec in cls.compsecs:
|
|
595
|
+
section_data = {
|
|
596
|
+
"SEC": compsec.SEC,
|
|
597
|
+
"ASTAGE": compsec.ASTAGE,
|
|
598
|
+
"TYPE": compsec.TYPE,
|
|
599
|
+
"bTAP": compsec.bTAP,
|
|
600
|
+
"vPARTINFO": compsec.vPARTINFO
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
json_data["Assign"][str(compsec.ID)] = section_data
|
|
604
|
+
|
|
605
|
+
return json_data
|
|
606
|
+
|
|
607
|
+
@classmethod
|
|
608
|
+
def create(cls):
|
|
609
|
+
"""Creates composite sections in the database"""
|
|
610
|
+
return MidasAPI("PUT", "/db/cscs", cls.json())
|
|
611
|
+
|
|
612
|
+
@classmethod
|
|
613
|
+
def get(cls):
|
|
614
|
+
"""Gets composite section data from the database"""
|
|
615
|
+
return MidasAPI("GET", "/db/cscs")
|
|
616
|
+
|
|
617
|
+
@classmethod
|
|
618
|
+
def sync(cls):
|
|
619
|
+
"""Updates the CompSec class with data from the database"""
|
|
620
|
+
cls.compsecs = []
|
|
621
|
+
response = cls.get()
|
|
622
|
+
|
|
623
|
+
if response != {'message': ''}:
|
|
624
|
+
if "CSCS" in response:
|
|
625
|
+
cscs_data_dict = response["CSCS"]
|
|
626
|
+
else:
|
|
627
|
+
return
|
|
628
|
+
|
|
629
|
+
for cscs_id, cscs_data in cscs_data_dict.items():
|
|
630
|
+
# Basic section data
|
|
631
|
+
astage = cscs_data.get("ASTAGE")
|
|
632
|
+
sec = cscs_data.get("SEC")
|
|
633
|
+
comp_type = cscs_data.get("TYPE", "GENERAL")
|
|
634
|
+
tapered_type = cscs_data.get("bTAP", False)
|
|
635
|
+
partinfo_data = cscs_data.get("vPARTINFO", [])
|
|
636
|
+
|
|
637
|
+
# Convert partinfo from dict format to list format
|
|
638
|
+
partinfo = []
|
|
639
|
+
for part in partinfo_data:
|
|
640
|
+
part_list = [
|
|
641
|
+
part.get("PART"),
|
|
642
|
+
part.get("MTYPE"),
|
|
643
|
+
part.get("MAT", ""),
|
|
644
|
+
part.get("CSTAGE", ""),
|
|
645
|
+
part.get("AGE", 0),
|
|
646
|
+
part.get("PARTINFO_H", "AUTO"),
|
|
647
|
+
part.get("PARTINFO_VS", 0),
|
|
648
|
+
part.get("PARTINFO_M", 0),
|
|
649
|
+
part.get("AREA", 1),
|
|
650
|
+
part.get("ASY", 1),
|
|
651
|
+
part.get("ASZ", 1),
|
|
652
|
+
part.get("IXX", 1),
|
|
653
|
+
part.get("IYY", 1),
|
|
654
|
+
part.get("IZZ", 1),
|
|
655
|
+
part.get("WAREA", 1),
|
|
656
|
+
part.get("IW", 1)
|
|
657
|
+
]
|
|
658
|
+
partinfo.append(part_list)
|
|
659
|
+
|
|
660
|
+
# Create a new CompSec object
|
|
661
|
+
new_compsec = CS.CompSec(
|
|
662
|
+
activation_stage=astage,
|
|
663
|
+
section_id=sec,
|
|
664
|
+
comp_type=comp_type,
|
|
665
|
+
tapered_type=tapered_type,
|
|
666
|
+
partinfo=partinfo,
|
|
667
|
+
id=int(cscs_id)
|
|
668
|
+
)
|
|
669
|
+
|
|
670
|
+
# Remove the automatically added instance and replace with synced data
|
|
671
|
+
CS.CompSec.compsecs.pop()
|
|
672
|
+
CS.CompSec.compsecs.append(new_compsec)
|
|
673
|
+
|
|
674
|
+
@classmethod
|
|
675
|
+
def delete(cls):
|
|
676
|
+
"""Deletes all composite sections from the database and resets the class"""
|
|
677
|
+
cls.compsecs = []
|
|
678
|
+
return MidasAPI("DELETE", "/db/cscs")
|
|
679
|
+
|
|
680
|
+
|
|
681
|
+
#-----------------------------------------------------------------------------------------------------------------------------------
|
|
682
|
+
|
|
683
|
+
class TimeLoad:
|
|
684
|
+
timeloads = []
|
|
685
|
+
|
|
686
|
+
def __init__(self,
|
|
687
|
+
element_id: int,
|
|
688
|
+
day: int,
|
|
689
|
+
group: str = "",
|
|
690
|
+
id: int = None):
|
|
691
|
+
"""
|
|
692
|
+
Time Loads for Construction Stage define.
|
|
693
|
+
|
|
694
|
+
Parameters:
|
|
695
|
+
element_id: Element ID (required)
|
|
696
|
+
day: Time Loads in days (required)
|
|
697
|
+
group: Load Group Name (optional, default blank)
|
|
698
|
+
id: The time loads ID (optional)
|
|
699
|
+
|
|
700
|
+
Examples:
|
|
701
|
+
```python
|
|
702
|
+
CS.TimeLoad(10, 35, "DL")
|
|
703
|
+
```
|
|
704
|
+
"""
|
|
705
|
+
|
|
706
|
+
self.ELEMENT_ID = element_id
|
|
707
|
+
self.DAY = day
|
|
708
|
+
self.GROUP_NAME = group
|
|
709
|
+
|
|
710
|
+
# Set ID
|
|
711
|
+
if id is None:
|
|
712
|
+
self.ID = len(CS.TimeLoad.timeloads) + 1
|
|
713
|
+
else:
|
|
714
|
+
self.ID = id
|
|
715
|
+
|
|
716
|
+
CS.TimeLoad.timeloads.append(self)
|
|
717
|
+
|
|
718
|
+
@classmethod
|
|
719
|
+
def json(cls):
|
|
720
|
+
"""
|
|
721
|
+
Converts Time Loads data to JSON format
|
|
722
|
+
Example:
|
|
723
|
+
# Get the JSON data for all time loads
|
|
724
|
+
json_data = CS.TimeLoad.json()
|
|
725
|
+
print(json_data)
|
|
726
|
+
"""
|
|
727
|
+
json_data = {"Assign": {}}
|
|
728
|
+
|
|
729
|
+
for timeload in cls.timeloads:
|
|
730
|
+
items_data = {
|
|
731
|
+
"ITEMS": [
|
|
732
|
+
{
|
|
733
|
+
"ID": 1,
|
|
734
|
+
"GROUP_NAME": timeload.GROUP_NAME,
|
|
735
|
+
"DAY": timeload.DAY
|
|
736
|
+
}
|
|
737
|
+
]
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
json_data["Assign"][str(timeload.ELEMENT_ID)] = items_data
|
|
741
|
+
|
|
742
|
+
return json_data
|
|
743
|
+
|
|
744
|
+
@classmethod
|
|
745
|
+
def create(cls):
|
|
746
|
+
"""Creates time loads in the CIVIL NX"""
|
|
747
|
+
return MidasAPI("PUT", "/db/tmld", cls.json())
|
|
748
|
+
|
|
749
|
+
@classmethod
|
|
750
|
+
def get(cls):
|
|
751
|
+
"""Gets time loads data from the CIVIL NX"""
|
|
752
|
+
return MidasAPI("GET", "/db/tmld")
|
|
753
|
+
|
|
754
|
+
@classmethod
|
|
755
|
+
def sync(cls):
|
|
756
|
+
"""Updates the TimeLoad class with data from the CIVIL NX"""
|
|
757
|
+
cls.timeloads = []
|
|
758
|
+
response = cls.get()
|
|
759
|
+
|
|
760
|
+
if response != {'message': ''}:
|
|
761
|
+
if "TMLD" in response:
|
|
762
|
+
stbk_data_dict = response["TMLD"]
|
|
763
|
+
else:
|
|
764
|
+
return
|
|
765
|
+
|
|
766
|
+
for element_id, stbk_data in stbk_data_dict.items():
|
|
767
|
+
items = stbk_data.get("ITEMS", [])
|
|
768
|
+
|
|
769
|
+
for item in items:
|
|
770
|
+
group_name = item.get("GROUP_NAME", "")
|
|
771
|
+
day = item.get("DAY", 0)
|
|
772
|
+
item_id = item.get("ID", 1)
|
|
773
|
+
|
|
774
|
+
# Create a new TimeLoad object
|
|
775
|
+
new_timeload = CS.TimeLoad(
|
|
776
|
+
element_id=int(element_id),
|
|
777
|
+
day=day,
|
|
778
|
+
group=group_name,
|
|
779
|
+
id=item_id
|
|
780
|
+
)
|
|
781
|
+
|
|
782
|
+
# Remove the automatically added instance and replace with synced data
|
|
783
|
+
CS.TimeLoad.timeloads.pop()
|
|
784
|
+
CS.TimeLoad.timeloads.append(new_timeload)
|
|
785
|
+
|
|
786
|
+
@classmethod
|
|
787
|
+
def delete(cls):
|
|
788
|
+
"""Deletes all time loads from the CIVIL NX and python class"""
|
|
789
|
+
cls.timeloads = []
|
|
790
|
+
return MidasAPI("DELETE", "/db/tmld")
|
|
791
|
+
|
|
792
|
+
class CreepCoeff:
|
|
793
|
+
creepcoeffs = []
|
|
794
|
+
|
|
795
|
+
def __init__(self,
|
|
796
|
+
element_id: int,
|
|
797
|
+
creep: float,
|
|
798
|
+
group: str = "",
|
|
799
|
+
id: int = None):
|
|
800
|
+
"""
|
|
801
|
+
Creep Coefficient for Construction Stage define.
|
|
802
|
+
|
|
803
|
+
Parameters:
|
|
804
|
+
element_id: Element ID (required)
|
|
805
|
+
creep: Creep Coefficient value (required)
|
|
806
|
+
group: Load Group Name (optional, default blank)
|
|
807
|
+
id: The creep coefficient ID (optional)
|
|
808
|
+
|
|
809
|
+
Examples:
|
|
810
|
+
```python
|
|
811
|
+
# Basic creep coefficient
|
|
812
|
+
CS.CreepCoeff(25, 1.2)
|
|
813
|
+
|
|
814
|
+
# With specific ID & Group
|
|
815
|
+
CS.CreepCoeff(26, 1.5, "GR", id=2)
|
|
816
|
+
```
|
|
817
|
+
"""
|
|
818
|
+
|
|
819
|
+
self.ELEMENT_ID = element_id
|
|
820
|
+
self.CREEP = creep
|
|
821
|
+
self.GROUP_NAME = group
|
|
822
|
+
|
|
823
|
+
# Set ID
|
|
824
|
+
if id is None:
|
|
825
|
+
self.ID = len(CS.CreepCoeff.creepcoeffs) + 1
|
|
826
|
+
else:
|
|
827
|
+
self.ID = id
|
|
828
|
+
|
|
829
|
+
CS.CreepCoeff.creepcoeffs.append(self)
|
|
830
|
+
|
|
831
|
+
@classmethod
|
|
832
|
+
def json(cls):
|
|
833
|
+
"""
|
|
834
|
+
Converts Creep Coefficient data to JSON format
|
|
835
|
+
Example:
|
|
836
|
+
# Get the JSON data for all creep coefficients
|
|
837
|
+
json_data = CS.CreepCoeff.json()
|
|
838
|
+
print(json_data)
|
|
839
|
+
"""
|
|
840
|
+
json_data = {"Assign": {}}
|
|
841
|
+
|
|
842
|
+
for creepcoeff in cls.creepcoeffs:
|
|
843
|
+
items_data = {
|
|
844
|
+
"ITEMS": [
|
|
845
|
+
{
|
|
846
|
+
"ID": 1,
|
|
847
|
+
"GROUP_NAME": creepcoeff.GROUP_NAME,
|
|
848
|
+
"CREEP": creepcoeff.CREEP
|
|
849
|
+
}
|
|
850
|
+
]
|
|
851
|
+
}
|
|
852
|
+
|
|
853
|
+
json_data["Assign"][str(creepcoeff.ELEMENT_ID)] = items_data
|
|
854
|
+
|
|
855
|
+
return json_data
|
|
856
|
+
|
|
857
|
+
@classmethod
|
|
858
|
+
def create(cls):
|
|
859
|
+
"""Creates creep coefficients in the database"""
|
|
860
|
+
return MidasAPI("PUT", "/db/crpc", cls.json())
|
|
861
|
+
|
|
862
|
+
@classmethod
|
|
863
|
+
def get(cls):
|
|
864
|
+
"""Gets creep coefficient data from the database"""
|
|
865
|
+
return MidasAPI("GET", "/db/crpc")
|
|
866
|
+
|
|
867
|
+
@classmethod
|
|
868
|
+
def sync(cls):
|
|
869
|
+
"""Updates the CreepCoeff class with data from the database"""
|
|
870
|
+
cls.creepcoeffs = []
|
|
871
|
+
response = cls.get()
|
|
872
|
+
|
|
873
|
+
if response != {'message': ''}:
|
|
874
|
+
if "CRPC" in response:
|
|
875
|
+
crpc_data_dict = response["CRPC"]
|
|
876
|
+
else:
|
|
877
|
+
return
|
|
878
|
+
|
|
879
|
+
for element_id, crpc_data in crpc_data_dict.items():
|
|
880
|
+
items = crpc_data.get("ITEMS", [])
|
|
881
|
+
|
|
882
|
+
for item in items:
|
|
883
|
+
group_name = item.get("GROUP_NAME", "")
|
|
884
|
+
creep = item.get("CREEP", 0.0)
|
|
885
|
+
item_id = item.get("ID", 1)
|
|
886
|
+
|
|
887
|
+
# Create a new CreepCoeff object
|
|
888
|
+
new_creepcoeff = CS.CreepCoeff(
|
|
889
|
+
element_id=int(element_id),
|
|
890
|
+
creep=creep,
|
|
891
|
+
group=group_name,
|
|
892
|
+
id=item_id
|
|
893
|
+
)
|
|
894
|
+
|
|
895
|
+
# Remove the automatically added instance and replace with synced data
|
|
896
|
+
CS.CreepCoeff.creepcoeffs.pop()
|
|
897
|
+
CS.CreepCoeff.creepcoeffs.append(new_creepcoeff)
|
|
898
|
+
|
|
899
|
+
@classmethod
|
|
900
|
+
def delete(cls):
|
|
901
|
+
"""Deletes all creep coefficients from the database and resets the class"""
|
|
902
|
+
cls.creepcoeffs = []
|
|
903
|
+
return MidasAPI("DELETE", "/db/crpc")
|
|
904
|
+
|
|
905
|
+
class Camber:
|
|
906
|
+
cambers = []
|
|
907
|
+
|
|
908
|
+
def __init__(self,
|
|
909
|
+
node_id: int,
|
|
910
|
+
camber: float,
|
|
911
|
+
deform: float,
|
|
912
|
+
id: int = None):
|
|
913
|
+
"""
|
|
914
|
+
Camber for Construction Stage define.
|
|
915
|
+
|
|
916
|
+
Parameters:
|
|
917
|
+
node_id: Node ID (required)
|
|
918
|
+
camber: User camber value (required)
|
|
919
|
+
deform: Deformation value (required)
|
|
920
|
+
id: The camber ID (optional)
|
|
921
|
+
|
|
922
|
+
Examples:
|
|
923
|
+
```python
|
|
924
|
+
|
|
925
|
+
CS.Camber(25, 0.17, 0.1)
|
|
926
|
+
```
|
|
927
|
+
"""
|
|
928
|
+
|
|
929
|
+
self.NODE_ID = node_id
|
|
930
|
+
self.USER = camber
|
|
931
|
+
self.DEFORM = deform
|
|
932
|
+
|
|
933
|
+
# Set ID
|
|
934
|
+
if id is None:
|
|
935
|
+
self.ID = len(CS.Camber.cambers) + 1
|
|
936
|
+
else:
|
|
937
|
+
self.ID = id
|
|
938
|
+
|
|
939
|
+
CS.Camber.cambers.append(self)
|
|
940
|
+
|
|
941
|
+
@classmethod
|
|
942
|
+
def json(cls):
|
|
943
|
+
"""
|
|
944
|
+
Converts Camber data to JSON format
|
|
945
|
+
Example:
|
|
946
|
+
# Get the JSON data for all cambers
|
|
947
|
+
json_data = CS.Camber.json()
|
|
948
|
+
print(json_data)
|
|
949
|
+
"""
|
|
950
|
+
json_data = {"Assign": {}}
|
|
951
|
+
|
|
952
|
+
for camber in cls.cambers:
|
|
953
|
+
camber_data = {
|
|
954
|
+
"DEFORM": camber.DEFORM,
|
|
955
|
+
"USER": camber.USER
|
|
956
|
+
}
|
|
957
|
+
|
|
958
|
+
json_data["Assign"][str(camber.NODE_ID)] = camber_data
|
|
959
|
+
|
|
960
|
+
return json_data
|
|
961
|
+
|
|
962
|
+
@classmethod
|
|
963
|
+
def create(cls):
|
|
964
|
+
"""Creates cambers in the database"""
|
|
965
|
+
return MidasAPI("PUT", "/db/cmcs", cls.json())
|
|
966
|
+
|
|
967
|
+
@classmethod
|
|
968
|
+
def get(cls):
|
|
969
|
+
"""Gets camber data from the database"""
|
|
970
|
+
return MidasAPI("GET", "/db/cmcs")
|
|
971
|
+
|
|
972
|
+
@classmethod
|
|
973
|
+
def sync(cls):
|
|
974
|
+
"""Updates the Camber class with data from the database"""
|
|
975
|
+
cls.cambers = []
|
|
976
|
+
response = cls.get()
|
|
977
|
+
|
|
978
|
+
if response != {'message': ''}:
|
|
979
|
+
if "CMCS" in response:
|
|
980
|
+
cmcs_data_dict = response["CMCS"]
|
|
981
|
+
else:
|
|
982
|
+
return
|
|
983
|
+
|
|
984
|
+
for node_id, cmcs_data in cmcs_data_dict.items():
|
|
985
|
+
deform = cmcs_data.get("DEFORM", 0.0)
|
|
986
|
+
user = cmcs_data.get("USER", 0.0)
|
|
987
|
+
|
|
988
|
+
# Create a new Camber object
|
|
989
|
+
new_camber = CS.Camber(
|
|
990
|
+
node_id=int(node_id),
|
|
991
|
+
camber=user,
|
|
992
|
+
deform=deform,
|
|
993
|
+
id=len(cls.cambers) + 1
|
|
994
|
+
)
|
|
995
|
+
|
|
996
|
+
# Remove the automatically added instance and replace with synced data
|
|
997
|
+
CS.Camber.cambers.pop()
|
|
998
|
+
CS.Camber.cambers.append(new_camber)
|
|
999
|
+
|
|
1000
|
+
@classmethod
|
|
1001
|
+
def delete(cls):
|
|
1002
|
+
"""Deletes all cambers from the database and resets the class"""
|
|
1003
|
+
cls.cambers = []
|
|
1004
|
+
return MidasAPI("DELETE", "/db/cmcs")
|