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
midas_civil/_model.py
ADDED
|
@@ -0,0 +1,522 @@
|
|
|
1
|
+
from ._mapi import MidasAPI,NX
|
|
2
|
+
from colorama import Fore,Style
|
|
3
|
+
from ._node import Node , NodeLocalAxis
|
|
4
|
+
from ._element import Element
|
|
5
|
+
from ._group import Group
|
|
6
|
+
from ._load import Load
|
|
7
|
+
from ._boundary import Boundary
|
|
8
|
+
|
|
9
|
+
from ._section import Section
|
|
10
|
+
from ._material import Material
|
|
11
|
+
from ._thickness import Thickness
|
|
12
|
+
|
|
13
|
+
from ._tendon import Tendon
|
|
14
|
+
from ._loadcomb import LoadCombination
|
|
15
|
+
from ._movingload import MovingLoad
|
|
16
|
+
|
|
17
|
+
from ._temperature import Temperature
|
|
18
|
+
from ._construction import CS
|
|
19
|
+
|
|
20
|
+
from collections import defaultdict
|
|
21
|
+
from typing import Literal
|
|
22
|
+
class Model:
|
|
23
|
+
|
|
24
|
+
#4 Function to check analysis status & perform analysis if not analyzed
|
|
25
|
+
@staticmethod
|
|
26
|
+
def analyse():
|
|
27
|
+
"""Checkes whether a model is analyzed or not and then performs analysis if required."""
|
|
28
|
+
json_body = {
|
|
29
|
+
"Argument": {
|
|
30
|
+
"HEIGHT" : 1,
|
|
31
|
+
"WIDTH" : 1,
|
|
32
|
+
"SET_MODE": "post"
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
resp = MidasAPI('POST','/view/CAPTURE',json_body)
|
|
36
|
+
|
|
37
|
+
if 'message' in resp or 'error' in resp:
|
|
38
|
+
MidasAPI("POST","/doc/ANAL",{"Assign":{}})
|
|
39
|
+
return True
|
|
40
|
+
print(" ⚠️ Model ananlysed. Switching to post-processing mode.")
|
|
41
|
+
|
|
42
|
+
#9 Function to remove duplicate nodes and elements from Node & Element classes\
|
|
43
|
+
# @staticmethod
|
|
44
|
+
# def merge_nodes(tolerance = 0):
|
|
45
|
+
# """This functions removes duplicate nodes defined in the Node Class and modifies Element class accordingly. \nSample: remove_duplicate()"""
|
|
46
|
+
# a=[]
|
|
47
|
+
# b=[]
|
|
48
|
+
# node_json = Node.json()
|
|
49
|
+
# elem_json = Element.json()
|
|
50
|
+
# node_di = node_json["Assign"]
|
|
51
|
+
# elem_di = elem_json["Assign"]
|
|
52
|
+
# for i in list(node_di.keys()):
|
|
53
|
+
# for j in list(node_di.keys()):
|
|
54
|
+
# if list(node_di.keys()).index(j) > list(node_di.keys()).index(i):
|
|
55
|
+
# if (node_di[i]["X"] >= node_di[j]["X"] - tolerance and node_di[i]["X"] <= node_di[j]["X"] + tolerance):
|
|
56
|
+
# if (node_di[i]["Y"] >= node_di[j]["Y"] - tolerance and node_di[i]["Y"] <= node_di[j]["Y"] + tolerance):
|
|
57
|
+
# if (node_di[i]["Z"] >= node_di[j]["Z"] - tolerance and node_di[i]["Z"] <= node_di[j]["Z"] + tolerance):
|
|
58
|
+
# a.append(i)
|
|
59
|
+
# b.append(j)
|
|
60
|
+
# for i in range(len(a)):
|
|
61
|
+
# for j in range(len(b)):
|
|
62
|
+
# if a[i] == b[j]:
|
|
63
|
+
# a[i] = a[j]
|
|
64
|
+
# for k in elem_di.keys():
|
|
65
|
+
# for i in range(len(a)):
|
|
66
|
+
# if elem_di[k]['NODE'][0] == b[i]: elem_di[k]['NODE'][0] = a[i]
|
|
67
|
+
# if elem_di[k]['NODE'][1] == b[i]: elem_di[k]['NODE'][1] = a[i]
|
|
68
|
+
# try:
|
|
69
|
+
# if elem_di[k]['NODE'][3] == b[i]: elem_di[k]['NODE'][3] = a[i]
|
|
70
|
+
# except: pass
|
|
71
|
+
# try:
|
|
72
|
+
# if elem_di[k]['NODE'][4] == b[i]: elem_di[k]['NODE'][4] = a[i]
|
|
73
|
+
# except: pass
|
|
74
|
+
|
|
75
|
+
# if len(b)>0:
|
|
76
|
+
# for i in range(len(b)):
|
|
77
|
+
# if b[i] in node_di: del node_di[b[i]]
|
|
78
|
+
# Node.nodes = []
|
|
79
|
+
# Node.ids = []
|
|
80
|
+
# for i in node_di.keys():
|
|
81
|
+
# Node(node_di[i]['X'], node_di[i]['Y'], node_di[i]['Z'], i)
|
|
82
|
+
# Element.elements = []
|
|
83
|
+
# Element.ids = []
|
|
84
|
+
# for i in elem_di.keys():
|
|
85
|
+
# Element(elem_di[i], i)
|
|
86
|
+
|
|
87
|
+
_forceType = Literal["KN", "N", "KGF", "TONF", "LBF", "KIPS"]
|
|
88
|
+
_lengthType = Literal["M", "CM", "MM", "FT", "IN"]
|
|
89
|
+
_heatType = Literal["CAL", "KCAL", "J", "KJ", "BTU"]
|
|
90
|
+
_tempType = Literal["C","F"]
|
|
91
|
+
|
|
92
|
+
@staticmethod
|
|
93
|
+
def units(force:_forceType = "KN",length:_lengthType = "M", heat:_heatType = "BTU", temp:_tempType = "C"):
|
|
94
|
+
"""force --> KN, N, KFG, TONF, LFB, KIPS ||
|
|
95
|
+
\ndist --> M, CM, MM, FT, IN ||
|
|
96
|
+
\nheat --> CAL, KCAL, J, KJ, BTU ||
|
|
97
|
+
\ntemp --> C, F
|
|
98
|
+
\nDefault --> KN, M, BTU, C"""
|
|
99
|
+
if temp not in ["C","F"]:
|
|
100
|
+
temp="C"
|
|
101
|
+
if force not in ["KN", "N", "KGF", "TONF", "LBF", "KIPS"]:
|
|
102
|
+
force = "KN"
|
|
103
|
+
if length not in ["M", "CM", "MM", "FT", "IN"]:
|
|
104
|
+
dist = "M"
|
|
105
|
+
if heat not in ["CAL", "KCAL", "J", "KJ", "BTU"]:
|
|
106
|
+
heat = "BTU"
|
|
107
|
+
unit={"Assign":{
|
|
108
|
+
1:{
|
|
109
|
+
"FORCE":force,
|
|
110
|
+
"DIST":length,
|
|
111
|
+
"HEAT":heat,
|
|
112
|
+
"TEMPER":temp
|
|
113
|
+
}
|
|
114
|
+
}}
|
|
115
|
+
MidasAPI("PUT","/db/UNIT",unit)
|
|
116
|
+
|
|
117
|
+
@staticmethod
|
|
118
|
+
def select(crit_1 = "X", crit_2 = 0, crit_3 = 0, st = 'a', en = 'a', tolerance = 0):
|
|
119
|
+
"""Get list of nodes/elements as required.\n
|
|
120
|
+
crit_1 (=> Along: "X", "Y", "Z". OR, IN: "XY", "YZ", "ZX". OR "USM"),\n
|
|
121
|
+
crit_2 (=> With Ordinate value: Y value, X value, X Value, Z value, X value, Y value. OR Material ID),\n
|
|
122
|
+
crit_3 (=> At Ordinate 2 value: Z value, Z value, Y value, 0, 0, 0. OR Section ID),\n
|
|
123
|
+
starting ordinate, end ordinate, tolerance, node dictionary, element dictionary.\n
|
|
124
|
+
Sample: get_select("Y", 0, 2) for selecting all nodes and elements parallel Y axis with X ordinate as 0 and Z ordinate as 2."""
|
|
125
|
+
output = {'NODE':[], 'ELEM':[]}
|
|
126
|
+
ok = 0
|
|
127
|
+
no = Node.json()
|
|
128
|
+
el = Element.json()
|
|
129
|
+
if crit_1 == "USM":
|
|
130
|
+
materials = Material.json()
|
|
131
|
+
sections = Section.json()
|
|
132
|
+
elements = el
|
|
133
|
+
k = list(elements.keys())[0]
|
|
134
|
+
mat_nos = list((materials["Assign"].keys()))
|
|
135
|
+
sect_nos = list((sections["Assign"].keys()))
|
|
136
|
+
elem = {}
|
|
137
|
+
for m in mat_nos:
|
|
138
|
+
elem[int(m)] = {}
|
|
139
|
+
for s in sect_nos:
|
|
140
|
+
elem[int(m)][int(s)] = []
|
|
141
|
+
for e in elements[k].keys(): elem[((elements[k][e]['MATL']))][((elements[k][e]['SECT']))].append(int(e))
|
|
142
|
+
output['ELEM'] = elem[crit_2][crit_3]
|
|
143
|
+
ok = 1
|
|
144
|
+
elif no != "" and el != "":
|
|
145
|
+
n_key = list(no.keys())[0]
|
|
146
|
+
e_key = list(el.keys())[0]
|
|
147
|
+
if n_key == "Assign": no["Assign"] = {str(key):value for key,value in no["Assign"].items()}
|
|
148
|
+
if e_key == "Assign": el["Assign"] = {str(key):value for key,value in el["Assign"].items()}
|
|
149
|
+
if crit_1 == "X":
|
|
150
|
+
cr2 = "Y"
|
|
151
|
+
cr3 = "Z"
|
|
152
|
+
ok = 1
|
|
153
|
+
if crit_1 == "Y":
|
|
154
|
+
cr2 = "X"
|
|
155
|
+
cr3 = "Z"
|
|
156
|
+
ok = 1
|
|
157
|
+
if crit_1 == "Z":
|
|
158
|
+
cr2 = "X"
|
|
159
|
+
cr3 = "Y"
|
|
160
|
+
ok = 1
|
|
161
|
+
if crit_1 == "XY" or crit_1 == "YX":
|
|
162
|
+
cr2 = "Z"
|
|
163
|
+
ok = 1
|
|
164
|
+
if crit_1 == "YZ" or crit_1 == "ZY":
|
|
165
|
+
cr2 = "X"
|
|
166
|
+
ok = 1
|
|
167
|
+
if crit_1 == "ZX" or crit_1 == "XZ":
|
|
168
|
+
cr2 = "Y"
|
|
169
|
+
ok = 1
|
|
170
|
+
if len(crit_1) == 1 and ok == 1:
|
|
171
|
+
if st == 'a': st = min([v[crit_1] for v in no[n_key].values()])
|
|
172
|
+
if en == 'a': en = max([v[crit_1] for v in no[n_key].values()])
|
|
173
|
+
for n in no[n_key].keys():
|
|
174
|
+
curr = no[n_key][n]
|
|
175
|
+
if curr[cr2] >= crit_2 - tolerance and curr[cr2] <= crit_2 + tolerance:
|
|
176
|
+
if curr[cr3] >= crit_3 - tolerance and curr[cr3] <= crit_3 + tolerance:
|
|
177
|
+
if curr[crit_1] >= st and curr[crit_1] <= en: output['NODE'].append(int(n))
|
|
178
|
+
for e in el[e_key].keys():
|
|
179
|
+
curr_0 = no[n_key][str(el[e_key][e]['NODE'][0])]
|
|
180
|
+
curr_1 = no[n_key][str(el[e_key][e]['NODE'][1])]
|
|
181
|
+
if curr_0[cr2] == curr_1[cr2] and curr_0[cr3] == curr_1[cr3]:
|
|
182
|
+
if curr_0[cr2] >= crit_2 - tolerance and curr_0[cr2] <= crit_2 + tolerance:
|
|
183
|
+
if curr_0[cr3] >= crit_3 - tolerance and curr_0[cr3] <= crit_3 + tolerance:
|
|
184
|
+
if curr_1[cr2] >= crit_2 - tolerance and curr_1[cr2] <= crit_2 + tolerance:
|
|
185
|
+
if curr_1[cr3] >= crit_3 - tolerance and curr_1[cr3] <= crit_3 + tolerance:
|
|
186
|
+
if curr_0[crit_1] >= st and curr_0[crit_1] <= en and curr_1[crit_1] >= st and curr_1[crit_1] <= en:
|
|
187
|
+
output['ELEM'].append(int(e))
|
|
188
|
+
if len(crit_1) == 2 and ok == 1:
|
|
189
|
+
if st == 'a': st = min(min([v[crit_1[0]] for v in no[n_key].values()]), min([v[crit_1[1]] for v in no[n_key].values()]))
|
|
190
|
+
if en == 'a': en = max(max([v[crit_1[0]] for v in no[n_key].values()]), max([v[crit_1[1]] for v in no[n_key].values()]))
|
|
191
|
+
for n in no[n_key].keys():
|
|
192
|
+
curr = no[n_key][n]
|
|
193
|
+
if curr[cr2] >= crit_2 - tolerance and curr[cr2] <= crit_2 + tolerance:
|
|
194
|
+
if curr[crit_1[0]] >= st and curr[crit_1[1]] >= st and curr[crit_1[0]] <= en and curr[crit_1[1]] <= en: output['NODE'].append(int(n))
|
|
195
|
+
for e in el[e_key].keys():
|
|
196
|
+
curr_0 = no[n_key][str(el[e_key][e]['NODE'][0])]
|
|
197
|
+
curr_1 = no[n_key][str(el[e_key][e]['NODE'][1])]
|
|
198
|
+
if curr_0[cr2] == curr_1[cr2]:
|
|
199
|
+
if curr_0[cr2] >= crit_2 - tolerance and curr_0[cr2] <= crit_2 + tolerance:
|
|
200
|
+
if curr_1[cr2] >= crit_2 - tolerance and curr_1[cr2] <= crit_2 + tolerance:
|
|
201
|
+
if curr_0[crit_1[0]] >= st and curr_0[crit_1[0]] <= en and curr_1[crit_1[0]] >= st and curr_1[crit_1[0]] <= en:
|
|
202
|
+
if curr_0[crit_1[1]] >= st and curr_0[crit_1[1]] <= en and curr_1[crit_1[1]] >= st and curr_1[crit_1[1]] <= en:
|
|
203
|
+
output['ELEM'].append(int(e))
|
|
204
|
+
if ok != 1: output = "Incorrect input. Please check the syntax!"
|
|
205
|
+
return output
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
# @staticmethod
|
|
210
|
+
# def _create2(request = "update", set = 1, force = "KN", length = "M", heat = "BTU", temp = "C"):
|
|
211
|
+
# """request["update" to update a model, "call" to get details of existing model], \nforce[Optional], length[Optional], heat[Optional], temp[Optional].
|
|
212
|
+
# \nSample: model() to update/create model. model("call") to get details of existing model and update classes.\n
|
|
213
|
+
# set = 1 => Functions that don't need to call data from connected model file.\n
|
|
214
|
+
# set = 2 => Functions that may need to call data from connected model file."""
|
|
215
|
+
# Model.units(force, length, heat, temp)
|
|
216
|
+
# if MAPI_KEY.data == []: print(f"Enter the MAPI key using the MAPI_KEY command.")
|
|
217
|
+
# if MAPI_KEY.data != []:
|
|
218
|
+
# if set == 1:
|
|
219
|
+
# if request == "update" or request == "create" or request == "PUT":
|
|
220
|
+
# if Node.json() != {"Assign":{}}: Node.create()
|
|
221
|
+
# if Element.json() != {"Assign":{}}: Element.create()
|
|
222
|
+
# if Section.json() != {"Assign":{}}: Section.create()
|
|
223
|
+
# if Group.json_BG() != {"Assign":{}}: Group.create_BG()
|
|
224
|
+
# if Group.json_LG() != {"Assign":{}}: Group.create_LG()
|
|
225
|
+
# if Group.json_TG() != {"Assign":{}}: Group.create_TG()
|
|
226
|
+
# if Material.json() != {"Assign":{}}: Material.create()
|
|
227
|
+
# if request == "call" or request == "GET":
|
|
228
|
+
# Node.sync()
|
|
229
|
+
# Element.sync()
|
|
230
|
+
# Section.sync()
|
|
231
|
+
# Group.sync()
|
|
232
|
+
# Material.sync()
|
|
233
|
+
# if set == 2:
|
|
234
|
+
# if request == "update" or request == "create" or request == "PUT":
|
|
235
|
+
# if Node.json() != {"Assign":{}}: Node.create()
|
|
236
|
+
# if Element.json() != {"Assign":{}}: Element.create()
|
|
237
|
+
# if Section.json() != {"Assign":{}}: Section.create()
|
|
238
|
+
# if Group.json_BG() != {"Assign":{}}: Group.create_BG()
|
|
239
|
+
# if Group.json_LG() != {"Assign":{}}: Group.create_LG()
|
|
240
|
+
# if Group.json_TG() != {"Assign":{}}: Group.create_TG()
|
|
241
|
+
# if Material.json() != {"Assign":{}}: Material.create()
|
|
242
|
+
# if Group.json_SG() != {"Assign":{}}: Group.create_SG()
|
|
243
|
+
# if request == "call" or request == "GET":
|
|
244
|
+
# Node.update_class()
|
|
245
|
+
# Element.update_class()
|
|
246
|
+
# Section.update_class()
|
|
247
|
+
# Group.update_class()
|
|
248
|
+
# Material.update_class()
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
@staticmethod
|
|
252
|
+
def maxID(dbNAME:str = 'NODE') -> int :
|
|
253
|
+
'''
|
|
254
|
+
Returns maximum ID of a DB in CIVIL NX
|
|
255
|
+
dbNAME - 'NODE' , 'ELEM' , 'THIK' , 'SECT'
|
|
256
|
+
If no data exist, 0 is returned
|
|
257
|
+
'''
|
|
258
|
+
dbJS = MidasAPI('GET',f'/db/{dbNAME}')
|
|
259
|
+
if dbJS == {'message': ''}:
|
|
260
|
+
return 0
|
|
261
|
+
return max(map(int, list(dbJS[dbNAME].keys())))
|
|
262
|
+
|
|
263
|
+
@staticmethod
|
|
264
|
+
def create():
|
|
265
|
+
"""Create Material, Section, Node, Elements, Groups and Boundary."""
|
|
266
|
+
from tqdm import tqdm
|
|
267
|
+
pbar = tqdm(total=15,desc="Creating Model...")
|
|
268
|
+
|
|
269
|
+
if Material.mats!=[]: Material.create()
|
|
270
|
+
pbar.update(1)
|
|
271
|
+
pbar.set_description_str("Creating Section...")
|
|
272
|
+
if Section.sect!=[]: Section.create()
|
|
273
|
+
pbar.update(1)
|
|
274
|
+
pbar.set_description_str("Creating Thickness...")
|
|
275
|
+
if Thickness.thick!=[]: Thickness.create()
|
|
276
|
+
pbar.update(1)
|
|
277
|
+
pbar.set_description_str("Creating Node...")
|
|
278
|
+
if Node.nodes!=[]: Node.create()
|
|
279
|
+
pbar.update(1)
|
|
280
|
+
pbar.set_description_str("Creating Element...")
|
|
281
|
+
if Element.elements!=[] : Element.create()
|
|
282
|
+
pbar.update(1)
|
|
283
|
+
pbar.set_description_str("Creating Node Local Axis...")
|
|
284
|
+
if NodeLocalAxis.skew!=[] : NodeLocalAxis.create()
|
|
285
|
+
pbar.update(1)
|
|
286
|
+
pbar.set_description_str("Creating Group...")
|
|
287
|
+
Group.create()
|
|
288
|
+
pbar.update(1)
|
|
289
|
+
pbar.set_description_str("Creating Boundary...")
|
|
290
|
+
Boundary.create()
|
|
291
|
+
pbar.update(1)
|
|
292
|
+
pbar.set_description_str("Creating Load...")
|
|
293
|
+
Load.create()
|
|
294
|
+
pbar.update(1)
|
|
295
|
+
pbar.set_description_str("Creating Temperature...")
|
|
296
|
+
Temperature.create()
|
|
297
|
+
pbar.update(1)
|
|
298
|
+
pbar.set_description_str("Creating Tendon...")
|
|
299
|
+
Tendon.create()
|
|
300
|
+
pbar.update(1)
|
|
301
|
+
pbar.set_description_str("Creating Tapered Group...")
|
|
302
|
+
if Section.TaperedGroup.data !=[] : Section.TaperedGroup.create()
|
|
303
|
+
pbar.update(1)
|
|
304
|
+
pbar.set_description_str("Creating Construction Stages...")
|
|
305
|
+
CS.create()
|
|
306
|
+
pbar.update(1)
|
|
307
|
+
pbar.set_description_str("Creating Moving Load...")
|
|
308
|
+
MovingLoad.create()
|
|
309
|
+
pbar.update(1)
|
|
310
|
+
pbar.set_description_str("Creating Load Combination...")
|
|
311
|
+
LoadCombination.create()
|
|
312
|
+
pbar.update(1)
|
|
313
|
+
pbar.set_description_str(Fore.GREEN+"Model creation complete"+Style.RESET_ALL)
|
|
314
|
+
|
|
315
|
+
|
|
316
|
+
|
|
317
|
+
|
|
318
|
+
|
|
319
|
+
|
|
320
|
+
@staticmethod
|
|
321
|
+
def clear():
|
|
322
|
+
Material.clearAll()
|
|
323
|
+
Section.clear()
|
|
324
|
+
Thickness.clear()
|
|
325
|
+
Node.clear()
|
|
326
|
+
Element.clear()
|
|
327
|
+
NodeLocalAxis.clear()
|
|
328
|
+
Group.clear()
|
|
329
|
+
Boundary.clear()
|
|
330
|
+
Load.clear()
|
|
331
|
+
Temperature.clear()
|
|
332
|
+
Tendon.clear()
|
|
333
|
+
Section.TaperedGroup.clear()
|
|
334
|
+
LoadCombination.clear()
|
|
335
|
+
|
|
336
|
+
|
|
337
|
+
|
|
338
|
+
@staticmethod
|
|
339
|
+
def type(strc_type=0,mass_type=1,gravity:float=0,mass_dir=1):
|
|
340
|
+
"""Structure Type option
|
|
341
|
+
--------------------------------
|
|
342
|
+
|
|
343
|
+
Structure Type:
|
|
344
|
+
0 = 3D
|
|
345
|
+
1 = X-Z Plane
|
|
346
|
+
2 = Y-Z Plane
|
|
347
|
+
3 = X-Y Plane
|
|
348
|
+
4 = Constraint RZ
|
|
349
|
+
|
|
350
|
+
Mass Type:
|
|
351
|
+
1 = Lumped Mass
|
|
352
|
+
2 = Consistent Mass
|
|
353
|
+
|
|
354
|
+
Gravity Acceleration (g) = 9.81 m/s^2
|
|
355
|
+
|
|
356
|
+
Mass Direction(Structure Mass type):
|
|
357
|
+
1 = Convert to X, Y, Z
|
|
358
|
+
2 = Convert to X, Y
|
|
359
|
+
3 = Convert to Z
|
|
360
|
+
"""
|
|
361
|
+
|
|
362
|
+
js = {"Assign": {
|
|
363
|
+
"1":{}}}
|
|
364
|
+
|
|
365
|
+
|
|
366
|
+
js["Assign"]["1"]["STYP"] = strc_type
|
|
367
|
+
|
|
368
|
+
js["Assign"]["1"]["MASS"] = mass_type
|
|
369
|
+
|
|
370
|
+
if mass_dir==0:
|
|
371
|
+
js["Assign"]["1"]["bSELFWEIGHT"] = False
|
|
372
|
+
else:
|
|
373
|
+
js["Assign"]["1"]["bSELFWEIGHT"] = True
|
|
374
|
+
js["Assign"]["1"]["SMASS"] = mass_dir
|
|
375
|
+
|
|
376
|
+
if gravity!=0:
|
|
377
|
+
js["Assign"]["1"]["GRAV"] = gravity
|
|
378
|
+
|
|
379
|
+
|
|
380
|
+
MidasAPI("PUT","/db/STYP",js)
|
|
381
|
+
|
|
382
|
+
@staticmethod
|
|
383
|
+
def save(location=""):
|
|
384
|
+
"""Saves the model\nFor the first save, provide location - \nModel.save("D:\\model2.mcb")"""
|
|
385
|
+
if location=="":
|
|
386
|
+
MidasAPI("POST","/doc/SAVE",{"Argument":{}})
|
|
387
|
+
else:
|
|
388
|
+
if location.endswith('.mcb') or location.endswith('.mcbz'):
|
|
389
|
+
MidasAPI("POST","/doc/SAVEAS",{"Argument":str(location)})#Dumy location
|
|
390
|
+
else:
|
|
391
|
+
print('⚠️ File extension is missing')
|
|
392
|
+
|
|
393
|
+
|
|
394
|
+
@staticmethod
|
|
395
|
+
def saveAs(location=""):
|
|
396
|
+
"""Saves the model at location provided
|
|
397
|
+
Model.saveAs("D:\\model2.mcb")"""
|
|
398
|
+
if location.endswith('.mcb') or location.endswith('.mcbz'):
|
|
399
|
+
MidasAPI("POST","/doc/SAVEAS",{"Argument":str(location)})
|
|
400
|
+
else:
|
|
401
|
+
print('⚠️ File extension is missing')
|
|
402
|
+
|
|
403
|
+
@staticmethod
|
|
404
|
+
def open(location=""):
|
|
405
|
+
"""Open Civil NX model file \n Model.open("D:\\model.mcb")"""
|
|
406
|
+
if location.endswith('.mcb') or location.endswith('.mcbz'):
|
|
407
|
+
MidasAPI("POST","/doc/OPEN",{"Argument":str(location)})
|
|
408
|
+
else:
|
|
409
|
+
print('⚠️ File extension is missing')
|
|
410
|
+
|
|
411
|
+
|
|
412
|
+
@staticmethod
|
|
413
|
+
def new():
|
|
414
|
+
"""Creates a new model"""
|
|
415
|
+
MidasAPI("POST","/doc/NEW",{"Argument":{}})
|
|
416
|
+
|
|
417
|
+
@staticmethod
|
|
418
|
+
def info(project_name="",revision="",user="",title="",comment =""):
|
|
419
|
+
"""Enter Project information"""
|
|
420
|
+
|
|
421
|
+
js = {"Assign": {
|
|
422
|
+
"1":{}}}
|
|
423
|
+
|
|
424
|
+
if project_name+revision+user+title=="":
|
|
425
|
+
return MidasAPI("GET","/db/PJCF",{})
|
|
426
|
+
else:
|
|
427
|
+
if project_name!="":
|
|
428
|
+
js["Assign"]["1"]["PROJECT"] = project_name
|
|
429
|
+
if revision!="":
|
|
430
|
+
js["Assign"]["1"]["REVISION"] = revision
|
|
431
|
+
if user!="":
|
|
432
|
+
js["Assign"]["1"]["USER"] = user
|
|
433
|
+
if title!="":
|
|
434
|
+
js["Assign"]["1"]["TITLE"] = title
|
|
435
|
+
if comment != "" :
|
|
436
|
+
js["Assign"]["1"]["COMMENT"] = comment
|
|
437
|
+
|
|
438
|
+
|
|
439
|
+
MidasAPI("PUT","/db/PJCF",js)
|
|
440
|
+
|
|
441
|
+
@staticmethod
|
|
442
|
+
def exportJSON(location=""):
|
|
443
|
+
"""Export the model data as JSON file
|
|
444
|
+
Model.exportJSON('D:\\model.json')"""
|
|
445
|
+
if location.endswith('.json'):
|
|
446
|
+
MidasAPI("POST","/doc/EXPORT",{"Argument":str(location)})
|
|
447
|
+
else:
|
|
448
|
+
print('⚠️ Location data in exportJSON is missing file extension')
|
|
449
|
+
|
|
450
|
+
@staticmethod
|
|
451
|
+
def exportMCT(location=""):
|
|
452
|
+
"""Export the model data as MCT file
|
|
453
|
+
Model.exportMCT('D:\\model.mct')"""
|
|
454
|
+
if location.endswith('.mct'):
|
|
455
|
+
MidasAPI("POST","/doc/EXPORTMXT",{"Argument":str(location)})
|
|
456
|
+
else:
|
|
457
|
+
print('⚠️ Location data in exportMCT is missing file extension')
|
|
458
|
+
|
|
459
|
+
|
|
460
|
+
@staticmethod
|
|
461
|
+
def importJSON(location=""):
|
|
462
|
+
"""Import JSON data file in MIDAS CIVIL NX
|
|
463
|
+
Model.importJSON('D:\\model.json')"""
|
|
464
|
+
if location.endswith('.json'):
|
|
465
|
+
MidasAPI("POST","/doc/IMPORT",{"Argument":str(location)})
|
|
466
|
+
else:
|
|
467
|
+
print('⚠️ Location data in importJSON is missing file extension')
|
|
468
|
+
|
|
469
|
+
@staticmethod
|
|
470
|
+
def importMCT(location=""):
|
|
471
|
+
"""Import MCT data file in MIDAS CIVIL NX
|
|
472
|
+
Model.importMCT('D:\\model.mct')"""
|
|
473
|
+
if location.endswith('.mct'):
|
|
474
|
+
MidasAPI("POST","/doc/IMPORTMXT",{"Argument":str(location)})
|
|
475
|
+
else:
|
|
476
|
+
print('⚠️ Location data in importMCT is missing file extension')
|
|
477
|
+
|
|
478
|
+
@staticmethod
|
|
479
|
+
def get_element_connectivity():
|
|
480
|
+
element_connectivity = {}
|
|
481
|
+
for element in Element.elements:
|
|
482
|
+
element_id = element.ID
|
|
483
|
+
connected_nodes = element.NODE
|
|
484
|
+
element_connectivity.update({element_id: connected_nodes})
|
|
485
|
+
return element_connectivity
|
|
486
|
+
|
|
487
|
+
@staticmethod
|
|
488
|
+
def get_node_connectivity():
|
|
489
|
+
element_connectivity = Model.get_element_connectivity()
|
|
490
|
+
node_connectivity = defaultdict(list)
|
|
491
|
+
|
|
492
|
+
for element_id, nodes in element_connectivity.items():
|
|
493
|
+
for node in nodes:
|
|
494
|
+
node_connectivity[node].append(element_id)
|
|
495
|
+
node_connectivity = dict(node_connectivity)
|
|
496
|
+
return node_connectivity
|
|
497
|
+
|
|
498
|
+
@staticmethod
|
|
499
|
+
def visualise():
|
|
500
|
+
if NX.visualiser:
|
|
501
|
+
try:
|
|
502
|
+
from ._visualise import displayWindow
|
|
503
|
+
displayWindow()
|
|
504
|
+
except:
|
|
505
|
+
pass
|
|
506
|
+
|
|
507
|
+
@staticmethod
|
|
508
|
+
def snap():
|
|
509
|
+
if NX.visualiser:
|
|
510
|
+
try:
|
|
511
|
+
from ._visualise import take_snapshot
|
|
512
|
+
take_snapshot()
|
|
513
|
+
except:
|
|
514
|
+
pass
|
|
515
|
+
|
|
516
|
+
|
|
517
|
+
|
|
518
|
+
|
|
519
|
+
|
|
520
|
+
|
|
521
|
+
|
|
522
|
+
|