midas-civil 0.0.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of midas-civil might be problematic. Click here for more details.

midas_civil/_load.py ADDED
@@ -0,0 +1,384 @@
1
+ from ._mapi import *
2
+ from ._model import *
3
+ from ._group import *
4
+
5
+ #11 Class to define Load Cases:
6
+ class Load_Case:
7
+ """Type symbol (Refer Static Load Case section in the Onine API Manual, Load Case names.
8
+ \nSample: Load_Case("USER", "Case 1", "Case 2", ..., "Case n")"""
9
+ cases = []
10
+ types = ["USER", "D", "DC", "DW", "DD", "EP", "EANN", "EANC", "EAMN", "EAMC", "EPNN", "EPNC", "EPMN", "EPMC", "EH", "EV", "ES", "EL", "LS", "LSC",
11
+ "L", "LC", "LP", "IL", "ILP", "CF", "BRK", "BK", "CRL", "PS", "B", "WP", "FP", "SF", "WPR", "W", "WL", "STL", "CR", "SH", "T", "TPG", "CO",
12
+ "CT", "CV", "E", "FR", "IP", "CS", "ER", "RS", "GE", "LR", "S", "R", "LF", "RF", "GD", "SHV", "DRL", "WA", "WT", "EVT", "EEP", "EX", "I", "EE"]
13
+ def __init__(self, type, *name):
14
+ self.TYPE = type
15
+ self.NAME = name
16
+ self.ID = []
17
+ for i in range(len(self.NAME)):
18
+ if Load_Case.cases == []: self.ID.append(i+1)
19
+ if Load_Case.cases != []: self.ID.append(max(Load_Case.cases[-1].ID) + i + 1)
20
+ Load_Case.cases.append(self)
21
+
22
+ @classmethod
23
+ def json(cls):
24
+ ng = []
25
+ json = {"Assign":{}}
26
+ for i in cls.cases:
27
+ if i.TYPE in cls.types:
28
+ for j in i.ID:
29
+ json['Assign'][j] = {
30
+ "NAME": i.NAME[i.ID.index(j)],
31
+ "TYPE": i.TYPE}
32
+ else:
33
+ ng.append(i.TYPE)
34
+ if ng != []: print(f"These load case types are incorrect: {ng}.\nPlease check API Manual.")
35
+ return json
36
+
37
+ @staticmethod
38
+ def create():
39
+ MidasAPI("PUT","/db/stld",Load_Case.json())
40
+
41
+ @staticmethod
42
+ def get():
43
+ return MidasAPI("GET","/db/stld")
44
+
45
+ @staticmethod
46
+ def sync():
47
+ a = Load_Case.get()
48
+ if a != {'message': ''}:
49
+ if list(a['STLD'].keys()) != []:
50
+ Load_Case.cases = []
51
+ for j in a['STLD'].keys():
52
+ Load_Case(a['STLD'][j]['TYPE'], a['STLD'][j]['NAME'])
53
+
54
+ @classmethod
55
+ def delete(cls):
56
+ cls.cases=[]
57
+ return MidasAPI("DELETE","/db/stld")
58
+ #---------------------------------------------------------------------------------------------------------------
59
+
60
+
61
+
62
+ class Load:
63
+
64
+ @classmethod
65
+ def create(cls):
66
+ if Load_Case.cases!=[]: Load_Case.create()
67
+ if cls.SW.data!=[]: cls.SW.create()
68
+ if cls.Nodal.data!=[]: cls.Nodal.create()
69
+ if cls.Beam.data!=[]: cls.Beam.create()
70
+
71
+
72
+ class SW:
73
+ """Load Case Name, direction, Value, Load Group.\n
74
+ Sample: Load_SW("Self-Weight", "Z", -1, "DL")"""
75
+ data = []
76
+ def __init__(self, load_case, dir = "Z", value = -1, load_group = ""):
77
+ chk = 0
78
+ for i in Load_Case.cases:
79
+ if load_case in i.NAME: chk = 1
80
+ if chk == 0: Load_Case("D", load_case)
81
+ if load_group != "":
82
+ chk = 0
83
+ a = [v['NAME'] for v in Group.Load.json()["Assign"].values()]
84
+ if load_group in a: chk = 1
85
+ if chk == 0: Group.Load(load_group)
86
+
87
+ if type(value)==int:
88
+ if dir == "X":
89
+ fv = [value, 0, 0]
90
+ elif dir == "Y":
91
+ fv = [0, value, 0]
92
+ else:
93
+ fv = [0, 0, value]
94
+ elif type(value)==list:
95
+ fv = value
96
+ else: fv = [0,0,-1]
97
+
98
+
99
+ self.LC = load_case
100
+ self.DIR = dir
101
+ self.FV = fv
102
+ self.LG = load_group
103
+ self.ID = len(Load.SW.data) + 1
104
+ Load.SW.data.append(self)
105
+
106
+ @classmethod
107
+ def json(cls):
108
+ json = {"Assign":{}}
109
+ for i in cls.data:
110
+ json["Assign"][i.ID] = {
111
+ "LCNAME": i.LC,
112
+ "GROUP_NAME": i.LG,
113
+ "FV": i.FV
114
+ }
115
+ return json
116
+
117
+ @staticmethod
118
+ def create():
119
+ MidasAPI("PUT","/db/BODF",Load.SW.json())
120
+
121
+ @staticmethod
122
+ def get():
123
+ return MidasAPI("GET","/db/BODF")
124
+
125
+ @staticmethod
126
+ def sync():
127
+ a = Load.SW.get()
128
+ if a != {'message': ''}:
129
+ for i in list(a['BODF'].keys()):
130
+ if a['BODF'][i]['FV'][0] != 0:
131
+ di = "X"
132
+ va = a['BODF'][i]['FV'][0]
133
+ elif a['BODF'][i]['FV'][1] != 0:
134
+ di = "Y"
135
+ va = a['BODF'][i]['FV'][1]
136
+ else:
137
+ di = "Z"
138
+ va = a['BODF'][i]['FV'][2]
139
+ Load.SW(a['BODF'][i]['LCNAME'], di, va, a['BODF'][i]['GROUP_NAME'])
140
+
141
+
142
+ #-------------------------------- NODAL LOADS ------------------------------------------------------------
143
+
144
+ #18 Class to add Nodal Loads:
145
+ class Nodal:
146
+ """Creates node loads and converts to JSON format.
147
+ Example: Load_Node(101, "LC1", "Group1", FZ = 10)
148
+ """
149
+ data = []
150
+ def __init__(self, node, load_case, load_group = "", FX:float = 0, FY:float = 0, FZ:float= 0, MX:float =0, MY:float =0, MZ:float=0, id = ""):
151
+
152
+
153
+ chk = 0
154
+ for i in Load_Case.cases:
155
+ if load_case in i.NAME: chk = 1
156
+ if chk == 0: Load_Case("D", load_case)
157
+ if load_group != "":
158
+ chk = 0
159
+ a = [v['NAME'] for v in Group.Load.json()["Assign"].values()]
160
+ if load_group in a: chk = 1
161
+ if chk == 0: Group.Load(load_group)
162
+
163
+
164
+ self.NODE = node
165
+ self.LCN = load_case
166
+ self.LDGR = load_group
167
+ self.FX = FX
168
+ self.FY = FY
169
+ self.FZ = FZ
170
+ self.MX = MX
171
+ self.MY = MY
172
+ self.MZ = MZ
173
+ if id == "": id = len(Load.Nodal.data) + 1
174
+ self.ID = id
175
+ Load.Nodal.data.append(self)
176
+
177
+ @classmethod
178
+ def json(cls):
179
+ json = {"Assign": {}}
180
+ for i in cls.data:
181
+ if i.NODE not in list(json["Assign"].keys()):
182
+ json["Assign"][i.NODE] = {"ITEMS": []}
183
+
184
+ json["Assign"][i.NODE]["ITEMS"].append({
185
+ "ID": i.ID,
186
+ "LCNAME": i.LCN,
187
+ "GROUP_NAME": i.LDGR,
188
+ "FX": i.FX,
189
+ "FY": i.FY,
190
+ "FZ": i.FZ,
191
+ "MX": i.MX,
192
+ "MY": i.MY,
193
+ "MZ": i.MZ
194
+ })
195
+ return json
196
+
197
+ @classmethod
198
+ def create(cls):
199
+ MidasAPI("PUT", "/db/CNLD",cls.json())
200
+
201
+ @classmethod
202
+ def get(cls):
203
+ return MidasAPI("GET", "/db/CNLD")
204
+
205
+ @classmethod
206
+ def delete(cls):
207
+ cls.data=[]
208
+ return MidasAPI("DELETE", "/db/CNLD")
209
+
210
+ @classmethod
211
+ def sync(cls):
212
+ cls.data = []
213
+ a = cls.get()
214
+ if a != {'message': ''}:
215
+ for i in a['CNLD'].keys():
216
+ for j in range(len(a['CNLD'][i]['ITEMS'])):
217
+ Load.Nodal(int(i),a['CNLD'][i]['ITEMS'][j]['LCNAME'], a['CNLD'][i]['ITEMS'][j]['GROUP_NAME'],
218
+ a['CNLD'][i]['ITEMS'][j]['FX'], a['CNLD'][i]['ITEMS'][j]['FY'], a['CNLD'][i]['ITEMS'][j]['FZ'],
219
+ a['CNLD'][i]['ITEMS'][j]['MX'], a['CNLD'][i]['ITEMS'][j]['MY'], a['CNLD'][i]['ITEMS'][j]['MZ'],
220
+ a['CNLD'][i]['ITEMS'][j]['ID'])
221
+ #---------------------------------------------------------------------------------------------------------------
222
+
223
+ #19 Class to define Beam Loads:
224
+ class Beam:
225
+ data = []
226
+ def __init__(self, element: int, load_case: str, value: float, load_group: str = "", direction: str = "GZ",
227
+ id = "", D = [0, 1, 0, 0], P = [0, 0, 0, 0], cmd = "BEAM", typ = "UNILOAD", use_ecc = False, use_proj = False,
228
+ eccn_dir = "LZ", eccn_type = 1, ieccn = 0, jeccn = 0.0000195, adnl_h = False, adnl_h_i = 0, adnl_h_j = 0.0000195):
229
+ """
230
+ element: Element Number
231
+ load_case (str): Load case name
232
+ load_group (str, optional): Load group name. Defaults to ""
233
+ value (float): Load value
234
+ direction (str): Load direction (e.g., "GX", "GY", "GZ", "LX", "LY", "LZ"). Defaults to "GZ"
235
+ id (str, optional): Load ID. Defaults to auto-generated
236
+ D: Relative distance (list with 4 values, optional) based on length of element. Defaults to [0, 1, 0, 0]
237
+ P: Magnitude of UDL at corresponding position of D (list with 4 values, optional). Defaults to [value, value, 0, 0]
238
+ cmd: Load command (e.g., "BEAM", "LINE", "TYPICAL")
239
+ typ: Load type (e.g., "CONLOAD", "CONMOMENT", "UNITLOAD", "UNIMOMENT", "PRESSURE")
240
+ use_ecc: Use eccentricity (True or False). Defaults to False.
241
+ use_proj: Use projection (True or False). Defaults to False.
242
+ eccn_dir: Eccentricity direction (e.g., "GX", "GY", "GZ", "LX", "LY", "LZ"). Defaults to "LZ"
243
+ eccn_type: Eccentricity from offset (1) or centroid (0). Defaults to 1.
244
+ ieccn, jeccn: Eccentricity values at i-end and j-end of the element
245
+ adnl_h: Consider additional H when applying pressure on beam (True or False). Defaults to False.
246
+ adnl_h_i, adnl_h_j: Additional H values at i-end and j-end of the beam. Defaults to 0.\n
247
+ Example:
248
+ - Load_Beam(115, "UDL_Case", "", -50.0, "GZ") # No eccentricity
249
+ - Load_Beam(115, "UDL_Case", "", -50.0, "GZ", ieccn=2.5) # With eccentricity
250
+ """
251
+
252
+ chk = 0
253
+ for i in Load_Case.cases:
254
+ if load_case in i.NAME: chk = 1
255
+ if chk == 0: Load_Case("D", load_case)
256
+ if load_group != "":
257
+ chk = 0
258
+ a = [v['NAME'] for v in Group.Load.json()["Assign"].values()]
259
+ if load_group in a: chk = 1
260
+ if chk == 0: Group.Load(load_group)
261
+
262
+
263
+
264
+ D = (D + [0] * 4)[:4]
265
+ P = (P + [0] * 4)[:4]
266
+ if P == [0, 0, 0, 0]: P = [value, value, 0, 0]
267
+ if eccn_type != 0 or eccn_type != 1: eccn_type = 0
268
+ if direction not in ("GX", "GY", "GZ", "LX", "LY", "LZ"): direction = "GZ"
269
+ if eccn_dir not in ("GX", "GY", "GZ", "LX", "LY", "LZ"): eccn_dir = "LY"
270
+ if cmd not in ("BEAM", "LINE", "TYPICAL"): cmd = "BEAM"
271
+ if typ not in ("CONLOAD", "CONMOMENT", "UNILOAD", "UNIMOMENT","PRESSURE"): typ = "UNILOAD"
272
+ if use_ecc == False:
273
+ if ieccn != 0 or jeccn != 0.0000195: use_ecc = True
274
+ self.ELEMENT = element
275
+ self.LCN = load_case
276
+ self.LDGR = load_group
277
+ self.VALUE = value
278
+ self.DIRECTION = direction
279
+ self.CMD = cmd
280
+ self.TYPE = typ
281
+ self.USE_PROJECTION = use_proj
282
+ self.USE_ECCEN = use_ecc
283
+ self.ECCEN_TYPE = eccn_type
284
+ self.ECCEN_DIR = eccn_dir
285
+ self.IECC = ieccn
286
+ if jeccn == 0.0000195:
287
+ self.JECC = 0
288
+ self.USE_JECC = False
289
+ else:
290
+ self.JECC = jeccn
291
+ self.USE_JECC = True
292
+ self.D = D
293
+ self.P = P
294
+ self.USE_H = adnl_h
295
+ self.I_H = adnl_h_i
296
+ if adnl_h == 0.0000195:
297
+ self.USE_JH = False
298
+ self.J_H = 0
299
+ else:
300
+ self.USE_JH = True
301
+ self.J_H = adnl_h_j
302
+
303
+ if id == "":
304
+ id = len(Load.Beam.data) + 1
305
+ self.ID = id
306
+ Load.Beam.data.append(self)
307
+
308
+ @classmethod
309
+ def json(cls):
310
+ json = {"Assign": {}}
311
+ for i in cls.data:
312
+ item_data = {
313
+ "ID": i.ID,
314
+ "LCNAME": i.LCN,
315
+ "GROUP_NAME": i.LDGR,
316
+ "CMD": i.CMD,
317
+ "TYPE": i.TYPE,
318
+ "DIRECTION": i.DIRECTION,
319
+ "USE_PROJECTION": i.USE_PROJECTION,
320
+ "USE_ECCEN": i.USE_ECCEN,
321
+ "D": i.D,
322
+ "P": i.P
323
+ }
324
+ if i.USE_ECCEN == True:
325
+ item_data.update({
326
+ "ECCEN_TYPE": i.ECCEN_TYPE,
327
+ "ECCEN_DIR": i.ECCEN_DIR,
328
+ "I_END": i.IECC,
329
+ "J_END": i.JECC,
330
+ "USE_J_END": i.USE_JECC
331
+ })
332
+ if i.TYPE == "PRESSURE":
333
+ item_data.update({
334
+ "USE_ADDITIONAL": i.USE_H,
335
+ "ADDITIONAL_I_END": i.I_H,
336
+ "ADDITIONAL_J_END": i.J_H,
337
+ "USE_ADDITIONAL_J_END": i.J_H
338
+ })
339
+ if i.ELEMENT not in json["Assign"]:
340
+ json["Assign"][i.ELEMENT] = {"ITEMS": []}
341
+ json["Assign"][i.ELEMENT]["ITEMS"].append(item_data)
342
+ return json
343
+
344
+ @classmethod
345
+ def create(cls):
346
+ MidasAPI("PUT", "/db/bmld", cls.json())
347
+
348
+ @classmethod
349
+ def get(cls):
350
+ return MidasAPI("GET", "/db/bmld")
351
+
352
+ @classmethod
353
+ def delete(cls):
354
+ cls.data=[]
355
+ return MidasAPI("DELETE", "/db/bmld")
356
+
357
+ @classmethod
358
+ def sync(cls):
359
+ cls.data = []
360
+ a = cls.get()
361
+ if a != {'message': ''}:
362
+ for i in a['BMLD'].keys():
363
+ for j in range(len(a['BMLD'][i]['ITEMS'])):
364
+ if a['BMLD'][i]['ITEMS'][j]['USE_ECCEN'] == True and a['BMLD'][i]['ITEMS'][j]['USE_ADDITIONAL'] == True:
365
+ Load.Beam(i,a['BMLD'][i]['ITEMS'][j]['LCNAME'], a['BMLD'][i]['ITEMS'][j]['P'][0], a['BMLD'][i]['ITEMS'][j]['GROUP_NAME'],
366
+ a['BMLD'][i]['ITEMS'][j]['DIRECTION'], a['BMLD'][i]['ITEMS'][j]['ID'], a['BMLD'][i]['ITEMS'][j]['D'], a['BMLD'][i]['ITEMS'][j]['P'],
367
+ a['BMLD'][i]['ITEMS'][j]['CMD'], a['BMLD'][i]['ITEMS'][j]['TYPE'], a['BMLD'][i]['ITEMS'][j]['USE_ECCEN'], a['BMLD'][i]['ITEMS'][j]['USE_PROJECTION'],
368
+ a['BMLD'][i]['ITEMS'][j]['ECCEN_DIR'], a['BMLD'][i]['ITEMS'][j]['ECCEN_TYPE'], a['BMLD'][i]['ITEMS'][j]['I_END'], a['BMLD'][i]['ITEMS'][j]['J_END'],
369
+ a['BMLD'][i]['ITEMS'][j]['USE_ADDITIONAL'], a['BMLD'][i]['ITEMS'][j]['ADDITIONAL_I_END'], a['BMLD'][i]['ITEMS'][j]['ADDITIONAL_J_END'])
370
+ elif a['BMLD'][i]['ITEMS'][j]['USE_ECCEN'] == False and a['BMLD'][i]['ITEMS'][j]['USE_ADDITIONAL'] == True:
371
+ Load.Beam(i,a['BMLD'][i]['ITEMS'][j]['LCNAME'], a['BMLD'][i]['ITEMS'][j]['P'][0], a['BMLD'][i]['ITEMS'][j]['GROUP_NAME'],
372
+ a['BMLD'][i]['ITEMS'][j]['DIRECTION'], a['BMLD'][i]['ITEMS'][j]['ID'], a['BMLD'][i]['ITEMS'][j]['D'], a['BMLD'][i]['ITEMS'][j]['P'],
373
+ a['BMLD'][i]['ITEMS'][j]['CMD'], a['BMLD'][i]['ITEMS'][j]['TYPE'], a['BMLD'][i]['ITEMS'][j]['USE_ECCEN'], a['BMLD'][i]['ITEMS'][j]['USE_PROJECTION'],
374
+ adnl_h = a['BMLD'][i]['ITEMS'][j]['USE_ADDITIONAL'], adnl_h_i = a['BMLD'][i]['ITEMS'][j]['ADDITIONAL_I_END'], adnl_h_j = a['BMLD'][i]['ITEMS'][j]['ADDITIONAL_J_END'])
375
+ elif a['BMLD'][i]['ITEMS'][j]['USE_ECCEN'] == True and a['BMLD'][i]['ITEMS'][j]['USE_ADDITIONAL'] == False:
376
+ Load.Beam(i,a['BMLD'][i]['ITEMS'][j]['LCNAME'], a['BMLD'][i]['ITEMS'][j]['P'][0], a['BMLD'][i]['ITEMS'][j]['GROUP_NAME'],
377
+ a['BMLD'][i]['ITEMS'][j]['DIRECTION'], a['BMLD'][i]['ITEMS'][j]['ID'], a['BMLD'][i]['ITEMS'][j]['D'], a['BMLD'][i]['ITEMS'][j]['P'],
378
+ a['BMLD'][i]['ITEMS'][j]['CMD'], a['BMLD'][i]['ITEMS'][j]['TYPE'], a['BMLD'][i]['ITEMS'][j]['USE_ECCEN'], a['BMLD'][i]['ITEMS'][j]['USE_PROJECTION'],
379
+ a['BMLD'][i]['ITEMS'][j]['ECCEN_DIR'], a['BMLD'][i]['ITEMS'][j]['ECCEN_TYPE'], a['BMLD'][i]['ITEMS'][j]['I_END'], a['BMLD'][i]['ITEMS'][j]['J_END'])
380
+ else:
381
+ Load.Beam(i,a['BMLD'][i]['ITEMS'][j]['LCNAME'], a['BMLD'][i]['ITEMS'][j]['P'][0], a['BMLD'][i]['ITEMS'][j]['GROUP_NAME'],
382
+ a['BMLD'][i]['ITEMS'][j]['DIRECTION'], a['BMLD'][i]['ITEMS'][j]['ID'], a['BMLD'][i]['ITEMS'][j]['D'], a['BMLD'][i]['ITEMS'][j]['P'],
383
+ a['BMLD'][i]['ITEMS'][j]['CMD'], a['BMLD'][i]['ITEMS'][j]['TYPE'], a['BMLD'][i]['ITEMS'][j]['USE_ECCEN'], a['BMLD'][i]['ITEMS'][j]['USE_PROJECTION'])
384
+ #---------------------------------------------------------------------------------------------------------------
midas_civil/_mapi.py ADDED
@@ -0,0 +1,66 @@
1
+ import requests
2
+ import sys
3
+
4
+ class MAPI_PRODUCT:
5
+ product = "civil"
6
+
7
+ def __init__(self,product:str):
8
+ """Product 'civil' or 'gen'"""
9
+ if product.lower() == 'gen':
10
+ MAPI_PRODUCT.product = 'gen'
11
+
12
+
13
+ class MAPI_KEY:
14
+ """MAPI key from Civil NX.\n\nEg: MAPI_Key("eadsfjaks568wqehhf.ajkgj345")"""
15
+ data = []
16
+
17
+ def __init__(self, mapi_key:str):
18
+ MAPI_KEY.data = []
19
+ self.KEY = mapi_key
20
+ MAPI_KEY.data.append(self.KEY)
21
+
22
+ @classmethod
23
+ def get_key(cls):
24
+ my_key = MAPI_KEY.data[-1]
25
+ return my_key
26
+ #---------------------------------------------------------------------------------------------------------------
27
+
28
+ #2 midas API link code:
29
+ def MidasAPI(method:str, command:str, body:dict={})->dict:
30
+ f"""Sends HTTP Request to MIDAS Civil NX
31
+ Parameters:
32
+ Method: "PUT" , "POST" , "GET" or "DELETE"
33
+ Command: eg. "/db/NODE"
34
+ Body: {{"Assign":{{1{{'X':0, 'Y':0, 'Z':0}}}}}}
35
+ Examples:
36
+ ```python
37
+ # Create a node
38
+ MidasAPI("PUT","/db/NODE",{{"Assign":{{"1":{{'X':0, 'Y':0, 'Z':0}}}}}})"""
39
+
40
+ base_url = f"https://moa-engineers.midasit.com:443/{MAPI_PRODUCT.product}"
41
+ mapi_key = MAPI_KEY.get_key()
42
+
43
+ url = base_url + command
44
+ headers = {
45
+ "Content-Type": "application/json",
46
+ "MAPI-Key": mapi_key
47
+ }
48
+
49
+ if method == "POST":
50
+ response = requests.post(url=url, headers=headers, json=body)
51
+ elif method == "PUT":
52
+ response = requests.put(url=url, headers=headers, json=body)
53
+ elif method == "GET":
54
+ response = requests.get(url=url, headers=headers)
55
+ elif method == "DELETE":
56
+ response = requests.delete(url=url, headers=headers)
57
+
58
+ if response.status_code == 404:
59
+ print(f"⚠️ Civil NX model is not connected. Click on 'Apps> Connect' in Civil NX. \nMake sure the MAPI Key in python code is matching with the MAPI key in Civil NX.\n\n")
60
+ sys.exit(0)
61
+
62
+ # print(method, command, response.status_code , "✅")
63
+
64
+ return response.json()
65
+
66
+