midas-civil 1.0.0__py3-none-any.whl → 1.0.2__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 CHANGED
@@ -26,6 +26,6 @@ from ._settlement import*
26
26
 
27
27
 
28
28
  print('')
29
- print('*'*20,' MIDAS CIVIL-NX PYTHON LIBRARY 🐍 ','*'*20)
29
+ print('*'*20,' MIDAS CIVIL-NX PYTHON LIBRARY v1.0.2 🐍 ','*'*20)
30
30
  print('')
31
31
 
midas_civil/_element.py CHANGED
@@ -2,9 +2,85 @@ from ._mapi import *
2
2
  from ._node import *
3
3
  from ._group import _add_elem_2_stGroup
4
4
  from ._group import _add_node_2_stGroup
5
-
6
5
  import numpy as np
6
+ from scipy.interpolate import splev, splprep
7
+ from math import hypot
8
+
9
+
10
+ def _interpolateAlignment(pointsArray,n_seg=10,deg=1,mSize=0,includePoint:bool=True) -> list:
11
+ ''' Returns point list and beta angle list'''
12
+ pointsArray = np.array(pointsArray)
13
+ x_p, y_p , z_p = pointsArray[:,0] , pointsArray[:,1] , pointsArray[:,2]
14
+
15
+ if deg < 1 :
16
+ deg = 1
17
+ if deg > len(pointsArray)-1:
18
+ deg = len(pointsArray)-1
19
+
20
+ #-- Actual length ----
21
+ dxq = np.diff(x_p)
22
+ dyq = np.diff(y_p)
23
+ dzq = np.diff(z_p)
24
+ dlq=[0]
25
+
26
+ for i in range(len(dxq)):
27
+ dlq.append(hypot(dxq[i],dyq[i],dzq[i]))
28
+
29
+ tck, u = splprep([x_p, y_p, z_p], s=0, k=deg)
30
+
31
+ u_fine = np.linspace(0, 1, 500)
32
+ x_den, y_den, z_den = splev(u_fine, tck)
33
+
34
+ dx = np.diff(x_den)
35
+ dy = np.diff(y_den)
36
+ dz = np.diff(z_den)
37
+ dl=[]
38
+ for i in range(len(dx)):
39
+ dl.append(hypot(dx[i],dy[i],dz[i]))
40
+
41
+ cum_l = np.insert(np.cumsum(dl),0,0)
42
+ total_l = cum_l[-1]
43
+
44
+
45
+ if n_seg==0 or mSize!=0:
46
+ n_seg=int(total_l/mSize)
47
+
48
+
49
+ eq_len = np.linspace(0,total_l,n_seg+1)
50
+
51
+ interp_u = np.interp(eq_len,cum_l,u_fine)
52
+
53
+ if includePoint:
54
+ interp_u = np.sort(np.append(interp_u,u[1:-1])).tolist()
55
+
56
+ eq_u = 1/n_seg # for filtering close points
57
+
58
+ new_u = []
59
+ skip=0
60
+ for i in range(len(interp_u)-1):
61
+ if skip == 1:
62
+ skip = 0
63
+ continue
64
+ if interp_u[i+1]-interp_u[i] < 0.2*eq_u:
65
+ if interp_u[i] in u:
66
+ new_u.append(interp_u[i])
67
+ skip=1
68
+ else:
69
+ new_u.append(interp_u[i+1])
70
+ skip=1
71
+ else:
72
+ new_u.append(interp_u[i])
73
+ new_u.append(interp_u[-1])
74
+ else:
75
+ new_u = interp_u
76
+
77
+
78
+ interp_x, interp_y , interp_z = splev(new_u, tck)
79
+
7
80
 
81
+ align_fine_points = [ [round(x,6), round(y,6), round(z,6)] for x, y, z in zip(interp_x, interp_y , interp_z) ]
82
+
83
+ return align_fine_points
8
84
 
9
85
 
10
86
 
@@ -273,6 +349,26 @@ class Element:
273
349
  beam_obj.append(Element.Beam(beam_nodes[i],beam_nodes[i+1],mat,sect,angle,group,id_new))
