midas-civil 0.1.3__py3-none-any.whl → 0.1.5__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 +3 -0
- midas_civil/_element.py +7 -7
- midas_civil/_group.py +20 -2
- midas_civil/_mapi.py +18 -5
- midas_civil/_model.py +3 -0
- midas_civil/_movingload.py +1431 -0
- midas_civil/_node.py +10 -6
- midas_civil/_result.py +2 -2
- midas_civil/_result_extract.py +17 -9
- midas_civil/_settlement.py +160 -0
- midas_civil/_temperature.py +262 -1
- midas_civil/_tendon.py +820 -56
- midas_civil/_thickness.py +1 -1
- {midas_civil-0.1.3.dist-info → midas_civil-0.1.5.dist-info}/METADATA +1 -1
- midas_civil-0.1.5.dist-info/RECORD +27 -0
- midas_civil-0.1.3.dist-info/RECORD +0 -25
- {midas_civil-0.1.3.dist-info → midas_civil-0.1.5.dist-info}/WHEEL +0 -0
- {midas_civil-0.1.3.dist-info → midas_civil-0.1.5.dist-info}/licenses/LICENSE +0 -0
- {midas_civil-0.1.3.dist-info → midas_civil-0.1.5.dist-info}/top_level.txt +0 -0
midas_civil/_node.py
CHANGED
|
@@ -48,9 +48,9 @@ class Node:
|
|
|
48
48
|
node_count = max(Node.ids)+1
|
|
49
49
|
|
|
50
50
|
|
|
51
|
-
self.X = x
|
|
52
|
-
self.Y = y
|
|
53
|
-
self.Z = z
|
|
51
|
+
self.X = round(x,6)
|
|
52
|
+
self.Y = round(y,6)
|
|
53
|
+
self.Z = round(z,6)
|
|
54
54
|
|
|
55
55
|
if id == 0 : self.ID = node_count
|
|
56
56
|
if id != 0 : self.ID = id
|
|
@@ -94,7 +94,9 @@ class Node:
|
|
|
94
94
|
Node.ids.append(self.ID)
|
|
95
95
|
Node.Grid[cell_loc].append(self)
|
|
96
96
|
|
|
97
|
-
|
|
97
|
+
if group !="":
|
|
98
|
+
_add_node_2_stGroup(self.ID,group)
|
|
99
|
+
|
|
98
100
|
|
|
99
101
|
|
|
100
102
|
|
|
@@ -115,13 +117,14 @@ class Node:
|
|
|
115
117
|
|
|
116
118
|
@staticmethod
|
|
117
119
|
def sync():
|
|
118
|
-
Node.nodes
|
|
120
|
+
Node.nodes=[]
|
|
119
121
|
Node.ids=[]
|
|
122
|
+
Node.Grid={}
|
|
120
123
|
a = Node.get()
|
|
121
124
|
if a != {'message': ''}:
|
|
122
125
|
if list(a['NODE'].keys()) != []:
|
|
123
126
|
for j in a['NODE'].keys():
|
|
124
|
-
Node(round(a['NODE'][j]['X'],6), round(a['NODE'][j]['Y'],6), round(a['NODE'][j]['Z'],6),int(j),0)
|
|
127
|
+
Node(round(a['NODE'][j]['X'],6), round(a['NODE'][j]['Y'],6), round(a['NODE'][j]['Z'],6), id=int(j), group='', merge=0)
|
|
125
128
|
|
|
126
129
|
@staticmethod
|
|
127
130
|
def delete2(nodes_list):
|
|
@@ -142,6 +145,7 @@ class Node:
|
|
|
142
145
|
MidasAPI("DELETE",f"/db/NODE/")
|
|
143
146
|
Node.nodes=[]
|
|
144
147
|
Node.ids=[]
|
|
148
|
+
Node.Grid={}
|
|
145
149
|
|
|
146
150
|
@staticmethod
|
|
147
151
|
def delete():
|
midas_civil/_result.py
CHANGED
|
@@ -142,13 +142,13 @@ class LoadCombination:
|
|
|
142
142
|
|
|
143
143
|
@classmethod
|
|
144
144
|
def delete(cls, classification = "All", ids = []):
|
|
145
|
-
json = LoadCombination.
|
|
145
|
+
json = LoadCombination.json(classification)
|
|
146
146
|
a = ""
|
|
147
147
|
for i in range(len(ids)):
|
|
148
148
|
a += str(ids[i]) + ","
|
|
149
149
|
a = "/" + a[:-1]
|
|
150
150
|
if json == {}:
|
|
151
|
-
print("No load combinations are defined to delete.
|
|
151
|
+
print("No load combinations are defined to delete.")
|
|
152
152
|
for i in list(json.keys()):
|
|
153
153
|
MidasAPI("DELETE",LoadCombination.com_map.get(i) + a)
|
|
154
154
|
#---------------------------------------------------------------------------------------------------------------
|
midas_civil/_result_extract.py
CHANGED
|
@@ -2,6 +2,7 @@ import polars as pl
|
|
|
2
2
|
import json
|
|
3
3
|
import xlsxwriter
|
|
4
4
|
from ._mapi import *
|
|
5
|
+
from ._model import *
|
|
5
6
|
# js_file = open('JSON_Excel Parsing\\test.json','r')
|
|
6
7
|
|
|
7
8
|
# print(js_file)
|
|
@@ -125,7 +126,7 @@ class Result :
|
|
|
125
126
|
|
|
126
127
|
# ---------- User defined TABLE (Dynamic Report Table) ------------------------------
|
|
127
128
|
@staticmethod
|
|
128
|
-
def UserDefinedTable(tableName:str, summary=0):
|
|
129
|
+
def UserDefinedTable(tableName:str, summary=0, force_unit='KN',len_unit='M'):
|
|
129
130
|
js_dat = {
|
|
130
131
|
"Argument": {
|
|
131
132
|
"TABLE_NAME": tableName,
|
|
@@ -135,11 +136,11 @@ class Result :
|
|
|
135
136
|
}
|
|
136
137
|
}
|
|
137
138
|
}
|
|
138
|
-
|
|
139
|
+
Model.units(force=force_unit,length=len_unit)
|
|
139
140
|
ss_json = MidasAPI("POST","/post/TABLE",js_dat)
|
|
140
141
|
return _JSToDF_UserDefined(tableName,ss_json,summary)
|
|
141
142
|
|
|
142
|
-
# ----------
|
|
143
|
+
# ---------- LIST ALL USER DEFINED TABLE ------------------------------
|
|
143
144
|
@staticmethod
|
|
144
145
|
def UserDefinedTables_print():
|
|
145
146
|
''' Print all the User defined table names '''
|
|
@@ -158,18 +159,17 @@ class Result :
|
|
|
158
159
|
|
|
159
160
|
# ---------- Result TABLE ------------------------------
|
|
160
161
|
@staticmethod
|
|
161
|
-
def ResultTable(tabletype:str,
|
|
162
|
+
def ResultTable(tabletype:str,keys=[],loadcase:list=[],cs_stage=[],force_unit='KN',len_unit='M'):
|
|
162
163
|
'''
|
|
163
164
|
TableType : REACTIONG | REACTIONL | DISPLACEMENTG | DISPLACEMENTL | TRUSSFORCE | TRUSSSTRESS
|
|
165
|
+
Keys : List{int} -> Element/ Node IDs | str -> Structure Group Name
|
|
166
|
+
Loadcase : Loadcase name followed by type. eg. DeadLoad(ST)
|
|
164
167
|
'''
|
|
168
|
+
|
|
165
169
|
js_dat = {
|
|
166
170
|
"Argument": {
|
|
167
171
|
"TABLE_NAME": "SS_Table",
|
|
168
172
|
"TABLE_TYPE": tabletype,
|
|
169
|
-
"UNIT": {
|
|
170
|
-
"FORCE": force_unit,
|
|
171
|
-
"DIST": len_unit
|
|
172
|
-
},
|
|
173
173
|
"STYLES": {
|
|
174
174
|
"FORMAT": "Fixed",
|
|
175
175
|
"PLACE": 12
|
|
@@ -185,9 +185,17 @@ class Result :
|
|
|
185
185
|
js_dat["Argument"]['STAGE_STEP'] = cs_stage
|
|
186
186
|
|
|
187
187
|
|
|
188
|
-
if
|
|
188
|
+
if isinstance(keys,list):
|
|
189
|
+
if keys!=[]:
|
|
190
|
+
js_dat["Argument"]['NODE_ELEMS'] = {"KEYS": keys}
|
|
191
|
+
elif isinstance(keys,str):
|
|
192
|
+
js_dat["Argument"]['NODE_ELEMS'] = {"STRUCTURE_GROUP_NAME": keys}
|
|
193
|
+
|
|
194
|
+
|
|
189
195
|
if loadcase!=[]: js_dat["Argument"]['LOAD_CASE_NAMES'] = loadcase
|
|
190
196
|
|
|
197
|
+
|
|
198
|
+
Model.units(force=force_unit,length=len_unit)
|
|
191
199
|
ss_json = MidasAPI("POST","/post/table",js_dat)
|
|
192
200
|
return _JSToDF_ResTable(ss_json)
|
|
193
201
|
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
from ._mapi import *
|
|
2
|
+
|
|
3
|
+
class Settlement:
|
|
4
|
+
|
|
5
|
+
@classmethod
|
|
6
|
+
def create(cls):
|
|
7
|
+
"""Creates Settlement Load in MIDAS Civil NX"""
|
|
8
|
+
if cls.Group.data != []: cls.Group.create()
|
|
9
|
+
if cls.Case.data != []: cls.Case.create()
|
|
10
|
+
|
|
11
|
+
@classmethod
|
|
12
|
+
def delete(cls):
|
|
13
|
+
"""Deletes Settlement load from MIDAS Civil NX and Python"""
|
|
14
|
+
cls.Group.delete()
|
|
15
|
+
cls.Case.delete()
|
|
16
|
+
|
|
17
|
+
@classmethod
|
|
18
|
+
def sync(cls):
|
|
19
|
+
"""Sync Settlement load from MIDAS Civil NX to Python"""
|
|
20
|
+
cls.Group.sync()
|
|
21
|
+
cls.Case.sync()
|
|
22
|
+
|
|
23
|
+
class Group:
|
|
24
|
+
"""
|
|
25
|
+
Parameters:
|
|
26
|
+
name: Settlement group name (string)
|
|
27
|
+
displacement: Settlement displacement value (number)
|
|
28
|
+
node_list: List of node IDs to include in the group (array of integers)
|
|
29
|
+
id: Group ID (optional, auto-generated if not provided)
|
|
30
|
+
|
|
31
|
+
Examples:
|
|
32
|
+
```python
|
|
33
|
+
Settlement.Group("SG1", 0.025, [100, 101])
|
|
34
|
+
Settlement.Group("SG2", 0.015, [102, 103])
|
|
35
|
+
```
|
|
36
|
+
"""
|
|
37
|
+
data = []
|
|
38
|
+
|
|
39
|
+
def __init__(self, name, displacement, node_list, id=""):
|
|
40
|
+
self.NAME = name
|
|
41
|
+
self.SETTLE = displacement
|
|
42
|
+
self.ITEMS = node_list
|
|
43
|
+
if id == "": id = len(Settlement.Group.data) + 1
|
|
44
|
+
self.ID = id
|
|
45
|
+
|
|
46
|
+
Settlement.Group.data.append(self)
|
|
47
|
+
|
|
48
|
+
@classmethod
|
|
49
|
+
def json(cls):
|
|
50
|
+
json = {"Assign": {}}
|
|
51
|
+
for i in cls.data:
|
|
52
|
+
json["Assign"][str(i.ID)] = {
|
|
53
|
+
"NAME": i.NAME,
|
|
54
|
+
"SETTLE": i.SETTLE,
|
|
55
|
+
"ITEMS": i.ITEMS
|
|
56
|
+
}
|
|
57
|
+
return json
|
|
58
|
+
|
|
59
|
+
@staticmethod
|
|
60
|
+
def create():
|
|
61
|
+
MidasAPI("PUT", "/db/smpt", Settlement.Group.json())
|
|
62
|
+
|
|
63
|
+
@staticmethod
|
|
64
|
+
def get():
|
|
65
|
+
return MidasAPI("GET", "/db/smpt")
|
|
66
|
+
|
|
67
|
+
@classmethod
|
|
68
|
+
def delete(cls):
|
|
69
|
+
cls.data = []
|
|
70
|
+
return MidasAPI("DELETE", "/db/smpt")
|
|
71
|
+
|
|
72
|
+
@classmethod
|
|
73
|
+
def sync(cls):
|
|
74
|
+
cls.data = []
|
|
75
|
+
a = cls.get()
|
|
76
|
+
if a != {'message': ''}:
|
|
77
|
+
for i in a['SMPT'].keys():
|
|
78
|
+
Settlement.Group(
|
|
79
|
+
a['SMPT'][i]['NAME'],
|
|
80
|
+
a['SMPT'][i]['SETTLE'],
|
|
81
|
+
a['SMPT'][i]['ITEMS'],
|
|
82
|
+
int(i)
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
class Case:
|
|
87
|
+
"""
|
|
88
|
+
|
|
89
|
+
Parameters:
|
|
90
|
+
name: Settlement load case name (string)
|
|
91
|
+
settlement_groups: List of settlement group names to include (array of strings, default [])
|
|
92
|
+
factor: Settlement scale factor (number, default 1.0)
|
|
93
|
+
min_groups: Minimum number of settlement groups (integer, default 1)
|
|
94
|
+
max_groups: Maximum number of settlement groups (integer, default 1)
|
|
95
|
+
desc: Description of the settlement case (string, default "")
|
|
96
|
+
id: Case ID (optional, auto-generated if not provided)
|
|
97
|
+
|
|
98
|
+
Examples:
|
|
99
|
+
```python
|
|
100
|
+
Settlement.Case("SMLC1", ["SG1"], 1.2, 1, 1, "Foundation Settlement Case")
|
|
101
|
+
Settlement.Case("SMLC2", ["SG1", "SG2"], 1.0, 1, 2, "Combined Settlement")
|
|
102
|
+
```
|
|
103
|
+
"""
|
|
104
|
+
data = []
|
|
105
|
+
|
|
106
|
+
def __init__(self, name, settlement_groups=[],factor=1.0, min_groups=1, max_groups=1, desc="", id=""):
|
|
107
|
+
self.NAME = name
|
|
108
|
+
self.DESC = desc
|
|
109
|
+
self.FACTOR = factor
|
|
110
|
+
self.MIN = min_groups
|
|
111
|
+
self.MAX = max_groups
|
|
112
|
+
self.ST_GROUPS = settlement_groups
|
|
113
|
+
if id == "": id = len(Settlement.Case.data) + 1
|
|
114
|
+
self.ID = id
|
|
115
|
+
|
|
116
|
+
Settlement.Case.data.append(self)
|
|
117
|
+
|
|
118
|
+
@classmethod
|
|
119
|
+
def json(cls):
|
|
120
|
+
json = {"Assign": {}}
|
|
121
|
+
for i in cls.data:
|
|
122
|
+
json["Assign"][str(i.ID)] = {
|
|
123
|
+
"NAME": i.NAME,
|
|
124
|
+
"DESC": i.DESC,
|
|
125
|
+
"FACTOR": i.FACTOR,
|
|
126
|
+
"MIN": i.MIN,
|
|
127
|
+
"MAX": i.MAX,
|
|
128
|
+
"ST_GROUPS": i.ST_GROUPS
|
|
129
|
+
}
|
|
130
|
+
return json
|
|
131
|
+
|
|
132
|
+
@staticmethod
|
|
133
|
+
def create():
|
|
134
|
+
MidasAPI("PUT", "/db/smlc", Settlement.Case.json())
|
|
135
|
+
|
|
136
|
+
@staticmethod
|
|
137
|
+
def get():
|
|
138
|
+
return MidasAPI("GET", "/db/smlc")
|
|
139
|
+
|
|
140
|
+
@classmethod
|
|
141
|
+
def delete(cls):
|
|
142
|
+
cls.data = []
|
|
143
|
+
return MidasAPI("DELETE", "/db/smlc")
|
|
144
|
+
|
|
145
|
+
@classmethod
|
|
146
|
+
def sync(cls):
|
|
147
|
+
cls.data = []
|
|
148
|
+
a = cls.get()
|
|
149
|
+
if a != {'message': ''}:
|
|
150
|
+
for i in a['SMLC'].keys():
|
|
151
|
+
Settlement.Case(
|
|
152
|
+
a['SMLC'][i]['NAME'],
|
|
153
|
+
a['SMLC'][i]['DESC'],
|
|
154
|
+
a['SMLC'][i]['FACTOR'],
|
|
155
|
+
a['SMLC'][i]['MIN'],
|
|
156
|
+
a['SMLC'][i]['MAX'],
|
|
157
|
+
a['SMLC'][i]['ST_GROUPS'],
|
|
158
|
+
int(i)
|
|
159
|
+
)
|
|
160
|
+
|
midas_civil/_temperature.py
CHANGED
|
@@ -16,6 +16,8 @@ class Temperature:
|
|
|
16
16
|
if cls.System.temps: cls.System.create()
|
|
17
17
|
if cls.Element.temps: cls.Element.create()
|
|
18
18
|
if cls.Gradient.temps: cls.Gradient.create()
|
|
19
|
+
if cls.Nodal.temps: cls.Nodal.create()
|
|
20
|
+
if cls.BeamSection.temps: cls.BeamSection.create()
|
|
19
21
|
|
|
20
22
|
@classmethod
|
|
21
23
|
def delete(cls):
|
|
@@ -23,6 +25,8 @@ class Temperature:
|
|
|
23
25
|
cls.System.delete()
|
|
24
26
|
cls.Element.delete()
|
|
25
27
|
cls.Gradient.delete()
|
|
28
|
+
cls.Nodal.delete()
|
|
29
|
+
cls.BeamSection.delete()
|
|
26
30
|
|
|
27
31
|
|
|
28
32
|
@classmethod
|
|
@@ -31,7 +35,9 @@ class Temperature:
|
|
|
31
35
|
cls.System.sync()
|
|
32
36
|
cls.Element.sync()
|
|
33
37
|
cls.Gradient.sync()
|
|
34
|
-
|
|
38
|
+
cls.Nodal.sync()
|
|
39
|
+
cls.BeamSection.sync()
|
|
40
|
+
|
|
35
41
|
# --------------------------------------------------------------------------------------------------
|
|
36
42
|
# System Temperature
|
|
37
43
|
# --------------------------------------------------------------------------------------------------
|
|
@@ -351,3 +357,258 @@ class Temperature:
|
|
|
351
357
|
return MidasAPI("DELETE", "/db/gtmp")
|
|
352
358
|
|
|
353
359
|
# --------------------------------------------------------------------------------------------------
|
|
360
|
+
# Nodal Temperature
|
|
361
|
+
# --------------------------------------------------------------------------------------------------
|
|
362
|
+
class Nodal:
|
|
363
|
+
"""
|
|
364
|
+
Create Nodal Temperature
|
|
365
|
+
|
|
366
|
+
Parameters:
|
|
367
|
+
node (int): Node ID
|
|
368
|
+
temperature (float): Temperature value
|
|
369
|
+
lcname (str): Load case name **(Must exist in the model)**
|
|
370
|
+
group (str): Load group name (default "")
|
|
371
|
+
id (int): Temperature ID (optional)
|
|
372
|
+
|
|
373
|
+
Example:
|
|
374
|
+
Temperature.Nodal(6, 10, "Test")
|
|
375
|
+
"""
|
|
376
|
+
temps = []
|
|
377
|
+
|
|
378
|
+
def __init__(self, node, temperature, lcname, group="", id=None):
|
|
379
|
+
if group:
|
|
380
|
+
chk = 0
|
|
381
|
+
try:
|
|
382
|
+
a = [v['NAME'] for v in Group.Load.json()["Assign"].values()]
|
|
383
|
+
if group in a:
|
|
384
|
+
chk = 1
|
|
385
|
+
except:
|
|
386
|
+
pass
|
|
387
|
+
if chk == 0:
|
|
388
|
+
Group.Load(group)
|
|
389
|
+
|
|
390
|
+
self.NODE = node
|
|
391
|
+
self.TEMPER = temperature
|
|
392
|
+
self.LCNAME = lcname
|
|
393
|
+
self.GROUP_NAME = group
|
|
394
|
+
|
|
395
|
+
if id is None:
|
|
396
|
+
existing_ids = []
|
|
397
|
+
for temp in Temperature.Nodal.temps:
|
|
398
|
+
if temp.NODE == node:
|
|
399
|
+
existing_ids.extend([item.get('ID', 0) for item in temp.ITEMS if hasattr(temp, 'ITEMS')])
|
|
400
|
+
self.ID = max(existing_ids, default=0) + 1
|
|
401
|
+
else:
|
|
402
|
+
self.ID = id
|
|
403
|
+
|
|
404
|
+
existing_temp = None
|
|
405
|
+
for temp in Temperature.Nodal.temps:
|
|
406
|
+
if temp.NODE == node:
|
|
407
|
+
existing_temp = temp
|
|
408
|
+
break
|
|
409
|
+
|
|
410
|
+
item_data = {
|
|
411
|
+
"ID": self.ID, "LCNAME": self.LCNAME,
|
|
412
|
+
"GROUP_NAME": self.GROUP_NAME, "TEMPER": self.TEMPER
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
if existing_temp:
|
|
416
|
+
if not hasattr(existing_temp, 'ITEMS'):
|
|
417
|
+
existing_temp.ITEMS = []
|
|
418
|
+
existing_temp.ITEMS.append(item_data)
|
|
419
|
+
else:
|
|
420
|
+
self.ITEMS = [item_data]
|
|
421
|
+
Temperature.Nodal.temps.append(self)
|
|
422
|
+
|
|
423
|
+
@classmethod
|
|
424
|
+
def json(cls):
|
|
425
|
+
"""Creates JSON with 'Assign' key from Nodal Temperature objects defined in Python"""
|
|
426
|
+
json_data = {"Assign": {}}
|
|
427
|
+
for temp in cls.temps:
|
|
428
|
+
json_data["Assign"][str(temp.NODE)] = {"ITEMS": temp.ITEMS}
|
|
429
|
+
return json_data
|
|
430
|
+
|
|
431
|
+
@staticmethod
|
|
432
|
+
def create():
|
|
433
|
+
"""Creates Nodal Temperatures in MIDAS Civil NX"""
|
|
434
|
+
MidasAPI("PUT", "/db/ntmp", Temperature.Nodal.json())
|
|
435
|
+
|
|
436
|
+
@staticmethod
|
|
437
|
+
def get():
|
|
438
|
+
"""Get the JSON of Nodal Temperatures from MIDAS Civil NX"""
|
|
439
|
+
return MidasAPI("GET", "/db/ntmp")
|
|
440
|
+
|
|
441
|
+
@staticmethod
|
|
442
|
+
def sync():
|
|
443
|
+
"""Sync Nodal Temperatures from MIDAS Civil NX to Python"""
|
|
444
|
+
Temperature.Nodal.temps = []
|
|
445
|
+
a = Temperature.Nodal.get()
|
|
446
|
+
|
|
447
|
+
if a and 'NTMP' in a:
|
|
448
|
+
temp_data = a.get('NTMP', {})
|
|
449
|
+
for node_id, node_data in temp_data.items():
|
|
450
|
+
node_obj = type('obj', (object,), {
|
|
451
|
+
'NODE': int(node_id),
|
|
452
|
+
'ITEMS': node_data.get('ITEMS', [])
|
|
453
|
+
})()
|
|
454
|
+
Temperature.Nodal.temps.append(node_obj)
|
|
455
|
+
|
|
456
|
+
@staticmethod
|
|
457
|
+
def delete():
|
|
458
|
+
"""Delete Nodal Temperatures from MIDAS Civil NX and Python"""
|
|
459
|
+
Temperature.Nodal.temps = []
|
|
460
|
+
return MidasAPI("DELETE", "/db/ntmp")
|
|
461
|
+
|
|
462
|
+
|
|
463
|
+
# --------------------------------------------------------------------------------------------------
|
|
464
|
+
# Beam Section Temperature
|
|
465
|
+
# --------------------------------------------------------------------------------------------------
|
|
466
|
+
class BeamSection:
|
|
467
|
+
"""
|
|
468
|
+
Create Beam Section Temperature Object in Python.
|
|
469
|
+
|
|
470
|
+
Parameters:
|
|
471
|
+
element (int): Element ID to apply the load.
|
|
472
|
+
lcname (str): Load Case Name (must exist in the model).
|
|
473
|
+
section_type (str, optional): 'General' or 'PSC'. Defaults to 'General'.
|
|
474
|
+
type (str, optional): 'Element' or 'Input'. Defaults to 'Element'.
|
|
475
|
+
group (str, optional): Load Group Name.
|
|
476
|
+
id (int, optional): Load ID.
|
|
477
|
+
dir (str, optional): Direction, 'LY' or 'LZ'. Defaults to 'LZ'.
|
|
478
|
+
ref_pos (str, optional): Reference Position, 'Centroid', 'Top', or 'Bot'. Defaults to 'Centroid'.
|
|
479
|
+
val_b (float, optional): B Value.
|
|
480
|
+
val_h1 (float, optional): H1 Value.
|
|
481
|
+
val_h2 (float, optional): H2 Value.
|
|
482
|
+
val_t1 (float, optional): T1 Value.
|
|
483
|
+
val_t2 (float, optional): T2 Value.
|
|
484
|
+
elast (float, optional): Modulus of Elasticity (required for 'Input' type).
|
|
485
|
+
thermal (float, optional): Thermal Coefficient (required for 'Input' type).
|
|
486
|
+
psc_ref (int, optional): Reference for PSC, 0 for Top, 1 for Bottom.
|
|
487
|
+
psc_opt_b (int, optional): B-Type option for PSC. (0 for Section type)
|
|
488
|
+
psc_opt_h1 (int, optional): H1-Type option for PSC. (0 - Z1 , 1- Z2 ,2 - Z2)
|
|
489
|
+
psc_opt_h2 (int, optional): H2-Type option for PSC. (0 - Z1 , 1- Z2 ,2 - Z2)
|
|
490
|
+
"""
|
|
491
|
+
temps = []
|
|
492
|
+
|
|
493
|
+
def __init__(self, element, lcname, section_type='General', type='Element', group="", id=None,
|
|
494
|
+
dir='LZ', ref_pos='Centroid', val_b=0, val_h1=0, val_h2=0, val_t1=0, val_t2=0,
|
|
495
|
+
elast=None, thermal=None, psc_ref=0, psc_opt_b=1, psc_opt_h1=3, psc_opt_h2=3):
|
|
496
|
+
|
|
497
|
+
# Validate required parameters for Input type
|
|
498
|
+
if type.upper() == 'INPUT':
|
|
499
|
+
if elast is None or thermal is None:
|
|
500
|
+
raise ValueError("For 'Input' type, both 'elast' and 'thermal' parameters are required.")
|
|
501
|
+
|
|
502
|
+
# Handle load group creation
|
|
503
|
+
if group:
|
|
504
|
+
chk = 0
|
|
505
|
+
try:
|
|
506
|
+
a = [v['NAME'] for v in Group.Load.json()["Assign"].values()]
|
|
507
|
+
if group in a:
|
|
508
|
+
chk = 1
|
|
509
|
+
except:
|
|
510
|
+
pass
|
|
511
|
+
if chk == 0:
|
|
512
|
+
Group.Load(group)
|
|
513
|
+
|
|
514
|
+
self.ELEMENT = element
|
|
515
|
+
|
|
516
|
+
# Auto-assign ID if not provided
|
|
517
|
+
if id is None:
|
|
518
|
+
existing_ids = []
|
|
519
|
+
for temp in Temperature.BeamSection.temps:
|
|
520
|
+
if temp.ELEMENT == element:
|
|
521
|
+
existing_ids.extend([item.get('ID', 0) for item in temp.ITEMS if hasattr(temp, 'ITEMS')])
|
|
522
|
+
self.ID = max(existing_ids, default=0) + 1
|
|
523
|
+
else:
|
|
524
|
+
self.ID = id
|
|
525
|
+
|
|
526
|
+
# Construct the nested dictionary for vSECTTMP
|
|
527
|
+
vsec_item = {
|
|
528
|
+
"TYPE": type.upper(),
|
|
529
|
+
"VAL_B": val_b,
|
|
530
|
+
"VAL_H1": val_h1,
|
|
531
|
+
"VAL_H2": val_h2,
|
|
532
|
+
"VAL_T1": val_t1,
|
|
533
|
+
"VAL_T2": val_t2,
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
is_psc = section_type.lower() == 'psc'
|
|
537
|
+
|
|
538
|
+
# Add material properties for Input type
|
|
539
|
+
if type.upper() == 'INPUT':
|
|
540
|
+
vsec_item["ELAST"] = elast
|
|
541
|
+
vsec_item["THERMAL"] = thermal
|
|
542
|
+
|
|
543
|
+
# Add PSC-specific parameters
|
|
544
|
+
if is_psc:
|
|
545
|
+
vsec_item["REF"] = psc_ref
|
|
546
|
+
vsec_item["OPT_B"] = psc_opt_b
|
|
547
|
+
vsec_item["OPT_H1"] = psc_opt_h1
|
|
548
|
+
vsec_item["OPT_H2"] = psc_opt_h2
|
|
549
|
+
|
|
550
|
+
# Construct the main item dictionary
|
|
551
|
+
item_data = {
|
|
552
|
+
"ID": self.ID,
|
|
553
|
+
"LCNAME": lcname,
|
|
554
|
+
"GROUP_NAME": group,
|
|
555
|
+
"DIR": dir,
|
|
556
|
+
"REF": ref_pos,
|
|
557
|
+
"NUM": 1,
|
|
558
|
+
"bPSC": is_psc,
|
|
559
|
+
"vSECTTMP": [vsec_item]
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
# Check if an object for this element already exists
|
|
563
|
+
existing_temp = None
|
|
564
|
+
for temp in Temperature.BeamSection.temps:
|
|
565
|
+
if temp.ELEMENT == element:
|
|
566
|
+
existing_temp = temp
|
|
567
|
+
break
|
|
568
|
+
|
|
569
|
+
if existing_temp:
|
|
570
|
+
if not hasattr(existing_temp, 'ITEMS'):
|
|
571
|
+
existing_temp.ITEMS = []
|
|
572
|
+
existing_temp.ITEMS.append(item_data)
|
|
573
|
+
else:
|
|
574
|
+
self.ITEMS = [item_data]
|
|
575
|
+
Temperature.BeamSection.temps.append(self)
|
|
576
|
+
|
|
577
|
+
@classmethod
|
|
578
|
+
def json(cls):
|
|
579
|
+
"""Creates JSON from Beam Section Temperature objects defined in Python"""
|
|
580
|
+
json_data = {"Assign": {}}
|
|
581
|
+
for temp in cls.temps:
|
|
582
|
+
json_data["Assign"][str(temp.ELEMENT)] = {"ITEMS": temp.ITEMS}
|
|
583
|
+
return json_data
|
|
584
|
+
|
|
585
|
+
@staticmethod
|
|
586
|
+
def create():
|
|
587
|
+
"""Creates Beam Section Temperatures in MIDAS Civil NX"""
|
|
588
|
+
MidasAPI("PUT", "/db/btmp", Temperature.BeamSection.json())
|
|
589
|
+
|
|
590
|
+
@staticmethod
|
|
591
|
+
def get():
|
|
592
|
+
"""Get the JSON of Beam Section Temperatures from MIDAS Civil NX"""
|
|
593
|
+
return MidasAPI("GET", "/db/btmp")
|
|
594
|
+
|
|
595
|
+
@staticmethod
|
|
596
|
+
def sync():
|
|
597
|
+
"""Sync Beam Section Temperatures from MIDAS Civil NX to Python"""
|
|
598
|
+
Temperature.BeamSection.temps = []
|
|
599
|
+
a = Temperature.BeamSection.get()
|
|
600
|
+
|
|
601
|
+
if a and 'BTMP' in a:
|
|
602
|
+
temp_data = a.get('BTMP', {})
|
|
603
|
+
for element_id, element_data in temp_data.items():
|
|
604
|
+
element_obj = type('obj', (object,), {
|
|
605
|
+
'ELEMENT': int(element_id),
|
|
606
|
+
'ITEMS': element_data.get('ITEMS', [])
|
|
607
|
+
})()
|
|
608
|
+
Temperature.BeamSection.temps.append(element_obj)
|
|
609
|
+
|
|
610
|
+
@staticmethod
|
|
611
|
+
def delete():
|
|
612
|
+
"""Delete Beam Section Temperatures from MIDAS Civil NX and Python"""
|
|
613
|
+
Temperature.BeamSection.temps = []
|
|
614
|
+
return MidasAPI("DELETE", "/db/btmp")
|