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.
Files changed (40) hide show
  1. midas_civil/_BoundaryChangeAssignment.py +278 -0
  2. midas_civil/__init__.py +51 -0
  3. midas_civil/_analysiscontrol.py +585 -0
  4. midas_civil/_boundary.py +888 -0
  5. midas_civil/_construction.py +1004 -0
  6. midas_civil/_element.py +1346 -0
  7. midas_civil/_group.py +337 -0
  8. midas_civil/_load.py +967 -0
  9. midas_civil/_loadcomb.py +159 -0
  10. midas_civil/_mapi.py +249 -0
  11. midas_civil/_material.py +1692 -0
  12. midas_civil/_model.py +522 -0
  13. midas_civil/_movingload.py +1479 -0
  14. midas_civil/_node.py +532 -0
  15. midas_civil/_result_table.py +929 -0
  16. midas_civil/_result_test.py +5455 -0
  17. midas_civil/_section/_TapdbSecSS.py +175 -0
  18. midas_civil/_section/__init__.py +413 -0
  19. midas_civil/_section/_compositeSS.py +283 -0
  20. midas_civil/_section/_dbSecSS.py +164 -0
  21. midas_civil/_section/_offsetSS.py +53 -0
  22. midas_civil/_section/_pscSS copy.py +455 -0
  23. midas_civil/_section/_pscSS.py +822 -0
  24. midas_civil/_section/_tapPSC12CellSS.py +565 -0
  25. midas_civil/_section/_unSupp.py +58 -0
  26. midas_civil/_settlement.py +161 -0
  27. midas_civil/_temperature.py +677 -0
  28. midas_civil/_tendon.py +1016 -0
  29. midas_civil/_thickness.py +147 -0
  30. midas_civil/_utils.py +529 -0
  31. midas_civil/_utilsFunc/__init__.py +0 -0
  32. midas_civil/_utilsFunc/_line2plate.py +636 -0
  33. midas_civil/_view.py +891 -0
  34. midas_civil/_view_trial.py +430 -0
  35. midas_civil/_visualise.py +347 -0
  36. midas_civil-1.4.1.dist-info/METADATA +74 -0
  37. midas_civil-1.4.1.dist-info/RECORD +40 -0
  38. midas_civil-1.4.1.dist-info/WHEEL +5 -0
  39. midas_civil-1.4.1.dist-info/licenses/LICENSE +21 -0
  40. midas_civil-1.4.1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,929 @@