274
350
 
275
351
  return beam_obj
352
+
353
+ @staticmethod
354
+ def PLine(points_loc:list,n_div:int=0,deg:int=1,includePoint:bool=True,mat:int=1,sect:int=1,angle:float=0, group = "" , id: int = 0):
355
+
356
+ beam_nodes =[]
357
+ beam_obj = []
358
+ if n_div == 0 :
359
+ i_loc = points_loc
360
+ else:
361
+ i_loc = _interpolateAlignment(points_loc,n_div,deg,0,includePoint)
362
+ for i in i_loc:
363
+ Enode=Node(i[0],i[1],i[2])
364
+ beam_nodes.append(Enode.ID)
365
+
366
+ for i in range(len(i_loc)-1):
367
+ if id == 0 : id_new = 0
368
+ else: id_new = id+i
369
+ beam_obj.append(Element.Beam(beam_nodes[i],beam_nodes[i+1],mat,sect,angle,group,id_new))
370
+
371
+ return beam_obj
276
372
 
277
373
  class Truss(_common):
278
374
  def __init__(self, i: int, j: int, mat: int = 1, sect: int = 1, angle: float = 0, group = "" , id: int = 0):
midas_civil/_group.py CHANGED
@@ -1,29 +1,44 @@
1
1
 
2
2
  from ._mapi import *
3
3
 
4
-
5
-
6
-
4
+ from ._utils import _convItem2List
5
+ from ._utils import sFlatten
7
6
 
8
7
  # ----------- HELPER FUNCTION -----------
9
8
  # -------- RETRIEVE NODE / ELEMENT FROM STRUCTURE GROUP -------
10
9
 
11
- def nodesInGroup(groupName:str) -> list | int:
10
+ def nodesInGroup(groupName:str|list,unique:bool=True) -> list:
12
11
  ''' Returns Node ID list in a Structure Group '''
13
- for i in Group.Structure.Groups:
14
- if i.NAME == groupName:
15
- return i.NLIST
16
- print('⚠️ Structure group not found !')
17
- return []
12
+ groupNames = _convItem2List(groupName)
13
+ nlist = []
14
+ for gName in groupNames:
15
+ chk=1
16
+ for i in Group.Structure.Groups:
17
+ if i.NAME == gName:
18
+ chk=0
19
+ nlist.append(i.NLIST)
20
+ if chk:
21
+ print(f'⚠️ "{gName}" - Structure group not found !')
22
+ if unique:
23
+ return list(dict.fromkeys(sFlatten(nlist)))
24
+ return sFlatten(nlist)
18
25
 
19
26
 
20
- def elemsInGroup(groupName:str) -> list:
27
+ def elemsInGroup(groupName:str|list,unique:bool=True) -> list:
21
28
  ''' Returns Element ID list in a Structure Group '''
22
- for i in Group.Structure.Groups:
23
- if i.NAME == groupName:
24
- return i.ELIST
25
- print('⚠️ Structure group not found !')
26
- return []
29
+ groupNames = _convItem2List(groupName)
30
+ elist = []
31
+ for gName in groupNames:
32
+ chk=1
33
+ for i in Group.Structure.Groups:
34
+ if i.NAME == gName:
35
+ chk=0
36
+ elist.append(i.ELIST)
37
+ if chk:
38
+ print(f'⚠️ "{gName}" - Structure group not found !')
39
+ if unique:
40
+ return list(dict.fromkeys(sFlatten(elist)))
41
+ return sFlatten(elist)
27
42
 
28
43
 
29
44
  # -------- ADD ELEMENT TO STRUCTURE GROUP -------
@@ -116,7 +131,7 @@ class Group:
116
131
  if up == 0: print(f"⚠️ Structure group {name} is not defined!")
117
132
 
118
133
  @classmethod
119
- def json(cls):
134
+ def json(cls) -> dict:
120
135
  """Generates the json file for all defined structure groups."""
121
136
  json = {"Assign":{}}
122
137
  for i in cls.Groups:
@@ -133,7 +148,7 @@ class Group:
133
148
  MidasAPI("PUT",cls.url,cls.json())
