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.
Files changed (40) hide show
  1. midas_civil/_BoundaryChangeAssignment.py +278 -0
  2. midas_civil/__init__.py +51 -0
  3. midas_civil/_analysiscontrol.py +585 -0
  4. midas_civil/_boundary.py +888 -0
  5. midas_civil/_construction.py +1004 -0
  6. midas_civil/_element.py +1346 -0
  7. midas_civil/_group.py +337 -0
  8. midas_civil/_load.py +967 -0
  9. midas_civil/_loadcomb.py +159 -0
  10. midas_civil/_mapi.py +249 -0
  11. midas_civil/_material.py +1692 -0
  12. midas_civil/_model.py +522 -0
  13. midas_civil/_movingload.py +1479 -0
  14. midas_civil/_node.py +532 -0
  15. midas_civil/_result_table.py +929 -0
  16. midas_civil/_result_test.py +5455 -0
  17. midas_civil/_section/_TapdbSecSS.py +175 -0
  18. midas_civil/_section/__init__.py +413 -0
  19. midas_civil/_section/_compositeSS.py +283 -0
  20. midas_civil/_section/_dbSecSS.py +164 -0
  21. midas_civil/_section/_offsetSS.py +53 -0
  22. midas_civil/_section/_pscSS copy.py +455 -0
  23. midas_civil/_section/_pscSS.py +822 -0
  24. midas_civil/_section/_tapPSC12CellSS.py +565 -0
  25. midas_civil/_section/_unSupp.py +58 -0
  26. midas_civil/_settlement.py +161 -0
  27. midas_civil/_temperature.py +677 -0
  28. midas_civil/_tendon.py +1016 -0
  29. midas_civil/_thickness.py +147 -0
  30. midas_civil/_utils.py +529 -0
  31. midas_civil/_utilsFunc/__init__.py +0 -0
  32. midas_civil/_utilsFunc/_line2plate.py +636 -0
  33. midas_civil/_view.py +891 -0
  34. midas_civil/_view_trial.py +430 -0
  35. midas_civil/_visualise.py +347 -0
  36. midas_civil-1.4.1.dist-info/METADATA +74 -0
  37. midas_civil-1.4.1.dist-info/RECORD +40 -0
  38. midas_civil-1.4.1.dist-info/WHEEL +5 -0
  39. midas_civil-1.4.1.dist-info/licenses/LICENSE +21 -0
  40. midas_civil-1.4.1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,677 @@
