midas-civil 0.1.5__py3-none-any.whl → 0.1.6__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
@@ -23,6 +23,8 @@ from ._view import *
23
23
  from ._movingload import*
24
24
  from ._settlement import*
25
25
 
26
+
27
+
26
28
  print('')
27
29
  print('*'*20,' MIDAS CIVIL-NX PYTHON LIBRARY 🐍 ','*'*20)
28
30
  print('')
midas_civil/_boundary.py CHANGED
@@ -10,6 +10,16 @@ def convList(item):
10
10
  return item
11
11
 
12
12
 
13
+ # ----- Extend for list of nodes/elems -----
14
+
15
+ def _ADD_Support(self):
16
+ if isinstance(self.NODE,int):
17
+ Boundary.Support.sups.append(self)
18
+ elif isinstance(self.NODE,list):
19
+ for nID in self.NODE:
20
+ Boundary.Support(nID,self.CONST,self.GROUP)
21
+
22
+
13
23
  class Boundary:
14
24
 
15
25
  @classmethod
@@ -67,7 +77,7 @@ class Boundary:
67
77
  self.CONST = string
68
78
  self.GROUP = group
69
79
  self.ID = len(Boundary.Support.sups) + 1
70
- Boundary.Support.sups.append(self)
80
+ _ADD_Support(self)
71
81
 
72
82
  @classmethod
73
83
  def json(cls):
midas_civil/_element.py CHANGED
@@ -1,9 +1,15 @@
1
1
  from ._mapi import *
2
2
  from ._node import *
3
3
  from ._group import _add_elem_2_stGroup
4
+ from ._group import _add_node_2_stGroup
4
5
 
5
6
  import numpy as np
6
7
 
8
+
9
+
10
+
11
+
12
+
7
13
  def _ADD(self):