134
149
 
135
150
  @classmethod
136
- def get(cls):
151
+ def get(cls) -> dict:
137
152
  return MidasAPI("GET",cls.url)
138
153
 
139
154
 
@@ -177,25 +192,9 @@ class Group:
177
192
  else: self.ID= max(Group.Boundary.ids)+1
178
193
  Group.Boundary.ids.append(self.ID)
179
194
  Group.Boundary.Groups.append(self)
180
-
181
- # @classmethod
182
- # def update(cls, name,operation = "r", nlist = [],elist = [] ):
183
- # """Group name, element list, node list, operation ("add" or "replace").\n
184
- # Sample: update_SG("Girder", [1,2,...20],[],"replace")"""
185
- # up = 0
186
- # for i in cls.Groups:
187
- # if name == i.NAME:
188
- # up = 1
189
- # if operation == "r":
190
- # i.ELIST = list(set(elist))
191
- # i.NLIST = list(set(nlist))
192
- # if operation == "a":
193
- # i.ELIST = list(set(i.ELIST + elist))
194
- # i.NLIST = list(set(i.NLIST + nlist))
195
- # if up == 0: print(f"⚠️ Boundary group {name} is not defined!")
196
195
 
197
196
  @classmethod
198
- def json(cls):
197
+ def json(cls) -> dict:
199
198
  "Generates the json file for all defined structure groups."
200
199
  json = {"Assign":{}}
201
200
  for i in cls.Groups:
@@ -210,7 +209,7 @@ class Group:
210
209
  MidasAPI("PUT",cls.url,cls.json())
211
210
 
212
211
  @classmethod
213
- def get(cls):
212
+ def get(cls) -> dict:
214
213
  return MidasAPI("GET",cls.url)
215
214
 
216
215
 
@@ -247,24 +246,9 @@ class Group:
247
246
  Group.Load.ids.append(self.ID)
248
247
  Group.Load.Groups.append(self)
249
248
 
250
- # @classmethod
251
- # def update(cls, name,operation = "r", nlist = [],elist = [] ):
252
- # """Group name, element list, node list, operation ("add" or "replace").\n
253
- # Sample: update_SG("Girder", [1,2,...20],[],"replace")"""
254
- # up = 0
255
- # for i in cls.Groups:
256
- # if name == i.NAME:
257
- # up = 1
258
- # if operation == "r":
259
- # i.ELIST = list(set(elist))
260
- # i.NLIST = list(set(nlist))
261
- # if operation == "a":
262
- # i.ELIST = list(set(i.ELIST + elist))
263
- # i.NLIST = list(set(i.NLIST + nlist))
264
- # if up == 0: print(f"⚠️ Boundary group {name} is not defined!")
265
249
 
266
250
  @classmethod
267
- def json(cls):
251
+ def json(cls) -> dict:
268
252
  "Generates the json file for all defined structure groups."
269
253
  json = {"Assign":{}}
270
254
  for i in cls.Groups:
@@ -278,7 +262,7 @@ class Group:
278
262
  MidasAPI("PUT",cls.url,cls.json())
279
263
 
280
264
  @classmethod
281
- def get(cls):
265
+ def get(cls) -> dict:
282
266
  return MidasAPI("GET",cls.url)
283
267
 
284
268
  @classmethod
@@ -312,25 +296,10 @@ class Group:
312
296
  else: self.ID= max(Group.Tendon.ids)+1
313
297
  Group.Tendon.ids.append(self.ID)
314
298
  Group.Tendon.Groups.append(self)
315
-
316
- # @classmethod
317
- # def update(cls, name,operation = "r", nlist = [],elist = [] ):
318
- # """Group name, element list, node list, operation ("add" or "replace").\n
319
- # Sample: update_SG("Girder", [1,2,...20],[],"replace")"""
320
- # up = 0
321
- # for i in cls.Groups:
322
- # if name == i.NAME:
323
- # up = 1
324
- # if operation == "r":
325
- # i.ELIST = list(set(elist))
326
- # i.NLIST = list(set(nlist))
327
- # if operation == "a":
328
- # i.ELIST = list(set(i.ELIST + elist))
329
- # i.NLIST = list(set(i.NLIST + nlist))
330
- # if up == 0: print(f"⚠️ Boundary group {name} is not defined!")
299
+
331
300
 