1
+
2
+ from ._mapi import MidasAPI
3
+ from ._model import Model
4
+ from typing import Literal
5
+ from ._mapi import _getUNIT
6
+ from ._mapi import _setUNIT
7
+ # js_file = open('JSON_Excel Parsing\\test.json','r')
8
+
9
+ # print(js_file)
10
+ # js_json = json.load(js_file)
11
+
12
+ _forceType = Literal["KN", "N", "KGF", "TONF", "LBF", "KIPS"]
13
+ _lengthType = Literal["M", "CM", "MM", "FT", "IN"]
14
+ _numFormat = Literal["Fixed","Scientific","General"]
15
+ _resTable = Literal["REACTIONG","REACTIONL","DISPLACEMENTG","DISPLACEMENTL","TRUSSFORCE","TRUSSSTRESS"]
16
+
17
+ _reactionType = Literal["Global", "Local", "SurfaceSpring"]
18
+ _dispdiaType = Literal["Global", "Local"]
19
+ _dispType = Literal["Accumulative", "Current", "Real"]
20
+ _plateforce = Literal["Global", "Local"]
21
+
22
+ #---- INPUT: JSON -> OUTPUT : Data FRAME --------- ---------
23
+ def _JSToDF_ResTable(js_json,excelLoc,sheetName,cellLoc="A1"):
24
+ # Check for SS_Table existence
25
+ import polars as pl
26
+ if "SS_Table" not in js_json:
27
+ if 'message' in js_json:
28
+ print(f'⚠️ Error from API: {js_json["message"]}')
29
+ else:
30
+ print('⚠️ Error: "SS_Table" not found in the response JSON.')
31
+ return pl.DataFrame() # Return empty DataFrame on error
32
+
33
+ res_json = {}
34
+ c=0
35
+
36
+ # Check for HEAD and DATA existence
37
+ if "HEAD" not in js_json["SS_Table"] or "DATA" not in js_json["SS_Table"]:
38
+ print('⚠️ Error: "HEAD" or "DATA" not found in "SS_Table".')
39
+ return pl.DataFrame() # Return empty DataFrame
40
+
41
+ for heading in js_json["SS_Table"]["HEAD"]:
42
+ for dat in js_json["SS_Table"]["DATA"]:
43
+ try:
44
+ res_json[heading].append(dat[c])
45
+ except:
46
+ res_json[heading]=[]
47
+ res_json[heading].append(dat[c])
48
+
49
+ c+=1
50
+
51
+ res_df = pl.DataFrame(res_json) # Final DF
52
+
53
+
54
+ # EXPORTING FILE STARTS HERE................
55
+ if excelLoc:
56
+ _write_df_to_existing_excel(res_df,(excelLoc,sheetName, cellLoc))
57
+
58
+ return(res_df)
59
+
60
+
61
+ def _Head_Data_2_DF_JSON(head,data):
62
+ res_json = {}
63
+ c=0
64
+ headers = []
65
+ for heading in head:
66
+ if heading not in headers:
67
+ headers.append(heading)
68
+ elif f"{heading}_2" not in headers:
69
+ headers.append(f"{heading}_2")
70
+ elif f"{heading}_3" not in headers:
71
+ headers.append(f"{heading}_3")
72
+ elif f"{heading}_4" not in headers:
73
+ headers.append(f"{heading}_4") # Upto 4 repeated column names | Manually handled here
74
+
75
+ for heading in headers:
76
+ for dat in data:
77
+ try:
78
+ res_json[heading].append(dat[c])
79
+ except:
80
+ res_json[heading]=[]
81
+ res_json[heading].append(dat[c])
82
+
83
+ c+=1
84
+ return res_json
85
+
86
+
87
+ def _JSToDF_UserDefined(tableName,js_json,summary,excelLoc,sheetName,cellLoc="A1"):
88
+ import polars as pl
89
+ if 'message' in js_json:
90
+ print(f'⚠️ {tableName} table name does not exist.')
91
+ Result.TABLE.UserDefinedTables_list()
92
+ return 'Check table name'
93
+
94
+ if tableName not in js_json:
95
+ print(f'⚠️ Error: Table "{tableName}" not found in API response.')
96
+ return 'Check table name'
97
+
98
+ if summary == 0:
99
+ head = js_json[tableName]["HEAD"]
100
+ data = js_json[tableName]["DATA"]
101
+ elif summary > 0 :
102
+ try :
103
+ sub_tab1 = js_json[tableName]["SUB_TABLES"][summary-1]
104
+ key_name = next(iter(sub_tab1))
105
+ head = sub_tab1[key_name]["HEAD"]
106
+ data = sub_tab1[key_name]["DATA"]
107
+ except :
108
+ print(' ⚠️ No Summary table exist')
109
+ return 'No Summary table exist'
110
+
111
+
112
+ res_json = _Head_Data_2_DF_JSON(head,data)
113
+ res_df = pl.DataFrame(res_json)
114
+
115
+ if excelLoc:
116
+ _write_df_to_existing_excel(res_df,(excelLoc,sheetName, cellLoc))
117
+
118
+ return(res_df)
119
+
120
+
121
+ def _write_df_to_existing_excel(res_df, existing_excel_input: list):
122
+ """
123
+ Writes a Polars DataFrame to an existing Excel file at a specific sheet and cell.
124
+ Uses openpyxl to modify the existing file.
125
+ """
126
+ import openpyxl
127
+ from openpyxl.utils import column_index_from_string
128
+ from openpyxl.styles import Font,PatternFill,Border,Side
129
+
130
+
131
+ try:
132
+ excel_path, sheet_name, start_cell = existing_excel_input
133
+ if not all([excel_path, sheet_name, start_cell]):
134
+ print("⚠️ `existing_excel_input` has empty values. Skipping update.")
135
+ return
136
+
137
+ # Load workbook
138
+ try:
139
+ wb = openpyxl.load_workbook(excel_path)
140
+ # FILE EXISTS -> OVERWRITE
141
+ except:
142
+ # CREATE A NEW FILE
143
+ wb = openpyxl.Workbook()
144
+ ws = wb.active
145
+ ws.title = sheet_name
146
+
147
+
148
+
149
+ # Get sheet
150
+ if sheet_name in wb.sheetnames:
151
+ ws = wb[sheet_name]
152
+ else:
153
+ print(f" ⚠️ Sheet '{sheet_name}' not found in {excel_path}. Creating new sheet.")
154
+ ws = wb.create_sheet(sheet_name)
155
+
156
+ # Find start row and column from cell_name (e.g., "A1")
157
+ if start_cell == "end":
158
+ nRow = ws.max_row
159
+ if nRow == 1 : nRow = -1
160
+ start_row_str = nRow+2
161
+ start_col = ws.min_column
162
+ else:
163
+ start_col_let = ''.join(filter(str.isalpha, start_cell))
164
+ start_row_str = ''.join(filter(str.isdigit, start_cell))
165
+ start_col = column_index_from_string(start_col_let)
166
+
167
+ start_row = int(start_row_str)
168
+
169
+
170
+ header_font = Font(bold=True, color="FFFFFF")
171
+ header_fill = PatternFill(fill_type="solid", fgColor="000000")
172
+
173
+ thin = Side(style="thin")
174
+
175
+
176
+
177
+ # Write header
178
+ headers = res_df.columns
179
+ for c_idx, header in enumerate(headers):
180
+ cell = ws.cell(row=start_row, column=start_col + c_idx, value=header)
181
+ cell.font = header_font
182
+ cell.fill = header_fill
183
+
184
+
185
+ # Write data rows
186
+ for r_idx, row_data in enumerate(res_df.rows()):
187
+ for c_idx, cell_value in enumerate(row_data):
188
+ cell = ws.cell(row=start_row + 1 + r_idx, column=start_col + c_idx, value=cell_value)
189
+ cell.border = Border(bottom=thin)
190
+
191
+ # Save the workbook
192
+ wb.save(excel_path)
193
+ wb.close()
194
+ print(f" ✅ Updated excel file: {excel_path} | Sheet: {sheet_name} | Cell: {start_cell} |")
195
+
196
+ except Exception as e:
197
+ print(f"⚠️ Error writing to existing Excel file: {e}")
198
+
199
+ def _changeUNITandGetData(js_dat,force_unit,len_unit,jsonloc,keyName):
200
+ # currUNIT = _getUNIT()
201
+ Model.units(force=force_unit,length=len_unit)
202
+ ss_json = MidasAPI("POST","/post/table",js_dat)
203
+ # _setUNIT(currUNIT)
204
+ if jsonloc:
205
+ if "SS_Table" in ss_json:
206
+ ss_json[keyName] = ss_json.pop("SS_Table")
207
+ _saveJSON(ss_json,jsonloc)
208
+ ss_json["SS_Table"] = ss_json.pop(keyName)
209
+ else:
210
+ _saveJSON(ss_json,jsonloc)
211
+ return ss_json
212
+
213
+
214
+ def _keys2JSON(keys):
215
+ if isinstance(keys,list):
216
+ if keys!=[]:
217
+ out_js = {"KEYS": keys}
218
+ elif isinstance(keys,str):
219
+ out_js = {"STRUCTURE_GROUP_NAME": keys}
220
+ return out_js
221
+
222
+
223
+ def _saveJSON(jsonData,fileLocation = "jsData.json"):
224
+ import json
225
+ with open(fileLocation, "w", encoding="utf-8") as f:
226
+ json.dump(jsonData, f, indent=4, ensure_ascii=False)
227
+
228
+
229
+ def _case2name(s):
230
+ if isinstance(s,str):
231
+ return f'{s.split("(")[0]} LCase'
232
+ if isinstance(s,list):
233
+ n = len(s)
234
+ if n==0:
235
+ return f"Table"
236
+ return f"{n} LCases"
237
+
238
+ def _generate(table_type,keys,loadcase,components,cs_stage,options):
239
+ js_dat = {
240
+ "Argument": {
241
+ "TABLE_NAME": "SS_Table",
242
+ "TABLE_TYPE": table_type,
243
+ "STYLES": options.Style,
244
+ }
245
+ }
246
+
247
+ if keys: js_dat["Argument"]['NODE_ELEMS'] = _keys2JSON(keys)
248
+ if loadcase: js_dat["Argument"]['LOAD_CASE_NAMES'] = loadcase
249
+ if components != ['all']: js_dat["Argument"]['COMPONENTS'] = components
250
+
251
+ if cs_stage !=[]:
252
+ if cs_stage == 'all' or cs_stage == ['all']:
253
+ js_dat["Argument"]['OPT_CS'] = True
254
+ else:
255
+ js_dat["Argument"]['OPT_CS'] = True
256
+ js_dat["Argument"]['STAGE_STEP'] = cs_stage
257
+
258
+ return js_dat
259
+
260
+ class TableOptions:
261
+ FORCE_UNIT = 'KN'
262
+ LEN_UNIT = 'M'
263
+ NUM_FORMAT = 'Fixed'
264
+ DECIMAL_PLACE = 5
265
+ # JSON_OUTPUT_LOC = None
266
+ EXCEL_FILE_LOC = None
267
+ EXCEL_SHEET_NAME = None
268
+ EXCEL_CELL_POS = "end"
269
+
270
+ def __init__(self,force_unit:_forceType=None,len_unit:_lengthType=None,num_format:_numFormat=None,decimal_place:int=None,
271
+ JSONFileLoc=None,ExcelFileLoc=None , ExcelSheetName = None,ExcelCellPos = None):
272
+
273
+ # existing_excel_input -> excel file , sheet , cell
274
+
275
+ '''
276
+ Table Options
277
+
278
+ :param force_unit: Enter force unit - "KN", "N", "KGF", "TONF", "LBF", "KIPS"
279
+ :param len_unit: Enter length unit - "M", "CM", "MM", "FT", "IN"
280
+ :param num_format: Enter number format - "Fixed","Scientific","General"
281
+ :param decimal_place: Number of decimal places for result output
282
+ '''
283
+ self.FORCE_UNIT = force_unit or TableOptions.FORCE_UNIT
284
+ self.LEN_UNIT = len_unit or TableOptions.LEN_UNIT
285
+ self.NUM_FORMAT = num_format or TableOptions.NUM_FORMAT
286
+ self.DECIMAL_PLACE = decimal_place or TableOptions.DECIMAL_PLACE
287
+ # self.JSON_OUTPUT_LOC = JSONLoc or TableOptions.JSON_OUTPUT_LOC
288
+ self.JSON_FILE_LOC = JSONFileLoc
289
+ self.EXCEL_FILE_LOC = ExcelFileLoc or TableOptions.EXCEL_FILE_LOC
290
+ self.EXCEL_SHEET_NAME = ExcelSheetName or TableOptions.EXCEL_SHEET_NAME
291
+ self.EXCEL_CELL_POS = ExcelCellPos or TableOptions.EXCEL_CELL_POS
292
+
293
+ @property
294
+ def Style(self):
295
+ '''rrr'''
296
+ if self.NUM_FORMAT == 'Fixed':
297
+ js = {"FORMAT" : "Fixed" , "PLACE":self.DECIMAL_PLACE}
298
+ else:
299
+ js = {"FORMAT" : self.NUM_FORMAT}
300
+ return js
301
+
302
+ @property
303
+ def Unit(self):
304
+ ''' rr '''
305
+ return {"FORCE": self.FORCE_UNIT, "DIST": self.LEN_UNIT }
306
+
307
+
308
+ def __str__(self):
309
+ return str(self.__dict__)
310
+
311
+ class Result :
312
+
313
+ # ---------- Result TABLE (For ALL TABLES)------------------------------
314
+
315
+ class TABLE :
316
+ '''
317
+ Extracts tabular result from MIDAS CIVIL NX
318
+ '''
319
+
320
+ def __new__(cls,tabletype:_resTable,keys=[],loadcase:list=[],cs_stage=[],options:TableOptions=None):
321
+ '''
322
+ TableType : REACTIONG | REACTIONL | DISPLACEMENTG | DISPLACEMENTL | TRUSSFORCE | TRUSSSTRESS
323
+ Keys : List{int} -> Element/ Node IDs | str -> Structure Group Name
324
+ Loadcase : Loadcase/Combination name followed by type. eg. DeadLoad(ST)
325
+ '''
326
+ instance = super().__new__(cls)
327
+ return instance._dispatch(tabletype, keys,loadcase,cs_stage,options)
328
+
329
+ @classmethod
330
+ def _dispatch(cls,tabletype, keys,loadcase,cs_stage,options):
331
+ if options == None : options = TableOptions()
332
+ sheetName = options.EXCEL_SHEET_NAME or f"{tabletype} {_case2name(loadcase)}"
333
+
334
+ js_dat = _generate(tabletype,keys,loadcase,[],cs_stage,options)
335
+
336
+ ResultJSON = _changeUNITandGetData(js_dat,options.FORCE_UNIT,options.LEN_UNIT,options.JSON_FILE_LOC,tabletype)
337
+ polarDF = _JSToDF_ResTable(ResultJSON,options.EXCEL_FILE_LOC,sheetName,options.EXCEL_CELL_POS)
338
+ return polarDF
339
+
340
+ # ---------- User defined TABLE (Dynamic Report Table) ------------------------------
341
+ @staticmethod
342
+ def UserDefinedTable(tableName:str, summary=0,options:TableOptions=None):
343
+ if options == None : options = TableOptions()
344
+ sheetName = options.EXCEL_SHEET_NAME or f"{tableName} Table"
345
+ js_dat = {
346
+ "Argument": {
347
+ "TABLE_NAME": tableName,
348
+ "STYLES": options.Style
349
+ }
350
+ }
351
+
352
+
353
+
354
+ ResultJSON = _changeUNITandGetData(js_dat,options.FORCE_UNIT,options.LEN_UNIT,options.JSON_FILE_LOC,tableName)
355
+ polarDF = _JSToDF_UserDefined(tableName,ResultJSON,summary,options.EXCEL_FILE_LOC,sheetName,options.EXCEL_CELL_POS)
356
+ return polarDF
357
+
358
+
359
+ # ---------- LIST ALL USER DEFINED TABLE ------------------------------
360
+ @staticmethod
361
+ def UserDefinedTables_list():
362
+ ''' Print all the User defined table names '''
363
+ ss_json = MidasAPI("GET","/ope/UTBLTYPES",{})
364
+ table_name =[]
365
+ try:
366
+ for tabName in ss_json['UTBLTYPES']:
367
+ table_name.append(tabName)
368
+
369
+ print('Available user-defined tables in Civil NX are : ')
370
+ print(*table_name,sep=' , ')
371
+ except:
372
+ print(' ⚠️ There are no user-defined tables in Civil NX')
373
+
374
+ return table_name
375
+
376
+ @staticmethod
377
+ def Reaction(keys=[], loadcase:list=[], components=['all'],
378
+ cs_stage=[],
379
+ type:_reactionType="Global",options:TableOptions= None):
380
+ '''
381
+ Fetches Reaction result tables (Global, Local, or Surface Spring).
382
+
383
+ Args:
384
+ keys (list/str): List of Node IDs or a Structure Group Name.
385
+ loadcase (list): List of load case names, e.g., ["DL(ST)"].
386
+ components (list): Table components to include. Defaults to ['all'].
387
+ cs_stage (list/str): Construction Stage options.
388
+ type (str): Reaction type. "Global", "Local", or "SurfaceSpring"
389
+ options : table option
390
+ '''
391
+ if options == None : options = TableOptions()
392
+ sheetName = options.EXCEL_SHEET_NAME or f"Reaction {_case2name(loadcase)}"
393
+
394
+ table_type_map = {
395
+ "Global": "REACTIONG",
396
+ "Local": "REACTIONL",
397
+ "SurfaceSpring": "REACTIONLSURFACESPRING"
398
+ }
399
+ table_type = table_type_map.get(type.capitalize(), "REACTIONG") # Default to Global
400
+ js_dat = _generate(table_type,keys,loadcase,components,cs_stage,options)
401
+
402
+ ResultJSON = _changeUNITandGetData(js_dat,options.FORCE_UNIT,options.LEN_UNIT,options.JSON_FILE_LOC,table_type)
403
+ polarDF = _JSToDF_ResTable(ResultJSON,options.EXCEL_FILE_LOC,sheetName,options.EXCEL_CELL_POS)
404
+ return polarDF
405
+
406
+ @staticmethod
407
+ def Displacement(keys=[], loadcase:list=[], components=['all'],
408
+ cs_stage=[],
409
+ type:_dispdiaType ="Global",
410
+ displacement_type:_dispType="Accumulative",
411
+ options:TableOptions=None):
412
+ '''
413
+ Fetches Displacement result tables (Global or Local).
414
+
415
+ Args:
416
+ keys (list/str): List of Node IDs or a Structure Group Name.
417
+ loadcase (list): List of load case names, e.g., ["Self(ST)"].
418
+ components (list): Table components to include. Defaults to ['all'].
419
+ cs_stage (list/str): Construction Stage options.
420
+ type (str): Displacement type. "Global" or "Local".
421
+ displacement_type (str): "Accumulative", "Current", or "Real".
422
+ options : Table options
423
+ '''
424
+ if options == None : options = TableOptions()
425
+ sheetName = options.EXCEL_SHEET_NAME or f"Displacement {_case2name(loadcase)}"
426
+
427
+ table_type_map = {
428
+ "Global": "DISPLACEMENTG",
429
+ "Local": "DISPLACEMENTL"
430
+ }
431
+ table_type = table_type_map.get(type.capitalize(), "DISPLACEMENTG")
432
+
433
+ js_dat = _generate(table_type,keys,loadcase,components,cs_stage,options)
434
+
435
+ if displacement_type in ["Accumulative", "Current", "Real"]:
436
+ js_dat["Argument"]["DISP_OPT"] = displacement_type
437
+
438
+ ResultJSON = _changeUNITandGetData(js_dat,options.FORCE_UNIT,options.LEN_UNIT,options.JSON_FILE_LOC,table_type)
439
+ polarDF = _JSToDF_ResTable(ResultJSON,options.EXCEL_FILE_LOC,sheetName,options.EXCEL_CELL_POS)
440
+ return polarDF
441
+
442
+ @staticmethod
443
+ def TrussForce(keys=[], loadcase:list=[], components=['all'],
444
+ cs_stage=[], options:TableOptions=None):
445
+ '''
446
+ Fetches Truss Force result tables.
447
+
448
+ Args:
449
+ keys (list/str): List of Element IDs or a Structure Group Name.
450
+ loadcase (list): List of load case names, e.g., ["DL(ST)"].
451
+ components (list): Table components to include. Defaults to ['all'].
452
+ cs_stage (list/str): Construction Stage options.
453
+ options : Table options
454
+ '''
455
+ if options == None: options = TableOptions()
456
+ sheetName = options.EXCEL_SHEET_NAME or f"TrussForce {_case2name(loadcase)}"
457
+
458
+ table_type = "TRUSSFORCE"
459
+
460
+ js_dat = _generate(table_type, keys, loadcase, components, cs_stage, options)
461
+
462
+ ResultJSON = _changeUNITandGetData(js_dat, options.FORCE_UNIT, options.LEN_UNIT, options.JSON_FILE_LOC, table_type)
463
+ polarDF = _JSToDF_ResTable(ResultJSON, options.EXCEL_FILE_LOC, sheetName, options.EXCEL_CELL_POS)
464
+ return polarDF
465
+
466
+ @staticmethod
467
+ def TrussStress(keys=[], loadcase:list=[], components=['all'],
468
+ cs_stage=[], options:TableOptions=None):
469
+ '''
470
+ Fetches Truss Stress result tables.
471
+
472
+ Args:
473
+ keys (list/str): List of Element IDs or a Structure Group Name.
474
+ loadcase (list): List of load case names, e.g., ["DL(ST)"].
475
+ components (list): Table components to include. Defaults to ['all'].
476
+ cs_stage (list/str): Construction Stage options.
477
+ options : Table options
478
+ '''
479
+ if options == None: options = TableOptions()
480
+ sheetName = options.EXCEL_SHEET_NAME or f"TrussStress {_case2name(loadcase)}"
481
+
482
+ table_type = "TRUSSSTRESS"
483
+
484
+ js_dat = _generate(table_type, keys, loadcase, components, cs_stage, options)
485
+
486
+ ResultJSON = _changeUNITandGetData(js_dat, options.FORCE_UNIT, options.LEN_UNIT, options.JSON_FILE_LOC, table_type)
487
+ polarDF = _JSToDF_ResTable(ResultJSON, options.EXCEL_FILE_LOC, sheetName, options.EXCEL_CELL_POS)
488
+ return polarDF
489
+
490
+ @staticmethod
491
+ def BeamForce(keys=[], loadcase:list=[], parts=["PartI", "PartJ"],
492
+ components=['all'], cs_stage=[], options:TableOptions=None):
493
+ '''
494
+ Fetches standard Beam Force result tables.
495
+
496
+ Args:
497
+ keys (list/str): List of Element IDs or a Structure Group Name.
498
+ loadcase (list): List of load case names, e.g., ["Selfweight(ST)"].
499
+ parts (list): Element parts: ["PartI", "Part1/4", "PartJ", etc.].
500
+ components (list): Table components to include. Defaults to ['all'].
501
+ cs_stage (list/str): Construction Stage options.
502
+ options : Table options
503
+ '''
504
+ if options == None: options = TableOptions()
505
+ sheetName = options.EXCEL_SHEET_NAME or f"BeamForce {_case2name(loadcase)}"
506
+
507
+ table_type = "BEAMFORCE"
508
+
509
+ js_dat = _generate(table_type, keys, loadcase, components, cs_stage, options)
510
+
511
+ if parts:
512
+ js_dat["Argument"]["PARTS"] = parts
513
+
514
+ ResultJSON = _changeUNITandGetData(js_dat, options.FORCE_UNIT, options.LEN_UNIT, options.JSON_FILE_LOC, table_type)
515
+ polarDF = _JSToDF_ResTable(ResultJSON, options.EXCEL_FILE_LOC, sheetName, options.EXCEL_CELL_POS)
516
+ return polarDF
517
+
518
+ @staticmethod
519
+ def BeamForce_VBM(keys=[], loadcase:list=[], items=['all'], parts=["PartI", "PartJ"],
520
+ components=['all'], cs_stage=[], options:TableOptions=None):
521
+ '''
522
+ Fetches Beam Force (View by Max Value) result tables.
523
+
524
+ Args:
525
+ keys (list/str): List of Element IDs or a Structure Group Name.
526
+ loadcase (list): List of load case names, e.g., ["STLENV_STR(CB:max)"].
527
+ items (list): Items to display: ["Axial", "Shear-y", "Moment-z", etc.].
528
+ parts (list): Element parts: ["PartI", "Part1/4", "PartJ", etc.].
529
+ components (list): Table components to include. Defaults to ['all'].
530
+ cs_stage (list/str): Construction Stage options.
531
+ options : Table options
532
+ '''
533
+ if options == None: options = TableOptions()
534
+ sheetName = options.EXCEL_SHEET_NAME or f"BeamForceVBM {_case2name(loadcase)}"
535
+
536
+ table_type = "BEAMFORCEVBM"
537
+
538
+ js_dat = _generate(table_type, keys, loadcase, components, cs_stage, options)
539
+
540
+ if parts:
541
+ js_dat["Argument"]["PARTS"] = parts
542
+
543
+ if items != ['all']:
544
+ js_dat["Argument"]['ITEM_TO_DISPLAY'] = items
545
+
546
+ ResultJSON = _changeUNITandGetData(js_dat, options.FORCE_UNIT, options.LEN_UNIT, options.JSON_FILE_LOC, table_type)
547
+ polarDF = _JSToDF_ResTable(ResultJSON, options.EXCEL_FILE_LOC, sheetName, options.EXCEL_CELL_POS)
548
+ return polarDF
549
+
550
+ @staticmethod
551
+ def BeamForce_StaticPrestress(keys=[], loadcase:list=[], parts=["PartI", "PartJ"],
552
+ components=['all'], options:TableOptions=None):
553
+ '''
554
+ Fetches Beam Force (Static Prestress) result tables.
555
+ Note: Construction Stage options are not applicable to this table type.
556
+
557
+ Args:
558
+ keys (list/str): List of Element IDs or a Structure Group Name.
559
+ loadcase (list): List of load case names, e.g., ["Prestress(ST)"].
560
+ parts (list): Element parts: ["PartI", "PartJ", etc.].
561
+ components (list): Table components to include. Defaults to ['all'].
562
+ options : Table options
563
+ '''
564
+ if options == None: options = TableOptions()
565
+ sheetName = options.EXCEL_SHEET_NAME or f"BeamForceSTP {_case2name(loadcase)}"
566
+
567
+ table_type = "BEAMFORCESTP"
568
+
569
+ # Note: cs_stage is intentionally omitted for this type
570
+ js_dat = _generate(table_type, keys, loadcase, components, [], options)
571
+
572
+ if parts:
573
+ js_dat["Argument"]["PARTS"] = parts
574
+
575
+ ResultJSON = _changeUNITandGetData(js_dat, options.FORCE_UNIT, options.LEN_UNIT, options.JSON_FILE_LOC, table_type)
576
+ polarDF = _JSToDF_ResTable(ResultJSON, options.EXCEL_FILE_LOC, sheetName, options.EXCEL_CELL_POS)
577
+ return polarDF
578
+
579
+ @staticmethod
580
+ def BeamStress(keys=[], loadcase:list=[], parts=["PartI", "PartJ"],
581
+ components=['all'], cs_stage=[], options:TableOptions=None):
582
+ '''
583
+ Fetches standard Beam Stress result tables.
584
+
585
+ Args:
586
+ keys (list/str): List of Element IDs or a Structure Group Name.
587
+ loadcase (list): List of load case names, e.g., ["Selfweight(ST)"].
588
+ parts (list): Element parts: ["PartI", "PartJ", etc.].
589
+ components (list): Table components to include. Defaults to ['all'].
590
+ cs_stage (list/str): Construction Stage options.
591
+ options : Table options
592
+ '''
593
+ if options == None: options = TableOptions()
594
+ sheetName = options.EXCEL_SHEET_NAME or f"BeamStress {_case2name(loadcase)}"
595
+
596
+ table_type = "BEAMSTRESS"
597
+
598
+ js_dat = _generate(table_type, keys, loadcase, components, cs_stage, options)
599
+
600
+ if parts:
601
+ js_dat["Argument"]["PARTS"] = parts
602
+
603
+ ResultJSON = _changeUNITandGetData(js_dat, options.FORCE_UNIT, options.LEN_UNIT, options.JSON_FILE_LOC, table_type)
604
+ polarDF = _JSToDF_ResTable(ResultJSON, options.EXCEL_FILE_LOC, sheetName, options.EXCEL_CELL_POS)
605
+ return polarDF
606
+
607
+ @staticmethod
608
+ def BeamStress_VBM(keys=[], loadcase:list=[], items=['all'], parts=["PartI", "PartJ"],
609
+ components=['all'], cs_stage=[], options:TableOptions=None):
610
+ '''
611
+ Fetches Beam Stress (View by Max Value) result tables.
612
+
613
+ Args:
614
+ keys (list/str): List of Element IDs or a Structure Group Name.
615
+ loadcase (list): List of load case names, e.g., ["STLENV_SER(CB:max)"].
616
+ items (list): Items to display: ["Axial", "Shear-y", "Bend(+y)", etc.].
617
+ parts (list): Element parts: ["PartI", "PartJ", etc.].
618
+ components (list): Table components to include. Defaults to ['all'].
619
+ cs_stage (list/str): Construction Stage options.
620
+ options : Table options
621
+ '''
622
+ if options == None: options = TableOptions()
623
+ sheetName = options.EXCEL_SHEET_NAME or f"BeamStressVBM {_case2name(loadcase)}"
624
+
625
+ table_type = "BEAMSTRESSVBM"
626
+
627
+ js_dat = _generate(table_type, keys, loadcase, components, cs_stage, options)
628
+
629
+ if parts:
630
+ js_dat["Argument"]["PARTS"] = parts
631
+
632
+ if items != ['all']:
633
+ js_dat["Argument"]['ITEM_TO_DISPLAY'] = items
634
+
635
+ ResultJSON = _changeUNITandGetData(js_dat, options.FORCE_UNIT, options.LEN_UNIT, options.JSON_FILE_LOC, table_type)
636
+ polarDF = _JSToDF_ResTable(ResultJSON, options.EXCEL_FILE_LOC, sheetName, options.EXCEL_CELL_POS)
637
+ return polarDF
638
+
639
+ @staticmethod
640
+ def BeamStress_7DOF(keys=[], loadcase:list=[], parts=["PartI", "PartJ"],
641
+ section_position=['Max'], components=['all'],
642
+ cs_stage=[], options:TableOptions=None):
643
+ '''
644
+ Fetches Beam Stress (7th DOF) result tables.
645
+
646
+ Args:
647
+ keys (list/str): List of Element IDs or a Structure Group Name.
648
+ loadcase (list): List of load case names, e.g., ["EccentricLoads(ST)"].
649
+ parts (list): Element parts: ["PartI", "PartJ", etc.].
650
+ section_position (list): Section positions: ["Pos-1", "Pos-4", "Max", etc.].
651
+ components (list): Table components to include. Defaults to ['all'].
652
+ cs_stage (list/str): Construction Stage options.
653
+ options : Table options
654
+ '''
655
+ if options == None: options = TableOptions()
656
+ sheetName = options.EXCEL_SHEET_NAME or f"BeamStress7DOF {_case2name(loadcase)}"
657
+
658
+ table_type = "BEAMSTRESS7DOF"
659
+
660
+ js_dat = _generate(table_type, keys, loadcase, components, cs_stage, options)
661
+
662
+ if parts:
663
+ js_dat["Argument"]["PARTS"] = parts
664
+
665
+ if section_position:
666
+ js_dat["Argument"]["SECTION_POSITION"] = section_position
667
+
668
+ ResultJSON = _changeUNITandGetData(js_dat, options.FORCE_UNIT, options.LEN_UNIT, options.JSON_FILE_LOC, table_type)
669
+ polarDF = _JSToDF_ResTable(ResultJSON, options.EXCEL_FILE_LOC, sheetName, options.EXCEL_CELL_POS)
670
+ return polarDF
671
+
672
+ @staticmethod
673
+ def BeamStress_PSC(keys=[], loadcase:list=[], parts=["PartI", "PartJ"],
674
+ section_position=['All'], components=['all'],
675
+ cs_stage=[], options:TableOptions=None):
676
+ '''
677
+ Fetches Beam Stress (PSC) result tables.
678
+
679
+ Args:
680
+ keys (list/str): List of Element IDs or a Structure Group Name.
681
+ loadcase (list): List of load case names, e.g., ["Selfweight(ST)"].
682
+ parts (list): Element parts: ["PartI", "PartJ", etc.].
683
+ section_position (list): Section positions: ["Pos-1", "Pos-10", "Max", "Min", "All"].
684
+ components (list): Table components to include. Defaults to ['all'].
685
+ cs_stage (list/str): Construction Stage options.
686
+ options : Table options
687
+ '''
688
+ if options == None: options = TableOptions()
689
+ sheetName = options.EXCEL_SHEET_NAME or f"BeamStressPSC {_case2name(loadcase)}"
690
+
691
+ table_type = "BEAMSTRESSPSC"
692
+
693
+ js_dat = _generate(table_type, keys, loadcase, components, cs_stage, options)
694
+
695
+ if parts:
696
+ js_dat["Argument"]["PARTS"] = parts
697
+
698
+ if section_position:
699
+ js_dat["Argument"]["SECTION_POSITION"] = section_position
700
+
701
+ ResultJSON = _changeUNITandGetData(js_dat, options.FORCE_UNIT, options.LEN_UNIT, options.JSON_FILE_LOC, table_type)
702
+ polarDF = _JSToDF_ResTable(ResultJSON, options.EXCEL_FILE_LOC, sheetName, options.EXCEL_CELL_POS)
703
+ return polarDF
704
+
705
+ @staticmethod
706
+ def BeamStress_7DOF_PSC(keys=[], loadcase:list=[], parts=["PartI", "PartJ"],
707
+ section_position=['All'], components=['all'],
708
+ cs_stage=[], options:TableOptions=None):
709
+ '''
710
+ Fetches Beam Stress (7th DOF PSC) result tables.
711
+
712
+ Args:
713
+ keys (list/str): List of Element IDs or a Structure Group Name.
714
+ loadcase (list): List of load case names, e.g., ["EccentricLoads(ST)"].
715
+ parts (list): Element parts: ["PartI", "PartJ", etc.].
716
+ section_position (list): Section positions: ["Pos-1", "Pos-10", "Max", "Min", "All"].
717
+ components (list): Table components to include. Defaults to ['all'].
718
+ cs_stage (list/str): Construction Stage options.
719
+ options : Table options
720
+ '''
721
+ if options == None: options = TableOptions()
722
+ sheetName = options.EXCEL_SHEET_NAME or f"BeamStress7DOFPSC {_case2name(loadcase)}"
723
+
724
+ table_type = "BEAMSTRESS7DOFPSC"
725
+
726
+ js_dat = _generate(table_type, keys, loadcase, components, cs_stage, options)
727
+
728
+ if parts:
729
+ js_dat["Argument"]["PARTS"] = parts
730
+
731
+ if section_position:
732
+ js_dat["Argument"]["SECTION_POSITION"] = section_position
733
+
734
+ ResultJSON = _changeUNITandGetData(js_dat, options.FORCE_UNIT, options.LEN_UNIT, options.JSON_FILE_LOC, table_type)
735
+ polarDF = _JSToDF_ResTable(ResultJSON, options.EXCEL_FILE_LOC, sheetName, options.EXCEL_CELL_POS)
736
+ return polarDF
737
+
738
+ @staticmethod
739
+ def PlateForce(keys=[], loadcase:list=[], components=['all'],
740
+ cs_stage=[], avg_nodal_result=False,
741
+ type:str="Local", options:TableOptions=None):
742
+ '''
743
+ Fetches Plate Force (Local or Global) result tables.
744
+
745
+ Args:
746
+ keys (list/str): List of Element IDs or a Structure Group Name.
747
+ loadcase (list): List of load case names, e.g., ["DL(ST)"].
748
+ components (list): Table components to include. Defaults to ['all'].
749
+ cs_stage (list/str): Construction Stage options.
750
+ avg_nodal_result (bool): Option to average nodal results.
751
+ type (str): Plate Force type. "Local" or "Global".
752
+ options : Table options
753
+ '''
754
+ if options == None: options = TableOptions()
755
+ sheetName = options.EXCEL_SHEET_NAME or f"PlateForce{type} {_case2name(loadcase)}"
756
+
757
+ table_type_map = {
758
+ "Local": "PLATEFORCEL",
759
+ "Global": "PLATEFORCEG"
760
+ }
761
+ table_type = table_type_map.get(type.capitalize(), "PLATEFORCEL")
762
+
763
+ js_dat = _generate(table_type, keys, loadcase, components, cs_stage, options)
764
+
765
+ if avg_nodal_result:
766
+ js_dat["Argument"]["AVERAGE_NODAL_RESULT"] = True
767
+
768
+ ResultJSON = _changeUNITandGetData(js_dat, options.FORCE_UNIT, options.LEN_UNIT, options.JSON_FILE_LOC, table_type)
769
+ polarDF = _JSToDF_ResTable(ResultJSON, options.EXCEL_FILE_LOC, sheetName, options.EXCEL_CELL_POS)
770
+ return polarDF
771
+
772
+ @staticmethod
773
+ def BeamStress_Equivalent(keys=[], loadcase:list=[], parts=["PartI", "PartJ"],
774
+ section_position=['Maximum'], components=['all'],
775
+ cs_stage=[], options:TableOptions=None):
776
+ '''
777
+ Fetches Beam Stress (Equivalent) result tables.
778
+
779
+ Args:
780
+ keys (list/str): List of Element IDs or a Structure Group Name.
781
+ loadcase (list): List of load case names, e.g., ["Selfweight(ST)"].
782
+ parts (list): Element parts: ["PartI", "PartJ", etc.].
783
+ section_position (list): Section positions: ["Maximum", "1", "12", etc.].
784
+ components (list): Table components to include. Defaults to ['all'].
785
+ cs_stage (list/str): Construction Stage options.
786
+ options : Table options
787
+ '''
788
+ if options == None: options = TableOptions()
789
+ sheetName = options.EXCEL_SHEET_NAME or f"BeamStressEq {_case2name(loadcase)}"
790
+
791
+ table_type = "BEAMSTRESSDETAIL"
792
+
793
+ js_dat = _generate(table_type, keys, loadcase, components, cs_stage, options)
794
+
795
+ if parts:
796
+ js_dat["Argument"]["PARTS"] = parts
797
+
798
+ if section_position:
799
+ js_dat["Argument"]["SECTION_POSITION"] = section_position
800
+
801
+ ResultJSON = _changeUNITandGetData(js_dat, options.FORCE_UNIT, options.LEN_UNIT, options.JSON_FILE_LOC, table_type)
802
+ polarDF = _JSToDF_ResTable(ResultJSON, options.EXCEL_FILE_LOC, sheetName, options.EXCEL_CELL_POS)
803
+ return polarDF
804
+
805
+ @staticmethod
806
+ def PlateForce_UnitLength(keys=[], loadcase:list=[], components=['all'],
807
+ cs_stage=[], avg_nodal_result=False,
808
+ node_flag_center=False, node_flag_nodes=True,
809
+ type:_plateforce="Local", options:TableOptions=None):
810
+ '''
811
+ Fetches Plate Force (Unit Length) for Local or UCS coordinates.
812
+
813
+ Args:
814
+ keys (list/str): List of Element IDs or a Structure Group Name.
815
+ loadcase (list): List of load case names, e.g., ["DL(ST)"].
816
+ components (list): Table components to include. Defaults to ['all'].
817
+ cs_stage (list/str): Construction Stage options.
818
+ avg_nodal_result (bool): Option to average nodal results.
819
+ node_flag_center (bool): Retrieve results at the center of the plate.
820
+ node_flag_nodes (bool): Retrieve results at the nodes of the plate.
821
+ type (str): Plate Force type. "Local" or "Global"
822
+ options : Table options
823
+ '''
824
+ if options == None: options = TableOptions()
825
+ sheetName = options.EXCEL_SHEET_NAME or f"PlateForceUL{type} {_case2name(loadcase)}"
826
+
827
+ table_type_map = {
828
+ "Local": "PLATEFORCEUL",
829
+ "Global": "PLATEFORCEUG"
830
+ }
831
+ table_type = table_type_map.get(type.capitalize(), "PLATEFORCEUL")
832
+
833
+ js_dat = _generate(table_type, keys, loadcase, components, cs_stage, options)
834
+
835
+ js_dat["Argument"]["NODE_FLAG"] = {
836
+ "CENTER": node_flag_center,
837
+ "NODES": node_flag_nodes
838
+ }
839
+
840
+ if avg_nodal_result:
841
+ js_dat["Argument"]["AVERAGE_NODAL_RESULT"] = True
842
+
843
+ ResultJSON = _changeUNITandGetData(js_dat, options.FORCE_UNIT, options.LEN_UNIT, options.JSON_FILE_LOC, table_type)
844
+ polarDF = _JSToDF_ResTable(ResultJSON, options.EXCEL_FILE_LOC, sheetName, options.EXCEL_CELL_POS)
845
+ return polarDF
846
+
847
+ @staticmethod
848
+ def PlateForce_UnitLength_VBM(keys=[], loadcase:list=[], items=['all'],
849
+ components=['all'], cs_stage=[],
850
+ avg_nodal_result=False,
851
+ node_flag_center=False, node_flag_nodes=True,
852
+ type:_plateforce="Local", options:TableOptions=None):
853
+ '''
854
+ Fetches Plate Force (Unit Length, View by Max Value) for Local or UCS coordinates.
855
+
856
+ Args:
857
+ keys (list/str): List of Element IDs or a Structure Group Name.
858
+ loadcase (list): List of load case names, e.g., ["STLENV_STR(CB:max)"].
859
+ items (list): Items to display: ["Fxx", "Fyy", "Mxx", etc.].
860
+ components (list): Table components to include. Defaults to ['all'].
861
+ cs_stage (list/str): Construction Stage options.
862
+ avg_nodal_result (bool): Option to average nodal results.
863
+ node_flag_center (bool): Retrieve results at the center of the plate.
864
+ node_flag_nodes (bool): Retrieve results at the nodes of the plate.
865
+ type (str): Plate Force type. "Local" or "Global"
866
+ options : Table options
867
+ '''
868
+ if options == None: options = TableOptions()
869
+ sheetName = options.EXCEL_SHEET_NAME or f"PlateForceULVBM{type} {_case2name(loadcase)}"
870
+
871
+ table_type_map = {
872
+ "Local": "PLATEFORCEULVBM",
873
+ "Global": "PLATEFORCEUGVBM"
874
+ }
875
+ table_type = table_type_map.get(type.capitalize(), "PLATEFORCEULVBM")
876
+
877
+ js_dat = _generate(table_type, keys, loadcase, components, cs_stage, options)
878
+
879
+ js_dat["Argument"]["NODE_FLAG"] = {
880
+ "CENTER": node_flag_center,
881
+ "NODES": node_flag_nodes
882
+ }
883
+
884
+ if items != ['all']:
885
+ js_dat["Argument"]['ITEM_TO_DISPLAY'] = items
886
+
887
+ if avg_nodal_result:
888
+ js_dat["Argument"]["AVERAGE_NODAL_RESULT"] = True
889
+
890
+ ResultJSON = _changeUNITandGetData(js_dat, options.FORCE_UNIT, options.LEN_UNIT, options.JSON_FILE_LOC, table_type)
891
+ polarDF = _JSToDF_ResTable(ResultJSON, options.EXCEL_FILE_LOC, sheetName, options.EXCEL_CELL_POS)
892
+ return polarDF
893
+
894
+ @staticmethod
895
+ def PlateForce_UnitLength_WA(keys=[], loadcase:list=[], components=['all'],
896
+ cs_stage=[], avg_nodal_result=False,
897
+ node_flag_center=False, node_flag_nodes=True,
898
+ options:TableOptions=None):
899
+ '''
900
+ Fetches Plate Force (Unit Length, W-A Moment) result tables.
901
+
902
+ Args:
903
+ keys (list/str): List of Element IDs or a Structure Group Name.
904
+ loadcase (list): List of load case names, e.g., ["DL(ST)"].
905
+ components (list): Table components to include. Defaults to ['all'].
906
+ cs_stage (list/str): Construction Stage options.
907
+ avg_nodal_result (bool): Option to average nodal results.
908
+ node_flag_center (bool): Retrieve results at the center of the plate.
909
+ node_flag_nodes (bool): Retrieve results at the nodes of the plate.
910
+ options : Table options
911
+ '''
912
+ if options == None: options = TableOptions()
913
+ sheetName = options.EXCEL_SHEET_NAME or f"PlateForceWA {_case2name(loadcase)}"
914
+
915
+ table_type = "PLATEFORCEWA"
916
+
917
+ js_dat = _generate(table_type, keys, loadcase, components, cs_stage, options)
918
+
919
+ js_dat["Argument"]["NODE_FLAG"] = {
920
+ "CENTER": node_flag_center,
921
+ "NODES": node_flag_nodes
922
+ }
923
+
924
+ if avg_nodal_result:
925
+ js_dat["Argument"]["AVERAGE_NODAL_RESULT"] = True
926
+
927
+ ResultJSON = _changeUNITandGetData(js_dat, options.FORCE_UNIT, options.LEN_UNIT, options.JSON_FILE_LOC, table_type)
928
+ polarDF = _JSToDF_ResTable(ResultJSON, options.EXCEL_FILE_LOC, sheetName, options.EXCEL_CELL_POS)
929
+ return polarDF