1
+ from ._mapi import MidasAPI
2
+ # from ._node import *
3
+ from ._group import Group
4
+ from ._load import Load_Case
5
+
6
+ def convList(item):
7
+ if type(item) != list:
8
+ return [item]
9
+ else:
10
+ return item
11
+
12
+ class Temperature:
13
+
14
+ @classmethod
15
+ def create(cls):
16
+ """Creates Temperature elements in MIDAS Civil NX"""
17
+ if cls.System.temps: cls.System.create()
18
+ if cls.Element.temps: cls.Element.create()
19
+ if cls.Gradient.temps: cls.Gradient.create()
20
+ if cls.Nodal.temps: cls.Nodal.create()
21
+ if cls.BeamSection.temps: cls.BeamSection.create()
22
+
23
+ @classmethod
24
+ def delete(cls):
25
+ """Deletes Temperature elements from MIDAS Civil NX and Python"""
26
+ cls.System.delete()
27
+ cls.Element.delete()
28
+ cls.Gradient.delete()
29
+ cls.Nodal.delete()
30
+ cls.BeamSection.delete()
31
+
32
+ @classmethod
33
+ def clear(cls):
34
+ """Deletes Temperature elements from MIDAS Civil NX and Python"""
35
+ cls.System.clear()
36
+ cls.Element.clear()
37
+ cls.Gradient.clear()
38
+ cls.Nodal.clear()
39
+ cls.BeamSection.clear()
40
+
41
+ @classmethod
42
+ def sync(cls):
43
+ """Sync Temperature elements from MIDAS Civil NX to Python"""
44
+ cls.System.sync()
45
+ cls.Element.sync()
46
+ cls.Gradient.sync()
47
+ cls.Nodal.sync()
48
+ cls.BeamSection.sync()
49
+
50
+ # --------------------------------------------------------------------------------------------------
51
+ # System Temperature
52
+ # --------------------------------------------------------------------------------------------------
53
+ class System:
54
+ """
55
+ Create System Temperature Object in Python
56
+
57
+ Parameters:
58
+ temperature (float): Temperature value
59
+ lcname (str): Load case name
60
+ group (str): Load group name (default "")
61
+ id (int): System ID (optional)
62
+
63
+ Example:
64
+ Temperature.System(12.5, "Temp(+)", "LoadGroup1", 1)
65
+ """
66
+ temps = []
67
+
68
+ def __init__(self, temperature, lcname, group="", id=None):
69
+ chk = 0
70
+ for i in Load_Case.cases:
71
+ if lcname in i.NAME: chk = 1
72
+ if chk == 0: Load_Case("T", lcname)
73
+
74
+ if group:
75
+ chk = 0
76
+ try:
77
+ a = [v['NAME'] for v in Group.Load.json()["Assign"].values()]
78
+ if group in a:
79
+ chk = 1
80
+ except:
81
+ pass
82
+ if chk == 0:
83
+ Group.Load(group)
84
+
85
+ self.TEMPER = temperature
86
+ self.LCNAME = lcname
87
+ self.GROUP_NAME = group
88
+
89
+ if id is None:
90
+ self.ID = len(Temperature.System.temps) + 1
91
+ else:
92
+ self.ID = id
93
+
94
+ Temperature.System.temps.append(self)
95
+
96
+ @classmethod
97
+ def json(cls):
98
+ """Creates JSON from System Temperature objects defined in Python"""
99
+ json_data = {"Assign": {}}
100
+ for temp in cls.temps:
101
+ json_data["Assign"][str(temp.ID)] = {
102
+ "TEMPER": temp.TEMPER,
103
+ "LCNAME": temp.LCNAME,
104
+ "GROUP_NAME": temp.GROUP_NAME
105
+ }
106
+ return json_data
107
+
108
+ @staticmethod
109
+ def create():
110
+ """Creates System Temperatures in MIDAS Civil NX"""
111
+ MidasAPI("PUT", "/db/stmp", Temperature.System.json())
112
+
113
+ @staticmethod
114
+ def get():
115
+ """Get the JSON of System Temperatures from MIDAS Civil NX"""
116
+ return MidasAPI("GET", "/db/stmp")
117
+
118
+ @staticmethod
119
+ def sync():
120
+ """Sync System Temperatures from MIDAS Civil NX to Python"""
121
+ Temperature.System.temps = []
122
+ a = Temperature.System.get()
123
+
124
+ if a and 'STMP' in a:
125
+ temp_data = a.get('STMP', {})
126
+ for temp_id, temp_info in temp_data.items():
127
+ Temperature.System(
128
+ temp_info.get('TEMPER', 0),
129
+ temp_info.get('LCNAME', ''),
130
+ temp_info.get('GROUP_NAME', ''),
131
+ int(temp_id)
132
+ )
133
+
134
+ @staticmethod
135
+ def delete():
136
+ """Delete System Temperatures from MIDAS Civil NX and Python"""
137
+ Temperature.System.clear()
138
+ return MidasAPI("DELETE", "/db/stmp")
139
+
140
+ @staticmethod
141
+ def clear():
142
+ """Delete System Temperatures from Python"""
143
+ Temperature.System.temps = []
144
+
145
+ # --------------------------------------------------------------------------------------------------
146
+ # Element Temperature
147
+ # --------------------------------------------------------------------------------------------------
148
+ class Element:
149
+ """
150
+ Create Element Temperature Object in Python
151
+
152
+ Parameters:
153
+ element (int): Element ID
154
+ temperature (float): Temperature value
155
+ lcname (str): Load case name
156
+ group (str): Load group name (default "")
157
+ id (int): Temperature ID (optional)
158
+
159
+ Example:
160
+ Temperature.Element(1, 35, "Temp(+)", "", 1)
161
+ """
162
+ temps = []
163
+
164
+ def __init__(self, element, temperature, lcname, group="", id=None):
165
+
166
+ chk = 0
167
+ for i in Load_Case.cases:
168
+ if lcname in i.NAME: chk = 1
169
+ if chk == 0: Load_Case("T", lcname)
170
+
171
+ if group:
172
+ chk = 0
173
+ try:
174
+ a = [v['NAME'] for v in Group.Load.json()["Assign"].values()]
175
+ if group in a:
176
+ chk = 1
177
+ except:
178
+ pass
179
+ if chk == 0:
180
+ Group.Load(group)
181
+
182
+ self.ELEMENT = element
183
+ self.TEMP = temperature
184
+ self.LCNAME = lcname
185
+ self.GROUP_NAME = group
186
+
187
+ if id is None:
188
+ existing_ids = []
189
+ for temp in Temperature.Element.temps:
190
+ if temp.ELEMENT == element:
191
+ existing_ids.extend([item.get('ID', 0) for item in temp.ITEMS if hasattr(temp, 'ITEMS')])
192
+ self.ID = max(existing_ids, default=0) + 1
193
+ else:
194
+ self.ID = id
195
+
196
+ existing_temp = None
197
+ for temp in Temperature.Element.temps:
198
+ if temp.ELEMENT == element:
199
+ existing_temp = temp
200
+ break
201
+
202
+ item_data = {
203
+ "ID": self.ID, "LCNAME": self.LCNAME,
204
+ "GROUP_NAME": self.GROUP_NAME, "TEMP": self.TEMP
205
+ }
206
+
207
+ if existing_temp:
208
+ if not hasattr(existing_temp, 'ITEMS'):
209
+ existing_temp.ITEMS = []
210
+ existing_temp.ITEMS.append(item_data)
211
+ else:
212
+ self.ITEMS = [item_data]
213
+ Temperature.Element.temps.append(self)
214
+
215
+ @classmethod
216
+ def json(cls):
217
+ """Creates JSON from Element Temperature objects defined in Python"""
218
+ json_data = {"Assign": {}}
219
+ for temp in cls.temps:
220
+ json_data["Assign"][str(temp.ELEMENT)] = {"ITEMS": temp.ITEMS}
221
+ return json_data
222
+
223
+ @staticmethod
224
+ def create():
225
+ """Creates Element Temperatures in MIDAS Civil NX"""
226
+ MidasAPI("PUT", "/db/etmp", Temperature.Element.json())
227
+
228
+ @staticmethod
229
+ def get():
230
+ """Get the JSON of Element Temperatures from MIDAS Civil NX"""
231
+ return MidasAPI("GET", "/db/etmp")
232
+
233
+ @staticmethod
234
+ def sync():
235
+ """Sync Element Temperatures from MIDAS Civil NX to Python"""
236
+ Temperature.Element.temps = []
237
+ a = Temperature.Element.get()
238
+
239
+ if a and 'ETMP' in a:
240
+ temp_data = a.get('ETMP', {})
241
+ for element_id, element_data in temp_data.items():
242
+ element_obj = type('obj', (object,), {
243
+ 'ELEMENT': int(element_id),
244
+ 'ITEMS': element_data.get('ITEMS', [])
245
+ })()
246
+ Temperature.Element.temps.append(element_obj)
247
+
248
+ @staticmethod
249
+ def delete():
250
+ """Delete Element Temperatures from MIDAS Civil NX and Python"""
251
+ Temperature.Element.clear()
252
+ return MidasAPI("DELETE", "/db/etmp")
253
+
254
+ @staticmethod
255
+ def clear():
256
+ """Delete Element Temperatures from MIDAS Civil NX and Python"""
257
+ Temperature.Element.temps = []
258
+
259
+ # --------------------------------------------------------------------------------------------------
260
+ # Temperature Gradient
261
+ # --------------------------------------------------------------------------------------------------
262
+ class Gradient:
263
+ """
264
+ Create Temperature Gradient Object in Python for Beam and Plate elements.
265
+
266
+ Parameters:
267
+ element (int): Element ID to apply the gradient.
268
+ type (str): Element type, either 'Beam' or 'Plate'.
269
+ lcname (str): Load Case Name (must exist in the model).
270
+ tz (float): Temperature difference in the local z-direction (T2z - T1z).
271
+ group (str, optional): Load Group Name. Defaults to "".
272
+ id (int, optional): Gradient ID. Auto-assigned if not provided.
273
+ hz (float, optional): Gradient value for local z-dir. If omitted, section default is used.
274
+ ty (float, optional): Temp. diff. in local y-dir (T2y - T1y). **Required for 'Beam' type.**
275
+ hy (float, optional): Gradient value for local y-dir. If omitted, section default is used.
276
+
277
+ Example for Beam (providing gradient values):
278
+ Temperature.Gradient(element=2, type='Beam', lcname='Temp(-)', tz=10, ty=-10, hz=1.2, hy=0.5)
279
+
280
+ Example for Beam (using section defaults):
281
+ Temperature.Gradient(element=2, type='Beam', lcname='Temp(+)', tz=10, ty=-10)
282
+
283
+ Example for Plate (providing gradient value):
284
+ Temperature.Gradient(element=21, type='Plate', lcname='Temp(-)', tz=10, hz=0.2)
285
+ """
286
+ temps = []
287
+
288
+ def __init__(self, element, type, lcname, tz, group="", hz=None, ty=0, hy=None,id=None):
289
+
290
+ chk = 0
291
+ for i in Load_Case.cases:
292
+ if lcname in i.NAME: chk = 1
293
+ if chk == 0: Load_Case("T", lcname)
294
+
295
+ if group:
296
+ chk = 0
297
+ try:
298
+ a = [v['NAME'] for v in Group.Load.json()["Assign"].values()]
299
+ if group in a:
300
+ chk = 1
301
+ except:
302
+ pass
303
+ if chk == 0:
304
+ Group.Load(group)
305
+
306
+ self.ELEMENT = element
307
+
308
+ if id is None:
309
+ existing_ids = []
310
+ for temp in Temperature.Gradient.temps:
311
+ if temp.ELEMENT == element:
312
+ existing_ids.extend([item.get('ID', 0) for item in temp.ITEMS if hasattr(temp, 'ITEMS')])
313
+ self.ID = max(existing_ids, default=0) + 1
314
+ else:
315
+ self.ID = id
316
+
317
+ use_hz = (hz is None)
318
+ use_hy = (hy is None)
319
+
320
+ item_data = {
321
+ "ID": self.ID,
322
+ "LCNAME": lcname,
323
+ "GROUP_NAME": group,
324
+ "TZ": tz,
325
+ "USE_HZ": use_hz,
326
+ }
327
+
328
+ if not use_hz:
329
+ item_data["HZ"] = hz
330
+
331
+ if type.lower() == 'beam':
332
+ item_data["TYPE"] = 1
333
+ item_data["TY"] = ty
334
+ item_data["USE_HY"] = use_hy
335
+ if not use_hy:
336
+ item_data["HY"] = hy
337
+ elif type.lower() == 'plate':
338
+ item_data["TYPE"] = 2
339
+ else:
340
+ raise ValueError("Element type for Gradient must be 'Beam' or 'Plate'.")
341
+
342
+ existing_temp = None
343
+ for temp in Temperature.Gradient.temps:
344
+ if temp.ELEMENT == element:
345
+ existing_temp = temp
346
+ break
347
+
348
+ if existing_temp:
349
+ if not hasattr(existing_temp, 'ITEMS'):
350
+ existing_temp.ITEMS = []
351
+ existing_temp.ITEMS.append(item_data)
352
+ else:
353
+ self.ITEMS = [item_data]
354
+ Temperature.Gradient.temps.append(self)
355
+
356
+ @classmethod
357
+ def json(cls):
358
+ """Creates JSON from Temperature Gradient objects defined in Python"""
359
+ json_data = {"Assign": {}}
360
+ for temp in cls.temps:
361
+ json_data["Assign"][str(temp.ELEMENT)] = {"ITEMS": temp.ITEMS}
362
+ return json_data
363
+
364
+ @staticmethod
365
+ def create():
366
+ """Creates Temperature Gradients in MIDAS Civil NX"""
367
+ MidasAPI("PUT", "/db/gtmp", Temperature.Gradient.json())
368
+
369
+ @staticmethod
370
+ def get():
371
+ """Get the JSON of Temperature Gradients from MIDAS Civil NX"""
372
+ return MidasAPI("GET", "/db/gtmp")
373
+
374
+ @staticmethod
375
+ def sync():
376
+ """Sync Temperature Gradients from MIDAS Civil NX to Python"""
377
+ Temperature.Gradient.temps = []
378
+ a = Temperature.Gradient.get()
379
+
380
+ if a and 'GTMP' in a:
381
+ temp_data = a.get('GTMP', {})
382
+ for element_id, element_data in temp_data.items():
383
+ element_obj = type('obj', (object,), {
384
+ 'ELEMENT': int(element_id),
385
+ 'ITEMS': element_data.get('ITEMS', [])
386
+ })()
387
+ Temperature.Gradient.temps.append(element_obj)
388
+
389
+ @staticmethod
390
+ def delete():
391
+ """Delete Temperature Gradients from MIDAS Civil NX and Python"""
392
+ Temperature.Gradient.clear()
393
+ return MidasAPI("DELETE", "/db/gtmp")
394
+
395
+ @staticmethod
396
+ def clear():
397
+ """Delete Temperature Gradients from MIDAS Civil NX and Python"""
398
+ Temperature.Gradient.temps = []
399
+
400
+ # --------------------------------------------------------------------------------------------------
401
+ # Nodal Temperature
402
+ # --------------------------------------------------------------------------------------------------
403
+ class Nodal:
404
+ """
405
+ Create Nodal Temperature
406
+
407
+ Parameters:
408
+ node (int): Node ID
409
+ temperature (float): Temperature value
410
+ lcname (str): Load case name **(Must exist in the model)**
411
+ group (str): Load group name (default "")
412
+ id (int): Temperature ID (optional)
413
+
414
+ Example:
415
+ Temperature.Nodal(6, 10, "Test")
416
+ """
417
+ temps = []
418
+
419
+ def __init__(self, node, temperature, lcname, group="", id=None):
420
+
421
+ chk = 0
422
+ for i in Load_Case.cases:
423
+ if lcname in i.NAME: chk = 1
424
+ if chk == 0: Load_Case("T", lcname)
425
+
426
+ if group:
427
+ chk = 0
428
+ try:
429
+ a = [v['NAME'] for v in Group.Load.json()["Assign"].values()]
430
+ if group in a:
431
+ chk = 1
432
+ except:
433
+ pass
434
+ if chk == 0:
435
+ Group.Load(group)
436
+
437
+ self.NODE = node
438
+ self.TEMPER = temperature
439
+ self.LCNAME = lcname
440
+ self.GROUP_NAME = group
441
+
442
+ if id is None:
443
+ existing_ids = []
444
+ for temp in Temperature.Nodal.temps:
445
+ if temp.NODE == node:
446
+ existing_ids.extend([item.get('ID', 0) for item in temp.ITEMS if hasattr(temp, 'ITEMS')])
447
+ self.ID = max(existing_ids, default=0) + 1
448
+ else:
449
+ self.ID = id
450
+
451
+ existing_temp = None
452
+ for temp in Temperature.Nodal.temps:
453
+ if temp.NODE == node:
454
+ existing_temp = temp
455
+ break
456
+
457
+ item_data = {
458
+ "ID": self.ID, "LCNAME": self.LCNAME,
459
+ "GROUP_NAME": self.GROUP_NAME, "TEMPER": self.TEMPER
460
+ }
461
+
462
+ if existing_temp:
463
+ if not hasattr(existing_temp, 'ITEMS'):
464
+ existing_temp.ITEMS = []
465
+ existing_temp.ITEMS.append(item_data)
466
+ else:
467
+ self.ITEMS = [item_data]
468
+ Temperature.Nodal.temps.append(self)
469
+
470
+ @classmethod
471
+ def json(cls):
472
+ """Creates JSON with 'Assign' key from Nodal Temperature objects defined in Python"""
473
+ json_data = {"Assign": {}}
474
+ for temp in cls.temps:
475
+ json_data["Assign"][str(temp.NODE)] = {"ITEMS": temp.ITEMS}
476
+ return json_data
477
+
478
+ @staticmethod
479
+ def create():
480
+ """Creates Nodal Temperatures in MIDAS Civil NX"""
481
+ MidasAPI("PUT", "/db/ntmp", Temperature.Nodal.json())
482
+
483
+ @staticmethod
484
+ def get():
485
+ """Get the JSON of Nodal Temperatures from MIDAS Civil NX"""
486
+ return MidasAPI("GET", "/db/ntmp")
487
+
488
+ @staticmethod
489
+ def sync():
490
+ """Sync Nodal Temperatures from MIDAS Civil NX to Python"""
491
+ Temperature.Nodal.temps = []
492
+ a = Temperature.Nodal.get()
493
+
494
+ if a and 'NTMP' in a:
495
+ temp_data = a.get('NTMP', {})
496
+ for node_id, node_data in temp_data.items():
497
+ node_obj = type('obj', (object,), {
498
+ 'NODE': int(node_id),
499
+ 'ITEMS': node_data.get('ITEMS', [])
500
+ })()
501
+ Temperature.Nodal.temps.append(node_obj)
502
+
503
+ @staticmethod
504
+ def delete():
505
+ """Delete Nodal Temperatures from MIDAS Civil NX and Python"""
506
+ Temperature.Nodal.clear()
507
+ return MidasAPI("DELETE", "/db/ntmp")
508
+
509
+ @staticmethod
510
+ def clear():
511
+ """Delete Nodal Temperatures from MIDAS Civil NX and Python"""
512
+ Temperature.Nodal.temps = []
513
+
514
+
515
+ # --------------------------------------------------------------------------------------------------
516
+ # Beam Section Temperature
517
+ # --------------------------------------------------------------------------------------------------
518
+ class BeamSection:
519
+ """
520
+ Create Beam Section Temperature Object in Python.
521
+
522
+ Parameters:
523
+ element (int): Element ID to apply the load.
524
+ lcname (str): Load Case Name (must exist in the model).
525
+ section_type (str, optional): 'General' or 'PSC'. Defaults to 'General'.
526
+ type (str, optional): 'Element' or 'Input'. Defaults to 'Element'.
527
+ group (str, optional): Load Group Name.
528
+ id (int, optional): Load ID.
529
+ dir (str, optional): Direction, 'LY' or 'LZ'. Defaults to 'LZ'.
530
+ ref_pos (str, optional): Reference Position, 'Centroid', 'Top', or 'Bot'. Defaults to 'Centroid'.
531
+ val_b (float, optional): B Value.
532
+ val_h1 (float, optional): H1 Value.
533
+ val_h2 (float, optional): H2 Value.
534
+ val_t1 (float, optional): T1 Value.
535
+ val_t2 (float, optional): T2 Value.
536
+ elast (float, optional): Modulus of Elasticity (required for 'Input' type).
537
+ thermal (float, optional): Thermal Coefficient (required for 'Input' type).
538
+ psc_ref (int, optional): Reference for PSC, 0 for Top, 1 for Bottom.
539
+ psc_opt_b (int, optional): B-Type option for PSC. (0 for Section type)
540
+ psc_opt_h1 (int, optional): H1-Type option for PSC. (0 - Z1 , 1- Z2 ,2 - Z2)
541
+ psc_opt_h2 (int, optional): H2-Type option for PSC. (0 - Z1 , 1- Z2 ,2 - Z2)
542
+ """
543
+ temps = []
544
+
545
+ def __init__(self, element, lcname, section_type='General', type='Element', group="",
546
+ dir='LZ', ref_pos='Centroid', val_b=0, val_h1=0, val_h2=0, val_t1=0, val_t2=0,
547
+ elast=None, thermal=None, psc_ref=0, psc_opt_b=1, psc_opt_h1=3, psc_opt_h2=3, id=None):
548
+
549
+ # Validate required parameters for Input type
550
+ if type.upper() == 'INPUT':
551
+ if elast is None or thermal is None:
552
+ raise ValueError("For 'Input' type, both 'elast' and 'thermal' parameters are required.")
553
+
554
+ # Handle load group creation
555
+
556
+ chk = 0
557
+ for i in Load_Case.cases:
558
+ if lcname in i.NAME: chk = 1
559
+ if chk == 0: Load_Case("T", lcname)
560
+
561
+ if group:
562
+ chk = 0
563
+ try:
564
+ a = [v['NAME'] for v in Group.Load.json()["Assign"].values()]
565
+ if group in a:
566
+ chk = 1
567
+ except:
568
+ pass
569
+ if chk == 0:
570
+ Group.Load(group)
571
+
572
+ self.ELEMENT = element
573
+
574
+ # Auto-assign ID if not provided
575
+ if id is None:
576
+ existing_ids = []
577
+ for temp in Temperature.BeamSection.temps:
578
+ if temp.ELEMENT == element:
579
+ existing_ids.extend([item.get('ID', 0) for item in temp.ITEMS if hasattr(temp, 'ITEMS')])
580
+ self.ID = max(existing_ids, default=0) + 1
581
+ else:
582
+ self.ID = id
583
+
584
+ # Construct the nested dictionary for vSECTTMP
585
+ vsec_item = {
586
+ "TYPE": type.upper(),
587
+ "VAL_B": val_b,
588
+ "VAL_H1": val_h1,
589
+ "VAL_H2": val_h2,
590
+ "VAL_T1": val_t1,
591
+ "VAL_T2": val_t2,
592
+ }
593
+
594
+ is_psc = section_type.lower() == 'psc'
595
+
596
+ # Add material properties for Input type
597
+ if type.upper() == 'INPUT':
598
+ vsec_item["ELAST"] = elast
599
+ vsec_item["THERMAL"] = thermal
600
+
601
+ # Add PSC-specific parameters
602
+ if is_psc:
603
+ vsec_item["REF"] = psc_ref
604
+ vsec_item["OPT_B"] = psc_opt_b
605
+ vsec_item["OPT_H1"] = psc_opt_h1
606
+ vsec_item["OPT_H2"] = psc_opt_h2
607
+
608
+ # Construct the main item dictionary
609
+ item_data = {
610
+ "ID": self.ID,
611
+ "LCNAME": lcname,
612
+ "GROUP_NAME": group,
613
+ "DIR": dir,
614
+ "REF": ref_pos,
615
+ "NUM": 1,
616
+ "bPSC": is_psc,
617
+ "vSECTTMP": [vsec_item]
618
+ }
619
+
620
+ # Check if an object for this element already exists
621
+ existing_temp = None
622
+ for temp in Temperature.BeamSection.temps:
623
+ if temp.ELEMENT == element:
624
+ existing_temp = temp
625
+ break
626
+
627
+ if existing_temp:
628
+ if not hasattr(existing_temp, 'ITEMS'):
629
+ existing_temp.ITEMS = []
630
+ existing_temp.ITEMS.append(item_data)
631
+ else:
632
+ self.ITEMS = [item_data]
633
+ Temperature.BeamSection.temps.append(self)
634
+
635
+ @classmethod
636
+ def json(cls):
637
+ """Creates JSON from Beam Section Temperature objects defined in Python"""
638
+ json_data = {"Assign": {}}
639
+ for temp in cls.temps:
640
+ json_data["Assign"][str(temp.ELEMENT)] = {"ITEMS": temp.ITEMS}
641
+ return json_data
642
+
643
+ @staticmethod
644
+ def create():
645
+ """Creates Beam Section Temperatures in MIDAS Civil NX"""
646
+ MidasAPI("PUT", "/db/btmp", Temperature.BeamSection.json())
647
+
648
+ @staticmethod
649
+ def get():
650
+ """Get the JSON of Beam Section Temperatures from MIDAS Civil NX"""
651
+ return MidasAPI("GET", "/db/btmp")
652
+
653
+ @staticmethod
654
+ def sync():
655
+ """Sync Beam Section Temperatures from MIDAS Civil NX to Python"""
656
+ Temperature.BeamSection.temps = []
657
+ a = Temperature.BeamSection.get()
658
+
659
+ if a and 'BTMP' in a:
660
+ temp_data = a.get('BTMP', {})
661
+ for element_id, element_data in temp_data.items():
662
+ element_obj = type('obj', (object,), {
663
+ 'ELEMENT': int(element_id),
664
+ 'ITEMS': element_data.get('ITEMS', [])
665
+ })()
666
+ Temperature.BeamSection.temps.append(element_obj)
667
+
668
+ @staticmethod
669
+ def delete():
670
+ """Delete Beam Section Temperatures from MIDAS Civil NX and Python"""
671
+ Temperature.BeamSection.clear()
672
+ return MidasAPI("DELETE", "/db/btmp")
673
+
674
+ @staticmethod
675
+ def clear():
676
+ """Delete Beam Section Temperatures from MIDAS Civil NX and Python"""
677
+ Temperature.BeamSection.temps = []