8
14
  """
9
15
  Adds an element to the main list. If the ID is 0, it auto-increments.
@@ -37,8 +43,12 @@ def _ADD(self):
37
43
  elif isinstance(self._GROUP, list):
38
44
  for gpName in self._GROUP:
39
45
  _add_elem_2_stGroup(self.ID,gpName)
46
+ for nd in self.NODE:
47
+ _add_node_2_stGroup(nd,gpName)
40
48
  elif isinstance(self._GROUP, str):
41
49
  _add_elem_2_stGroup(self.ID,self._GROUP)
50
+ for nd in self.NODE:
51
+ _add_node_2_stGroup(nd,self._GROUP)
42
52
 
43
53
 
44
54
 
@@ -516,10 +526,179 @@ class Element:
516
526
  _ADD(self)
517
527
 
518
528
 
529
+ #-----------------------------------------------Stiffness Scale Factor------------------------------
519
530
 
531
+ class StiffnessScaleFactor:
532
+
533
+ data = []
534
+
535
+ def __init__(self,
536
+ element_id,
537
+ area_sf: float = 1.0,
538
+ asy_sf: float = 1.0,
539
+ asz_sf: float = 1.0,
540
+ ixx_sf: float = 1.0,
541
+ iyy_sf: float = 1.0,
542
+ izz_sf: float = 1.0,
543
+ wgt_sf: float = 1.0,
544
+ group: str = "",
545
+ id: int = None):
546
+ """
547
+ element_id: Element ID(s) where scale factor is applied (can be int or list)
548
+ area_sf: Cross-sectional area scale factor
549
+ asy_sf: Effective Shear Area scale factor (y-axis)
550
+ asz_sf: Effective Shear Area scale factor (z-axis)
551
+ ixx_sf: Torsional Resistance scale factor (x-axis)
552
+ iyy_sf: Area Moment of Inertia scale factor (y-axis)
553
+ izz_sf: Area Moment of Inertia scale factor (z-axis)
554
+ wgt_sf: Weight scale factor
555
+ group: Group name (default "")
556
+ id: Scale factor ID (optional, auto-assigned if None)
557
+
558
+ Examples:
559
+ StiffnessScaleFactor(908, area_sf=0.5, asy_sf=0.6, asz_sf=0.7,
560
+ ixx_sf=0.8, iyy_sf=0.8, izz_sf=0.9, wgt_sf=0.95)
561
+
562
+ """
563
+
564
+ # Check if group exists, create if not
565
+ if group != "":
566
+ chk = 0
567
+ a = [v['NAME'] for v in Group.Boundary.json()["Assign"].values()]
568
+ if group in a:
569
+ chk = 1
570
+ if chk == 0:
571
+ Group.Boundary(group)
572
+
573
+ # Handle element_id as single int or list
574
+ if isinstance(element_id, (list, tuple)):
575
+ self.ELEMENT_IDS = list(element_id)
576
+ else:
577
+ self.ELEMENT_IDS = [element_id]
578
+
579
+ self.AREA_SF = area_sf
580
+ self.ASY_SF = asy_sf
581
+ self.ASZ_SF = asz_sf
582
+ self.IXX_SF = ixx_sf
583
+ self.IYY_SF = iyy_sf
584
+ self.IZZ_SF = izz_sf
585
+ self.WGT_SF = wgt_sf
586
+ self.GROUP_NAME = group
587
+
588
+ # Auto-assign ID if not provided
589
+ if id is None:
590
+ self.ID = len(Element.StiffnessScaleFactor.data) + 1
591
+ else:
592
+ self.ID = id
593
+
594
+ # Add to static list
595
+ Element.StiffnessScaleFactor.data.append(self)
596
+
597
+ @classmethod
598
+ def json(cls):
599
+ """
600
+ Converts StiffnessScaleFactor data to JSON format
601
+ """
602
+ json_data = {"Assign": {}}
603
+
604
+ for scale_factor in cls.data:
605
+ # Create scale factor item
606
+ scale_factor_item = {
607
+ "ID": scale_factor.ID,
608
+ "AREA_SF": scale_factor.AREA_SF,
609
+ "ASY_SF": scale_factor.ASY_SF,
610
+ "ASZ_SF": scale_factor.ASZ_SF,
611
+ "IXX_SF": scale_factor.IXX_SF,
612
+ "IYY_SF": scale_factor.IYY_SF,
613
+ "IZZ_SF": scale_factor.IZZ_SF,
614
+ "WGT_SF": scale_factor.WGT_SF,
615
+ "GROUP_NAME": scale_factor.GROUP_NAME
616
+ }
617
+
618
+ # Assign to each element ID
619
+ for element_id in scale_factor.ELEMENT_IDS:
620
+ if str(element_id) not in json_data["Assign"]:
621
+ json_data["Assign"][str(element_id)] = {"ITEMS": []}
622
+
623
+ json_data["Assign"][str(element_id)]["ITEMS"].append(scale_factor_item)
624
+
625
+ return json_data
626
+
627
+ @classmethod
628
+ def create(cls):
629
+ """
630
+ Sends all StiffnessScaleFactor data to the API
631
+ """
632
+ MidasAPI("PUT", "/db/essf", cls.json())
633
+
634
+ @classmethod
635
+ def get(cls):
636
+ """
637
+ Retrieves StiffnessScaleFactor data from the API
638
+ """
639
+ return MidasAPI("GET", "/db/essf")
640
+
641
+ @classmethod
642
+ def sync(cls):
643
+ """
644
+ Updates the StiffnessScaleFactor class with data from the API
645
+ """
646
+ cls.data = []
647
+ response = cls.get()
648
+
649
+ if response != {'message': ''}:
650
+ processed_ids = set() # To avoid duplicate processing
651
+
652
+ for element_data in response.get("ESSF", {}).items():
653
+ for item in element_data.get("ITEMS", []):
654
+ scale_factor_id = item.get("ID", 1)
655
+
656
+ # Skip if already processed (for multi-element scale factors)
657
+ if scale_factor_id in processed_ids:
658
+ continue
659
+
660
+ # Find all elements with the same scale factor ID
661
+ element_ids = []
662
+ for eid, edata in response.get("ESSF", {}).items():
663
+ for eitem in edata.get("ITEMS", []):
664
+ if eitem.get("ID") == scale_factor_id:
665
+ element_ids.append(int(eid))
666
+
667
+ # Create StiffnessScaleFactor object
668
+ Element.StiffnessScaleFactor(
669
+ element_id=element_ids if len(element_ids) > 1 else element_ids[0],
670
+ area_sf=item.get("AREA_SF", 1.0),
671
+ asy_sf=item.get("ASY_SF", 1.0),
672
+ asz_sf=item.get("ASZ_SF", 1.0),
673
+ ixx_sf=item.get("IXX_SF", 1.0),
674
+ iyy_sf=item.get("IYY_SF", 1.0),
675
+ izz_sf=item.get("IZZ_SF", 1.0),
676
+ wgt_sf=item.get("WGT_SF", 1.0),
677
+ group=item.get("GROUP_NAME", ""),
678
+ id=scale_factor_id
679
+ )
680
+
681
+ processed_ids.add(scale_factor_id)
682
+
683
+ @classmethod
684
+ def delete(cls):
685
+ """
686
+ Deletes all stiffness scale factors from the database and resets the class.
687
+ """
688
+ cls.data = []
689
+ return MidasAPI("DELETE", "/db/essf")
520
690
 
521
691
 
522
692
 
523
693
 
694
+ # ---- GET ELEMENT OBJECT FROM ID ----------
524
695
 
696
+ def elemByID(elemID:int) -> Element:
697
+ ''' Return Element object with the input ID '''
698
+ for elem in Element.elements:
699
+ if elem.ID == elemID:
700
+ return elem
701
+
702
+ print(f'There is no element with ID {elemID}')
703
+ return None
525
704
 
midas_civil/_group.py CHANGED
@@ -8,18 +8,21 @@ from ._mapi import *
8
8
  # ----------- HELPER FUNCTION -----------
9
9
  # -------- RETRIEVE NODE / ELEMENT FROM STRUCTURE GROUP -------
10
10
 
11
- def getNode(groupName):
11
+ def nodesInGroup(groupName:str) -> list | int:
12
12
  ''' Returns Node ID list in a Structure Group '''
13
13
  for i in Group.Structure.Groups:
14
14
  if i.NAME == groupName:
15
15
  return i.NLIST
16
+ print('⚠️ Structure group not found !')
16
17
  return []
17
18
 
18
- def getElement(groupName):
19
+
20
+ def elemsInGroup(groupName:str) -> list:
19
21
  ''' Returns Element ID list in a Structure Group '''
20
22
  for i in Group.Structure.Groups:
21
23
  if i.NAME == groupName:
22
24
  return i.ELIST
25
+ print('⚠️ Structure group not found !')
23
26
  return []
24
27
 
25
28
 
midas_civil/_load.py CHANGED
@@ -2,6 +2,28 @@ from ._mapi import *
2
2
  from ._model import *
3
3
  from ._group import *
4
4
 
5
+
6
+
7
+ # ----- Extend for list of nodes/elems -----
8
+
9
+ def _ADD_NodalLoad(self):
10
+ if isinstance(self.NODE,int):
11
+ Load.Nodal.data.append(self)
12
+ elif isinstance(self.NODE,list):
13
+ for nID in self.NODE:
14
+ Load.Nodal(nID,self.LCN,self.LDGR,self.FX,self.FY,self.FZ,self.MX,self.MY,self.MZ,self.ID)
15
+
16
+
17
+ def _ADD_BeamLoad(self):
18
+ if isinstance(self.ELEMENT,int):
19
+ Load.Beam.data.append(self)
20
+ elif isinstance(self.ELEMENT,list):
21
+ for eID in self.ELEMENT:
22
+ Load.Beam(eID,self.LCN,self.LDGR,self.VALUE,self.DIRECTION,self.ID,self.D,self.P,self.CMD,self.TYPE,self.USE_ECCEN,self.USE_PROJECTION,
23
+ self.ECCEN_DIR,self.ECCEN_TYPE,self.IECC,self.JECC,self.USE_H,self.I_H,self.J_H)
24
+
25
+
26
+
5
27
  #11 Class to define Load Cases:
6
28
  class Load_Case:
7
29
  """Type symbol (Refer Static Load Case section in the Onine API Manual, Load Case names.
@@ -177,7 +199,9 @@ class Load:
177
199
  self.MZ = MZ
178
200
  if id == "": id = len(Load.Nodal.data) + 1
179
201
  self.ID = id
180
- Load.Nodal.data.append(self)
202
+
203
+ _ADD_NodalLoad(self)
204
+ # Load.Nodal.data.append(self)
181
205
 
182
206
  @classmethod
183
207
  def json(cls):
@@ -228,9 +252,9 @@ class Load:
228
252
  #19 Class to define Beam Loads:
229
253
  class Beam:
230
254
  data = []
231
- def __init__(self, element: int, load_case: str, value: float, load_group: str = "", direction: str = "GZ",
255
+ def __init__(self, element, load_case: str, load_group: str = "", value: float=0, direction: str = "GZ",
232
256
  id = "", D = [0, 1, 0, 0], P = [0, 0, 0, 0], cmd = "BEAM", typ = "UNILOAD", use_ecc = False, use_proj = False,
233
- eccn_dir = "LZ", eccn_type = 1, ieccn = 0, jeccn = 0.0000195, adnl_h = False, adnl_h_i = 0, adnl_h_j = 0.0000195):
257
+ eccn_dir = "LZ", eccn_type = 1, ieccn = 0, jeccn = 0, adnl_h = False, adnl_h_i = 0, adnl_h_j = 0):
234
258
  """
235
259
  element: Element Number
236
260
  load_case (str): Load case name
@@ -276,7 +300,7 @@ class Load:
276
300
  if cmd not in ("BEAM", "LINE", "TYPICAL"): cmd = "BEAM"
277
301
  if typ not in ("CONLOAD", "CONMOMENT", "UNILOAD", "UNIMOMENT","PRESSURE"): typ = "UNILOAD"
278
302
  if use_ecc == False:
279
- if ieccn != 0 or jeccn != 0.0000195: use_ecc = True
303
+ if ieccn != 0 or jeccn != 0: use_ecc = True
280
304
  self.ELEMENT = element
281
305
  self.LCN = load_case
282
306
  self.LDGR = load_group
@@ -289,7 +313,7 @@ class Load:
289
313
  self.ECCEN_TYPE = eccn_type
290
314
  self.ECCEN_DIR = eccn_dir
291
315
  self.IECC = ieccn
292
- if jeccn == 0.0000195:
316
+ if jeccn == 0:
293
317
  self.JECC = 0
294
318
  self.USE_JECC = False
295
319
  else:
@@ -299,7 +323,7 @@ class Load:
299
323
  self.P = P
300
324
  self.USE_H = adnl_h
301
325
  self.I_H = adnl_h_i
302
- if adnl_h == 0.0000195:
326
+ if adnl_h == 0:
303
327
  self.USE_JH = False
304
328
  self.J_H = 0
305
329
  else:
@@ -309,7 +333,8 @@ class Load:
309
333
  if id == "":
310
334
  id = len(Load.Beam.data) + 1
311
335
  self.ID = id
312
- Load.Beam.data.append(self)
336
+ _ADD_BeamLoad(self)
337
+ # Load.Beam.data.append(self)
313
338
 
314
339
  @classmethod
315
340
  def json(cls):
@@ -368,23 +393,23 @@ class Load:
368
393
  for i in a['BMLD'].keys():
369
394
  for j in range(len(a['BMLD'][i]['ITEMS'])):
370
395
  if a['BMLD'][i]['ITEMS'][j]['USE_ECCEN'] == True 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'],
396
+ Load.Beam(i,a['BMLD'][i]['ITEMS'][j]['LCNAME'], a['BMLD'][i]['ITEMS'][j]['GROUP_NAME'], a['BMLD'][i]['ITEMS'][j]['P'][0],
372
397
  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
398
  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
399
  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'],
375
400
  a['BMLD'][i]['ITEMS'][j]['USE_ADDITIONAL'], a['BMLD'][i]['ITEMS'][j]['ADDITIONAL_I_END'], a['BMLD'][i]['ITEMS'][j]['ADDITIONAL_J_END'])
376
401
  elif a['BMLD'][i]['ITEMS'][j]['USE_ECCEN'] == False and a['BMLD'][i]['ITEMS'][j]['USE_ADDITIONAL'] == True:
377
- Load.Beam(i,a['BMLD'][i]['ITEMS'][j]['LCNAME'], a['BMLD'][i]['ITEMS'][j]['P'][0], a['BMLD'][i]['ITEMS'][j]['GROUP_NAME'],
402
+ Load.Beam(i,a['BMLD'][i]['ITEMS'][j]['LCNAME'], a['BMLD'][i]['ITEMS'][j]['GROUP_NAME'], a['BMLD'][i]['ITEMS'][j]['P'][0],
378
403
  a['BMLD'][i]['ITEMS'][j]['DIRECTION'], a['BMLD'][i]['ITEMS'][j]['ID'], a['BMLD'][i]['ITEMS'][j]['D'], a['BMLD'][i]['ITEMS'][j]['P'],
379
404
  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'],
380
405
  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'])
381
406
  elif a['BMLD'][i]['ITEMS'][j]['USE_ECCEN'] == True and a['BMLD'][i]['ITEMS'][j]['USE_ADDITIONAL'] == False:
382
- Load.Beam(i,a['BMLD'][i]['ITEMS'][j]['LCNAME'], a['BMLD'][i]['ITEMS'][j]['P'][0], a['BMLD'][i]['ITEMS'][j]['GROUP_NAME'],
407
+ Load.Beam(i,a['BMLD'][i]['ITEMS'][j]['LCNAME'], a['BMLD'][i]['ITEMS'][j]['GROUP_NAME'], a['BMLD'][i]['ITEMS'][j]['P'][0],
383
408
  a['BMLD'][i]['ITEMS'][j]['DIRECTION'], a['BMLD'][i]['ITEMS'][j]['ID'], a['BMLD'][i]['ITEMS'][j]['D'], a['BMLD'][i]['ITEMS'][j]['P'],
384
409
  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'],
385
410
  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'])
386
411
  else:
387
- Load.Beam(i,a['BMLD'][i]['ITEMS'][j]['LCNAME'], a['BMLD'][i]['ITEMS'][j]['P'][0], a['BMLD'][i]['ITEMS'][j]['GROUP_NAME'],
412
+ Load.Beam(i,a['BMLD'][i]['ITEMS'][j]['LCNAME'], a['BMLD'][i]['ITEMS'][j]['GROUP_NAME'],a['BMLD'][i]['ITEMS'][j]['P'][0],
388
413
  a['BMLD'][i]['ITEMS'][j]['DIRECTION'], a['BMLD'][i]['ITEMS'][j]['ID'], a['BMLD'][i]['ITEMS'][j]['D'], a['BMLD'][i]['ITEMS'][j]['P'],
389
414
  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'])
390
415
 
@@ -521,12 +546,13 @@ class Load:
521
546
 
522
547
  class NodalMass:
523
548
  """Creates nodal mass and converts to JSON format.
524
- Example: NodalMass(1.5, 2.0, 3.0, 0.1, 0.2, 0.3)
549
+ Example: NodalMass(1, 1.5, 2.0, 3.0, 0.1, 0.2, 0.3)
525
550
  """
526
551
  data = []
527
-
528
- def __init__(self, mX, mY=0, mZ=0, rmX=0, rmY=0, rmZ=0):
552
+
553
+ def __init__(self, node_id, mX, mY=0, mZ=0, rmX=0, rmY=0, rmZ=0):
529
554
  """
555
+ node_id (int): Node ID where the mass is applied (Required)
530
556
  mX (float): Translational Lumped Mass in GCS X-direction (Required)
531
557
  mY (float): Translational Lumped Mass in GCS Y-direction. Defaults to 0
532
558
  mZ (float): Translational Lumped Mass in GCS Z-direction. Defaults to 0
@@ -534,6 +560,7 @@ class Load:
534
560
  rmY (float): Rotational Mass Moment of Inertia about GCS Y-axis. Defaults to 0
535
561
  rmZ (float): Rotational Mass Moment of Inertia about GCS Z-axis. Defaults to 0
536
562
  """
563
+ self.NODE_ID = node_id
537
564
  self.MX = mX
538
565
  self.MY = mY
539
566
  self.MZ = mZ
@@ -547,10 +574,8 @@ class Load:
547
574
  def json(cls):
548
575
  json_data = {"Assign": {}}
549
576
 
550
- # Use the last added mass data (or first if only one exists)
551
- if cls.data:
552
- mass_obj = cls.data[-1] # Get the most recent mass object
553
- json_data["Assign"]["1"] = {
577
+ for mass_obj in cls.data:
578
+ json_data["Assign"][mass_obj.NODE_ID] = {
554
579
  "mX": mass_obj.MX,
555
580
  "mY": mass_obj.MY,
556
581
  "mZ": mass_obj.MZ,
@@ -567,23 +592,24 @@ class Load:
567
592
 
568
593
  @classmethod
569
594
  def get(cls):
570
- return MidasAPI("GET", "/db/nmas")
595
+ MidasAPI("GET", "/db/nmas")
571
596
 
572
597
  @classmethod
573
598
  def delete(cls):
574
599
  cls.data = []
575
- return MidasAPI("DELETE", "/db/nmas")
600
+ MidasAPI("DELETE", "/db/nmas")
576
601
 
577
602
  @classmethod
578
603
  def sync(cls):
579
604
  cls.data = []
580
605
  response = cls.get()
581
606
 
582
- if response != {'message': ''}:
607
+ if response and response != {'message': ''}:
583
608
  nmas_data = response.get('NMAS', {})
584
- if "1" in nmas_data:
585
- item_data = nmas_data["1"]
609
+
610
+ for node_id, item_data in nmas_data.items():
586
611
  Load.NodalMass(
612
+ node_id=int(node_id),
587
613
  mX=item_data.get('mX'),
588
614
  mY=item_data.get('mY'),
589
615
  mZ=item_data.get('mZ'),
midas_civil/_model.py CHANGED
@@ -11,6 +11,7 @@ from ._material import *
11
11
  from ._thickness import *
12
12
 
13
13
  from ._tendon import *
14
+ from ._result import *
14
15
 
15
16
  class Model:
16
17
 
@@ -242,6 +243,8 @@ class Model:
242
243
  Load.create()
243
244
  Tendon.create()
244
245
 
246
+ LoadCombination.create()
247
+
245
248
 
246
249
 
247
250
 
midas_civil/_node.py CHANGED
@@ -12,7 +12,10 @@ def dist_tol(a,b):
12
12
  def cell(point,size=1): #SIZE OF GRID
13
13
  return (int(point.X//size),int(point.Y//size),int(point.Z//size))
14
14
 
15
- #-- NEW SYSTEM
15
+
16
+ # -------- FUNCTIONS ARE DEFINED BELOW TO RECOGNISE NODE CLASS ----------------
17
+
18
+
16
19
 
17
20
  #5 Class to create nodes
18
21
  class Node:
@@ -161,6 +164,16 @@ class Node:
161
164
 
162
165
 
163
166
 
167
+ # ---- GET NODE OBJECT FROM ID ----------
168
+
169
+ def nodeByID(nodeID:int) -> Node:
170
+ ''' Return Node object with the input ID '''
171
+ for node in Node.nodes:
172
+ if node.ID == nodeID:
173
+ return node
174
+
175
+ print(f'There is no node with ID {nodeID}')
176
+ return None
164
177
 
165
178
 
166
179
 
midas_civil/_result.py CHANGED
@@ -111,7 +111,7 @@ class LoadCombination:
111
111
  @classmethod
112
112
  def create(cls, classification = "All"):
113
113
  if len(LoadCombination.data) == 0:
114
- print("No Load Combinations defined! Define the load combination using the 'LoadCombination' class before creating these in the model.")
114
+ # print("No Load Combinations defined! Define the load combination using the 'LoadCombination' class before creating these in the model.")
115
115
  return
116
116
  if classification not in LoadCombination.valid:
117
117
  print(f'"{classification}" is not a valid input. It is changed to "General".')
midas_civil/_section.py CHANGED
@@ -732,8 +732,142 @@ class Section:
732
732
  _SectionADD(self)
733
733
 
734
734
 
735
+ #=======================================================Tapered Group===========================================
735
736
 
736
-
737
+ class TaperedGroup:
738
+
739
+ data = []
740
+
741
+ def __init__(self, name, elem_list, z_var, y_var, z_exp=None, z_from=None, z_dist=None,
742
+ y_exp=None, y_from=None, y_dist=None, id=""):
743
+ """
744
+ Args:
745
+ name (str): Tapered Group Name (Required).
746
+ elem_list (list): List of element numbers (Required).
747
+ z_var (str): Section shape variation for Z-axis: "LINEAR" or "POLY" (Required).
748
+ y_var (str): Section shape variation for Y-axis: "LINEAR" or "POLY" (Required).
749
+ z_exp (float, optional): Z-axis exponent. Required if z_var is "POLY".
750
+ z_from (str, optional): Z-axis symmetric plane ("i" or "j"). Defaults to "i" for "POLY".
751
+ z_dist (float, optional): Z-axis symmetric plane distance. Defaults to 0 for "POLY".
752
+ y_exp (float, optional): Y-axis exponent. Required if y_var is "POLY".
753
+ y_from (str, optional): Y-axis symmetric plane ("i" or "j"). Defaults to "i" for "POLY".
754
+ y_dist (float, optional): Y-axis symmetric plane distance. Defaults to 0 for "POLY".
755
+ id (str, optional): ID for the tapered group. Auto-generated if not provided.
737
756
 
738
-
739
-
757
+ Example:
758
+ Section.TapperGroup("Linear", [1, 2, 3], "LINEAR", "LINEAR")
759
+ Section.TapperGroup("ZPoly", [4, 5], "POLY", "LINEAR", z_exp=2.5)
760
+ """
761
+ self.NAME = name
762
+ self.ELEM_LIST = elem_list
763
+ self.Z_VAR = z_var
764
+ self.Y_VAR = y_var
765
+
766
+ # Z-axis parameters (only for POLY)
767
+ if z_var == "POLY":
768
+ if z_exp is None:
769
+ raise ValueError("z_exp is required when z_var is 'POLY'")
770
+ self.Z_EXP = z_exp
771
+ self.Z_FROM = z_from if z_from is not None else "i"
772
+ self.Z_DIST = z_dist if z_dist is not None else 0
773
+ else:
774
+ self.Z_EXP = None
775
+ self.Z_FROM = None
776
+ self.Z_DIST = None
777
+
778
+ # Y-axis parameters (only for POLY)
779
+ if y_var == "POLY":
780
+ if y_exp is None:
781
+ raise ValueError("y_exp is required when y_var is 'POLY'")
782
+ self.Y_EXP = y_exp
783
+ self.Y_FROM = y_from if y_from is not None else "i"
784
+ self.Y_DIST = y_dist if y_dist is not None else 0
785
+ else:
786
+ self.Y_EXP = None
787
+ self.Y_FROM = None
788
+ self.Y_DIST = None
789
+
790
+ if id == "":
791
+ id = len(Section.TaperedGroup.data) + 1
792
+ self.ID = id
793
+
794
+ Section.TaperedGroup.data.append(self)
795
+
796
+ @classmethod
797
+ def json(cls):
798
+ json_data = {"Assign": {}}
799
+ for i in cls.data:
800
+ # Base data that's always included
801
+ tapper_data = {
802
+ "NAME": i.NAME,
803
+ "ELEMLIST": i.ELEM_LIST,
804
+ "ZVAR": i.Z_VAR,
805
+ "YVAR": i.Y_VAR
806
+ }
807
+
808
+ # Add Z-axis polynomial parameters only if Z_VAR is "POLY"
809
+ if i.Z_VAR == "POLY":
810
+ tapper_data["ZEXP"] = i.Z_EXP
811
+ tapper_data["ZFROM"] = i.Z_FROM
812
+ tapper_data["ZDIST"] = i.Z_DIST
813
+
814
+ # Add Y-axis polynomial parameters only if Y_VAR is "POLY"
815
+ if i.Y_VAR == "POLY":
816
+ tapper_data["YEXP"] = i.Y_EXP
817
+ tapper_data["YFROM"] = i.Y_FROM
818
+ tapper_data["YDIST"] = i.Y_DIST
819
+
820
+ json_data["Assign"][str(i.ID)] = tapper_data
821
+
822
+ return json_data
823
+
824
+ @classmethod
825
+ def create(cls):
826
+ MidasAPI("PUT", "/db/tsgr", cls.json())
827
+
828
+ @classmethod
829
+ def get(cls):
830
+ return MidasAPI("GET", "/db/tsgr")
831
+
832
+ @classmethod
833
+ def delete(cls):
834
+ cls.data = []
835
+ return MidasAPI("DELETE", "/db/tsgr")
836
+
837
+ @classmethod
838
+ def sync(cls):
839
+ cls.data = []
840
+ response = cls.get()
841
+
842
+ if response and response != {'message': ''}:
843
+ tsgr_data = response.get('TSGR', {})
844
+ # Iterate through the dictionary of tapered groups from the API response
845
+ for tsgr_id, item_data in tsgr_data.items():
846
+ # Extract base parameters
847
+ name = item_data.get('NAME')
848
+ elem_list = item_data.get('ELEMLIST')
849
+ z_var = item_data.get('ZVAR')
850
+ y_var = item_data.get('YVAR')
851
+
852
+ # Extract optional parameters based on variation type
853
+ z_exp = item_data.get('ZEXP') if z_var == "POLY" else None
854
+ z_from = item_data.get('ZFROM') if z_var == "POLY" else None
855
+ z_dist = item_data.get('ZDIST') if z_var == "POLY" else None
856
+
857
+ y_exp = item_data.get('YEXP') if y_var == "POLY" else None
858
+ y_from = item_data.get('YFROM') if y_var == "POLY" else None
859
+ y_dist = item_data.get('YDIST') if y_var == "POLY" else None
860
+
861
+ Section.TaperedGroup(
862
+ name=name,
863
+ elem_list=elem_list,
864
+ z_var=z_var,
865
+ y_var=y_var,
866
+ z_exp=z_exp,
867
+ z_from=z_from,
868
+ z_dist=z_dist,
869
+ y_exp=y_exp,
870
+ y_from=y_from,
871
+ y_dist=y_dist,
872
+ id=tsgr_id
873
+ )
midas_civil/_tendon.py CHANGED
@@ -668,6 +668,7 @@ class Tendon:
668
668
  self.R = R_spline3d
669
669
  self.RADIUS = R_round3d
670
670
 
671
+
671
672
 
672
673
  #----- 2D Profile Spline (only)-------------
673
674
  xy_loc = []
@@ -703,7 +704,25 @@ class Tendon:
703
704
  Tendon.Profile.profiles.append(self)
704
705
  Tendon.Profile.ids.append(self.ID)
705
706
 
707
+ def update_profile(self,points_xyz):
708
+ xyz_loc = []
709
+ bFix = []
710
+ R_spline3d = []
711
+ R_round3d = []
706
712
 
713
+ for point in points_xyz:
714
+ xyz_loc.append(_POINT_(point[0],point[1],point[2]))
715
+ bFix.append(False) # Default not defining here
716
+ R_spline3d.append([0,0]) # Default not defining here
717
+
718
+ self.P_XYZ = xyz_loc
719
+ self.INPUT = '3D'
720
+ self.CURVE = 'SPLINE'
721
+ self.SHAPE = 'STRAIGHT'
722
+
723
+ self.bFIX = bFix
724
+ self.R = R_spline3d
725
+ self.RADIUS = R_round3d
707
726
 
708
727
  @classmethod
709
728
  def json(cls):
midas_civil/_view.py CHANGED
@@ -6,6 +6,11 @@ from ._model import *
6
6
  class View:
7
7
 
8
8
  def Capture(location="D:\\API_temp\\img3.jpg",img_w = 1280 , img_h = 720,view='',stage:str=''):
9
+ ''' Location - image location
10
+ Image height and width
11
+ View - 'pre' or 'post'
12
+ stage - CS name
13
+ '''
9
14
  json_body = {
10
15
  "Argument": {
11
16
  "EXPORT_PATH": location,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: midas_civil
3
- Version: 0.1.5
3
+ Version: 0.1.6
4
4
  Summary: Python library for MIDAS Civil NX
5
5
  Author: Sumit Shekhar
6
6
  Author-email: sumit.midasit@gmail.com
@@ -0,0 +1,27 @@
1
+ midas_civil/__init__.py,sha256=t0XkmZiEBYodUkU2gJWLQmqrpQdZc8ikPM3Z0xrSVPg,575
2
+ midas_civil/_boundary.py,sha256=s5mgZIc1b0-P7AdWuaPAQ5cIbHL5CR1YRKJA7KE4W_U,32958
3
+ midas_civil/_construction.py,sha256=EqpJ46w4dqtlmk8dy9ChQq2cF-R2duXcgmpJy4cWLz0,19965
4
+ midas_civil/_construction_backup.py,sha256=Pj7V-NYCkkT-aMjKXfs1jKa9klsGh48UXDLwn3BLYTY,18225
5
+ midas_civil/_element.py,sha256=4IjJSlsXMr2llv7gC66KBxPoikt9rWbwGBePMaH9gYg,26935
6
+ midas_civil/_group.py,sha256=9EsPGW8lWpzJBW25Gfd-G5S_9oP8ER3zNzeqknDsfmw,11480
7
+ midas_civil/_load.py,sha256=4D4Ici2ghyK1KGNXb7oCl6ylOLwnPhFBeazR3_yJBZo,30346
8
+ midas_civil/_mapi.py,sha256=oYYfWe3FIFWlMZEpuiIMJQhl42l1rzz2M1rY8-4DQ94,2930
9
+ midas_civil/_material.py,sha256=uJEIHJM9OhwTRWUI2mtd_0BQSxdlYhATYJu9P7tNNBA,69511
10
+ midas_civil/_model.py,sha256=G5Kh7u2DSodvKGQ0fOzAUx4Ilj8-rn-nGDTFeI6AkUU,16442
11
+ midas_civil/_movingload.py,sha256=_XgERsk5tkTx4u1vhe23kdz0xNr41X2tRaiyNaFNt84,79999
12
+ midas_civil/_node.py,sha256=wRttDbebQWT6aZWeNd72AgzVWUETyNzMng5kJQmV3WM,4760
13
+ midas_civil/_result copy.py,sha256=siTMENLIwF_6rvydSjP9aQAWaIlt0pReiqNyDhDevGk,24290
14
+ midas_civil/_result.py,sha256=ZJf2CQG2ZjlTKuWo3zBnG7W8EwI1UkhWhWJVWRzlXUU,7640
15
+ midas_civil/_result_extract.py,sha256=J-9eeWDbFeaDL-C41TAynYuooiHYsayAe3WbfGRO8sM,5537
16
+ midas_civil/_section.py,sha256=zhUkiIaRI9DqYHAdpmQvhFpg6SuTgAM7xPEz-3Wingg,32390
17
+ midas_civil/_settlement.py,sha256=U7lJYBqGbuCv7qziEEznDyA4M_SCjJeIjc0lDeGfE4Y,5125
18
+ midas_civil/_temperature.py,sha256=KDY_gG5PZ3SvTk824Z7LD3Ku856RKzkw3p_Zy-cp30c,23400
19
+ midas_civil/_tendon.py,sha256=qfkcRAZ8MKe36xCec4Nr5TQ17_zDCk2TMW4T5lc85e0,33308
20
+ midas_civil/_thickness.py,sha256=4xQsLA3Q_gIGCwLc_glFmiErdWdQUSwhlEhJ_IPJseA,3248
21
+ midas_civil/_utils.py,sha256=eymiqO8KaTKdhVY3saebqNS0BbUUmGmgw3-ELKqew0A,2611
22
+ midas_civil/_view.py,sha256=o7rkfoQzmgAb3dT0ujPIQLVwVlveo3rMRIbZU1UosZo,849
23
+ midas_civil-0.1.6.dist-info/licenses/LICENSE,sha256=zrL4RwZC4rb-by_ZHKXwKdIwcs6ATy59TPZ9HxPHCrs,1071
24
+ midas_civil-0.1.6.dist-info/METADATA,sha256=Cf0qSp0OPDQ0pqjTaOsWTMxDupKsLS7lNxQEZk1TvPg,1709
25
+ midas_civil-0.1.6.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
26
+ midas_civil-0.1.6.dist-info/top_level.txt,sha256=_NFmrlN5V9OxJ-PAO4s_om8OA8uupXho3QqZcSsnbuI,12
27
+ midas_civil-0.1.6.dist-info/RECORD,,
@@ -1,27 +0,0 @@
1
- midas_civil/__init__.py,sha256=8kl0ZFsGAlXwo7afdLe6XfDq8th42f-jNeGI1p1x7Zc,573
2
- midas_civil/_boundary.py,sha256=zXoVbZfvWnCIrSdN1lvUAj7cgzxzY3-U1-3ejVzwFfE,32701
3
- midas_civil/_construction.py,sha256=EqpJ46w4dqtlmk8dy9ChQq2cF-R2duXcgmpJy4cWLz0,19965
4
- midas_civil/_construction_backup.py,sha256=Pj7V-NYCkkT-aMjKXfs1jKa9klsGh48UXDLwn3BLYTY,18225
5
- midas_civil/_element.py,sha256=9-JFrh3wyH4zhTBq7ldaIYbteuDRdq-qsUH9o8BnATs,19876
6
- midas_civil/_group.py,sha256=QpZFt0CnPGO_GHp496oiYjga-5mMtcCSZed75PiNIj0,11342
7
- midas_civil/_load.py,sha256=Wg2Cyn7meaCkb28vQSxWi1H1slBQKXdXyoKPGvsHesQ,29557
8
- midas_civil/_mapi.py,sha256=oYYfWe3FIFWlMZEpuiIMJQhl42l1rzz2M1rY8-4DQ94,2930
9
- midas_civil/_material.py,sha256=uJEIHJM9OhwTRWUI2mtd_0BQSxdlYhATYJu9P7tNNBA,69511
10
- midas_civil/_model.py,sha256=t8wcnu6XlbZ0rFE79jCXuP8mI7Fvpi5mbsXNiRUzpIg,16385
11
- midas_civil/_movingload.py,sha256=_XgERsk5tkTx4u1vhe23kdz0xNr41X2tRaiyNaFNt84,79999
12
- midas_civil/_node.py,sha256=mwKywpDXBLW22oVA3p1fkIWR1mCyE0MRiLi3cERlIqg,4411
13
- midas_civil/_result copy.py,sha256=siTMENLIwF_6rvydSjP9aQAWaIlt0pReiqNyDhDevGk,24290
14
- midas_civil/_result.py,sha256=oRVNbbtAwz_8s4zD0UcL7vi6bs6xHHr3SsTgerZNDAY,7638
15
- midas_civil/_result_extract.py,sha256=J-9eeWDbFeaDL-C41TAynYuooiHYsayAe3WbfGRO8sM,5537
16
- midas_civil/_section.py,sha256=56RWJdyvDr7Es7Is8Fxq3jPCPP57WW8ECCYZzhm6bf0,26375
17
- midas_civil/_settlement.py,sha256=U7lJYBqGbuCv7qziEEznDyA4M_SCjJeIjc0lDeGfE4Y,5125
18
- midas_civil/_temperature.py,sha256=KDY_gG5PZ3SvTk824Z7LD3Ku856RKzkw3p_Zy-cp30c,23400
19
- midas_civil/_tendon.py,sha256=xMZRPbE3CcYG6OgkfUCslHd2pzUte2grQ9XREH9jcQc,32677
20
- midas_civil/_thickness.py,sha256=4xQsLA3Q_gIGCwLc_glFmiErdWdQUSwhlEhJ_IPJseA,3248
21
- midas_civil/_utils.py,sha256=eymiqO8KaTKdhVY3saebqNS0BbUUmGmgw3-ELKqew0A,2611
22
- midas_civil/_view.py,sha256=68gfsyN6QJ2B5CopNVlP3MQ-833MxfrVWz7p_hMdm4c,701
23
- midas_civil-0.1.5.dist-info/licenses/LICENSE,sha256=zrL4RwZC4rb-by_ZHKXwKdIwcs6ATy59TPZ9HxPHCrs,1071
24
- midas_civil-0.1.5.dist-info/METADATA,sha256=R8p-c_trOMCbZgDbim6cDUfw1HbJ3AuOi5UpSecNfXQ,1709
25
- midas_civil-0.1.5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
26
- midas_civil-0.1.5.dist-info/top_level.txt,sha256=_NFmrlN5V9OxJ-PAO4s_om8OA8uupXho3QqZcSsnbuI,12
27
- midas_civil-0.1.5.dist-info/RECORD,,