332
301
  @classmethod
333
- def json(cls):
302
+ def json(cls) -> dict:
334
303
  "Generates the json file for all defined structure groups."
335
304
  json = {"Assign":{}}
336
305
  for i in cls.Groups:
@@ -344,7 +313,7 @@ class Group:
344
313
  MidasAPI("PUT",cls.url,cls.json())
345
314
 
346
315
  @classmethod
347
- def get(cls):
316
+ def get(cls) -> dict:
348
317
  return MidasAPI("GET",cls.url)
349
318
 
350
319
  @classmethod
midas_civil/_mapi.py CHANGED
@@ -130,3 +130,15 @@ def MidasAPI(method:str, command:str, body:dict={})->dict:
130
130
  return response.json()
131
131
 
132
132
 
133
+ #--------------------------------------------------------------------
134
+
135
+ def _getUNIT():
136
+ return MidasAPI('GET','/db/UNIT',{})['UNIT']['1']
137
+
138
+ def _setUNIT(unitJS):
139
+ js = {
140
+ "Assign" : {
141
+ "1" : unitJS
142
+ }
143
+ }
144
+ MidasAPI('PUT','/db/UNIT',js)
midas_civil/_model.py CHANGED
@@ -19,10 +19,19 @@ class Model:
19
19
  @staticmethod
20
20
  def analyse():
21
21
  """Checkes whether a model is analyzed or not and then performs analysis if required."""
22
- r = (MidasAPI("POST","/post/TABLE",{"Argument": {"TABLE_NAME": "Reaction(Global)","TABLE_TYPE": "REACTIONG",}}))
23
- if 'error' in r.keys():
24
- MidasAPI("POST","/doc/SAVE",{"Argument":{}})
25
- MidasAPI("POST","/doc/ANAL",{"Assign":{}})
22
+ json_body = {
23
+ "Argument": {
24
+ "HEIGHT" : 1,
25
+ "WIDTH" : 1,
26
+ "SET_MODE": "post"
27
+ }
28
+ }
29
+ resp = MidasAPI('POST','/view/CAPTURE',json_body)
30
+
31
+ if 'message' in resp or 'error' in resp:
32
+ MidasAPI("POST","/doc/ANAL",{"Assign":{}})
33
+ return True
34
+ print(" ⚠️ Model ananlysed. Switching to post-processing mode.")
26
35
 
27
36
  #9 Function to remove duplicate nodes and elements from Node & Element classes\
28
37
  @staticmethod
@@ -3,6 +3,9 @@ import json
3
3
  import xlsxwriter
4
4
  from ._mapi import *
5
5
  from ._model import *
6
+
7
+ from ._mapi import _getUNIT
8
+ from ._mapi import _setUNIT
6
9
  # js_file = open('JSON_Excel Parsing\\test.json','r')
7
10
 
8
11
  # print(js_file)
@@ -136,8 +139,10 @@ class Result :
136
139
  }
137
140
  }
138
141
  }
142
+ currUNIT = _getUNIT()
139
143
  Model.units(force=force_unit,length=len_unit)
140
144
  ss_json = MidasAPI("POST","/post/TABLE",js_dat)
145
+ _setUNIT(currUNIT)
141
146
  return _JSToDF_UserDefined(tableName,ss_json,summary)
142
147
 
143
148
  # ---------- LIST ALL USER DEFINED TABLE ------------------------------
@@ -194,8 +199,9 @@ class Result :
194
199
 
195
200
  if loadcase!=[]: js_dat["Argument"]['LOAD_CASE_NAMES'] = loadcase
196
201
 
197
-
202
+ currUNIT = _getUNIT()
198
203
  Model.units(force=force_unit,length=len_unit)
199
204
  ss_json = MidasAPI("POST","/post/table",js_dat)
