midas-civil 1.4.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- midas_civil/_BoundaryChangeAssignment.py +278 -0
- midas_civil/__init__.py +51 -0
- midas_civil/_analysiscontrol.py +585 -0
- midas_civil/_boundary.py +888 -0
- midas_civil/_construction.py +1004 -0
- midas_civil/_element.py +1346 -0
- midas_civil/_group.py +337 -0
- midas_civil/_load.py +967 -0
- midas_civil/_loadcomb.py +159 -0
- midas_civil/_mapi.py +249 -0
- midas_civil/_material.py +1692 -0
- midas_civil/_model.py +522 -0
- midas_civil/_movingload.py +1479 -0
- midas_civil/_node.py +532 -0
- midas_civil/_result_table.py +929 -0
- midas_civil/_result_test.py +5455 -0
- midas_civil/_section/_TapdbSecSS.py +175 -0
- midas_civil/_section/__init__.py +413 -0
- midas_civil/_section/_compositeSS.py +283 -0
- midas_civil/_section/_dbSecSS.py +164 -0
- midas_civil/_section/_offsetSS.py +53 -0
- midas_civil/_section/_pscSS copy.py +455 -0
- midas_civil/_section/_pscSS.py +822 -0
- midas_civil/_section/_tapPSC12CellSS.py +565 -0
- midas_civil/_section/_unSupp.py +58 -0
- midas_civil/_settlement.py +161 -0
- midas_civil/_temperature.py +677 -0
- midas_civil/_tendon.py +1016 -0
- midas_civil/_thickness.py +147 -0
- midas_civil/_utils.py +529 -0
- midas_civil/_utilsFunc/__init__.py +0 -0
- midas_civil/_utilsFunc/_line2plate.py +636 -0
- midas_civil/_view.py +891 -0
- midas_civil/_view_trial.py +430 -0
- midas_civil/_visualise.py +347 -0
- midas_civil-1.4.1.dist-info/METADATA +74 -0
- midas_civil-1.4.1.dist-info/RECORD +40 -0
- midas_civil-1.4.1.dist-info/WHEEL +5 -0
- midas_civil-1.4.1.dist-info/licenses/LICENSE +21 -0
- midas_civil-1.4.1.dist-info/top_level.txt +1 -0
midas_civil/_load.py
ADDED
|
@@ -0,0 +1,967 @@
|
|
|
1
|
+
from ._mapi import MidasAPI
|
|
2
|
+
from ._group import Group
|
|
3
|
+
from ._element import elemByID
|
|
4
|
+
import numpy as np
|
|
5
|
+
from typing import Literal
|
|
6
|
+
|
|
7
|
+
_presDir = Literal['LX','LY','LZ','GX','GY','GZ','VECTOR']
|
|
8
|
+
_beamLoadDir = Literal['LX','LY','LZ','GX','GY','GZ']
|
|
9
|
+
_beamLoadType = Literal['CONLOAD','CONMOMENT','UNILOAD','UNIMOMENT']
|
|
10
|
+
_lineDistType = Literal['Abs','Rel']
|
|
11
|
+
# ----- Extend for list of nodes/elems -----
|
|
12
|
+
|
|
13
|
+
def _ADD_NodalLoad(self):
|
|
14
|
+
if isinstance(self.NODE,int):
|
|
15
|
+
Load.Nodal.data.append(self)
|
|
16
|
+
elif isinstance(self.NODE,list):
|
|
17
|
+
for nID in self.NODE:
|
|
18
|
+
Load.Nodal(nID,self.LCN,self.LDGR,self.FX,self.FY,self.FZ,self.MX,self.MY,self.MZ,self.ID)
|
|
19
|
+
|
|
20
|
+
def _ADD_PressureLoad(self):
|
|
21
|
+
if isinstance(self.ELEM,int):
|
|
22
|
+
Load.Pressure.data.append(self)
|
|
23
|
+
elif isinstance(self.ELEM,list):
|
|
24
|
+
for eID in self.ELEM:
|
|
25
|
+
Load.Pressure(eID,self.LCN,self.LDGR,self.DIR,self.PRES,self.VECTOR,self.bPROJ,self.ID)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def _ADD_BeamLoad(self):
|
|
29
|
+
if isinstance(self.ELEMENT,int):
|
|
30
|
+
Load.Beam.data.append(self)
|
|
31
|
+
elif isinstance(self.ELEMENT,list):
|
|
32
|
+
for eID in self.ELEMENT:
|
|
33
|
+
Load.Beam(eID,self.LCN,self.LDGR,self.VALUE,self.DIRECTION,self.D,self.P,self.CMD,self.TYPE,self.USE_ECCEN,self.USE_PROJECTION,
|
|
34
|
+
self.ECCEN_DIR,self.ECCEN_TYPE,self.IECC,self.JECC,self.USE_H,self.I_H,self.J_H,self.ID)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
#11 Class to define Load Cases:
|
|
39
|
+
class Load_Case:
|
|
40
|
+
"""Type symbol (Refer Static Load Case section in the Onine API Manual, Load Case names.
|
|
41
|
+
\nSample: Load_Case("USER", "Case 1", "Case 2", ..., "Case n")"""
|
|
42
|
+
maxID = 0
|
|
43
|
+
maxNO = 0
|
|
44
|
+
cases = []
|
|
45
|
+
types = ["USER", "D", "DC", "DW", "DD", "EP", "EANN", "EANC", "EAMN", "EAMC", "EPNN", "EPNC", "EPMN", "EPMC", "EH", "EV", "ES", "EL", "LS", "LSC",
|
|
46
|
+
"L", "LC", "LP", "IL", "ILP", "CF", "BRK", "BK", "CRL", "PS", "B", "WP", "FP", "SF", "WPR", "W", "WL", "STL", "CR", "SH", "T", "TPG", "CO",
|
|
47
|
+
"CT", "CV", "E", "FR", "IP", "CS", "ER", "RS", "GE", "LR", "S", "R", "LF", "RF", "GD", "SHV", "DRL", "WA", "WT", "EVT", "EEP", "EX", "I", "EE"]
|
|
48
|
+
def __init__(self, type, *name):
|
|
49
|
+
self.TYPE = type
|
|
50
|
+
self.NAME = name
|
|
51
|
+
self.ID = []
|
|
52
|
+
self.NO = []
|
|
53
|
+
for i in range(len(self.NAME)):
|
|
54
|
+
if Load_Case.cases == []:
|
|
55
|
+
self.ID.append(i+1)
|
|
56
|
+
self.NO.append(i+1)
|
|
57
|
+
if Load_Case.cases != []:
|
|
58
|
+
self.ID.append(Load_Case.maxID + i + 1)
|
|
59
|
+
self.NO.append(Load_Case.maxNO + i + 1)
|
|
60
|
+
Load_Case.cases.append(self)
|
|
61
|
+
Load_Case.maxID = max(max(self.ID),Load_Case.maxID)
|
|
62
|
+
Load_Case.maxNO = max(max(self.NO),Load_Case.maxNO)
|
|
63
|
+
|
|
64
|
+
@classmethod
|
|
65
|
+
def json(cls):
|
|
66
|
+
ng = []
|
|
67
|
+
json = {"Assign":{}}
|
|
68
|
+
for i in cls.cases:
|
|
69
|
+
if i.TYPE in cls.types:
|
|
70
|
+
for j in i.ID:
|
|
71
|
+
json['Assign'][j] = {
|
|
72
|
+
"NO": i.NO[i.ID.index(j)],
|
|
73
|
+
"NAME": i.NAME[i.ID.index(j)],
|
|
74
|
+
"TYPE": i.TYPE}
|
|
75
|
+
else:
|
|
76
|
+
ng.append(i.TYPE)
|
|
77
|
+
if ng != []: print(f"These load case types are incorrect: {ng}.\nPlease check API Manual.")
|
|
78
|
+
return json
|
|
79
|
+
|
|
80
|
+
@staticmethod
|
|
81
|
+
def create():
|
|
82
|
+
MidasAPI("PUT","/db/stld",Load_Case.json())
|
|
83
|
+
|
|
84
|
+
@staticmethod
|
|
85
|
+
def get():
|
|
86
|
+
return MidasAPI("GET","/db/stld")
|
|
87
|
+
|
|
88
|
+
@staticmethod
|
|
89
|
+
def sync():
|
|
90
|
+
Load_Case.maxID = 0
|
|
91
|
+
Load_Case.maxNO = 0
|
|
92
|
+
a = Load_Case.get()
|
|
93
|
+
if a != {'message': ''}:
|
|
94
|
+
if list(a['STLD'].keys()) != []:
|
|
95
|
+
Load_Case.cases = []
|
|
96
|
+
for j in a['STLD'].keys():
|
|
97
|
+
lc = Load_Case(a['STLD'][j]['TYPE'], a['STLD'][j]['NAME'])
|
|
98
|
+
lcID = int(j)
|
|
99
|
+
lCNO = int(a['STLD'][j]['NO'])
|
|
100
|
+
lc.ID = [lcID]
|
|
101
|
+
lc.NO = [lCNO]
|
|
102
|
+
|
|
103
|
+
Load_Case.maxID = max(Load_Case.maxID ,lcID )
|
|
104
|
+
Load_Case.maxNO = max(Load_Case.maxNO ,lCNO )
|
|
105
|
+
|
|
106
|
+
@classmethod
|
|
107
|
+
def delete(cls):
|
|
108
|
+
cls.clear()
|
|
109
|
+
return MidasAPI("DELETE","/db/stld")
|
|
110
|
+
|
|
111
|
+
@classmethod
|
|
112
|
+
def clear(cls):
|
|
113
|
+
cls.maxID = 0
|
|
114
|
+
cls.maxNO = 0
|
|
115
|
+
cls.cases=[]
|
|
116
|
+
#---------------------------------------------------------------------------------------------------------------
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
class Load:
|
|
121
|
+
|
|
122
|
+
@classmethod
|
|
123
|
+
def create(cls):
|
|
124
|
+
if Load_Case.cases!=[]: Load_Case.create()
|
|
125
|
+
if cls.SW.data!=[]: cls.SW.create()
|
|
126
|
+
if cls.Nodal.data!=[]: cls.Nodal.create()
|
|
127
|
+
if cls.Beam.data!=[]: cls.Beam.create()
|
|
128
|
+
if cls.Pressure.data!=[]: cls.Pressure.create()
|
|
129
|
+
|
|
130
|
+
@classmethod
|
|
131
|
+
def clear(cls):
|
|
132
|
+
Load_Case.clear()
|
|
133
|
+
cls.SW.clear()
|
|
134
|
+
cls.Nodal.clear()
|
|
135
|
+
cls.Beam.clear()
|
|
136
|
+
cls.Pressure.clear()
|
|
137
|
+
|
|
138
|
+
class SW:
|
|
139
|
+
"""Load Case Name, direction, Value, Load Group.\n
|
|
140
|
+
Sample: Load_SW("Self-Weight", "Z", -1, "DL")"""
|
|
141
|
+
data = []
|
|
142
|
+
def __init__(self, load_case, dir = "Z", value = -1, load_group = ""):
|
|
143
|
+
|
|
144
|
+
chk = 0
|
|
145
|
+
for i in Load_Case.cases:
|
|
146
|
+
if load_case in i.NAME: chk = 1
|
|
147
|
+
if chk == 0: Load_Case("D", load_case)
|
|
148
|
+
|
|
149
|
+
if load_group != "":
|
|
150
|
+
chk = 0
|
|
151
|
+
a = [v['NAME'] for v in Group.Load.json()["Assign"].values()]
|
|
152
|
+
if load_group in a: chk = 1
|
|
153
|
+
if chk == 0: Group.Load(load_group)
|
|
154
|
+
|
|
155
|
+
if type(value)==int:
|
|
156
|
+
if dir == "X":
|
|
157
|
+
fv = [value, 0, 0]
|
|
158
|
+
elif dir == "Y":
|
|
159
|
+
fv = [0, value, 0]
|
|
160
|
+
else:
|
|
161
|
+
fv = [0, 0, value]
|
|
162
|
+
elif type(value)==list:
|
|
163
|
+
fv = value
|
|
164
|
+
else: fv = [0,0,-1]
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
self.LC = load_case
|
|
168
|
+
self.DIR = dir
|
|
169
|
+
self.FV = fv
|
|
170
|
+
self.LG = load_group
|
|
171
|
+
self.ID = len(Load.SW.data) + 1
|
|
172
|
+
Load.SW.data.append(self)
|
|
173
|
+
|
|
174
|
+
@classmethod
|
|
175
|
+
def json(cls):
|
|
176
|
+
json = {"Assign":{}}
|
|
177
|
+
for i in cls.data:
|
|
178
|
+
json["Assign"][i.ID] = {
|
|
179
|
+
"LCNAME": i.LC,
|
|
180
|
+
"GROUP_NAME": i.LG,
|
|
181
|
+
"FV": i.FV
|
|
182
|
+
}
|
|
183
|
+
return json
|
|
184
|
+
|
|
185
|
+
@staticmethod
|
|
186
|
+
def create():
|
|
187
|
+
MidasAPI("PUT","/db/BODF",Load.SW.json())
|
|
188
|
+
|
|
189
|
+
@staticmethod
|
|
190
|
+
def get():
|
|
191
|
+
return MidasAPI("GET","/db/BODF")
|
|
192
|
+
|
|
193
|
+
@classmethod
|
|
194
|
+
def delete(cls):
|
|
195
|
+
cls.clear()
|
|
196
|
+
return MidasAPI("DELETE","/db/BODF")
|
|
197
|
+
|
|
198
|
+
@classmethod
|
|
199
|
+
def clear(cls):
|
|
200
|
+
cls.data=[]
|
|
201
|
+
|
|
202
|
+
@staticmethod
|
|
203
|
+
def sync():
|
|
204
|
+
a = Load.SW.get()
|
|
205
|
+
if a != {'message': ''}:
|
|
206
|
+
for i in list(a['BODF'].keys()):
|
|
207
|
+
if a['BODF'][i]['FV'][0] != 0:
|
|
208
|
+
di = "X"
|
|
209
|
+
va = a['BODF'][i]['FV'][0]
|
|
210
|
+
elif a['BODF'][i]['FV'][1] != 0:
|
|
211
|
+
di = "Y"
|
|
212
|
+
va = a['BODF'][i]['FV'][1]
|
|
213
|
+
else:
|
|
214
|
+
di = "Z"
|
|
215
|
+
va = a['BODF'][i]['FV'][2]
|
|
216
|
+
Load.SW(a['BODF'][i]['LCNAME'], di, va, a['BODF'][i]['GROUP_NAME'])
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
#-------------------------------- NODAL LOADS ------------------------------------------------------------
|
|
220
|
+
|
|
221
|
+
#18 Class to add Nodal Loads:
|
|
222
|
+
class Nodal:
|
|
223
|
+
"""Creates node loads and converts to JSON format.
|
|
224
|
+
Example: Load_Node(101, "LC1", "Group1", FZ = 10)
|
|
225
|
+
"""
|
|
226
|
+
data = []
|
|
227
|
+
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 = None):
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
chk = 0
|
|
231
|
+
for i in Load_Case.cases:
|
|
232
|
+
if load_case in i.NAME: chk = 1
|
|
233
|
+
if chk == 0: Load_Case("D", load_case)
|
|
234
|
+
if load_group != "":
|
|
235
|
+
chk = 0
|
|
236
|
+
a = [v['NAME'] for v in Group.Load.json()["Assign"].values()]
|
|
237
|
+
if load_group in a: chk = 1
|
|
238
|
+
if chk == 0: Group.Load(load_group)
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
self.NODE = node
|
|
242
|
+
self.LCN = load_case
|
|
243
|
+
self.LDGR = load_group
|
|
244
|
+
self.FX = FX
|
|
245
|
+
self.FY = FY
|
|
246
|
+
self.FZ = FZ
|
|
247
|
+
self.MX = MX
|
|
248
|
+
self.MY = MY
|
|
249
|
+
self.MZ = MZ
|
|
250
|
+
|
|
251
|
+
if id is None:
|
|
252
|
+
self.ID = len(Load.Nodal.data) + 1
|
|
253
|
+
else:
|
|
254
|
+
self.ID = id
|
|
255
|
+
|
|
256
|
+
_ADD_NodalLoad(self)
|
|
257
|
+
# Load.Nodal.data.append(self)
|
|
258
|
+
|
|
259
|
+
@classmethod
|
|
260
|
+
def json(cls):
|
|
261
|
+
json = {"Assign": {}}
|
|
262
|
+
for i in cls.data:
|
|
263
|
+
if i.NODE not in list(json["Assign"].keys()):
|
|
264
|
+
json["Assign"][i.NODE] = {"ITEMS": []}
|
|
265
|
+
|
|
266
|
+
json["Assign"][i.NODE]["ITEMS"].append({
|
|
267
|
+
"ID": i.ID,
|
|
268
|
+
"LCNAME": i.LCN,
|
|
269
|
+
"GROUP_NAME": i.LDGR,
|
|
270
|
+
"FX": i.FX,
|
|
271
|
+
"FY": i.FY,
|
|
272
|
+
"FZ": i.FZ,
|
|
273
|
+
"MX": i.MX,
|
|
274
|
+
"MY": i.MY,
|
|
275
|
+
"MZ": i.MZ
|
|
276
|
+
})
|
|
277
|
+
return json
|
|
278
|
+
|
|
279
|
+
@classmethod
|
|
280
|
+
def create(cls):
|
|
281
|
+
MidasAPI("PUT", "/db/CNLD",cls.json())
|
|
282
|
+
|
|
283
|
+
@classmethod
|
|
284
|
+
def get(cls):
|
|
285
|
+
return MidasAPI("GET", "/db/CNLD")
|
|
286
|
+
|
|
287
|
+
@classmethod
|
|
288
|
+
def delete(cls):
|
|
289
|
+
cls.clear()
|
|
290
|
+
return MidasAPI("DELETE", "/db/CNLD")
|
|
291
|
+
|
|
292
|
+
@classmethod
|
|
293
|
+
def clear(cls):
|
|
294
|
+
cls.data=[]
|
|
295
|
+
|
|
296
|
+
@classmethod
|
|
297
|
+
def sync(cls):
|
|
298
|
+
cls.data = []
|
|
299
|
+
a = cls.get()
|
|
300
|
+
if a != {'message': ''}:
|
|
301
|
+
for i in a['CNLD'].keys():
|
|
302
|
+
for j in range(len(a['CNLD'][i]['ITEMS'])):
|
|
303
|
+
Load.Nodal(int(i),a['CNLD'][i]['ITEMS'][j]['LCNAME'], a['CNLD'][i]['ITEMS'][j]['GROUP_NAME'],
|
|
304
|
+
a['CNLD'][i]['ITEMS'][j]['FX'], a['CNLD'][i]['ITEMS'][j]['FY'], a['CNLD'][i]['ITEMS'][j]['FZ'],
|
|
305
|
+
a['CNLD'][i]['ITEMS'][j]['MX'], a['CNLD'][i]['ITEMS'][j]['MY'], a['CNLD'][i]['ITEMS'][j]['MZ'],
|
|
306
|
+
a['CNLD'][i]['ITEMS'][j]['ID'])
|
|
307
|
+
#---------------------------------------------------------------------------------------------------------------
|
|
308
|
+
|
|
309
|
+
#19 Class to define Beam Loads:
|
|
310
|
+
class Beam:
|
|
311
|
+
data = []
|
|
312
|
+
def __init__(self, element:int, load_case: str, load_group: str = "", value: float=0, direction:_beamLoadDir = "GZ",
|
|
313
|
+
D:list = [0, 1, 0, 0], P = [0, 0, 0, 0], cmd = "BEAM", typ:_beamLoadType = "UNILOAD", use_ecc = False, use_proj = False,
|
|
314
|
+
eccn_dir = "LY", eccn_type = 1, ieccn = 0, jeccn = 0, adnl_h = False, adnl_h_i = 0, adnl_h_j = 0,id = None):
|
|
315
|
+
"""
|
|
316
|
+
element: Element ID or list of Element IDs
|
|
317
|
+
load_case (str): Load case name
|
|
318
|
+
load_group (str, optional): Load group name. Defaults to ""
|
|
319
|
+
value (float): Load value
|
|
320
|
+
direction (str): Load direction (e.g., "GX", "GY", "GZ", "LX", "LY", "LZ"). Defaults to "GZ"
|
|
321
|
+
D: Relative distance (list with 4 values, optional) based on length of element. Defaults to [0, 1, 0, 0]
|
|
322
|
+
P: Magnitude of UDL at corresponding position of D (list with 4 values, optional). Defaults to [value, value, 0, 0]
|
|
323
|
+
cmd: Load command (e.g., "BEAM", "LINE", "TYPICAL")
|
|
324
|
+
typ: Load type (e.g., "CONLOAD", "CONMOMENT", "UNITLOAD", "UNIMOMENT", "PRESSURE")
|
|
325
|
+
use_ecc: Use eccentricity (True or False). Defaults to False.
|
|
326
|
+
use_proj: Use projection (True or False). Defaults to False.
|
|
327
|
+
eccn_dir: Eccentricity direction (e.g., "GX", "GY", "GZ", "LX", "LY", "LZ"). Defaults to "LZ"
|
|
328
|
+
eccn_type: Eccentricity from offset (1) or centroid (0). Defaults to 1.
|
|
329
|
+
ieccn, jeccn: Eccentricity values at i-end and j-end of the element
|
|
330
|
+
adnl_h: Consider additional H when applying pressure on beam (True or False). Defaults to False.
|
|
331
|
+
adnl_h_i, adnl_h_j: Additional H values at i-end and j-end of the beam. Defaults to 0.
|
|
332
|
+
id (default=None): Load ID. Defaults to auto-generated\n
|
|
333
|
+
Example:
|
|
334
|
+
- Load_Beam(115, "UDL_Case", "", -50.0, "GZ") # No eccentricity
|
|
335
|
+
- Load_Beam(115, "UDL_Case", "", -50.0, "GZ", ieccn=2.5) # With eccentricity
|
|
336
|
+
"""
|
|
337
|
+
|
|
338
|
+
chk = 0
|
|
339
|
+
for i in Load_Case.cases:
|
|
340
|
+
if load_case in i.NAME: chk = 1
|
|
341
|
+
if chk == 0: Load_Case("D", load_case)
|
|
342
|
+
if load_group != "":
|
|
343
|
+
chk = 0
|
|
344
|
+
a = [v['NAME'] for v in Group.Load.json()["Assign"].values()]
|
|
345
|
+
if load_group in a: chk = 1
|
|
346
|
+
if chk == 0: Group.Load(load_group)
|
|
347
|
+
D = (D + [0] * 4)[:4]
|
|
348
|
+
P = (P + [0] * 4)[:4]
|
|
349
|
+
if P == [0, 0, 0, 0]: P = [value, value, 0, 0]
|
|
350
|
+
if eccn_type not in (0, 1):
|
|
351
|
+
eccn_type = 1
|
|
352
|
+
if direction not in ("GX", "GY", "GZ", "LX", "LY", "LZ"): direction = "GZ"
|
|
353
|
+
if eccn_dir not in ("GX", "GY", "GZ", "LX", "LY", "LZ"): eccn_dir = "LY"
|
|
354
|
+
if cmd not in ("BEAM", "LINE", "TYPICAL"): cmd = "BEAM"
|
|
355
|
+
if typ not in ("CONLOAD", "CONMOMENT", "UNILOAD", "UNIMOMENT","PRESSURE"): typ = "UNILOAD"
|
|
356
|
+
if use_ecc == False:
|
|
357
|
+
if ieccn != 0 or jeccn != 0: use_ecc = True
|
|
358
|
+
self.ELEMENT = element
|
|
359
|
+
self.LCN = load_case
|
|
360
|
+
self.LDGR = load_group
|
|
361
|
+
self.VALUE = value
|
|
362
|
+
self.DIRECTION = direction
|
|
363
|
+
self.CMD = cmd
|
|
364
|
+
self.TYPE = typ
|
|
365
|
+
self.USE_PROJECTION = use_proj
|
|
366
|
+
self.USE_ECCEN = use_ecc
|
|
367
|
+
self.ECCEN_TYPE = eccn_type
|
|
368
|
+
self.ECCEN_DIR = eccn_dir
|
|
369
|
+
self.IECC = ieccn
|
|
370
|
+
if jeccn == 0:
|
|
371
|
+
self.JECC = 0
|
|
372
|
+
self.USE_JECC = False
|
|
373
|
+
else:
|
|
374
|
+
self.JECC = jeccn
|
|
375
|
+
self.USE_JECC = True
|
|
376
|
+
self.D = D
|
|
377
|
+
self.P = P
|
|
378
|
+
self.USE_H = adnl_h
|
|
379
|
+
self.I_H = adnl_h_i
|
|
380
|
+
if adnl_h == 0:
|
|
381
|
+
self.USE_JH = False
|
|
382
|
+
self.J_H = 0
|
|
383
|
+
else:
|
|
384
|
+
self.USE_JH = True
|
|
385
|
+
self.J_H = adnl_h_j
|
|
386
|
+
|
|
387
|
+
if id is None:
|
|
388
|
+
self.ID = len(Load.Beam.data) + 1
|
|
389
|
+
else:
|
|
390
|
+
self.ID = id
|
|
391
|
+
|
|
392
|
+
_ADD_BeamLoad(self)
|
|
393
|
+
# Load.Beam.data.append(self)
|
|
394
|
+
|
|
395
|
+
@classmethod
|
|
396
|
+
def json(cls):
|
|
397
|
+
json = {"Assign": {}}
|
|
398
|
+
for i in cls.data:
|
|
399
|
+
item_data = {
|
|
400
|
+
"ID": i.ID,
|
|
401
|
+
"LCNAME": i.LCN,
|
|
402
|
+
"GROUP_NAME": i.LDGR,
|
|
403
|
+
"CMD": i.CMD,
|
|
404
|
+
"TYPE": i.TYPE,
|
|
405
|
+
"DIRECTION": i.DIRECTION,
|
|
406
|
+
"USE_PROJECTION": i.USE_PROJECTION,
|
|
407
|
+
"USE_ECCEN": i.USE_ECCEN,
|
|
408
|
+
"D": i.D,
|
|
409
|
+
"P": i.P
|
|
410
|
+
}
|
|
411
|
+
if i.USE_ECCEN == True:
|
|
412
|
+
item_data.update({
|
|
413
|
+
"ECCEN_TYPE": i.ECCEN_TYPE,
|
|
414
|
+
"ECCEN_DIR": i.ECCEN_DIR,
|
|
415
|
+
"I_END": i.IECC,
|
|
416
|
+
"J_END": i.JECC,
|
|
417
|
+
"USE_J_END": i.USE_JECC
|
|
418
|
+
})
|
|
419
|
+
if i.TYPE == "PRESSURE":
|
|
420
|
+
item_data.update({
|
|
421
|
+
"USE_ADDITIONAL": i.USE_H,
|
|
422
|
+
"ADDITIONAL_I_END": i.I_H,
|
|
423
|
+
"ADDITIONAL_J_END": i.J_H,
|
|
424
|
+
"USE_ADDITIONAL_J_END": i.J_H
|
|
425
|
+
})
|
|
426
|
+
if i.ELEMENT not in json["Assign"]:
|
|
427
|
+
json["Assign"][i.ELEMENT] = {"ITEMS": []}
|
|
428
|
+
json["Assign"][i.ELEMENT]["ITEMS"].append(item_data)
|
|
429
|
+
return json
|
|
430
|
+
|
|
431
|
+
@classmethod
|
|
432
|
+
def create(cls):
|
|
433
|
+
MidasAPI("PUT", "/db/bmld", cls.json())
|
|
434
|
+
|
|
435
|
+
@classmethod
|
|
436
|
+
def get(cls):
|
|
437
|
+
return MidasAPI("GET", "/db/bmld")
|
|
438
|
+
|
|
439
|
+
@classmethod
|
|
440
|
+
def delete(cls):
|
|
441
|
+
cls.clear()
|
|
442
|
+
return MidasAPI("DELETE", "/db/bmld")
|
|
443
|
+
|
|
444
|
+
@classmethod
|
|
445
|
+
def clear(cls):
|
|
446
|
+
cls.data=[]
|
|
447
|
+
|
|
448
|
+
@classmethod
|
|
449
|
+
def sync(cls):
|
|
450
|
+
cls.data = []
|
|
451
|
+
a = cls.get()
|
|
452
|
+
if a != {'message': ''}:
|
|
453
|
+
for i in a['BMLD'].keys():
|
|
454
|
+
for j in range(len(a['BMLD'][i]['ITEMS'])):
|
|
455
|
+
if a['BMLD'][i]['ITEMS'][j]['USE_ECCEN'] == True and a['BMLD'][i]['ITEMS'][j]['USE_ADDITIONAL'] == True:
|
|
456
|
+
Load.Beam(int(i),a['BMLD'][i]['ITEMS'][j]['LCNAME'], a['BMLD'][i]['ITEMS'][j]['GROUP_NAME'], a['BMLD'][i]['ITEMS'][j]['P'],
|
|
457
|
+
a['BMLD'][i]['ITEMS'][j]['DIRECTION'], a['BMLD'][i]['ITEMS'][j]['D'], a['BMLD'][i]['ITEMS'][j]['P'],
|
|
458
|
+
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'],
|
|
459
|
+
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'],
|
|
460
|
+
a['BMLD'][i]['ITEMS'][j]['USE_ADDITIONAL'], a['BMLD'][i]['ITEMS'][j]['ADDITIONAL_I_END'], a['BMLD'][i]['ITEMS'][j]['ADDITIONAL_J_END'], a['BMLD'][i]['ITEMS'][j]['ID'])
|
|
461
|
+
elif a['BMLD'][i]['ITEMS'][j]['USE_ECCEN'] == False and a['BMLD'][i]['ITEMS'][j]['USE_ADDITIONAL'] == True:
|
|
462
|
+
Load.Beam(int(i),a['BMLD'][i]['ITEMS'][j]['LCNAME'], a['BMLD'][i]['ITEMS'][j]['GROUP_NAME'], a['BMLD'][i]['ITEMS'][j]['P'],
|
|
463
|
+
a['BMLD'][i]['ITEMS'][j]['DIRECTION'], a['BMLD'][i]['ITEMS'][j]['D'], a['BMLD'][i]['ITEMS'][j]['P'],
|
|
464
|
+
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'],
|
|
465
|
+
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'],id= a['BMLD'][i]['ITEMS'][j]['ID'])
|
|
466
|
+
elif a['BMLD'][i]['ITEMS'][j]['USE_ECCEN'] == True and a['BMLD'][i]['ITEMS'][j]['USE_ADDITIONAL'] == False:
|
|
467
|
+
Load.Beam(int(i),a['BMLD'][i]['ITEMS'][j]['LCNAME'], a['BMLD'][i]['ITEMS'][j]['GROUP_NAME'], a['BMLD'][i]['ITEMS'][j]['P'],
|
|
468
|
+
a['BMLD'][i]['ITEMS'][j]['DIRECTION'], a['BMLD'][i]['ITEMS'][j]['D'], a['BMLD'][i]['ITEMS'][j]['P'],
|
|
469
|
+
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'],
|
|
470
|
+
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'],id=a['BMLD'][i]['ITEMS'][j]['ID'])
|
|
471
|
+
else:
|
|
472
|
+
Load.Beam(int(i),a['BMLD'][i]['ITEMS'][j]['LCNAME'], a['BMLD'][i]['ITEMS'][j]['GROUP_NAME'],a['BMLD'][i]['ITEMS'][j]['P'],
|
|
473
|
+
a['BMLD'][i]['ITEMS'][j]['DIRECTION'], a['BMLD'][i]['ITEMS'][j]['D'], a['BMLD'][i]['ITEMS'][j]['P'],
|
|
474
|
+
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'],id= a['BMLD'][i]['ITEMS'][j]['ID'])
|
|
475
|
+
|
|
476
|
+
|
|
477
|
+
#-------------------------------- Load to Mass ------------------------------------------------------------
|
|
478
|
+
|
|
479
|
+
#20 Class to add Load to Mass:
|
|
480
|
+
class LoadToMass:
|
|
481
|
+
"""
|
|
482
|
+
Creates load-to-mass conversion entries and converts them to JSON format.
|
|
483
|
+
|
|
484
|
+
Example:
|
|
485
|
+
Load.LoadToMass("Z", ["DL", "LL"], [1.0, 0.5])
|
|
486
|
+
|
|
487
|
+
Args:
|
|
488
|
+
dir (str):
|
|
489
|
+
Mass Direction - "X", "Y", "Z", "XY", "YZ", "XZ", "XYZ".
|
|
490
|
+
If invalid, defaults to "XYZ".
|
|
491
|
+
load_case (list | str):
|
|
492
|
+
List of load case names or a single case name as string.
|
|
493
|
+
load_factor (list | float, optional):
|
|
494
|
+
List of scale factors corresponding to `load_case`.
|
|
495
|
+
If None or shorter than `load_case`, remaining factors default to 1.0.
|
|
496
|
+
nodal_load (bool, optional):
|
|
497
|
+
Include nodal loads. Defaults to True.
|
|
498
|
+
beam_load (bool, optional):
|
|
499
|
+
Include beam loads. Defaults to True.
|
|
500
|
+
floor_load (bool, optional):
|
|
501
|
+
Include floor loads. Defaults to True.
|
|
502
|
+
pressure (bool, optional):
|
|
503
|
+
Include pressure loads. Defaults to True.
|
|
504
|
+
gravity (float, optional):
|
|
505
|
+
Gravity acceleration. Defaults to 9.806.
|
|
506
|
+
"""
|
|
507
|
+
data = []
|
|
508
|
+
|
|
509
|
+
def __init__(self, dir, load_case, load_factor=None, nodal_load=True, beam_load=True,
|
|
510
|
+
floor_load=True, pressure=True, gravity=9.806):
|
|
511
|
+
|
|
512
|
+
valid_directions = ["X", "Y", "Z", "XY", "YZ", "XZ", "XYZ"]
|
|
513
|
+
if dir not in valid_directions:
|
|
514
|
+
dir = "XYZ"
|
|
515
|
+
|
|
516
|
+
if not isinstance(load_case, list):
|
|
517
|
+
load_case = [load_case]
|
|
518
|
+
|
|
519
|
+
if load_factor is None:
|
|
520
|
+
load_factor = [1.0] * len(load_case)
|
|
521
|
+
elif not isinstance(load_factor, list):
|
|
522
|
+
load_factor = [load_factor]
|
|
523
|
+
|
|
524
|
+
while len(load_factor) < len(load_case):
|
|
525
|
+
load_factor.append(1.0)
|
|
526
|
+
|
|
527
|
+
for case in load_case:
|
|
528
|
+
chk = 0
|
|
529
|
+
for i in Load_Case.cases:
|
|
530
|
+
if case in i.NAME:
|
|
531
|
+
chk = 1
|
|
532
|
+
if chk == 0:
|
|
533
|
+
print(f"Warning: Load case '{case}' does not exist!")
|
|
534
|
+
|
|
535
|
+
self.DIR = dir
|
|
536
|
+
self.LOAD_CASE = load_case
|
|
537
|
+
self.LOAD_FACTOR = load_factor
|
|
538
|
+
self.NODAL = nodal_load
|
|
539
|
+
self.BEAM = beam_load
|
|
540
|
+
self.FLOOR = floor_load
|
|
541
|
+
self.PRESSURE = pressure
|
|
542
|
+
self.GRAVITY = gravity
|
|
543
|
+
|
|
544
|
+
Load.LoadToMass.data.append(self)
|
|
545
|
+
|
|
546
|
+
@classmethod
|
|
547
|
+
def json(cls):
|
|
548
|
+
json_data = {"Assign": {}}
|
|
549
|
+
|
|
550
|
+
for idx, load_obj in enumerate(cls.data, start=1):
|
|
551
|
+
vlc_array = []
|
|
552
|
+
for i, case_name in enumerate(load_obj.LOAD_CASE):
|
|
553
|
+
vlc_array.append({
|
|
554
|
+
"LCNAME": case_name,
|
|
555
|
+
"FACTOR": load_obj.LOAD_FACTOR[i]
|
|
556
|
+
})
|
|
557
|
+
|
|
558
|
+
json_data["Assign"][str(idx)] = {
|
|
559
|
+
"DIR": load_obj.DIR,
|
|
560
|
+
"bNODAL": load_obj.NODAL,
|
|
561
|
+
"bBEAM": load_obj.BEAM,
|
|
562
|
+
"bFLOOR": load_obj.FLOOR,
|
|
563
|
+
"bPRES": load_obj.PRESSURE,
|
|
564
|
+
"GRAV": load_obj.GRAVITY,
|
|
565
|
+
"vLC": vlc_array
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
return json_data
|
|
569
|
+
|
|
570
|
+
@classmethod
|
|
571
|
+
def create(cls):
|
|
572
|
+
return MidasAPI("PUT", "/db/ltom", cls.json())
|
|
573
|
+
|
|
574
|
+
@classmethod
|
|
575
|
+
def get(cls):
|
|
576
|
+
return MidasAPI("GET", "/db/ltom")
|
|
577
|
+
|
|
578
|
+
@classmethod
|
|
579
|
+
def delete(cls):
|
|
580
|
+
cls.data = []
|
|
581
|
+
return MidasAPI("DELETE", "/db/ltom")
|
|
582
|
+
|
|
583
|
+
@classmethod
|
|
584
|
+
def sync(cls):
|
|
585
|
+
cls.data = []
|
|
586
|
+
response = cls.get()
|
|
587
|
+
|
|
588
|
+
if response != {'message': ''}:
|
|
589
|
+
for key, item_data in response.get('LTOM', {}).items():
|
|
590
|
+
load_cases = []
|
|
591
|
+
load_factors = []
|
|
592
|
+
|
|
593
|
+
for lc_item in item_data.get('vLC', []):
|
|
594
|
+
load_cases.append(lc_item.get('LCNAME'))
|
|
595
|
+
load_factors.append(lc_item.get('FACTOR'))
|
|
596
|
+
|
|
597
|
+
Load.LoadToMass(
|
|
598
|
+
dir=item_data.get('DIR'),
|
|
599
|
+
load_case=load_cases,
|
|
600
|
+
load_factor=load_factors,
|
|
601
|
+
nodal_load=item_data.get('bNODAL'),
|
|
602
|
+
beam_load=item_data.get('bBEAM'),
|
|
603
|
+
floor_load=item_data.get('bFLOOR'),
|
|
604
|
+
pressure=item_data.get('bPRES'),
|
|
605
|
+
gravity=item_data.get('GRAV')
|
|
606
|
+
)
|
|
607
|
+
|
|
608
|
+
|
|
609
|
+
#-----------------------------------------------------------NodalMass-----------------
|
|
610
|
+
#21NodalMass
|
|
611
|
+
|
|
612
|
+
class NodalMass:
|
|
613
|
+
"""Creates nodal mass and converts to JSON format.
|
|
614
|
+
Example: NodalMass(1, 1.5, 2.0, 3.0, 0.1, 0.2, 0.3)
|
|
615
|
+
"""
|
|
616
|
+
data = []
|
|
617
|
+
|
|
618
|
+
def __init__(self, node_id, mX, mY=0, mZ=0, rmX=0, rmY=0, rmZ=0):
|
|
619
|
+
"""
|
|
620
|
+
node_id (int): Node ID where the mass is applied (Required)
|
|
621
|
+
mX (float): Translational Lumped Mass in GCS X-direction (Required)
|
|
622
|
+
mY (float): Translational Lumped Mass in GCS Y-direction. Defaults to 0
|
|
623
|
+
mZ (float): Translational Lumped Mass in GCS Z-direction. Defaults to 0
|
|
624
|
+
rmX (float): Rotational Mass Moment of Inertia about GCS X-axis. Defaults to 0
|
|
625
|
+
rmY (float): Rotational Mass Moment of Inertia about GCS Y-axis. Defaults to 0
|
|
626
|
+
rmZ (float): Rotational Mass Moment of Inertia about GCS Z-axis. Defaults to 0
|
|
627
|
+
"""
|
|
628
|
+
self.NODE_ID = node_id
|
|
629
|
+
self.MX = mX
|
|
630
|
+
self.MY = mY
|
|
631
|
+
self.MZ = mZ
|
|
632
|
+
self.RMX = rmX
|
|
633
|
+
self.RMY = rmY
|
|
634
|
+
self.RMZ = rmZ
|
|
635
|
+
|
|
636
|
+
Load.NodalMass.data.append(self)
|
|
637
|
+
|
|
638
|
+
@classmethod
|
|
639
|
+
def json(cls):
|
|
640
|
+
json_data = {"Assign": {}}
|
|
641
|
+
|
|
642
|
+
for mass_obj in cls.data:
|
|
643
|
+
json_data["Assign"][mass_obj.NODE_ID] = {
|
|
644
|
+
"mX": mass_obj.MX,
|
|
645
|
+
"mY": mass_obj.MY,
|
|
646
|
+
"mZ": mass_obj.MZ,
|
|
647
|
+
"rmX": mass_obj.RMX,
|
|
648
|
+
"rmY": mass_obj.RMY,
|
|
649
|
+
"rmZ": mass_obj.RMZ
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
return json_data
|
|
653
|
+
|
|
654
|
+
@classmethod
|
|
655
|
+
def create(cls):
|
|
656
|
+
return MidasAPI("PUT", "/db/nmas", cls.json())
|
|
657
|
+
|
|
658
|
+
@classmethod
|
|
659
|
+
def get(cls):
|
|
660
|
+
MidasAPI("GET", "/db/nmas")
|
|
661
|
+
|
|
662
|
+
@classmethod
|
|
663
|
+
def delete(cls):
|
|
664
|
+
cls.data = []
|
|
665
|
+
MidasAPI("DELETE", "/db/nmas")
|
|
666
|
+
|
|
667
|
+
@classmethod
|
|
668
|
+
def sync(cls):
|
|
669
|
+
cls.data = []
|
|
670
|
+
response = cls.get()
|
|
671
|
+
|
|
672
|
+
if response and response != {'message': ''}:
|
|
673
|
+
nmas_data = response.get('NMAS', {})
|
|
674
|
+
|
|
675
|
+
for node_id, item_data in nmas_data.items():
|
|
676
|
+
Load.NodalMass(
|
|
677
|
+
node_id=int(node_id),
|
|
678
|
+
mX=item_data.get('mX'),
|
|
679
|
+
mY=item_data.get('mY'),
|
|
680
|
+
mZ=item_data.get('mZ'),
|
|
681
|
+
rmX=item_data.get('rmX'),
|
|
682
|
+
rmY=item_data.get('rmY'),
|
|
683
|
+
rmZ=item_data.get('rmZ')
|
|
684
|
+
)
|
|
685
|
+
|
|
686
|
+
#-----------------------------------------------------------Specified Displacement-------------------------------------------------
|
|
687
|
+
class SpDisp:
|
|
688
|
+
"""Creates specified displacement loads and converts to JSON format.
|
|
689
|
+
Example: SpDisp(10, "LL", "Group1", [1.5, 1.5, 1.5, 1.5, 0.5, 0.5])
|
|
690
|
+
"""
|
|
691
|
+
data = []
|
|
692
|
+
|
|
693
|
+
def __init__(self, node, load_case, load_group="", values=[0, 0, 0, 0, 0, 0], id=None):
|
|
694
|
+
"""
|
|
695
|
+
node (int): Node number (Required)
|
|
696
|
+
load_case (str): Load case name (Required)
|
|
697
|
+
load_group (str, optional): Load group name. Defaults to ""
|
|
698
|
+
values (list): Displacement values [Dx, Dy, Dz, Rx, Ry, Rz]. Defaults to [0, 0, 0, 0, 0, 0]
|
|
699
|
+
id (default=None): Load ID. Defaults to auto-generated
|
|
700
|
+
"""
|
|
701
|
+
|
|
702
|
+
# Check if load case exists - give warning if not
|
|
703
|
+
chk = 0
|
|
704
|
+
for i in Load_Case.cases:
|
|
705
|
+
if load_case in i.NAME:
|
|
706
|
+
chk = 1
|
|
707
|
+
if chk == 0:
|
|
708
|
+
print(f"Warning: Load case '{load_case}' does not exist!")
|
|
709
|
+
|
|
710
|
+
# Check if load group exists and create if specified
|
|
711
|
+
if load_group != "":
|
|
712
|
+
chk = 0
|
|
713
|
+
a = [v['NAME'] for v in Group.Load.json()["Assign"].values()]
|
|
714
|
+
if load_group in a:
|
|
715
|
+
chk = 1
|
|
716
|
+
if chk == 0:
|
|
717
|
+
print(f"Warning: Load group '{load_group}' does not exist!")
|
|
718
|
+
|
|
719
|
+
# Ensure values is a list of 6 elements [Dx, Dy, Dz, Rx, Ry, Rz]
|
|
720
|
+
if not isinstance(values, list):
|
|
721
|
+
values = [0, 0, 0, 0, 0, 0]
|
|
722
|
+
|
|
723
|
+
# Pad or truncate to exactly 6 values
|
|
724
|
+
values = (values + [0] * 6)[:6]
|
|
725
|
+
|
|
726
|
+
self.NODE = node
|
|
727
|
+
self.LCN = load_case
|
|
728
|
+
self.LDGR = load_group
|
|
729
|
+
self.VALUES = values
|
|
730
|
+
|
|
731
|
+
if id is None:
|
|
732
|
+
self.ID = len(Load.SpDisp.data) + 1
|
|
733
|
+
else:
|
|
734
|
+
self.ID = id
|
|
735
|
+
|
|
736
|
+
Load.SpDisp.data.append(self)
|
|
737
|
+
|
|
738
|
+
@classmethod
|
|
739
|
+
def json(cls):
|
|
740
|
+
json_data = {"Assign": {}}
|
|
741
|
+
|
|
742
|
+
for i in cls.data:
|
|
743
|
+
if i.NODE not in list(json_data["Assign"].keys()):
|
|
744
|
+
json_data["Assign"][i.NODE] = {"ITEMS": []}
|
|
745
|
+
|
|
746
|
+
# Create VALUES array with OPT_FLAG logic
|
|
747
|
+
values_array = []
|
|
748
|
+
displacement_labels = ["Dx", "Dy", "Dz", "Rx", "Ry", "Rz"]
|
|
749
|
+
|
|
750
|
+
for idx, value in enumerate(i.VALUES):
|
|
751
|
+
values_array.append({
|
|
752
|
+
"OPT_FLAG": value != 0, # True if value > 0, False if value = 0
|
|
753
|
+
"DISPLACEMENT": float(value)
|
|
754
|
+
})
|
|
755
|
+
|
|
756
|
+
json_data["Assign"][i.NODE]["ITEMS"].append({
|
|
757
|
+
"ID": i.ID,
|
|
758
|
+
"LCNAME": i.LCN,
|
|
759
|
+
"GROUP_NAME": i.LDGR,
|
|
760
|
+
"VALUES": values_array
|
|
761
|
+
})
|
|
762
|
+
|
|
763
|
+
return json_data
|
|
764
|
+
|
|
765
|
+
@classmethod
|
|
766
|
+
def create(cls):
|
|
767
|
+
return MidasAPI("PUT", "/db/sdsp", cls.json())
|
|
768
|
+
|
|
769
|
+
@classmethod
|
|
770
|
+
def get(cls):
|
|
771
|
+
return MidasAPI("GET", "/db/sdsp")
|
|
772
|
+
|
|
773
|
+
@classmethod
|
|
774
|
+
def delete(cls):
|
|
775
|
+
cls.data = []
|
|
776
|
+
return MidasAPI("DELETE", "/db/sdsp")
|
|
777
|
+
|
|
778
|
+
@classmethod
|
|
779
|
+
def sync(cls):
|
|
780
|
+
cls.data = []
|
|
781
|
+
response = cls.get()
|
|
782
|
+
|
|
783
|
+
if response != {'message': ''}:
|
|
784
|
+
for node_key in response['SDSP'].keys():
|
|
785
|
+
for j in range(len(response['SDSP'][node_key]['ITEMS'])):
|
|
786
|
+
item = response['SDSP'][node_key]['ITEMS'][j]
|
|
787
|
+
|
|
788
|
+
# Extract displacement values from VALUES array
|
|
789
|
+
values = []
|
|
790
|
+
for val_item in item.get('VALUES', []):
|
|
791
|
+
values.append(val_item.get('DISPLACEMENT', 0))
|
|
792
|
+
|
|
793
|
+
Load.SpDisp(
|
|
794
|
+
int(node_key),
|
|
795
|
+
item['LCNAME'],
|
|
796
|
+
item['GROUP_NAME'],
|
|
797
|
+
values,
|
|
798
|
+
item['ID']
|
|
799
|
+
)
|
|
800
|
+
class Line:
|
|
801
|
+
def __init__(self, element_ids, load_case: str, load_group: str = "", D = [0, 1], P = [0, 0], direction:_beamLoadDir = "GZ",
|
|
802
|
+
type:_beamLoadType = "UNILOAD", distType:_lineDistType='Abs',use_ecc = False, use_proj = False,
|
|
803
|
+
eccn_dir:_beamLoadDir = "LY", eccn_type = 1, ieccn = 0, jeccn = 0, adnl_h = False, adnl_h_i = 0, adnl_h_j = 0,id = None) :
|
|
804
|
+
|
|
805
|
+
elem_IDS = []
|
|
806
|
+
elem_LEN = []
|
|
807
|
+
|
|
808
|
+
for eID in element_ids:
|
|
809
|
+
try:
|
|
810
|
+
elm_len = elemByID(eID).LENGTH
|
|
811
|
+
elem_IDS.append(eID)
|
|
812
|
+
elem_LEN.append(elm_len)
|
|
813
|
+
# print(f"ID = {eID} LEN = {elm_len}")
|
|
814
|
+
except: pass
|
|
815
|
+
cum_LEN = np.insert(np.cumsum(elem_LEN),0,0)
|
|
816
|
+
tot_LEN = cum_LEN[-1]
|
|
817
|
+
|
|
818
|
+
if distType == 'Rel':
|
|
819
|
+
D = np.array(D)*tot_LEN
|
|
820
|
+
|
|
821
|
+
if type == 'CONLOAD':
|
|
822
|
+
for i in range(len(D)):
|
|
823
|
+
for q in range(len(cum_LEN)):
|
|
824
|
+
if D[i] >= 0:
|
|
825
|
+
if D[i] < cum_LEN[q] :
|
|
826
|
+
# print(f'LOADING ELEMENT at {D[i]}m = {elem_IDS[q-1]}')
|
|
827
|
+
rel_loc = (D[i] - cum_LEN[q-1]) / elem_LEN[q-1]
|
|
828
|
+
# print(f"Relative location = {rel_loc}")
|
|
829
|
+
Load.Beam(element=elem_IDS[q-1],load_case=load_case,load_group=load_group,D=[rel_loc],P=[P[i]],direction=direction,
|
|
830
|
+
typ = "CONLOAD", use_ecc = use_ecc, use_proj = use_proj,
|
|
831
|
+
eccn_dir = eccn_dir, eccn_type = eccn_type, ieccn = ieccn, jeccn = jeccn, adnl_h = adnl_h, adnl_h_i = adnl_h_i, adnl_h_j = adnl_h_j,id=id)
|
|
832
|
+
break
|
|
833
|
+
if D[-1] == tot_LEN:
|
|
834
|
+
Load.Beam(element=elem_IDS[-1],load_case=load_case,load_group=load_group,D=[1,0,0,0],P=[P[-1]],direction=direction,
|
|
835
|
+
typ = "CONLOAD", use_ecc = use_ecc, use_proj = use_proj,
|
|
836
|
+
eccn_dir = eccn_dir, eccn_type = eccn_type, ieccn = ieccn, jeccn = jeccn, adnl_h = adnl_h, adnl_h_i = adnl_h_i, adnl_h_j = adnl_h_j,id=id)
|
|
837
|
+
|
|
838
|
+
if type == 'UNILOAD':
|
|
839
|
+
n_req = len(D)-1
|
|
840
|
+
D_orig = D
|
|
841
|
+
P_orig = P
|
|
842
|
+
for k in range(n_req):
|
|
843
|
+
D = D_orig[0+k:2+k]
|
|
844
|
+
P = P_orig[0+k:2+k]
|
|
845
|
+
elms_indx = []
|
|
846
|
+
for i in range(2):
|
|
847
|
+
for q in range(len(cum_LEN)):
|
|
848
|
+
if D[i] < cum_LEN[q] :
|
|
849
|
+
# print(f'LOADING ELEMENT at {D[i]}m = {elem_IDS[q-1]}')
|
|
850
|
+
elms_indx.append(q-1)
|
|
851
|
+
# rel_loc = (D[i] - cum_LEN[q-1]) / elem_LEN[q-1]
|
|
852
|
+
break
|
|
853
|
+
if len(elms_indx)==1: elms_indx.append(len(cum_LEN)-2)
|
|
854
|
+
if elms_indx != []:
|
|
855
|
+
for i in range(elms_indx[0],elms_indx[1]+1):
|
|
856
|
+
rel1 = float((max(D[0],cum_LEN[i]) - cum_LEN[i]) / elem_LEN[i])
|
|
857
|
+
rel2 = float((min(D[1],cum_LEN[i+1]) - cum_LEN[i]) / elem_LEN[i])
|
|
858
|
+
|
|
859
|
+
p1 = float(P[0]+(max(D[0],cum_LEN[i])-D[0])*(P[1]-P[0])/(D[1]-D[0]))
|
|
860
|
+
p2 = float(P[0]+(min(D[1],cum_LEN[i+1])-D[0])*(P[1]-P[0])/(D[1]-D[0]))
|
|
861
|
+
if rel2-rel1 == 0: continue
|
|
862
|
+
|
|
863
|
+
|
|
864
|
+
# print(f"Loading ELEM -> {elem_IDS[i]} , D1 = {rel1} , P1 = {p1} | D2 = {rel2} , P2 = {p2}")
|
|
865
|
+
# Load.Beam(elem_IDS[i],load_case,load_group,D=[rel1,rel2],P=[p1,p2],typ=typ,direction=direction)
|
|
866
|
+
Load.Beam(element=elem_IDS[i],load_case=load_case,load_group=load_group,D=[rel1,rel2],P=[p1,p2],direction=direction,
|
|
867
|
+
typ = "UNILOAD", use_ecc = use_ecc, use_proj = use_proj,
|
|
868
|
+
eccn_dir = eccn_dir, eccn_type = eccn_type, ieccn = ieccn, jeccn = jeccn, adnl_h = adnl_h, adnl_h_i = adnl_h_i, adnl_h_j = adnl_h_j,id = id)
|
|
869
|
+
|
|
870
|
+
|
|
871
|
+
|
|
872
|
+
class Pressure:
|
|
873
|
+
""" Assign Pressure load to plates faces.
|
|
874
|
+
|
|
875
|
+
"""
|
|
876
|
+
data = []
|
|
877
|
+
def __init__(self, element:list, load_case:str, load_group:str = "", D:_presDir='LZ', P:list=0, VectorDir:list = [1,0,0],bProjection:bool = False,id:int = None):
|
|
878
|
+
|
|
879
|
+
|
|
880
|
+
chk = 0
|
|
881
|
+
for i in Load_Case.cases:
|
|
882
|
+
if load_case in i.NAME: chk = 1
|
|
883
|
+
if chk == 0: Load_Case("D", load_case)
|
|
884
|
+
if load_group != "":
|
|
885
|
+
chk = 0
|
|
886
|
+
a = [v['NAME'] for v in Group.Load.json()["Assign"].values()]
|
|
887
|
+
if load_group in a: chk = 1
|
|
888
|
+
if chk == 0: Group.Load(load_group)
|
|
889
|
+
|
|
890
|
+
|
|
891
|
+
self.ELEM = element
|
|
892
|
+
self.LCN = load_case
|
|
893
|
+
self.LDGR = load_group
|
|
894
|
+
self.DIR = D
|
|
895
|
+
self.VECTOR = VectorDir
|
|
896
|
+
self.PRES = P
|
|
897
|
+
|
|
898
|
+
if D in ['GX','GY','GZ']: self.bPROJ = bProjection
|
|
899
|
+
else: self.bPROJ = False
|
|
900
|
+
|
|
901
|
+
if id is None:
|
|
902
|
+
self.ID = len(Load.Pressure.data) + 1
|
|
903
|
+
else:
|
|
904
|
+
self.ID = id
|
|
905
|
+
|
|
906
|
+
_ADD_PressureLoad(self)
|
|
907
|
+
|
|
908
|
+
|
|
909
|
+
@classmethod
|
|
910
|
+
def json(cls):
|
|
911
|
+
json = {"Assign": {}}
|
|
912
|
+
for i in cls.data:
|
|
913
|
+
if i.ELEM not in list(json["Assign"].keys()):
|
|
914
|
+
json["Assign"][i.ELEM] = {"ITEMS": []}
|
|
915
|
+
|
|
916
|
+
js = {
|
|
917
|
+
"ID": i.ID,
|
|
918
|
+
"LCNAME": i.LCN,
|
|
919
|
+
"GROUP_NAME": i.LDGR,
|
|
920
|
+
"CMD": "PRES",
|
|
921
|
+
"ELEM_TYPE": "PLATE",
|
|
922
|
+
"FACE_EDGE_TYPE": "FACE",
|
|
923
|
+
"DIRECTION": i.DIR,
|
|
924
|
+
"VECTORS" : i.VECTOR,
|
|
925
|
+
"FORCES": i.PRES
|
|
926
|
+
}
|
|
927
|
+
if isinstance(i.PRES,float): newP = [i.PRES,0,0,0,0]
|
|
928
|
+
elif isinstance(i.PRES,list):
|
|
929
|
+
trimP = i.PRES[:4]
|
|
930
|
+
newP = [0] + trimP
|
|
931
|
+
js["FORCES"] = newP
|
|
932
|
+
if i.bPROJ:
|
|
933
|
+
js["OPT_PROJECTION"] = True
|
|
934
|
+
|
|
935
|
+
json["Assign"][i.ELEM]["ITEMS"].append(js)
|
|
936
|
+
|
|
937
|
+
return json
|
|
938
|
+
|
|
939
|
+
@classmethod
|
|
940
|
+
def create(cls):
|
|
941
|
+
MidasAPI("PUT", "/db/PRES",cls.json())
|
|
942
|
+
|
|
943
|
+
@classmethod
|
|
944
|
+
def get(cls):
|
|
945
|
+
return MidasAPI("GET", "/db/PRES")
|
|
946
|
+
|
|
947
|
+
@classmethod
|
|
948
|
+
def delete(cls):
|
|
949
|
+
cls.clear()
|
|
950
|
+
return MidasAPI("DELETE", "/db/PRES")
|
|
951
|
+
|
|
952
|
+
@classmethod
|
|
953
|
+
def clear(cls):
|
|
954
|
+
cls.data=[]
|
|
955
|
+
|
|
956
|
+
# @classmethod
|
|
957
|
+
# def sync(cls):
|
|
958
|
+
# cls.data = []
|
|
959
|
+
# a = cls.get()
|
|
960
|
+
# if a != {'message': ''}:
|
|
961
|
+
# for i in a['PRES'].keys():
|
|
962
|
+
# for j in range(len(a['CNLD'][i]['ITEMS'])):
|
|
963
|
+
# Load.Nodal(int(i),a['CNLD'][i]['ITEMS'][j]['LCNAME'], a['CNLD'][i]['ITEMS'][j]['GROUP_NAME'],
|
|
964
|
+
# a['CNLD'][i]['ITEMS'][j]['FX'], a['CNLD'][i]['ITEMS'][j]['FY'], a['CNLD'][i]['ITEMS'][j]['FZ'],
|
|
965
|
+
# a['CNLD'][i]['ITEMS'][j]['MX'], a['CNLD'][i]['ITEMS'][j]['MY'], a['CNLD'][i]['ITEMS'][j]['MZ'],
|
|
966
|
+
# a['CNLD'][i]['ITEMS'][j]['ID'])
|
|
967
|
+
|