205
+ _setUNIT(currUNIT)
200
206
  return _JSToDF_ResTable(ss_json)
201
207
 
midas_civil/_utils.py CHANGED
@@ -80,4 +80,10 @@ def zz_add_to_dict(dictionary, key, value):
80
80
  if key in dictionary:
81
81
  dictionary[key].append(value)
82
82
  else:
83
- dictionary[key] = [value]
83
+ dictionary[key] = [value]
84
+
85
+
86
+ def _convItem2List(item):
87
+ if isinstance(item,list):
88
+ return item
89
+ return [item]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: midas_civil
3
- Version: 1.0.0
3
+ Version: 1.0.2
4
4
  Summary: Python library for MIDAS Civil NX
5
5
  Home-page: https://github.com/MIDASIT-Co-Ltd/midas-civil-python
6
6
  Author: Sumit Shekhar
@@ -13,6 +13,7 @@ Requires-Dist: numpy
13
13
  Requires-Dist: polars
14
14
  Requires-Dist: xlsxwriter
15
15
  Requires-Dist: requests
16
+ Requires-Dist: scipy
16
17
  Dynamic: author
17
18
  Dynamic: author-email
18
19
  Dynamic: description
@@ -28,10 +29,14 @@ Dynamic: summary
28
29
 
29
30
  ![MIDAS PYTHON](https://midas-rnd.github.io/midasapi-python/assets/banner.png)
30
31
 
32
+ ---
33
+
34
+ [![PyPI Downloads](https://static.pepy.tech/badge/midas-civil)](https://pepy.tech/projects/midas-civil)
35
+
31
36
  **`midas-civil`** is a Python library that provides an interface to interact with MIDAS Civil NX using Python scripts.
32
37
  This library allows engineers and developers to automate tasks, extract structural analysis results, manipulate model data, and integrate MIDAS Civil NX with other tools or pipelines using Python.
33
38
 
34
- ---
39
+
35
40
 
36
41
  ## Features
37
42
 
@@ -1,27 +1,27 @@
1
- midas_civil/__init__.py,sha256=t0XkmZiEBYodUkU2gJWLQmqrpQdZc8ikPM3Z0xrSVPg,575
1
+ midas_civil/__init__.py,sha256=FLQxclh4avM2ich9ZhAxFcFLM1fVCGKlFjVNnwW9B2o,581
2
2
  midas_civil/_boundary.py,sha256=s5mgZIc1b0-P7AdWuaPAQ5cIbHL5CR1YRKJA7KE4W_U,32958
3
3
  midas_civil/_construction.py,sha256=q9C3gGdvky5t7jCDzd6lBRv6pm8cMycI91xfkgDV37Y,40673
4
4
  midas_civil/_construction_backup.py,sha256=Pj7V-NYCkkT-aMjKXfs1jKa9klsGh48UXDLwn3BLYTY,18225
5
- midas_civil/_element.py,sha256=hlH6NZfSBOrKQO7R22wZYbmLA20MB8rX7g_Td6G4mgo,27544
6
- midas_civil/_group.py,sha256=BPZcsuIVKr2vR1SezfCXS0sUn1W7aJfOJGc8ZvTAXvo,11526
5
+ midas_civil/_element.py,sha256=O6PBn5yWI_EFpHpCMOVoo8zsA5fup1pwdY058LSc0pY,30411
6
+ midas_civil/_group.py,sha256=Go4If-cwdKMfIDlNi1MYYq4jPYOa3MlVvNkX2pTkyCs,9864
7
7
  midas_civil/_load.py,sha256=TltWAjDaeC5MNW8IIPKgpLahDQgJR3J6SzinkCrJS7A,30171
8
- midas_civil/_mapi.py,sha256=Fabn3QX6OHJeV_s_01KMvOwkSye0kfgpiUUgPplAzxA,4597
8
+ midas_civil/_mapi.py,sha256=SnX16e19jAuFEc7W_95FtY7aadfmdkgVxZie6hkgyEY,4867
9
9
  midas_civil/_material.py,sha256=uJEIHJM9OhwTRWUI2mtd_0BQSxdlYhATYJu9P7tNNBA,69511
10
- midas_civil/_model.py,sha256=G5Kh7u2DSodvKGQ0fOzAUx4Ilj8-rn-nGDTFeI6AkUU,16442
10
+ midas_civil/_model.py,sha256=I7lzMsOhqWcDcBYtPSqBUs97sBEf5M1mJ0KLftyGGB4,16597
11
11
  midas_civil/_movingload.py,sha256=kzTbi4vFjOnUYOyhDDTmSHFU-sDGb_MgMBNXUmFmUZc,80001
12
12
  midas_civil/_node.py,sha256=wRttDbebQWT6aZWeNd72AgzVWUETyNzMng5kJQmV3WM,4760
13
13
  midas_civil/_result copy.py,sha256=siTMENLIwF_6rvydSjP9aQAWaIlt0pReiqNyDhDevGk,24290
14
14
  midas_civil/_result.py,sha256=ZJf2CQG2ZjlTKuWo3zBnG7W8EwI1UkhWhWJVWRzlXUU,7640
15
- midas_civil/_result_extract.py,sha256=J-9eeWDbFeaDL-C41TAynYuooiHYsayAe3WbfGRO8sM,5537
15
+ midas_civil/_result_extract.py,sha256=cZgWMxvZV9Pc-Ec0KzGrerDRv1Sj3AJKqlZwj_uVi9w,5707
16
16
  midas_civil/_section.py,sha256=-mpGOYceus_dURE80lsGExSBDDpqDKqsNjBeOE3kZEM,36433
17
17
  midas_civil/_settlement.py,sha256=U7lJYBqGbuCv7qziEEznDyA4M_SCjJeIjc0lDeGfE4Y,5125
18
18
  midas_civil/_temperature.py,sha256=EfvivFWfxyM8yFCvWJgXLhaCofGwLKEBGFUuW8yHnfQ,24209
19
19
  midas_civil/_tendon.py,sha256=mXNJeLikFsBpgn8u9fED2qx9oqnKh3XtIpYwp3moEfk,33395
20
20
  midas_civil/_thickness.py,sha256=4xQsLA3Q_gIGCwLc_glFmiErdWdQUSwhlEhJ_IPJseA,3248
21
- midas_civil/_utils.py,sha256=eymiqO8KaTKdhVY3saebqNS0BbUUmGmgw3-ELKqew0A,2611
21
+ midas_civil/_utils.py,sha256=GR9cj-mgRPmtwmgqEj4JeEjMlRS6zmvhcxFV5IHbpRk,2708
22
22
  midas_civil/_view.py,sha256=o7rkfoQzmgAb3dT0ujPIQLVwVlveo3rMRIbZU1UosZo,849
23
- midas_civil-1.0.0.dist-info/licenses/LICENSE,sha256=zrL4RwZC4rb-by_ZHKXwKdIwcs6ATy59TPZ9HxPHCrs,1071
24
- midas_civil-1.0.0.dist-info/METADATA,sha256=BlyY3us0N1lB2l6slGBPScjlDiS1WrTmw7qHRx7pWCA,1957
25
- midas_civil-1.0.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
26
- midas_civil-1.0.0.dist-info/top_level.txt,sha256=_NFmrlN5V9OxJ-PAO4s_om8OA8uupXho3QqZcSsnbuI,12
27
- midas_civil-1.0.0.dist-info/RECORD,,
23
+ midas_civil-1.0.2.dist-info/licenses/LICENSE,sha256=zrL4RwZC4rb-by_ZHKXwKdIwcs6ATy59TPZ9HxPHCrs,1071
24
+ midas_civil-1.0.2.dist-info/METADATA,sha256=25Lm__RTdXyuo2Gwkgm3Qp4snPVKVP-CMHqpHgd1fLI,2085
25
+ midas_civil-1.0.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
26
+ midas_civil-1.0.2.dist-info/top_level.txt,sha256=_NFmrlN5V9OxJ-PAO4s_om8OA8uupXho3QqZcSsnbuI,12
27
+ midas_civil-1.0.2.dist-info/RECORD,,