ANYstructure 5.2.0__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 (99) hide show
  1. anystruct/ANYstructure_documentation.pdf +0 -0
  2. anystruct/SN_curve_parameters.py +35 -0
  3. anystruct/__init__.py +0 -0
  4. anystruct/__main__.py +24 -0
  5. anystruct/api.py +772 -0
  6. anystruct/buckling_calc_external.py +120 -0
  7. anystruct/bulb_anglebar_tbar_flatbar.csv +677 -0
  8. anystruct/calc_loads.py +526 -0
  9. anystruct/calc_structure.py +4838 -0
  10. anystruct/compartment_window.py +176 -0
  11. anystruct/example_data.py +532 -0
  12. anystruct/example_data_puls.py +46 -0
  13. anystruct/excel_inteface.py +244 -0
  14. anystruct/fatigue_window.py +352 -0
  15. anystruct/grid_window.py +307 -0
  16. anystruct/gui.py +24 -0
  17. anystruct/helper.py +623 -0
  18. anystruct/images/ANYstructure_logo.jpg +0 -0
  19. anystruct/images/Buckling_Strength_of_Shells.png +0 -0
  20. anystruct/images/Panel_geometry_definitions.png +0 -0
  21. anystruct/images/current_comps_NONE.png +0 -0
  22. anystruct/images/fls_button.gif +0 -0
  23. anystruct/images/img_T_L_FB.gif +0 -0
  24. anystruct/images/img_axial_stresses.gif +0 -0
  25. anystruct/images/img_ext_pressure_button.gif +0 -0
  26. anystruct/images/img_ext_pressure_button_def.gif +0 -0
  27. anystruct/images/img_fixation_parameters.gif +0 -0
  28. anystruct/images/img_generate_report.gif +0 -0
  29. anystruct/images/img_int_pressure_button.gif +0 -0
  30. anystruct/images/img_int_pressure_button_search.gif +0 -0
  31. anystruct/images/img_multi_opt.gif +0 -0
  32. anystruct/images/img_optimize.gif +0 -0
  33. anystruct/images/img_plate_and_stiffener.gif +0 -0
  34. anystruct/images/img_stf_button.gif +0 -0
  35. anystruct/images/img_stiffener.gif +0 -0
  36. anystruct/images/img_stress_button.gif +0 -0
  37. anystruct/images/img_title.gif +0 -0
  38. anystruct/images/img_transverse_stress.gif +0 -0
  39. anystruct/load_factor_window.py +166 -0
  40. anystruct/load_window.py +721 -0
  41. anystruct/main_application.py +7918 -0
  42. anystruct/make_grid_numpy.py +506 -0
  43. anystruct/make_queue.py +52 -0
  44. anystruct/make_stack.py +52 -0
  45. anystruct/ml_files/CL_CSR-Tank_req_cl_predictor.pickle +0 -0
  46. anystruct/ml_files/CL_CSR-Tank_req_cl_scaler.pickle +0 -0
  47. anystruct/ml_files/CL_CSR_plate_cl,_CSR_web_cl,_CSR_web_flange_cl,_CSR_flange_cl_predictor.pickle +0 -0
  48. anystruct/ml_files/CL_CSR_plate_cl,_CSR_web_cl,_CSR_web_flange_cl,_CSR_flange_cl_scaler.pickle +0 -0
  49. anystruct/ml_files/CL_output_cl_str_buc_110_predictor_In-plane_support_cl_1_SP.pickle +0 -0
  50. anystruct/ml_files/CL_output_cl_str_buc_110_predictor_In-plane_support_cl_1_UP.pickle +0 -0
  51. anystruct/ml_files/CL_output_cl_str_buc_110_predictor_In-plane_support_cl_2,_3_SP.pickle +0 -0
  52. anystruct/ml_files/CL_output_cl_str_buc_110_predictor_In-plane_support_cl_2,_3_UP.pickle +0 -0
  53. anystruct/ml_files/CL_output_cl_str_buc_110_scaler_In-plane_support_cl_1_SP.pickle +0 -0
  54. anystruct/ml_files/CL_output_cl_str_buc_110_scaler_In-plane_support_cl_1_UP.pickle +0 -0
  55. anystruct/ml_files/CL_output_cl_str_buc_110_scaler_In-plane_support_cl_2,_3_SP.pickle +0 -0
  56. anystruct/ml_files/CL_output_cl_str_buc_110_scaler_In-plane_support_cl_2,_3_UP.pickle +0 -0
  57. anystruct/ml_files/CL_output_cl_str_buc_115_predictor_In-plane_support_cl_1_SP.pickle +0 -0
  58. anystruct/ml_files/CL_output_cl_str_buc_115_predictor_In-plane_support_cl_1_UP.pickle +0 -0
  59. anystruct/ml_files/CL_output_cl_str_buc_115_predictor_In-plane_support_cl_2,_3_SP.pickle +0 -0
  60. anystruct/ml_files/CL_output_cl_str_buc_115_predictor_In-plane_support_cl_2,_3_UP.pickle +0 -0
  61. anystruct/ml_files/CL_output_cl_str_buc_115_scaler_In-plane_support_cl_1_SP.pickle +0 -0
  62. anystruct/ml_files/CL_output_cl_str_buc_115_scaler_In-plane_support_cl_1_UP.pickle +0 -0
  63. anystruct/ml_files/CL_output_cl_str_buc_115_scaler_In-plane_support_cl_2,_3_SP.pickle +0 -0
  64. anystruct/ml_files/CL_output_cl_str_buc_115_scaler_In-plane_support_cl_2,_3_UP.pickle +0 -0
  65. anystruct/ml_files/CL_output_cl_str_ult_110_predictor_In-plane_support_cl_1_SP.pickle +0 -0
  66. anystruct/ml_files/CL_output_cl_str_ult_110_predictor_In-plane_support_cl_1_UP.pickle +0 -0
  67. anystruct/ml_files/CL_output_cl_str_ult_110_predictor_In-plane_support_cl_2,_3_SP.pickle +0 -0
  68. anystruct/ml_files/CL_output_cl_str_ult_110_predictor_In-plane_support_cl_2,_3_UP.pickle +0 -0
  69. anystruct/ml_files/CL_output_cl_str_ult_110_scaler_In-plane_support_cl_1_SP.pickle +0 -0
  70. anystruct/ml_files/CL_output_cl_str_ult_110_scaler_In-plane_support_cl_1_UP.pickle +0 -0
  71. anystruct/ml_files/CL_output_cl_str_ult_110_scaler_In-plane_support_cl_2,_3_SP.pickle +0 -0
  72. anystruct/ml_files/CL_output_cl_str_ult_110_scaler_In-plane_support_cl_2,_3_UP.pickle +0 -0
  73. anystruct/ml_files/CL_output_cl_str_ult_115_predictor_In-plane_support_cl_1_SP.pickle +0 -0
  74. anystruct/ml_files/CL_output_cl_str_ult_115_predictor_In-plane_support_cl_1_UP.pickle +0 -0
  75. anystruct/ml_files/CL_output_cl_str_ult_115_predictor_In-plane_support_cl_2,_3_SP.pickle +0 -0
  76. anystruct/ml_files/CL_output_cl_str_ult_115_predictor_In-plane_support_cl_2,_3_UP.pickle +0 -0
  77. anystruct/ml_files/CL_output_cl_str_ult_115_scaler_In-plane_support_cl_1_SP.pickle +0 -0
  78. anystruct/ml_files/CL_output_cl_str_ult_115_scaler_In-plane_support_cl_1_UP.pickle +0 -0
  79. anystruct/ml_files/CL_output_cl_str_ult_115_scaler_In-plane_support_cl_2,_3_SP.pickle +0 -0
  80. anystruct/ml_files/CL_output_cl_str_ult_115_scaler_In-plane_support_cl_2,_3_UP.pickle +0 -0
  81. anystruct/opt_problem.py +31 -0
  82. anystruct/optimize.py +1680 -0
  83. anystruct/optimize_cylinder.py +898 -0
  84. anystruct/optimize_geometry.py +1708 -0
  85. anystruct/optimize_multiple_window.py +1507 -0
  86. anystruct/optimize_window.py +1117 -0
  87. anystruct/pl_stf_window.py +572 -0
  88. anystruct/report_generator.py +912 -0
  89. anystruct/sections.csv +202 -0
  90. anystruct/sesam_interface.py +115 -0
  91. anystruct/ship_section_example.txt +1 -0
  92. anystruct/stresses_window.py +269 -0
  93. anystruct/testCalc.py +118 -0
  94. anystructure-5.2.0.dist-info/METADATA +86 -0
  95. anystructure-5.2.0.dist-info/RECORD +99 -0
  96. anystructure-5.2.0.dist-info/WHEEL +5 -0
  97. anystructure-5.2.0.dist-info/entry_points.txt +2 -0
  98. anystructure-5.2.0.dist-info/licenses/LICENSE +21 -0
  99. anystructure-5.2.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,4838 @@
1
+ from scipy.special import gammaln
2
+ from scipy.stats import gamma as gammadist
3
+ import numpy as np
4
+ from scipy.integrate import simpson
5
+ import os, time, datetime, json, random, math
6
+ from scipy.optimize import minimize
7
+
8
+ try:
9
+ import anystruct.helper as hlp
10
+ import anystruct.SN_curve_parameters as snc
11
+ except ModuleNotFoundError:
12
+ import ANYstructure.anystruct.helper as hlp
13
+ import ANYstructure.anystruct.SN_curve_parameters as snc
14
+
15
+ class Structure():
16
+ '''
17
+ Setting the properties for the plate and the stiffener. Takes a dictionary as argument.
18
+ '''
19
+ def __init__(self, main_dict: dict = None, *args, **kwargs):
20
+ super(Structure,self).__init__()
21
+ if main_dict is None:
22
+ self._panel_or_shell = None
23
+ self._plate_th = None
24
+ self._web_height = None
25
+ self._web_th = None
26
+ self._flange_width = None
27
+ self._flange_th = None
28
+ self._mat_yield = None
29
+ self._mat_factor = None
30
+ self._span = None
31
+ self._spacing = None
32
+ self._structure_type = None
33
+ self._sigma_y1 = None
34
+ self._sigma_y2 = None
35
+ self._sigma_x1 = None
36
+ self._sigma_x2 = None
37
+ self._tauxy = None
38
+ self._plate_kpp = None
39
+ self._stf_kps = None
40
+ self._km1 = None
41
+ self._km2 = None
42
+ self._km3 = None
43
+ self._stiffener_type = None
44
+ self._structure_types = None
45
+ self._dynamic_variable_orientation = None
46
+ if self._structure_type is None:
47
+ self._dynamic_variable_orientation = None
48
+ self._puls_method = None
49
+ self._puls_boundary = None
50
+ self._puls_stf_end = None
51
+ self._puls_sp_or_up = None
52
+ self._puls_up_boundary = None
53
+ self._zstar_optimization = None
54
+ try:
55
+ self._girder_lg = None
56
+ except KeyError:
57
+ self._girder_lg = None
58
+ try:
59
+ self._pressure_side = None
60
+ except KeyError:
61
+ self._pressure_side = None
62
+ self._panel_or_shell = None
63
+ else:
64
+ self._main_dict = main_dict
65
+ if 'panel or shell' not in main_dict.keys():
66
+ self._panel_or_shell = 'panel'
67
+ else:
68
+ self._panel_or_shell = main_dict['panel or shell'][0]
69
+ self._plate_th = main_dict['plate_thk'][0]
70
+ self._web_height = main_dict['stf_web_height'][0]
71
+ self._web_th = main_dict['stf_web_thk'][0]
72
+ self._flange_width = main_dict['stf_flange_width'][0]
73
+ self._flange_th = main_dict['stf_flange_thk'][0]
74
+ self._mat_yield = main_dict['mat_yield'][0]
75
+ self._mat_factor = main_dict['mat_factor'][0]
76
+ self._span = main_dict['span'][0]
77
+ self._spacing = main_dict['spacing'][0]
78
+ self._structure_type = main_dict['structure_type'][0]
79
+ self._sigma_y1=main_dict['sigma_y1'][0]
80
+ self._sigma_y2=main_dict['sigma_y2'][0]
81
+ self._sigma_x1 = main_dict['sigma_x1'][0]
82
+ self._sigma_x2 = main_dict['sigma_x2'][0]
83
+ self._tauxy=main_dict['tau_xy'][0]
84
+ self._plate_kpp = main_dict['plate_kpp'][0]
85
+ self._stf_kps = main_dict['stf_kps'][0]
86
+ self._km1 = main_dict['stf_km1'][0]
87
+ self._km2 = main_dict['stf_km2'][0]
88
+ self._km3 = main_dict['stf_km3'][0]
89
+ self._stiffener_type=main_dict['stf_type'][0]
90
+ self._structure_types = main_dict['structure_types'][0]
91
+ self._dynamic_variable_orientation = None
92
+ if self._structure_type in self._structure_types['vertical']:
93
+ self._dynamic_variable_orientation = 'z - vertical'
94
+ elif self._structure_type in self._structure_types['horizontal']:
95
+ self._dynamic_variable_orientation = 'x - horizontal'
96
+ self._puls_method = main_dict['puls buckling method'][0]
97
+ self._puls_boundary = main_dict['puls boundary'][0]
98
+ self._puls_stf_end = main_dict['puls stiffener end'][0]
99
+ self._puls_sp_or_up = main_dict['puls sp or up'][0]
100
+ self._puls_up_boundary = main_dict['puls up boundary'][0]
101
+
102
+ self._zstar_optimization = main_dict['zstar_optimization'][0]
103
+ try:
104
+ self._girder_lg=main_dict['girder_lg'][0]
105
+ except KeyError:
106
+ self._girder_lg = 10
107
+ try:
108
+ self._pressure_side = main_dict['press_side'][0]
109
+ except KeyError:
110
+ self._pressure_side = 'both sides'
111
+ self._panel_or_shell = main_dict['panel or shell'][0]
112
+
113
+ # Property decorators are used in buckling of shells. IN mm!
114
+ @property # in mm
115
+ def hw(self):
116
+ assert self._web_height is not None, 'Variable missing: self._web_height'
117
+ return self._web_height * 1000
118
+ @hw.setter # in mm
119
+ def hw(self, val):
120
+ self._web_height = val / 1000
121
+ @property # in mm
122
+ def tw(self):
123
+ assert self._web_th is not None, 'Variable missing: self._web_th - web thickness'
124
+ return self._web_th * 1000
125
+ @tw.setter # in mm
126
+ def tw(self, val):
127
+ self._web_th = val / 1000
128
+ @property # in mm
129
+ def b(self):
130
+ assert self._flange_width is not None, 'Variable missing: self._flange_width'
131
+ return self._flange_width * 1000
132
+ @b.setter # in mm
133
+ def b(self, val):
134
+ self._flange_width = val / 1000
135
+ @property # in mm
136
+ def tf(self):
137
+ assert self._flange_th is not None, 'Variable missing: self._flange_th'
138
+ return self._flange_th * 1000
139
+ @tf.setter # in mm
140
+ def tf(self, val):
141
+ self._flange_th = val / 1000
142
+ @property # in mm
143
+ def spacing(self):
144
+ assert self._spacing is not None, 'Variable missing: self._spacing'
145
+ return self._spacing* 1000
146
+ @spacing.setter # in mm
147
+ def spacing(self, val):
148
+ self._spacing = val / 1000
149
+ @property # in mm
150
+ def t(self):
151
+ assert self._plate_th is not None, 'Variable missing: self._plate_th'
152
+ return self._plate_th* 1000
153
+ @t.setter # in mm
154
+ def t(self, val):
155
+ self._plate_th = val / 1000
156
+ @property # in mm
157
+ def panel_or_shell(self):
158
+
159
+ return self._panel_or_shell
160
+ @panel_or_shell.setter # in mm
161
+ def panel_or_shell(self, val):
162
+ self._panel_or_shell = val
163
+ @property
164
+ def stiffener_type(self):
165
+ return self._stiffener_type
166
+ @stiffener_type.setter
167
+ def stiffener_type(self, val):
168
+ self._stiffener_type = val
169
+
170
+ @property
171
+ def E(self):
172
+ return self._E
173
+ @E.setter
174
+ def E(self, val):
175
+ self._E = val
176
+ @property
177
+ def v(self):
178
+ return self._v
179
+ @v.setter
180
+ def v(self, val):
181
+ self._v = val
182
+ @property
183
+ def mat_yield(self):
184
+ return self._mat_yield
185
+ @mat_yield.setter
186
+ def mat_yield(self, val):
187
+ self._mat_yield = val
188
+
189
+ @property
190
+ def mat_factor(self):
191
+ assert self._mat_factor is not None, 'Missing variable: self._mat_factor'
192
+ return self._mat_factor
193
+ @mat_factor.setter
194
+ def mat_factor(self, val):
195
+ self._mat_factor = val
196
+
197
+ @property
198
+ def span(self):
199
+ assert self._span is not None, 'Missing variable: self._span: span of stiffener'
200
+ return self._span
201
+ @span.setter
202
+ def span(self, val):
203
+ self._span = val
204
+
205
+ @property
206
+ def sigma_x1(self):
207
+ assert self._sigma_x1 is not None, 'Missing variable: self._sigma_x1'
208
+ return self._sigma_x1
209
+ @sigma_x1.setter
210
+ def sigma_x1(self, val):
211
+ self._sigma_x1 = val
212
+ @property
213
+ def sigma_x2(self):
214
+ assert self._sigma_x2 is not None, 'Missing variable: self._sigma_x2'
215
+ return self._sigma_x2
216
+ @sigma_x2.setter
217
+ def sigma_x2(self, val):
218
+ self._sigma_x2 = val
219
+
220
+ @property
221
+ def sigma_y1(self):
222
+ assert self._sigma_y1 is not None, 'Missing variable: self._sigma_y1'
223
+ return self._sigma_y1
224
+ @sigma_y1.setter
225
+ def sigma_y1(self, val):
226
+ self._sigma_y1 = val
227
+
228
+ @property
229
+ def sigma_y2(self):
230
+ assert self._sigma_y2 is not None, 'Missing variable: self._sigma_y2'
231
+ return self._sigma_y2
232
+ @sigma_y2.setter
233
+ def sigma_y2(self, val):
234
+ self._sigma_y2 = val
235
+
236
+ @property
237
+ def tau_xy(self):
238
+ assert self._tauxy is not None, 'Missing variable: self._tauxy'
239
+ return self._tauxy
240
+ @tau_xy.setter
241
+ def tau_xy(self, val):
242
+ self._tauxy = val
243
+
244
+ @property
245
+ def girder_lg(self):
246
+ assert self._girder_lg is not None, 'Missing variable: self._girder_lg'
247
+ return self._girder_lg
248
+ @girder_lg.setter
249
+ def girder_lg(self, val):
250
+ self._girder_lg = val
251
+
252
+
253
+ def __str__(self):
254
+ '''
255
+ Returning all properties.
256
+ '''
257
+ try:
258
+ return \
259
+ str(
260
+ '\n Plate field span: ' + str(round(self._span*1000)) + ' mm' +
261
+ '\n Stiffener spacing: ' + str(self._spacing*1000)+' mm'+
262
+ '\n Plate thickness: ' + str(self._plate_th*1000)+' mm'+
263
+ '\n Stiffener web height: ' + str(self._web_height*1000)+' mm'+
264
+ '\n Stiffener web thickness: ' + str(self._web_th*1000)+' mm'+
265
+ '\n Stiffener flange width: ' + str(self._flange_width*1000)+' mm'+
266
+ '\n Stiffener flange thickness: ' + str(self._flange_th*1000)+' mm'+
267
+ '\n Material yield: ' + str(self._mat_yield/1e6)+' MPa'+
268
+ '\n Structure/stiffener type: ' + str(self._structure_type)+'/'+(self._stiffener_type)+
269
+ '\n Dynamic load varible_ ' + str(self._dynamic_variable_orientation)+
270
+ '\n Plate fixation paramter,kpp: ' + str(self._plate_kpp) + ' ' +
271
+ '\n Stf. fixation paramter,kps: ' + str(self._stf_kps) + ' ' +
272
+ '\n Global stress, sig_y1/sig_y2: ' + str(round(self._sigma_y1,3))+'/'+str(round(self._sigma_y2,3))+ ' MPa' +
273
+ '\n Global stress, sig_x1/sig_x2: ' + str(round(self._sigma_x1,3))+'/'+str(round(self._sigma_x2,3))+ ' MPa' +
274
+ '\n Global shear, tau_xy: ' + str(round(self._tauxy,3)) + ' MPa' +
275
+ '\n km1,km2,km3: ' + str(self._km1)+'/'+str(self._km2)+'/'+str(self._km3)+
276
+ '\n Pressure side (p-plate/s-stf): ' + str(self._pressure_side) + ' ')
277
+ except TypeError:
278
+ return \
279
+ str(
280
+ '\n Stiffener spacing: ' + str(self._spacing * 1000) + ' mm' +
281
+ '\n Plate thickness: ' + str(self._plate_th * 1000) + ' mm' +
282
+ '\n Stiffener web height: ' + str(self._web_height * 1000) + ' mm' +
283
+ '\n Stiffener web thickness: ' + str(self._web_th * 1000) + ' mm' +
284
+ '\n Stiffener flange width: ' + str(self._flange_width * 1000) + ' mm' +
285
+ '\n Stiffener flange thickness: ' + str(self._flange_th * 1000) + ' mm' )
286
+
287
+ def get_beam_string(self, short = False):
288
+ ''' Returning a string. '''
289
+ if type(self._stiffener_type) != str:
290
+ print('error')
291
+
292
+ base_name = self._stiffener_type+ '_' + str(round(self._web_height*1000, 0)) + 'x' + \
293
+ str(round(self._web_th*1000, 0))
294
+ if self._stiffener_type == 'FB':
295
+ ret_str = base_name
296
+ elif self._stiffener_type in ['L-bulb', 'bulb', 'hp']:
297
+ if not short:
298
+ ret_str = 'Bulb'+str(int(self._web_height*1000 + self._flange_th*1000))+'x'+\
299
+ str(round(self._web_th*1000, 0))+ '_(' +str(round(self._web_height*1000, 0)) + 'x' + \
300
+ str(round(self._web_th*1000, 0))+'_'+ str(round(self._flange_width*1000, 0)) + 'x' + \
301
+ str(round(self._flange_th*1000, 0))+')'
302
+ else:
303
+ ret_str = 'Bulb'+str(int(self._web_height*1000 + self._flange_th*1000))+'x'+\
304
+ str(round(self._web_th*1000, 0))
305
+ else:
306
+ ret_str = base_name + '__' + str(round(self._flange_width*1000, 0)) + 'x' + \
307
+ str(round(self._flange_th*1000, 0))
308
+
309
+ ret_str = ret_str.replace('.', '_')
310
+
311
+ return ret_str
312
+ # base_name = self._stiffener_type+ '_' + str(round(self._web_height*1000, 0)) + 'x' + \
313
+ # str(round(self._web_th*1000, 0))
314
+ # if self._stiffener_type == 'FB':
315
+ # ret_str = base_name
316
+ # else:
317
+ # ret_str = base_name + '__' + str(round(self._flange_width*1000, 0)) + 'x' + \
318
+ # str(round(self._flange_th*1000, 0))
319
+ #
320
+ # ret_str = ret_str.replace('.', '_')
321
+ #
322
+ # return ret_str
323
+
324
+ def get_structure_types(self):
325
+ return self._structure_types
326
+
327
+ def get_z_opt(self):
328
+ return self._zstar_optimization
329
+
330
+ def get_puls_method(self):
331
+ return self._puls_method
332
+
333
+ def get_puls_boundary(self):
334
+ return self._puls_boundary
335
+
336
+ def get_puls_stf_end(self):
337
+ return self._puls_stf_end
338
+
339
+ def get_puls_sp_or_up(self):
340
+ return self._puls_sp_or_up
341
+
342
+ def get_puls_up_boundary(self):
343
+ return self._puls_up_boundary
344
+
345
+ def get_one_line_string(self):
346
+ ''' Returning a one line string. '''
347
+ return 'pl_'+str(round(self._spacing*1000, 1))+'x'+str(round(self._plate_th*1000,1))+' stf_'+self._stiffener_type+\
348
+ str(round(self._web_height*1000,1))+'x'+str(round(self._web_th*1000,1))+'+'\
349
+ +str(round(self._flange_width*1000,1))+'x'+\
350
+ str(round(self._flange_th*1000,1))
351
+
352
+ def get_report_stresses(self):
353
+ 'Return the stresses to the report'
354
+ return 'sigma_y1: '+str(round(self._sigma_y1,1))+' sigma_y2: '+str(round(self._sigma_y2,1))+ \
355
+ ' sigma_x1: ' + str(round(self._sigma_x1,1)) +' sigma_x2: ' + str(round(self._sigma_x2,1))+\
356
+ ' tauxy: '+ str(round(self._tauxy,1))
357
+
358
+ def get_extended_string(self):
359
+ ''' Some more information returned. '''
360
+ return 'span: '+str(round(self._span,4))+' structure type: '+ self._structure_type + ' stf. type: ' + \
361
+ self._stiffener_type + ' pressure side: ' + self._pressure_side
362
+
363
+ def get_s(self):
364
+ '''
365
+ Return the spacing
366
+ :return:
367
+ '''
368
+ return self._spacing
369
+ def get_pl_thk(self):
370
+ '''
371
+ Return the plate thickness
372
+ :return:
373
+ '''
374
+ return self._plate_th
375
+ def get_web_h(self):
376
+ '''
377
+ Return the web heigh
378
+ :return:
379
+ '''
380
+ return self._web_height
381
+ def get_web_thk(self):
382
+ '''
383
+ Return the spacing
384
+ :return:
385
+ '''
386
+ return self._web_th
387
+ def get_fl_w(self):
388
+ '''
389
+ Return the flange width
390
+ :return:
391
+ '''
392
+ return self._flange_width
393
+ def get_fl_thk(self):
394
+ '''
395
+ Return the flange thickness
396
+ :return:
397
+ '''
398
+ return self._flange_th
399
+ def get_fy(self):
400
+ '''
401
+ Return material yield
402
+ :return:
403
+ '''
404
+ return self._mat_yield
405
+
406
+ def get_span(self):
407
+ '''
408
+ Return the span
409
+ :return:
410
+ '''
411
+ return self._span
412
+ def get_kpp(self):
413
+ '''
414
+ Return var
415
+ :return:
416
+ '''
417
+ return self._plate_kpp
418
+ def get_kps(self):
419
+ '''
420
+ Return var
421
+ :return:
422
+ '''
423
+ return self._stf_kps
424
+ def get_km1(self):
425
+ '''
426
+ Return var
427
+ :return:
428
+ '''
429
+ return self._km1
430
+ def get_km2(self):
431
+ '''
432
+ Return var
433
+ :return:
434
+ '''
435
+ return self._km2
436
+ def get_km3(self):
437
+ '''
438
+ Return var
439
+ :return:
440
+ '''
441
+ return self._km3
442
+ def get_side(self):
443
+ '''
444
+ Return the checked pressure side.
445
+ :return:
446
+ '''
447
+ return self._pressure_side
448
+ def get_tuple(self):
449
+ ''' Return a tuple of the plate stiffener'''
450
+ return (self._spacing, self._plate_th, self._web_height, self._web_th, self._flange_width,
451
+ self._flange_th, self._span, self._girder_lg, self._stiffener_type)
452
+
453
+ def get_section_modulus(self, efficient_se = None, dnv_table = False):
454
+ '''
455
+ Returns the section modulus.
456
+ :param efficient_se:
457
+ :return:
458
+ '''
459
+ #Plate. When using DNV table, default values are used for the plate
460
+ b1 = self._spacing if efficient_se==None else efficient_se
461
+ tf1 = self._plate_th
462
+
463
+ #Stiffener
464
+ tf2 = self._flange_th
465
+ b2 = self._flange_width
466
+ h = self._flange_th+self._web_height+self._plate_th
467
+ tw = self._web_th
468
+ hw = self._web_height
469
+
470
+ # cross section area
471
+ Ax = tf1 * b1 + tf2 * b2 + hw * tw
472
+
473
+ assert Ax != 0, 'Ax cannot be 0'
474
+ # distance to center of gravity in z-direction
475
+ ez = (tf1 * b1 * tf1 / 2 + hw * tw * (tf1 + hw / 2) + tf2 * b2 * (tf1 + hw + tf2 / 2)) / Ax
476
+
477
+ #ez = (tf1 * b1 * (h - tf1 / 2) + hw * tw * (tf2 + hw / 2) + tf2 * b2 * (tf2 / 2)) / Ax
478
+ # moment of inertia in y-direction (c is centroid)
479
+
480
+ Iyc = (1 / 12) * (b1 * math.pow(tf1, 3) + b2 * math.pow(tf2, 3) + tw * math.pow(hw, 3))
481
+ Iy = Iyc + (tf1 * b1 * math.pow(tf1 / 2, 2) + tw * hw * math.pow(tf1+hw / 2, 2) +
482
+ tf2 * b2 * math.pow(tf1+hw+tf2 / 2, 2)) - Ax * math.pow(ez, 2)
483
+
484
+ # elastic section moduluses y-axis
485
+ Wey1 = Iy / (h - ez)
486
+ Wey2 = Iy / ez
487
+
488
+ return Wey1, Wey2
489
+ def get_plasic_section_modulus(self):
490
+ '''
491
+ Returns the plastic section modulus
492
+ :return:
493
+ '''
494
+ tf1 = self._plate_th
495
+ tf2 = self._flange_th
496
+ b1 = self._spacing
497
+ b2 = self._flange_width
498
+ h = self._flange_th+self._web_height+self._plate_th
499
+ tw = self._web_th
500
+ hw = self._web_height
501
+
502
+ Ax = tf1 * b1 + tf2 * b2 + (h-tf1-tf2) * tw
503
+
504
+ ezpl = (Ax/2-b1*tf1)/tw+tf1
505
+
506
+ az1 = h-ezpl-tf1
507
+ az2 = ezpl-tf2
508
+
509
+ Wy1 = b1*tf1*(az1+tf1/2) + (tw/2)*math.pow(az1,2)
510
+ Wy2 = b2*tf2*(az2+tf2/2)+(tw/2)*math.pow(az2,2)
511
+
512
+ return Wy1+Wy2
513
+ def get_shear_center(self):
514
+ '''
515
+ Returning the shear center
516
+ :return:
517
+ '''
518
+ tf1 = self._plate_th
519
+ tf2 = self._flange_th
520
+ b1 = self._spacing
521
+ b2 = self._flange_width
522
+ h = self._flange_th+self._web_height+self._plate_th
523
+ tw = self._web_th
524
+ hw = self._web_height
525
+ Ax = tf1 * b1 + tf2 * b2 + (h-tf1-tf2) * tw
526
+ # distance to center of gravity in z-direction
527
+ ez = (b2*tf2*tf2/2 + tw*hw*(tf2+hw/2)+tf1*b1*(tf2+hw+tf1/2)) / Ax
528
+
529
+ # Shear center:
530
+ # moment of inertia, z-axis
531
+ Iz1 = tf1 * math.pow(b1, 3)
532
+ Iz2 = tf2 * math.pow(b2, 3)
533
+ ht = h - tf1 / 2 - tf2 / 2
534
+ return (Iz1 * ht) / (Iz1 + Iz2) + tf2 / 2 - ez
535
+
536
+ def get_moment_of_intertia_hp(self):
537
+
538
+ # class Stiffener:
539
+ # def __init__(self, h, tw, plate_width, plate_thickness):
540
+ # self.h = h
541
+ # self.tw = tw
542
+ # self.bf = 2.5 * self.tw
543
+ # self.tf = 2.5 * self.tw
544
+ # self.r = self.tw
545
+ # self.plate_width = plate_width
546
+ # self.plate_thickness = plate_thickness
547
+ #
548
+ # @classmethod
549
+ # def from_hp(cls, h, tw, plate_width, plate_thickness):
550
+ # return cls(h, tw, plate_width, plate_thickness)
551
+ #
552
+ # def _distance(self, x, c, r):
553
+ # y1 = (self.h - self.tf) / 2
554
+ # y2 = self.tf / 2
555
+ # if (x <= -c).any() or (x >= c).any():
556
+ # return np.abs(x) - c + r
557
+ # else:
558
+ # theta = np.arcsin((y1 - y2) / r)
559
+ # A1 = theta * r ** 2 / 2
560
+ # A2 = (y1 - r) * (x + c - r)
561
+ # A3 = (y2 - r) * (c - r) + r ** 2 * theta
562
+ # if x <= 0:
563
+ # return A1 - A2
564
+ # else:
565
+ # return A1 - A3 - (x - c - r) * y1
566
+ #
567
+ # def _integrand(self, x, c, r):
568
+ # y = self._distance(x, c, r)
569
+ # return y ** 2
570
+ #
571
+ # def get_moment_of_inertia_hp(self):
572
+ # # Create points for integration
573
+ # c = (self.h - 2 * self.tw) / 2
574
+ # r = self.tw
575
+ # x = np.linspace(-c, c, num=1000)
576
+ #
577
+ # # Integrate to find moment of inertia
578
+ # integrand = lambda x: self._integrand(x, c, r)
579
+ # y = self._distance(x, c, r)
580
+ # I = simps(y * integrand(x), x)
581
+ #
582
+ # return I
583
+ #
584
+ # def get_moment_of_inertia_plate(self):
585
+ # I_plate = (self.plate_width * self.plate_thickness ** 3) / 12
586
+ # return I_plate
587
+ #
588
+ # def get_moment_of_inertia_combined(self):
589
+ # I_stiffener = self.get_moment_of_inertia_hp()
590
+ # I_plate = self.get_moment_of_inertia_plate()
591
+ # I_combined = I_stiffener + I_plate
592
+ # return I_stiffener, I_plate, I_combined
593
+
594
+
595
+ class Stiffener:
596
+ def __init__(self, hp_height, hp_thickness, plate_width, plate_thickness):
597
+ self.hp_height = hp_height
598
+ self.hp_thickness = hp_thickness
599
+ self.plate_width = plate_width
600
+ self.plate_thickness = plate_thickness
601
+
602
+ def _integrand(self, x, c, r):
603
+ if (x <= -c).any() or (x >= c).any():
604
+ return (x ** 2 + r ** 2) ** 0.5
605
+ else:
606
+ return r
607
+
608
+ def _distance(self, x, c, r):
609
+ if (x <= -c).any() or (x >= c).any():
610
+ return self.hp_height / 2 - self.hp_thickness - r
611
+ elif x >= c:
612
+ return self.hp_height / 2 - self.hp_thickness - r
613
+ else:
614
+ return self.hp_height / 2 - self.hp_thickness - (x ** 2 - c ** 2) ** 0.5
615
+
616
+ def get_moment_of_inertia_hp(self):
617
+ # Create points for integration
618
+ c = (self.hp_height - 2 * self.hp_thickness) / 2
619
+ r = self.hp_thickness
620
+ x = np.linspace(-c, c, num=1000)
621
+
622
+ # Integrate to find moment of inertia
623
+ integrand = lambda x: self._integrand(x, c, r)
624
+ y = self._distance(x, c, r)
625
+ I = simpson(y * integrand(x), x)
626
+
627
+ return I
628
+
629
+ def get_moment_of_inertia(self):
630
+ I_stiffener = self.get_moment_of_inertia_hp()
631
+ I_plate = self.plate_thickness * (self.plate_width ** 3 / 12)
632
+ I_total = I_stiffener + I_plate
633
+
634
+ return I_stiffener, I_plate, I_total
635
+
636
+ stiffener = Stiffener(hp_height=300, hp_thickness=12, plate_width=680, plate_thickness=25)
637
+ I_stiffener, I_plate, I_total = stiffener.get_moment_of_inertia()
638
+ print(f"Moment of inertia of stiffener: {I_stiffener:.3e} mm^4")
639
+ print(f"Moment of inertia of plate: {I_plate:.3e} mm^4")
640
+ print(f"Moment of inertia of combined: {I_total:.3e} mm^4")
641
+
642
+ def get_moment_of_intertia(self, efficent_se=None, only_stf = False, tf1 = None, reduced_tw = None,
643
+ plate_thk = None, plate_spacing = None):
644
+ '''
645
+ Returning moment of intertia.
646
+ :return:
647
+ '''
648
+
649
+ if only_stf:
650
+ tf1 = t = 0
651
+ b1 = s_e = 0
652
+ else:
653
+ # if tf1 == None:
654
+ # tf1 = self._plate_th
655
+ tf1 = t = self._plate_th if tf1 == None else tf1
656
+ b1 = s_e =self._spacing if efficent_se==None else efficent_se
657
+
658
+ e_f = 0
659
+
660
+ h = self._flange_th+self._web_height+tf1
661
+ tw = self._web_th if reduced_tw == None else reduced_tw/1000
662
+ hw = self._web_height
663
+ tf2 = tf = self._flange_th
664
+ b2 = bf = self._flange_width
665
+
666
+ Ax = tf1 * b1 + tf2 * b2 + hw * tw
667
+ Iyc = (1 / 12) * (b1 * math.pow(tf1, 3) + b2 * math.pow(tf2, 3) + tw * math.pow(hw, 3))
668
+ ez = (tf1 * b1 * (h - tf1 / 2) + hw * tw * (tf2 + hw / 2) + tf2 * b2 * (tf2 / 2)) / Ax
669
+ Iy = Iyc + (tf1 * b1 * math.pow(tf2 + hw + tf1 / 2, 2) + tw * hw * math.pow(tf2 + hw / 2, 2) +
670
+ tf2 * b2 * math.pow(tf2 / 2, 2)) - Ax * math.pow(ez, 2)
671
+
672
+ # ###
673
+ # z_c = bf * tf * e_f / (s_e * t + hw * tw + bf * tf)
674
+ # I_z = 1.0 / 12.0 * t * math.pow(s_e,3) + 1.0 / 12.0 * hw * math.pow(tw,3) + 1.0 / 12.0 * tf * math.pow(bf,3) +\
675
+ # t * s_e * math.pow(z_c,2) + \
676
+ # tw * hw * math.pow(z_c,2) + bf * tf * math.pow(e_f - z_c,2)
677
+ # ###
678
+ #
679
+ # z_c = (bf * tf * (tf / 2.0 + t / 2.0 + hw) + hw * tw * (hw / 2.0 + t / 2.0)) / (s_e * t + hw * tw + bf * tf)
680
+ # I_sef = 1.0 / 12.0 * tw * hw ** 3 + 1.0 / 12.0 * bf * tf ** 3 + 1.0 / 12.0 * s_e * t ** 3 + tw * hw * (
681
+ # hw / 2.0 + t / 2.0 - z_c) ** 2 + tf * bf * (hw + t / 2.0 + tf / 2.0 - z_c) ** 2 + s_e * t * z_c ** 2
682
+ # print(I_sef, I_z, Iy)
683
+ #print(2*(bf*(h/2)**3/12 + tf*(h-tf)**3/12) + tw*h**3/12, Iy)
684
+ return Iy
685
+
686
+ def get_Iz_moment_of_inertia(self, reduced_tw = None):
687
+ tw = self._web_th*1000 if reduced_tw is None else reduced_tw
688
+ hw = self._web_height * 1000
689
+ tf2 = self._flange_th * 1000
690
+ b2 = self._flange_width * 1000
691
+
692
+ if self._stiffener_type == 'FB':
693
+ Iz = math.pow(tw,3)*hw/12
694
+ elif self._stiffener_type == 'T':
695
+ Iz = hw*math.pow(tw,3)/12 + tf2*math.pow(b2,3)/12
696
+ else:
697
+ Czver = tw/2
698
+ Czhor = b2/2
699
+ Aver = hw*tw
700
+ Ahor = b2*tf2
701
+ Atot = Aver+Ahor
702
+
703
+ Czoverall = Aver*Czver/Atot + Ahor*Czhor/Atot
704
+ dz = Czver - Czoverall
705
+
706
+ Iver = (1/12)*hw*math.pow(tw,3) + Aver*math.pow(dz,2)
707
+
708
+ dz = Czhor-Czoverall
709
+ Ihor = (1/12)*tf2*math.pow(b2,3) + Ahor*math.pow(dz,2)
710
+
711
+ Iz = Iver + Ihor
712
+
713
+ return Iz
714
+
715
+ def get_moment_of_interia_iacs(self, efficent_se=None, only_stf = False, tf1 = None):
716
+ if only_stf:
717
+ tf1 = 0
718
+ b1 = 0
719
+ else:
720
+ tf1 = self._plate_th if tf1 == None else tf1
721
+ b1 = self._spacing if efficent_se==None else efficent_se
722
+ h = self._flange_th+self._web_height+tf1
723
+ tw = self._web_th
724
+ hw = self._web_height
725
+ tf2 = self._flange_th
726
+ b2 = self._flange_width
727
+
728
+ Af = b2*tf2
729
+ Aw = hw*tw
730
+
731
+ ef = hw + tf2/2
732
+
733
+ Iy = (Af*math.pow(ef,2)*math.pow(b2,2)/12) * ( (Af+2.6*Aw) / (Af+Aw))
734
+ return Iy
735
+
736
+ def get_torsional_moment_venant(self, reduced_tw = None, efficient_flange = True):
737
+ # if efficient_flange:
738
+ # ef = self.get_ef_iacs()*1000
739
+ # else:
740
+ # ef = self._flange_width * 1000
741
+ tf = self._flange_th*1000
742
+ tw = self._web_th*1000 if reduced_tw is None else reduced_tw
743
+ bf = self._flange_width*1000
744
+ hw = self._web_height*1000
745
+
746
+ # if self._stiffener_type == 'FB':
747
+ # It = ((hw*math.pow(tw,3)/3e4) * (1-0.63*(tw/hw)) )
748
+ # else:
749
+ # It = ((((ef-0.5*tf)*math.pow(tw,3))/3e4) * (1-0.63*(tw/(ef-0.5*tf))) + ((bf*math.pow(tf,3))/3e4)
750
+ # * (1-0.63*(tf/bf)) )
751
+ # G = 80769.2
752
+ # It2 = (2/3) * (math.pow(tw,3)*hw + bf*math.pow(tf, 3)) *(hw+tf/2)
753
+ # print(It, It2*G)
754
+ # print(hw, tw, bf, tf)
755
+ I_t1 = 1.0 / 3.0 * math.pow(tw , 3) * hw + 1.0 / 3.0 * math.pow(tf, 3) * bf
756
+ # I_t2 = 1.0 / 3.0 * math.pow(tw , 3) * (hw + tf) + 1.0 / 3.0 * math.pow(tf, 3) * (bf - tw)
757
+ # print('It', I_t1, I_t2, It* 1e4)
758
+
759
+ return I_t1# * 1e4
760
+
761
+ def get_polar_moment(self, reduced_tw = None):
762
+ tf = self._flange_th*1000
763
+ tw = self._web_th*1000 if reduced_tw is None else reduced_tw
764
+ ef = self.get_flange_eccentricity()*1000
765
+ hw = self._web_height*1000
766
+ b = self._flange_width*1000
767
+
768
+ #Ipo = (A|w*(ef-0.5*tf)**2/3+Af*ef**2)*10e-4 #polar moment of interia in cm^4
769
+ #Ipo = (tw/3)*math.pow(hw, 3) + tf*(math.pow(hw+tf/2,2)*b)+(tf/3)*(math.pow(ef+b/2,3)-math.pow(ef-b/2,3))
770
+
771
+ # C24/3*C70^3+C26*((C70+C26/2)^2*C25)+C26/3*((C72+C25/2)^3-(C72-C25/2)^3) + (C25*C26^3)/12 + (C70*C24^3)/12
772
+ Ipo = tw/3*math.pow(hw, 3)+tf*(math.pow(hw+tf/2,2)*b)+tf/3*(math.pow(ef+b/2,3)-math.pow(ef-b/2,3)) + \
773
+ (b*math.pow(tf,3))/12 + (hw*math.pow(tw,3))/12
774
+
775
+ return Ipo
776
+
777
+ def get_flange_eccentricity(self):
778
+ ecc = 0 if self._stiffener_type in ['FB', 'T'] else self._flange_width / 2 - self._web_th / 2
779
+ return ecc
780
+
781
+ def get_ef_iacs(self):
782
+
783
+ if self._stiffener_type == 'FB':
784
+ ef = self._web_height
785
+ # elif self._stiffener_type == 'L-bulb':
786
+ # ef = self._web_height-0.5*self._flange_th
787
+ elif self._stiffener_type in ['L', 'T', 'L-bulb', 'HP-profile', 'HP', 'HP-bulb', 'bulb']:
788
+ ef = self._web_height + 0.5*self._flange_th
789
+ return ef
790
+
791
+ def get_stf_cog_eccentricity(self):
792
+ e = (self._web_height * self._web_th * (self._web_height / 2) + self._flange_width * self._flange_th *
793
+ (self._web_height + self._web_th / 2)) / (self._web_height * self._web_th + self._flange_width * self._flange_th)
794
+ return e
795
+
796
+ def get_structure_prop(self):
797
+ return self._main_dict
798
+
799
+ def get_structure_type(self):
800
+ return self._structure_type
801
+
802
+ def get_stiffener_type(self):
803
+ return self._stiffener_type
804
+
805
+ def get_shear_area(self):
806
+ '''
807
+ Returning the shear area in [m^2]
808
+ :return:
809
+ '''
810
+ return ((self._flange_th*self._web_th) + (self._web_th*self._plate_th) + (self._web_height*self._web_th))
811
+
812
+ def set_main_properties(self, main_dict):
813
+ '''
814
+ Resettting all properties
815
+ :param input_dictionary:
816
+ :return:
817
+ '''
818
+
819
+ self._main_dict = main_dict
820
+ self._plate_th = main_dict['plate_thk'][0]
821
+ self._web_height = main_dict['stf_web_height'][0]
822
+ self._web_th = main_dict['stf_web_thk'][0]
823
+ self._flange_width = main_dict['stf_flange_width'][0]
824
+ self._flange_th = main_dict['stf_flange_thk'][0]
825
+ self._mat_yield = main_dict['mat_yield'][0]
826
+ self._mat_factor = main_dict['mat_factor'][0]
827
+ self._span = main_dict['span'][0]
828
+ self._spacing = main_dict['spacing'][0]
829
+ self._structure_type = main_dict['structure_type'][0]
830
+ self._sigma_y1=main_dict['sigma_y1'][0]
831
+ self._sigma_y2=main_dict['sigma_y2'][0]
832
+ self._sigma_x1 = main_dict['sigma_x1'][0]
833
+ self._sigma_x2 = main_dict['sigma_x2'][0]
834
+ self._tauxy=main_dict['tau_xy'][0]
835
+ self._plate_kpp = main_dict['plate_kpp'][0]
836
+ self._stf_kps = main_dict['stf_kps'][0]
837
+ self._km1 = main_dict['stf_km1'][0]
838
+ self._km2 = main_dict['stf_km2'][0]
839
+ self._km3 = main_dict['stf_km3'][0]
840
+ self._stiffener_type=main_dict['stf_type'][0]
841
+ try:
842
+ self._girder_lg=main_dict['girder_lg'][0]
843
+ except KeyError:
844
+ self._girder_lg = 10
845
+ try:
846
+ self._pressure_side = main_dict['press_side'][0]
847
+ except KeyError:
848
+ self._pressure_side = 'p'
849
+ self._zstar_optimization = main_dict['zstar_optimization'][0]
850
+ self._puls_method = main_dict['puls buckling method'][0]
851
+ self._puls_boundary = main_dict['puls boundary'][0]
852
+ self._puls_stf_end = main_dict['puls stiffener end'][0]
853
+ self._puls_sp_or_up = main_dict['puls sp or up'][0]
854
+ self._puls_up_boundary = main_dict['puls up boundary'][0]
855
+ self._panel_or_shell = main_dict['panel or shell'][0]
856
+
857
+ def set_stresses(self,sigy1,sigy2,sigx1,sigx2,tauxy):
858
+ '''
859
+ Setting the global stresses.
860
+ :param sigy1:
861
+ :param sigy2:
862
+ :param sigx:
863
+ :param tauxy:
864
+ :return:
865
+ '''
866
+ self._main_dict['sigma_y1'][0]= sigy1
867
+ self._sigma_y1 = sigy1
868
+
869
+ self._main_dict['sigma_y2'][0]= sigy2
870
+ self._sigma_y2 = sigy2
871
+
872
+ self._main_dict['sigma_x1'][0]= sigx1
873
+ self._sigma_x1 = sigx1
874
+
875
+ self._main_dict['sigma_x2'][0]= sigx2
876
+ self._sigma_x2 = sigx2
877
+
878
+ self._main_dict['tau_xy'][0]= tauxy
879
+ self._tauxy = tauxy
880
+
881
+ def get_cross_section_area(self, efficient_se = None, include_plate = True):
882
+ '''
883
+ Returns the cross section area.
884
+ :return:
885
+ '''
886
+ tf1 = self._plate_th if include_plate else 0
887
+ tf2 = self._flange_th
888
+ if include_plate:
889
+ b1 = self._spacing if efficient_se==None else efficient_se
890
+ else:
891
+ b1 = 0
892
+ b2 = self._flange_width
893
+ #h = self._flange_th+self._web_height+self._plate_th
894
+ h = self._web_height
895
+ tw = self._web_th
896
+ #print('Plate: thk', tf1, 's', b1, 'Flange: thk', tf2, 'width', b2, 'Web: thk', tw, 'h', h)
897
+ return tf1 * b1 + tf2 * b2 + h * tw
898
+
899
+ def get_cross_section_centroid_with_effective_plate(self, se = None, tf1 = None, include_plate = True,
900
+ reduced_tw = None):
901
+ '''
902
+ Returns cross section centroid
903
+ :return:
904
+ '''
905
+ # checked with example
906
+ if include_plate:
907
+ tf1 = self._plate_th if tf1 == None else tf1
908
+ b1 = self._spacing if se == None else se
909
+ else:
910
+ tf1 = 0
911
+ b1 = 0
912
+ tf2 = self._flange_th
913
+ b2 = self._flange_width
914
+ tw = self._web_th if reduced_tw == None else reduced_tw/1000
915
+ hw = self._web_height
916
+ Ax = tf1 * b1 + tf2 * b2 + hw * tw
917
+ effana = (tf1 * b1 * tf1/2 + hw * tw * (tf1 + hw / 2) + tf2 * b2 * (tf1+hw+tf2/2)) / Ax
918
+
919
+ return effana
920
+
921
+ def get_weight(self):
922
+ '''
923
+ Return the weight.
924
+ :return:
925
+ '''
926
+ return 7850*self._span*(self._spacing*self._plate_th+self._web_height*self._web_th+self._flange_width*self._flange_th)
927
+
928
+ def get_weight_width_lg(self):
929
+ '''
930
+ Return the weight including Lg
931
+ :return:
932
+ '''
933
+ pl_area = self._girder_lg*self._plate_th
934
+ stf_area = (self._web_height*self._web_th+self._flange_width*self._flange_th)*(self._girder_lg//self._spacing)
935
+ return (pl_area+stf_area)*7850*self._span
936
+
937
+ def set_span(self,span):
938
+ '''
939
+ Setting the span. Used when moving a point.
940
+ :return:
941
+ '''
942
+ self._span = span
943
+ self._main_dict['span'][0] = span
944
+
945
+ def get_puls_input(self, run_type: str = 'SP'):
946
+
947
+ if self._stiffener_type == 'FB':
948
+ stf_type = 'F'
949
+ else:
950
+ stf_type = self._stiffener_type
951
+ map_boundary = {'Continuous': 'C', 'Sniped': 'S'}
952
+ sig_x1 = self._sigma_x1
953
+ sig_x2 = self._sigma_x2
954
+ if sig_x1 * sig_x2 >= 0:
955
+ sigxd = sig_x1 if abs(sig_x1) > abs(sig_x2) else sig_x2
956
+ else:
957
+ sigxd = max(sig_x1, sig_x2)
958
+ if self._puls_sp_or_up == 'SP':
959
+ return_dict = {'Identification': None, 'Length of panel': self._span*1000, 'Stiffener spacing': self._spacing*1000,
960
+ 'Plate thickness': self._plate_th*1000,
961
+ 'Number of primary stiffeners': 10,
962
+ 'Stiffener type (L,T,F)': stf_type,
963
+ 'Stiffener boundary': map_boundary[self._puls_stf_end]
964
+ if map_boundary[self._puls_stf_end] in ['C', 'S']
965
+ else 'C' if self._puls_stf_end == 'Continuous' else 'S',
966
+ 'Stiff. Height': self._web_height*1000, 'Web thick.': self._web_th*1000,
967
+ 'Flange width': self._flange_width*1000,
968
+ 'Flange thick.': self._flange_th*1000, 'Tilt angle': 0,
969
+ 'Number of sec. stiffeners': 0, 'Modulus of elasticity': 2.1e11/1e6, "Poisson's ratio": 0.3,
970
+ 'Yield stress plate': self._mat_yield/1e6, 'Yield stress stiffener': self._mat_yield/1e6,
971
+ 'Axial stress': 0 if self._puls_boundary == 'GT' else sigxd,
972
+ 'Trans. stress 1': 0 if self._puls_boundary == 'GL' else self._sigma_y1,
973
+ 'Trans. stress 2': 0 if self._puls_boundary == 'GL' else self._sigma_y2,
974
+ 'Shear stress': self._tauxy,
975
+ 'Pressure (fixed)': None, 'In-plane support': self._puls_boundary,
976
+ 'sp or up': self._puls_sp_or_up}
977
+ else:
978
+ boundary = self._puls_up_boundary
979
+ blist = list()
980
+ if len(boundary) != 4:
981
+ blist = ['SS', 'SS', 'SS', 'SS']
982
+ else:
983
+ for letter in boundary:
984
+ if letter.upper() == 'S':
985
+ blist.append('SS')
986
+ elif letter.upper() == 'C':
987
+ blist.append('CL')
988
+ else:
989
+ blist.append('SS')
990
+
991
+ return_dict = {'Identification': None, 'Length of plate': self._span*1000, 'Width of c': self._spacing*1000,
992
+ 'Plate thickness': self._plate_th*1000,
993
+ 'Modulus of elasticity': 2.1e11/1e6, "Poisson's ratio": 0.3,
994
+ 'Yield stress plate': self._mat_yield/1e6,
995
+ 'Axial stress 1': 0 if self._puls_boundary == 'GT' else sigxd,
996
+ 'Axial stress 2': 0 if self._puls_boundary == 'GT' else sigxd,
997
+ 'Trans. stress 1': 0 if self._puls_boundary == 'GL' else self._sigma_y1,
998
+ 'Trans. stress 2': 0 if self._puls_boundary == 'GL' else self._sigma_y2,
999
+ 'Shear stress': self._tauxy, 'Pressure (fixed)': None, 'In-plane support': self._puls_boundary,
1000
+ 'Rot left': blist[0], 'Rot right': blist[1], 'Rot upper': blist[2], 'Rot lower': blist[3],
1001
+ 'sp or up': self._puls_sp_or_up}
1002
+ return return_dict
1003
+
1004
+ def get_buckling_ml_input(self, design_lat_press: float = 0, sp_or_up: str = 'SP', alone = True, csr = False):
1005
+ '''
1006
+ Classes in data from ML
1007
+
1008
+ {'negative utilisation': 1, 'non-zero': 2, 'Division by zero': 3, 'Overflow': 4, 'aspect ratio': 5,
1009
+ 'global slenderness': 6, 'pressure': 7, 'web-flange-ratio': 8, 'below 0.87': 9,
1010
+ 'between 0.87 and 1': 10, 'above 1': 11}
1011
+ '''
1012
+ stf_type = {'T-bar': 1,'T': 1, 'L-bulb': 2, 'Angle': 3, 'Flatbar': 4, 'FB': 4, 'L': 3}
1013
+ stf_end = {'Cont': 1, 'C':1 , 'Sniped': 2, 'S': 2}
1014
+ field_type = {'Integrated': 1,'Int': 1, 'Girder - long': 2,'GL': 2, 'Girder - trans': 3, 'GT': 3}
1015
+ up_boundary = {'SS': 1, 'CL': 2}
1016
+ map_boundary = {'Continuous': 'C', 'Sniped': 'S'}
1017
+ sig_x1 = self._sigma_x1
1018
+ sig_x2 = self._sigma_x2
1019
+ if sig_x1 * sig_x2 >= 0:
1020
+ sigxd = sig_x1 if abs(sig_x1) > abs(sig_x2) else sig_x2
1021
+ else:
1022
+ sigxd = max(sig_x1, sig_x2)
1023
+ if self._puls_sp_or_up == 'SP':
1024
+
1025
+ if csr == False:
1026
+
1027
+ this_field = [self._span * 1000, self._spacing * 1000, self._plate_th * 1000, self._web_height * 1000,
1028
+ self._web_th * 1000, self._flange_width * 1000, self._flange_th * 1000, self._mat_yield / 1e6,
1029
+ self._mat_yield / 1e6, sigxd, self._sigma_y1, self._sigma_y2, self._tauxy,
1030
+ design_lat_press/1000, stf_type[self._stiffener_type],
1031
+ stf_end[map_boundary[self._puls_stf_end]]]
1032
+ else:
1033
+ this_field = [self._span * 1000, self._spacing * 1000, self._plate_th * 1000, self._web_height * 1000,
1034
+ self._web_th * 1000, self._flange_width * 1000, self._flange_th * 1000, self._mat_yield / 1e6,
1035
+ self._mat_yield / 1e6, sigxd, self._sigma_y1, self._sigma_y2, self._tauxy,
1036
+ design_lat_press/1000, stf_type[self._stiffener_type],
1037
+ stf_end[map_boundary[self._puls_stf_end]],
1038
+ field_type[self._puls_boundary]]
1039
+ else:
1040
+ ss_cl_list = list()
1041
+ for letter_i in self._puls_up_boundary:
1042
+ if letter_i == 'S':
1043
+ ss_cl_list.append(up_boundary['SS'])
1044
+ else:
1045
+ ss_cl_list.append(up_boundary['CL'])
1046
+ b1, b2, b3, b4 = ss_cl_list
1047
+ if csr == False:
1048
+ this_field = [self._span * 1000, self._spacing * 1000, self._plate_th * 1000, self._mat_yield / 1e6,
1049
+ sigxd, self._sigma_y1, self._sigma_y2, self._tauxy, design_lat_press/1000,
1050
+ b1, b2, b3, b4]
1051
+ else:
1052
+ this_field = [self._span * 1000, self._spacing * 1000, self._plate_th * 1000, self._mat_yield / 1e6,
1053
+ sigxd, self._sigma_y1, self._sigma_y2, self._tauxy, design_lat_press/1000,
1054
+ field_type[self._puls_boundary], b1, b2, b3, b4]
1055
+ if alone:
1056
+ return [this_field,]
1057
+ else:
1058
+ return this_field
1059
+
1060
+ class CalcScantlings(Structure):
1061
+ '''
1062
+ This Class does the calculations for the plate fields.
1063
+ Input is a structure object, same as for the structure class.
1064
+ The class inherits from Structure class.
1065
+ '''
1066
+
1067
+ def __init__(self, main_dict: dict = None, lat_press = True, category = 'secondary'):
1068
+ super(CalcScantlings,self).__init__(main_dict=main_dict)
1069
+
1070
+ self.lat_press = lat_press
1071
+ self.category = category
1072
+ self._need_recalc = True
1073
+
1074
+ @property
1075
+ def need_recalc(self):
1076
+ return self._need_recalc
1077
+
1078
+ @need_recalc.setter
1079
+ def need_recalc(self, val):
1080
+ self._need_recalc = val
1081
+
1082
+ def get_results_for_report(self,lat_press=0):
1083
+ '''
1084
+ Returns a string for the report.
1085
+ :return:
1086
+ '''
1087
+ buc = [round(res,1) for res in self.calculate_buckling_all(design_lat_press=lat_press)]
1088
+
1089
+ return 'Minimum section modulus:'\
1090
+ +str(int(self.get_dnv_min_section_modulus(design_pressure_kpa=lat_press)*1000**3))\
1091
+ +'mm^3 '+' Minium plate thickness: '\
1092
+ +str(round(self.get_dnv_min_thickness(design_pressure_kpa=lat_press),1))+\
1093
+ ' Buckling results: eq7_19: '+str(buc[0])+' eq7_50: '+str(buc[1])+ ' eq7_51: '\
1094
+ +str(buc[2])+ ' eq7_52: '+str(buc[3])+ ' eq7_53: '+str(buc[4])
1095
+
1096
+ def calculate_slamming_plate(self, slamming_pressure, red_fac = 1):
1097
+ ''' Slamming pressure input is Pa '''
1098
+ ka1 = 1.1
1099
+ ka2 = min(max(0.4, self._spacing / self._span), 1)
1100
+
1101
+ ka = math.pow(ka1 - 0.25*ka2,2)
1102
+ sigmaf = self._mat_yield/1e6 # MPa
1103
+
1104
+ psl = red_fac * slamming_pressure/1000 # kPa
1105
+ Cd = 1.5
1106
+
1107
+ return 0.0158*ka*self._spacing*1000*math.sqrt(psl/(Cd*sigmaf))
1108
+
1109
+ def calculate_slamming_stiffener(self, slamming_pressure, angle = 90, red_fac = 1):
1110
+ tk = 0
1111
+ psl = slamming_pressure / 1000 # kPa
1112
+ Pst = psl * red_fac # Currently DNV does not use psl/2 for slamming.
1113
+ sigmaf = self._mat_yield / 1e6 # MPa
1114
+ hw, twa, tp, tf, bf, s = [(val - tk) * 1000 for val in [self._web_height, self._web_th, self._plate_th,
1115
+ self._flange_th, self._flange_width, self._spacing]]
1116
+ ns = 2
1117
+ tau_eH = sigmaf/math.sqrt(3)
1118
+ h_stf = (self._web_height+self._flange_th)*1000
1119
+ f_shr = 0.7
1120
+ lbdg = self._span
1121
+ lshr = self._span - self._spacing/4000
1122
+ dshr = h_stf + tp if 75 <= angle <= 90 else (h_stf + tp)*math.sin(math.radians(angle))
1123
+ tw = (f_shr*Pst*s*lshr)/(dshr*tau_eH)
1124
+
1125
+ if self._web_th*1000 < tw:
1126
+ return {'tw_req': tw, 'Zp_req':None}
1127
+ fpl = 8* (1+(ns/2))
1128
+ Zp_req = (1.2*Pst*s*math.pow(lbdg,2)/(fpl*sigmaf)) + \
1129
+ (ns*(1-math.sqrt(1-math.pow(tw/twa,2)))*hw*tw*(hw+tp))/8000
1130
+
1131
+ return {'tw_req': tw, 'Zp_req':Zp_req}
1132
+
1133
+ def check_all_slamming(self, slamming_pressure, stf_red_fact = 1, pl_red_fact = 1):
1134
+ ''' A summary check of slamming '''
1135
+
1136
+ pl_chk = self.calculate_slamming_plate(slamming_pressure, red_fac= pl_red_fact)
1137
+ if self._plate_th*1000 < pl_chk:
1138
+ chk1 = pl_chk / self._plate_th*1000
1139
+ return False, chk1
1140
+
1141
+ stf_res = self.calculate_slamming_stiffener(slamming_pressure, red_fac = stf_red_fact)
1142
+ #print('Slamming checked')
1143
+ if self._web_th*1000 < stf_res['tw_req']:
1144
+ chk2 = stf_res['tw_req'] / self._web_th*1000
1145
+ return False, chk2
1146
+
1147
+ if stf_res['Zp_req'] is not None:
1148
+ eff_pl_sec_mod = self.get_net_effective_plastic_section_modulus()
1149
+ if eff_pl_sec_mod < stf_res['Zp_req']:
1150
+ chk3 = stf_res['Zp_req']/eff_pl_sec_mod
1151
+ return False, chk3
1152
+
1153
+ return True, None
1154
+
1155
+ def get_net_effective_plastic_section_modulus(self, angle = 90):
1156
+ ''' Calculated according to Rules for classification: Ships — DNVGL-RU-SHIP Pt.3 Ch.3. Edition July 2017,
1157
+ page 83 '''
1158
+ tk = 0
1159
+ angle_rad = math.radians(angle)
1160
+ hw, tw, tp, tf, bf = [(val - tk) * 1000 for val in [self._web_height, self._web_th, self._plate_th, self._flange_th,
1161
+ self._flange_width]]
1162
+ h_stf = (self._web_height+self._flange_th)*1000
1163
+ de_gr = 0
1164
+ tw_gr = self._web_th*1000
1165
+ hf_ctr = h_stf-0.5*tf if self.get_stiffener_type() not in ['L','L-bulb'] else h_stf - de_gr - 0.5*tf
1166
+ bf_ctr = 0 if self.get_stiffener_type() == 'T' else 0.5*(tf - tw_gr)
1167
+ beta = 0.5
1168
+ gamma = (1 + math.sqrt(3+12*beta))/4
1169
+
1170
+ Af = 0 if self.get_stiffener_type() == 'FB' else bf*tf
1171
+
1172
+ if 75 <= angle <= 90:
1173
+ zpl = (hw*tw*(hw+tp)/2000) + ( (2*gamma-1) * Af * ((hf_ctr + tp/2)) / 1000)
1174
+ elif angle < 75:
1175
+ zpl = (hw*tw*(hw+tp)/2000)+\
1176
+ ( (2*gamma-1) * Af * ((hf_ctr + tp/2) * math.sin(angle_rad) - bf_ctr*math.cos(angle_rad)) / 1000)
1177
+
1178
+ return zpl
1179
+
1180
+ def get_dnv_min_section_modulus(self, design_pressure_kpa, printit = False):
1181
+ ''' Section modulus according to DNV rules '''
1182
+
1183
+ design_pressure = design_pressure_kpa
1184
+ fy = self._mat_yield / 1e6
1185
+ fyd = fy/self._mat_factor
1186
+
1187
+ sigma_y = self._sigma_y2 + (self._sigma_y1-self._sigma_y2)\
1188
+ *(min(0.25*self._span,0.5*self._spacing)/self._span)
1189
+ sig_x1 = self._sigma_x1
1190
+ sig_x2 = self._sigma_x2
1191
+ if sig_x1 * sig_x2 >= 0:
1192
+ sigxd = sig_x1 if abs(sig_x1) > abs(sig_x2) else sig_x2
1193
+ else:
1194
+ sigxd =max(sig_x1 , sig_x2)
1195
+
1196
+ sigma_jd = math.sqrt(math.pow(sigxd,2)+math.pow(sigma_y,2)-
1197
+ sigxd*sigma_y+3*math.pow(self._tauxy,2))
1198
+
1199
+ sigma_pd2 = fyd-sigma_jd # design_bending_stress_mpa
1200
+
1201
+ kps = self._stf_kps # 1 is clamped, 0.9 is simply supported.
1202
+ km_sides = min(self._km1,self._km3) # see table 3 in DNVGL-OS-C101 (page 62)
1203
+ km_middle = self._km2 # see table 3 in DNVGL-OS-C101 (page 62)
1204
+
1205
+ Zs = ((math.pow(self._span, 2) * self._spacing * design_pressure) /
1206
+ (min(km_middle, km_sides) * (sigma_pd2) * kps)) * math.pow(10, 6)
1207
+ if printit:
1208
+ print('Sigma y1', self._sigma_y1, 'Sigma y2', self._sigma_y2, 'Sigma x', self._sigma_x1,
1209
+ 'Pressure', design_pressure, 'fy', fy,
1210
+ 'Section mod', max(math.pow(15, 3) / math.pow(1000, 3), Zs / math.pow(1000, 3)))
1211
+ return max(math.pow(15, 3) / math.pow(1000, 3), Zs / math.pow(1000, 3))
1212
+
1213
+ def get_dnv_min_thickness(self, design_pressure_kpa):
1214
+ '''
1215
+ Return minimum thickness in mm
1216
+ :param design_pressure_kpa:
1217
+ :return:
1218
+ '''
1219
+
1220
+ design_pressure = design_pressure_kpa
1221
+ #print(self._sigma_x1)
1222
+ self.span
1223
+ sigma_y = self._sigma_y2 + (self._sigma_y1-self._sigma_y2)\
1224
+ *(min(0.25*self.span,0.5*self._spacing)/self._span)
1225
+
1226
+ sig_x1 = self._sigma_x1
1227
+ sig_x2 = self._sigma_x2
1228
+ if sig_x1 * sig_x2 >= 0:
1229
+ sigxd = sig_x1 if abs(sig_x1) > abs(sig_x2) else sig_x2
1230
+ else:
1231
+ sigxd =max(sig_x1 , sig_x2)
1232
+
1233
+ sigma_jd = math.sqrt(math.pow(sigxd,2)+math.pow(sigma_y,2)-
1234
+ sigxd*sigma_y+3*math.pow(self._tauxy,2))
1235
+
1236
+ fy = self._mat_yield / 1000000
1237
+ fyd = fy/self._mat_factor
1238
+ sigma_pd1 = min(1.3*(fyd-sigma_jd), fyd)
1239
+ sigma_pd1 = abs(sigma_pd1)
1240
+ #print(fyd, sigma_jd, fyd)
1241
+ if self.category == 'secondary':
1242
+ t0 = 5
1243
+ else:
1244
+ t0 = 7
1245
+
1246
+ t_min = (14.3 * t0) / math.sqrt(fyd)
1247
+
1248
+ ka = math.pow(1.1 - 0.25 * self._spacing/self._span, 2)
1249
+
1250
+ if ka > 1:
1251
+ ka =1
1252
+ elif ka<0.72:
1253
+ ka = 0.72
1254
+
1255
+ assert sigma_pd1 > 0, 'sigma_pd1 must be negative | current value is: ' + str(sigma_pd1)
1256
+ assert self._plate_kpp is not None, 'Fixation parameters must be set.'
1257
+ t_min_bend = (15.8 * ka * self._spacing * math.sqrt(design_pressure)) / \
1258
+ math.sqrt(sigma_pd1 *self._plate_kpp)
1259
+
1260
+ if self.lat_press:
1261
+ return max(t_min, t_min_bend)
1262
+ else:
1263
+ return t_min
1264
+
1265
+ def get_minimum_shear_area(self, pressure):
1266
+ '''
1267
+ Calculating minimum section area according to ch 6.4.4.
1268
+
1269
+ Return [m^2]
1270
+ :return:
1271
+ '''
1272
+ #print('SIGMA_X ', self._sigma_x1)
1273
+ l = self._span
1274
+ s = self._spacing
1275
+ fy = self._mat_yield
1276
+
1277
+ fyd = (fy/self._mat_factor)/1e6 #yield strength
1278
+ sig_x1 = self._sigma_x1
1279
+ sig_x2 = self._sigma_x2
1280
+ if sig_x1 * sig_x2 >= 0:
1281
+ sigxd = sig_x1 if abs(sig_x1) > abs(sig_x2) else sig_x2
1282
+ else:
1283
+ sigxd =max(sig_x1 , sig_x2)
1284
+
1285
+ taupds = 0.577*math.sqrt(math.pow(fyd, 2) - math.pow(sigxd, 2))
1286
+
1287
+ As = ((l*s*pressure)/(2*taupds)) * math.pow(10,3)
1288
+
1289
+ return As/math.pow(1000,2)
1290
+
1291
+ def is_acceptable_sec_mod(self, section_module, pressure):
1292
+ '''
1293
+ Checking if the result is accepable.
1294
+ :param section_module:
1295
+ :param pressure:
1296
+ :return:
1297
+ '''
1298
+
1299
+ return min(section_module) >= self.get_dnv_min_section_modulus(pressure)
1300
+
1301
+ def is_acceptable_shear_area(self, shear_area, pressure):
1302
+ '''
1303
+ Returning if the shear area is ok.
1304
+ :param shear_area:
1305
+ :param pressure:
1306
+ :return:
1307
+ '''
1308
+
1309
+ return shear_area >= self.get_minimum_shear_area(pressure)
1310
+
1311
+ def get_plate_efficent_b(self,design_lat_press=0,axial_stress=50,
1312
+ trans_stress_small=100,trans_stress_large=100):
1313
+ '''
1314
+ Simple buckling calculations according to DNV-RP-C201
1315
+ :return:
1316
+ '''
1317
+
1318
+ #7.2 Forces in the idealised stiffened plate
1319
+
1320
+ s = self._spacing #ok
1321
+ t = self._plate_th #ok
1322
+ l = self._span #ok
1323
+
1324
+ E = 2.1e11 #ok
1325
+
1326
+ pSd = design_lat_press*1000
1327
+ sigy1Sd =trans_stress_large*1e6
1328
+ sigy2Sd =trans_stress_small*1e6
1329
+ sigxSd = axial_stress*1e6
1330
+
1331
+ fy = self._mat_yield #ok
1332
+
1333
+ #7.3 Effective plate width
1334
+ alphap=0.525*(s/t)*math.sqrt(fy/E) # reduced plate slenderness, checked not calculated with ex
1335
+ alphac = 1.1*(s/t)*math.sqrt(fy/E) # checked not calculated with example
1336
+ mu6_9 = 0.21*(alphac-0.2)
1337
+
1338
+ if alphac<=0.2: kappa = 1 # eq6.7, all kappa checked not calculated with example
1339
+ elif 0.2<alphac<2: kappa = (1/(2*math.pow(alphac,2)))*(1+mu6_9+math.pow(alphac,2)
1340
+ -math.sqrt(math.pow(1+mu6_9+math.pow(alphac,2),2)
1341
+ -4*math.pow(alphac,2))) # ok
1342
+ else: kappa=(1/(2*math.pow(alphac,2)))+0.07 # ok
1343
+
1344
+ ha = 0.05*(s/t)-0.75
1345
+ assert ha>= 0,'ha must be larger than 0'
1346
+ kp = 1 if pSd<=2*((t/s)**2)*fy else 1-ha*((pSd/fy)-2*(t/s)**2)
1347
+
1348
+ sigyR=( (1.3*t/l)*math.sqrt(E/fy)+kappa*(1-(1.3*t/l)*math.sqrt(E/fy)))*fy*kp # checked not calculated with example
1349
+ l1 = min(0.25*l,0.5*s)
1350
+
1351
+ sig_min, sig_max = min(sigy1Sd,sigy2Sd),max(sigy1Sd,sigy2Sd) # self-made
1352
+ sigySd = sig_min+(sig_max-sig_min)*(1-l1/l) # see 6.8, page 15
1353
+
1354
+ ci = 1-s/(120*t) if (s/t)<=120 else 0 # checked not calculated with example
1355
+
1356
+ Cxs = (alphap-0.22)/math.pow(alphap,2) if alphap > 0.673 else 1 # reduction factor longitudinal
1357
+ # eq7.16, reduction factor transverse, compression (positive) else tension
1358
+
1359
+ Cys = math.sqrt(1-math.pow(sigySd/sigyR,2) + ci*((sigxSd*sigySd)/(Cxs*fy*sigyR))) if sigySd >= 0 \
1360
+ else min(0.5*(math.sqrt(4-3*math.pow(sigySd/fy,2))+sigySd/fy),1) #ok, checked
1361
+
1362
+ #7.7.3 Resistance parameters for stiffeners
1363
+ return s * Cxs * Cys # 7.3, eq7.13, che
1364
+
1365
+ def buckling_local_stiffener(self):
1366
+ '''
1367
+ Local requirements for stiffeners. Chapter 9.11.
1368
+ :return:
1369
+ '''
1370
+
1371
+ epsilon = math.sqrt(235 / (self._mat_yield / 1e6))
1372
+
1373
+ if self._stiffener_type in ['L', 'L-bulb']:
1374
+ c = self._flange_width - self._web_th/2
1375
+ elif self._stiffener_type == 'T':
1376
+ c = self._flange_width/2 - self._web_th/2
1377
+ elif self._stiffener_type == 'FB':
1378
+ return self._web_height <= 42 * self._web_th * epsilon, self._web_height/(42 * self._web_th * epsilon)
1379
+
1380
+ # print(self._web_height, self._web_th, self._flange_width ,self._flange_th )
1381
+ # print('c:',c, 14 * self._flange_th * epsilon, ' | ', self._web_height, 42 * self._web_th * epsilon)
1382
+ # print(c <= (14 * self._flange_th * epsilon) and self._web_height <= 42 * self._web_th * epsilon)
1383
+ # print(c/(14 * self._flange_th * epsilon), self._web_height / (42 * self._web_th * epsilon))
1384
+ # print('')
1385
+
1386
+ return c <= (14 * self._flange_th * epsilon) and self._web_height <= 42 * self._web_th * epsilon, \
1387
+ max(c/(14 * self._flange_th * epsilon), self._web_height / (42 * self._web_th * epsilon))
1388
+
1389
+ def is_acceptable_pl_thk(self, design_pressure):
1390
+ '''
1391
+ Checking if the thickness is acceptable.
1392
+ :return:
1393
+ '''
1394
+ return self.get_dnv_min_thickness(design_pressure) <= self._plate_th*1000
1395
+
1396
+ class AllStructure():
1397
+ '''
1398
+ Calculation of structure
1399
+ '''
1400
+ def __init__(self, Plate: CalcScantlings = None, Stiffener: CalcScantlings = None, Girder: CalcScantlings = None,
1401
+ main_dict = None, calculation_domain: str = None):
1402
+ super(AllStructure, self).__init__()
1403
+ self._Plate = Plate # This contain the stresses
1404
+ self._Stiffener = Stiffener
1405
+ self._Girder = Girder
1406
+ self._lat_press = None
1407
+
1408
+ self._v = 0.3
1409
+ self._E = 2.1e11
1410
+ if main_dict is not None:
1411
+ self._min_lat_press_adj_span = None if main_dict['minimum pressure in adjacent spans'][0] == 0 else \
1412
+ main_dict['minimum pressure in adjacent spans'][0]
1413
+ self._mat_yield = main_dict['material yield'][0]
1414
+ self._stress_load_factor = main_dict['load factor on stresses'][0]
1415
+ self._lat_load_factor = main_dict['load factor on pressure'][0]
1416
+ self._method = main_dict['buckling method'][0]
1417
+ self._stf_end_support = main_dict['stiffener end support'][0]#'Continuous'
1418
+ self._girder_end_support = main_dict['girder end support'][0]#'Continuous'
1419
+ self._tension_field_action = main_dict['tension field'][0]# 'not allowed'
1420
+ self._stiffened_plate_effective_aginst_sigy = main_dict['plate effective agains sigy'][0] #True
1421
+ self._buckling_length_factor_stf = None if main_dict['buckling length factor stf'][0] == 0 else \
1422
+ main_dict['buckling length factor stf'][0]
1423
+ self._buckling_length_factor_girder = None if main_dict['buckling length factor girder'][0] == 0 else \
1424
+ main_dict['buckling length factor girder'][0]
1425
+ self._km3 = main_dict['km3'][0]#12
1426
+ self._km2 = main_dict['km2'][0]#24
1427
+ self._stf_dist_between_lateral_supp = None if main_dict['stiffener distance between lateral support'][0] == 0 \
1428
+ else main_dict['stiffener distance between lateral support'][0]
1429
+ self._girder_dist_between_lateral_supp = None if main_dict['girder distance between lateral support'][0] == 0 \
1430
+ else main_dict['girder distance between lateral support'][0]
1431
+ self._panel_length_Lp = None if main_dict['panel length, Lp'][0] == 0 else main_dict['panel length, Lp'][0]
1432
+ self._overpressure_side = main_dict['pressure side'][0] # either 'stiffener side', 'plate side', 'both sides'
1433
+ self._fab_method_stiffener = main_dict['fabrication method stiffener'][0]#'welded'
1434
+ self._fab_method_girder = main_dict['fabrication method girder'][0]#'welded'
1435
+ self._calculation_domain = main_dict['calculation domain'][0]
1436
+ self._need_recalc = True
1437
+ else: # setting default values
1438
+ self._stf_end_support = 'Continuous'
1439
+ self._girder_end_support = 'Continuous'
1440
+ self._tension_field_action = 'not allowed'
1441
+ self._stiffened_plate_effective_aginst_sigy = ['Stf. pl. effective against sigma y',
1442
+ 'All sigma y to girder'][0]
1443
+ self._km3 = 12
1444
+ self._km2 = 24
1445
+ self._overpressure_side = 'both sides'
1446
+ self._fab_method_stiffener = 'welded'
1447
+ self._fab_method_girder = 'welded'
1448
+ self._need_recalc = True
1449
+ self._mat_yield = None
1450
+ self._lat_load_factor = 1
1451
+ self._stress_load_factor = 1
1452
+ self._lat_press = 0
1453
+ self._buckling_length_factor_stf = None
1454
+ self._buckling_length_factor_girder = None
1455
+ self._stf_dist_between_lateral_supp = None
1456
+ self._girder_dist_between_lateral_supp = None
1457
+ self._panel_length_Lp = None
1458
+ self._calculation_domain = calculation_domain
1459
+
1460
+
1461
+ @property
1462
+ def method(self):
1463
+ return self._method
1464
+ @method.setter
1465
+ def method(self, val):
1466
+ self._method = val
1467
+ @property
1468
+ def tension_field_action(self):
1469
+ return self._tension_field_action
1470
+ @tension_field_action.setter
1471
+ def tension_field_action(self, val):
1472
+ self._tension_field_action = val
1473
+ @property
1474
+ def stiffened_plate_effective_aginst_sigy(self):
1475
+ return self._stiffened_plate_effective_aginst_sigy
1476
+ @stiffened_plate_effective_aginst_sigy.setter
1477
+ def stiffened_plate_effective_aginst_sigy(self, val):
1478
+ self._stiffened_plate_effective_aginst_sigy = val
1479
+ @property
1480
+ def km3(self):
1481
+ return self._km3
1482
+ @km3.setter
1483
+ def km3(self, val):
1484
+ self._km3 = val
1485
+ @property
1486
+ def km2(self):
1487
+ return self._km2
1488
+ @km2.setter
1489
+ def km2(self, val):
1490
+ self._km2 = val
1491
+
1492
+ @property
1493
+ def need_recalc(self):
1494
+ return self._need_recalc
1495
+ @need_recalc.setter
1496
+ def need_recalc(self, val):
1497
+ self._need_recalc = val
1498
+
1499
+ @property
1500
+ def overpressure_side(self):
1501
+ return self._overpressure_side
1502
+ @overpressure_side.setter
1503
+ def overpressure_side(self, val):
1504
+ self._overpressure_side = val
1505
+ @property
1506
+ def fab_method_stiffener(self):
1507
+ return self._fab_method_stiffener
1508
+ @fab_method_stiffener.setter
1509
+ def fab_method_stiffener(self, val):
1510
+ self._fab_method_stiffener = val
1511
+
1512
+ @property
1513
+ def fab_method_girder(self):
1514
+ return self._fab_method_girder
1515
+ @fab_method_girder.setter
1516
+ def fab_method_girder(self, val):
1517
+ self._fab_method_girder = val
1518
+ @property
1519
+ def stf_end_support(self):
1520
+ return self._stf_end_support
1521
+ @stf_end_support.setter
1522
+ def stf_end_support(self, val):
1523
+ self._stf_end_support = val
1524
+ @property
1525
+ def girder_end_support(self):
1526
+ return self._girder_end_support
1527
+ @girder_end_support.setter
1528
+ def girder_end_support(self, val):
1529
+ self._girder_end_support = val
1530
+ @property
1531
+ def need_recalc(self):
1532
+ return self._need_recalc
1533
+ @need_recalc.setter
1534
+ def need_recalc(self, val):
1535
+ self._need_recalc = val
1536
+
1537
+ @property
1538
+ def lat_press(self):
1539
+ return self._lat_press
1540
+
1541
+ @lat_press.setter
1542
+ def lat_press(self, val):
1543
+ self._lat_press = val
1544
+
1545
+ @property
1546
+ def Plate(self):
1547
+ return self._Plate
1548
+
1549
+ @Plate.setter
1550
+ def Plate(self, val):
1551
+ self._Plate = val
1552
+
1553
+ @property
1554
+ def Stiffener(self):
1555
+ return self._Stiffener
1556
+ @Stiffener.setter
1557
+ def Stiffener(self, val):
1558
+ self._Stiffener = val
1559
+
1560
+ @property
1561
+ def Girder(self):
1562
+ return self._Girder
1563
+ @Girder.setter
1564
+ def Girder(self, val):
1565
+ self._Girder = val
1566
+
1567
+ @property
1568
+ def overpressure_side(self):
1569
+ return self._overpressure_side
1570
+ @overpressure_side.setter
1571
+ def overpressure_side(self, val):
1572
+ self._overpressure_side = val
1573
+
1574
+ @property
1575
+ def calculation_domain(self):
1576
+ return self._calculation_domain
1577
+ @calculation_domain.setter
1578
+ def calculation_domain(self, val):
1579
+ self._calculation_domain = val
1580
+
1581
+ @property
1582
+ def E(self):
1583
+ assert self._E is not None, 'Missing variable: self._E'
1584
+ return self._E
1585
+ @E.setter
1586
+ def E(self, val):
1587
+ self._E = val
1588
+ @property
1589
+ def v(self):
1590
+ assert self._v is not None, 'Missing variable: self._v'
1591
+ return self._v
1592
+ @v.setter
1593
+ def v(self, val):
1594
+ self._v = val
1595
+ @property
1596
+ def mat_yield(self):
1597
+ assert self._mat_yield is not None, 'Missing variable: self._mat_yield'
1598
+ return self._mat_yield
1599
+ @mat_yield.setter
1600
+ def mat_yield(self, val):
1601
+ self._mat_yield = val
1602
+
1603
+ def get_method(self):
1604
+ gird_opt = ['Stf. pl. effective against sigma y', 'All sigma y to girder']
1605
+ #stf_opt = ['allowed', 'not allowed']
1606
+ # if self.calculation_domain == "Flat plate, stiffened with girder":
1607
+
1608
+ if self._stiffened_plate_effective_aginst_sigy == True:
1609
+ self._stiffened_plate_effective_aginst_sigy = gird_opt[0]
1610
+ elif self._stiffened_plate_effective_aginst_sigy == False:
1611
+ self._stiffened_plate_effective_aginst_sigy = gird_opt[1]
1612
+
1613
+ if self.calculation_domain == "Flat plate, stiffened with girder":
1614
+ if self._stiffened_plate_effective_aginst_sigy == gird_opt[0]:
1615
+ return 1
1616
+ else:
1617
+ return 2
1618
+ else:
1619
+ return 1
1620
+ # else:
1621
+ # if self._tension_field_action == stf_opt[0]:
1622
+ # return 1
1623
+ # else:
1624
+ # return 2
1625
+
1626
+ def get_main_properties(self):
1627
+ main_dict = dict()
1628
+ main_dict['minimum pressure in adjacent spans'] = [self._min_lat_press_adj_span, '']
1629
+ main_dict['material yield'] = [self._mat_yield, 'Pa']
1630
+ main_dict['load factor on stresses'] = [self._stress_load_factor, '']
1631
+ main_dict['load factor on pressure'] = [self._lat_load_factor, '']
1632
+ main_dict['buckling method'] = [self._method, '']
1633
+ main_dict['stiffener end support'] = [self._stf_end_support, ''] # 'Continuous'
1634
+ main_dict['girder end support'] = [self._girder_end_support, ''] # 'Continuous'
1635
+ main_dict['tension field'] = [self._tension_field_action, ''] # 'not allowed'
1636
+ main_dict['plate effective agains sigy'] = [self._stiffened_plate_effective_aginst_sigy, ''] # True
1637
+ main_dict['buckling length factor stf'] = [self._buckling_length_factor_stf, '']
1638
+ main_dict['buckling length factor girder'] = [self._buckling_length_factor_girder, '']
1639
+ main_dict['km3'] = [self._km3, ''] # 12
1640
+ main_dict['km2'] = [self._km2, ''] # 24
1641
+ main_dict['girder distance between lateral support'] = [self._girder_dist_between_lateral_supp, '']
1642
+ main_dict['stiffener distance between lateral support'] = [self._stf_dist_between_lateral_supp, '']
1643
+ main_dict['panel length, Lp'] = [self._panel_length_Lp, '']
1644
+ main_dict['pressure side'] = [self._overpressure_side, ''] # either 'stiffener', 'plate', 'both'
1645
+ main_dict['fabrication method stiffener'] = [self._fab_method_stiffener, '']
1646
+ main_dict['fabrication method girder'] = [self._fab_method_girder, '']
1647
+ main_dict['calculation domain']= [self._calculation_domain, '']
1648
+
1649
+ return {'main dict': main_dict, 'Plate': self._Plate.get_structure_prop(),
1650
+ 'Stiffener': None if self._Stiffener is None else self._Stiffener.get_structure_prop(),
1651
+ 'Girder': None if self._Girder is None else self._Girder.get_structure_prop()}
1652
+
1653
+ def set_main_properties(self, prop_dict):
1654
+ main_dict = prop_dict['main dict']
1655
+ self._min_lat_press_adj_span = None if main_dict['minimum pressure in adjacent spans'][0] == 0 else \
1656
+ main_dict['minimum pressure in adjacent spans'][0]
1657
+ self._mat_yield = main_dict['material yield'][0]
1658
+ self._stress_load_factor = main_dict['load factor on stresses'][0]
1659
+ self._lat_load_factor = main_dict['load factor on pressure'][0]
1660
+ self._method = main_dict['buckling method'][0]
1661
+ self._stf_end_support = main_dict['stiffener end support'][0]#'Continuous'
1662
+ self._girder_end_support = main_dict['girder end support'][0]#'Continuous'
1663
+ self._tension_field_action = main_dict['tension field'][0]# 'not allowed'
1664
+ self._stiffened_plate_effective_aginst_sigy = main_dict['plate effective agains sigy'][0] #True
1665
+ self._buckling_length_factor_stf = None if main_dict['buckling length factor stf'][0] == 0 else \
1666
+ main_dict['buckling length factor stf'][0]
1667
+ self._buckling_length_factor_girder = None if main_dict['buckling length factor girder'][0] == 0 else \
1668
+ main_dict['buckling length factor girder'][0]
1669
+ self._km3 = main_dict['km3'][0]#12
1670
+ self._km2 = main_dict['km2'][0]#24
1671
+ self._girder_dist_between_lateral_supp = None if main_dict['girder distance between lateral support'][0] in [0, None, ''] else \
1672
+ main_dict['girder distance between lateral support'][0]
1673
+ self._stf_dist_between_lateral_supp = None if main_dict['stiffener distance between lateral support'][0] in [0, None, ''] else \
1674
+ main_dict['stiffener distance between lateral support'][0]
1675
+ self._panel_length_Lp = None if main_dict['panel length, Lp'][0] == 0 else main_dict['panel length, Lp'][0]
1676
+ self._overpressure_side = main_dict['pressure side'][0] # either 'stiffener', 'plate', 'both'
1677
+ self._fab_method_stiffener = main_dict['fabrication method stiffener'][0]#'welded'
1678
+ self._fab_method_girder = main_dict['fabrication method girder'][0]#'welded'
1679
+
1680
+ self._Plate.set_main_properties(prop_dict['Plate'])
1681
+
1682
+ if prop_dict['Stiffener'] is not None and self._Stiffener is None:
1683
+ self._Stiffener = CalcScantlings(prop_dict['Stiffener'])
1684
+ elif prop_dict['Stiffener'] is not None and self._Stiffener is not None:
1685
+ self._Stiffener.set_main_properties(prop_dict['Stiffener'])
1686
+ else:
1687
+ self._Stiffener = None
1688
+
1689
+ if prop_dict['Girder'] is not None and self._Girder is None:
1690
+ self._Girder = CalcScantlings(prop_dict['Girder'])
1691
+ elif prop_dict['Girder'] is not None and self._Girder is not None:
1692
+ self._Girder.set_main_properties(prop_dict['Girder'])
1693
+ else:
1694
+ self._Girder = None
1695
+
1696
+ self._calculation_domain = main_dict['calculation domain'][0]
1697
+
1698
+ def plate_buckling(self, optimizing = False):
1699
+ '''
1700
+ Summary
1701
+ '''
1702
+ return_dummy = {'Plate': {'Plate buckling': 0},
1703
+ 'Stiffener': {'Overpressure plate side': 0, 'Overpressure stiffener side': 0,
1704
+ 'Resistance between stiffeners': 0, 'Shear capacity': 0},
1705
+ 'Girder': {'Overpressure plate side': 0, 'Overpressure girder side': 0, 'Shear capacity': 0},
1706
+ 'Local buckling': 0}
1707
+
1708
+ unstf_pl = self.unstiffened_plate_buckling(optimizing = optimizing)
1709
+ up_buckling = max([unstf_pl['UF Pnt. 5 Lateral loaded plates'], unstf_pl['UF sjsd'],
1710
+ max([unstf_pl['UF Longitudinal stress'], unstf_pl['UF transverse stresses'],
1711
+ unstf_pl['UF Shear stresses'], unstf_pl['UF Combined stresses']])
1712
+ if all([self._Girder is None, self._Stiffener is None]) else 0])
1713
+ if optimizing and up_buckling > 1:
1714
+ return_dummy['Plate']['Plate buckling'] = up_buckling
1715
+ return return_dummy
1716
+
1717
+ if not optimizing:
1718
+ local_buckling = self.local_buckling()
1719
+
1720
+ if self._Stiffener is not None:
1721
+ stf_pla = self.stiffened_panel(unstf_pl_data=unstf_pl, optimizing=optimizing)
1722
+ if all([optimizing, type(stf_pla) == list]):
1723
+ return_dummy['Stiffener'][stf_pla[0]] = stf_pla[1]
1724
+ return return_dummy
1725
+
1726
+ stf_buckling_pl_side = stf_pla['UF Plate side'] if self._stf_end_support == 'Continuous' else \
1727
+ stf_pla['UF simply supported plate side']
1728
+ stf_buckling_stf_side = stf_pla['UF Stiffener side'] if self._stf_end_support == 'Continuous' else \
1729
+ stf_pla['UF simply supported stf side']
1730
+ stf_plate_resistance = stf_pla['UF Plate resistance']
1731
+ stf_shear_capacity = stf_pla['UF Shear force']
1732
+ else:
1733
+ stf_buckling_pl_side, stf_buckling_pl_side, stf_buckling_stf_side, stf_plate_resistance, \
1734
+ stf_shear_capacity = 0,0,0,0,0
1735
+
1736
+ if self._Girder is not None:
1737
+ girder = self.girder(unstf_pl_data=unstf_pl, stf_pl_data=stf_pla, optmizing=optimizing)
1738
+ if all([optimizing, type(girder) == list]):
1739
+ return_dummy['Girder'][stf_pla[0]] = stf_pla[1]
1740
+ return return_dummy
1741
+
1742
+ girder_buckling_pl_side = girder['UF Cont. plate side'] if self._girder_end_support == 'Continuous' else \
1743
+ stf_pla['UF Simplified plate side']
1744
+ girder_buckling_girder_side = girder['UF Cont. girder side'] if self._girder_end_support == 'Continuous' \
1745
+ else \
1746
+ stf_pla['UF Simplified girder side']
1747
+ girder_shear_capacity = girder['UF shear force']
1748
+ else:
1749
+ girder_buckling_pl_side, girder_buckling_girder_side, girder_shear_capacity = 0,0,0
1750
+
1751
+ return {'Plate': {'Plate buckling': up_buckling},
1752
+ 'Stiffener': {'Overpressure plate side': stf_buckling_pl_side,
1753
+ 'Overpressure stiffener side': stf_buckling_stf_side,
1754
+ 'Resistance between stiffeners': stf_plate_resistance,
1755
+ 'Shear capacity': stf_shear_capacity},
1756
+ 'Girder': {'Overpressure plate side': girder_buckling_pl_side,
1757
+ 'Overpressure girder side': girder_buckling_girder_side,
1758
+ 'Shear capacity': girder_shear_capacity},
1759
+ 'Local buckling': 0 if optimizing else local_buckling}
1760
+
1761
+ def unstiffened_plate_buckling(self, optimizing = False):
1762
+
1763
+ unstf_pl_data = dict()
1764
+
1765
+ E = self._E/1e6
1766
+ v = self._v
1767
+ fy = self._mat_yield/1e6
1768
+ gammaM = self._Plate.mat_factor
1769
+ t = self._Plate.t
1770
+ s = self._Plate.spacing
1771
+ l = self._Plate.span*1000
1772
+
1773
+ tsd = self._Plate.tau_xy
1774
+ psd = self._lat_press*self._lat_load_factor
1775
+
1776
+ sig_x1 = self._Plate.sigma_x1*self._stress_load_factor
1777
+ sig_x2 = self._Plate.sigma_x2*self._stress_load_factor
1778
+
1779
+ sig_y1 = self._Plate.sigma_y1 * self._stress_load_factor
1780
+ sig_y2 = self._Plate.sigma_y2 * self._stress_load_factor
1781
+
1782
+
1783
+ if sig_x1 * sig_x2 >= 0:
1784
+ Use_Smax_x = sxsd = sig_x1 if abs(sig_x1) > abs(sig_x2) else sig_x2
1785
+ else:
1786
+ Use_Smax_x = sxsd =max(sig_x1 , sig_x2)
1787
+
1788
+ if sig_y1 * sig_y2 >= 0:
1789
+ Use_Smax_y = sy1sd = sig_y1 if abs(sig_y1) > abs(sig_y2) else sig_y2
1790
+ else:
1791
+ Use_Smax_y = sy1sd = max(sig_y1 , sig_y2)
1792
+
1793
+ if sig_x1 * sig_x2 >= 0:
1794
+ Use_Smin_x = sig_x2 if abs(sig_x1) > abs(sig_x2) else sig_x1
1795
+ else:
1796
+ Use_Smin_x = min(sig_x1 , sig_x2)
1797
+
1798
+ if sig_y1 * sig_y2 >= 0:
1799
+ Use_Smin_y = sig_y2 if abs(sig_y1) > abs(sig_y2) else sig_y1
1800
+ else:
1801
+ Use_Smin_y = min(sig_y1 , sig_y2)
1802
+
1803
+ shear_ratio_long = 1 if Use_Smax_x == 0 else Use_Smin_x / Use_Smax_x
1804
+ shear_ratio_trans = 1 if Use_Smax_y == 0 else Use_Smin_y/Use_Smax_y
1805
+
1806
+ Max_vonMises_x = sig_x1 if abs(sig_x1) > abs(sig_x2) else sig_x2
1807
+
1808
+ unstf_pl_data['sxsd'] = sxsd
1809
+ unstf_pl_data['sy1sd'] = sy1sd
1810
+
1811
+ l1 = min(l/4, s/2)
1812
+ if l == 0:
1813
+ sig_trans_l1 = Use_Smax_y
1814
+ else:
1815
+ sig_trans_l1 = Use_Smax_y*(shear_ratio_trans+(1-shear_ratio_trans)*(l-l1)/l)
1816
+
1817
+ trans_stress_used = sysd = 0.75*Use_Smax_y if abs(0.75*Use_Smax_y) > abs(Use_Smax_y) else sig_trans_l1
1818
+ unstf_pl_data['sysd'] = sysd
1819
+ #Pnt. 5 Lateral loaded plates
1820
+
1821
+ sjsd =math.sqrt(math.pow(Max_vonMises_x,2) + math.pow(sysd,2)-Max_vonMises_x*sysd+3*math.pow(tsd,2))
1822
+
1823
+ uf_sjsd = sjsd/fy*gammaM
1824
+ unstf_pl_data['UF sjsd'] = uf_sjsd
1825
+
1826
+ #psi_x =max([0,(1-math.pow(sjsd/fy,2))/math.sqrt(1-3/4*math.pow(sysd/fy,2)-3*math.pow(tsd/fy,2))])
1827
+ psi_x =max([0,(1-math.pow(sjsd/fy,2))/math.sqrt(1-3/4*math.pow(sysd/fy,2)-3*math.pow(tsd/fy,2))]) \
1828
+ if 1-3/4*math.pow(sysd/fy,2)-3*math.pow(tsd/fy,2) > 0 else 0
1829
+ psi_x_chk = (1-3/4*math.pow(sy1sd/fy,2)-3*math.pow(tsd/fy,2))>0
1830
+
1831
+ psi_y = max([0,(1-math.pow(sjsd/fy,2))/math.sqrt(1-3/4*math.pow(sxsd/fy,2)-3*math.pow(tsd/fy,2))]) \
1832
+ if 1-3/4*math.pow(sxsd/fy,2)-3*math.pow(tsd/fy,2) > 0 else 0
1833
+ psi_y_chk = (1 - 3 / 4 * math.pow(sxsd / fy, 2) - 3 * math.pow(tsd / fy, 2)) > 0
1834
+
1835
+ if gammaM * s * l == 0:
1836
+ Psd_max_press = 0
1837
+ else:
1838
+ if all([psi_x_chk, psi_y_chk]):
1839
+ Psd_max_press = (4 * fy / gammaM * math.pow(t / s,2) * (psi_y + math.pow(s / l, 2) * psi_x))
1840
+ else:
1841
+ Psd_max_press = -1
1842
+
1843
+ if Psd_max_press == 0:
1844
+ uf_lat_load_pl_press = 0
1845
+ else:
1846
+ uf_lat_load_pl_press = 9 if Psd_max_press < 0 else abs(psd/Psd_max_press)
1847
+
1848
+ unstf_pl_data['UF Pnt. 5 Lateral loaded plates'] = uf_lat_load_pl_press
1849
+ #6.2 & 6.6 Longitudinal stress
1850
+ if shear_ratio_long <= -2:
1851
+ ksig = "Unknown"
1852
+ elif 0 <= shear_ratio_long <= 1:
1853
+ ksig = 8.2 / (1.05 + shear_ratio_long)
1854
+ elif shear_ratio_long <= -1:
1855
+ ksig = 7.81 - 6.29 * shear_ratio_long + 9.78 * math.pow(shear_ratio_long, 2)
1856
+ elif -2 < shear_ratio_long < -1:
1857
+ ksig = 5.98 * math.pow(1 - shear_ratio_long, 2)
1858
+
1859
+ #print(sxsd, sy1sd, tsd, sjsd, uf_lat_load_pl, psi_x, psi_y, uf_lat_load_pl_press, psd, Psd_max_press,ksig)
1860
+
1861
+ if t*E == 0:
1862
+ alpha_p = 0
1863
+ elif ksig == "Unknown":
1864
+ alpha_p = 1.05*s/t*math.sqrt(fy/E)
1865
+ else:
1866
+ alpha_p = s/t/(28.4*math.sqrt(ksig*235/fy))
1867
+
1868
+ Cx =(alpha_p-0.055*(3+max([-2,shear_ratio_long])))/math.pow(alpha_p, 2)
1869
+
1870
+ sxRd = Cx*fy/gammaM if not all([sig_x1<0, sig_x2<0]) else 1*fy/gammaM # Corrected 07.08.2023, issue 126
1871
+
1872
+ uf_unstf_pl_long_stress = 0 if sxRd == 0 else abs(sxsd/sxRd)
1873
+ unstf_pl_data['UF Longitudinal stress'] = uf_unstf_pl_long_stress
1874
+ #print(uf_unstf_pl_long_stress)
1875
+
1876
+ #6.3 & 6.8 Transverse stresses:
1877
+ ha = 0 if t == 0 else max([0,0.05*s/t-0.75])
1878
+ kp_1_for_Psd = 0 if s == 0 else 2*math.pow(t/s,2)*fy
1879
+ kp_used = 1-ha*(psd/fy-2*math.pow(t/s,2)) if psd>kp_1_for_Psd else 1
1880
+
1881
+ alpha_c = 0 if t*E == 0 else 1.1*s/t*math.sqrt(fy/E)
1882
+ mu = 0.21*(alpha_c-0.2)
1883
+
1884
+ if alpha_c <= 0.2:
1885
+ kappa = 1
1886
+ elif 0.2 < alpha_c < 2:
1887
+ kappa = 0 if alpha_c == 0 else 1/(2*math.pow(alpha_c,2))*(1+mu+math.pow(alpha_c,2)-
1888
+ math.sqrt(math.pow(1+mu+math.pow(alpha_c,2),2)-
1889
+ 4*math.pow(alpha_c,2)))
1890
+ elif alpha_c >= 2:
1891
+ kappa = 0 if alpha_c == 0 else 1/(2*math.pow(alpha_c,2))+0.07
1892
+
1893
+
1894
+ syR = 0 if l*fy == 0 else (1.3*t/l*math.sqrt(E/fy)+kappa*(1-1.3*t/l*math.sqrt(E/fy)))*fy*kp_used
1895
+ syRd = syR if not all([sig_y1<0, sig_y2<0]) else fy
1896
+ syRd = syRd/gammaM
1897
+ uf_unstf_pl_trans_stress = 0 if syRd == 0 else abs(sysd)/syRd
1898
+ #print(uf_unstf_pl_trans_stress)
1899
+ unstf_pl_data['syR'] = syR
1900
+ unstf_pl_data['syRd'] = syRd
1901
+ unstf_pl_data['UF transverse stresses'] = uf_unstf_pl_trans_stress
1902
+ #6.4 Shear stress
1903
+ if l >= s:
1904
+ kl = 0 if l == 0 else 5.34+4*math.pow(s/l,2)
1905
+ else:
1906
+ kl = 0 if l == 0 else 5.34*math.pow(s/l,2)+4
1907
+ unstf_pl_data['kl'] = kl
1908
+ alpha_w = 0 if t*E*kl == 0 else 0.795*s/t*math.sqrt(fy/E/kl)
1909
+ if alpha_w <= 0.8:
1910
+ Ctau = 1
1911
+ elif 0.8 < alpha_w < 1.25:
1912
+ Ctau = 1-0.675*(alpha_w-0.8)
1913
+ else:
1914
+ Ctau = 0 if alpha_w == 0 else 0.9/alpha_w
1915
+
1916
+ tauRd = Ctau*fy/gammaM/math.sqrt(3)
1917
+ uf_unstf_pl_shear_stress = 0 if tauRd == 0 else tsd/tauRd
1918
+ unstf_pl_data['UF Shear stresses'] = uf_unstf_pl_shear_stress
1919
+ #print(uf_unstf_pl_shear_stress)
1920
+
1921
+ #6.5 Combined stresses
1922
+
1923
+ if alpha_w <= 0.8:
1924
+ Ctaue = 1
1925
+ elif 0.8 < alpha_w < 1.25:
1926
+ Ctaue = 1-0.8*(alpha_w-0.8)
1927
+ else:
1928
+ Ctaue = 0 if alpha_w == 0 else 1/math.pow(alpha_w,2)
1929
+
1930
+ tauRd_comb = Ctaue*fy/gammaM/math.sqrt(3)
1931
+ tauRd_comb = tauRd if sysd>0 else tauRd
1932
+
1933
+ if s/t <= 120:
1934
+ ci = 0 if t == 0 else 1-s/120/t
1935
+ elif s/t > 120:
1936
+ ci = 0
1937
+ else:
1938
+ ci = 1
1939
+
1940
+ sxRd_comb = fy/gammaM if all([sig_x1<0, sig_x2<0]) else sxRd
1941
+ syRd_comb = syRd
1942
+
1943
+ sxsd_div_sxrd = 0 if sxRd_comb == 0 else sxsd/sxRd_comb
1944
+ sysd_div_syrd = 0 if syRd_comb == 0 else sysd / syRd_comb
1945
+ tausd_div_taurd = 0 if tauRd_comb == 0 else tsd/tauRd_comb
1946
+
1947
+ comb_req = math.pow(sxsd_div_sxrd, 2)+math.pow(sysd_div_syrd, 2)-ci*sxsd_div_sxrd*sysd_div_syrd+\
1948
+ math.pow(tausd_div_taurd, 2)
1949
+ uf_unstf_pl_comb_stress = comb_req
1950
+ unstf_pl_data['UF Combined stresses'] = uf_unstf_pl_comb_stress
1951
+
1952
+ return unstf_pl_data
1953
+
1954
+ def stiffened_panel(self, unstf_pl_data = None, optimizing = False):
1955
+ E = self._E / 1e6
1956
+ v = self._v
1957
+ G = E/(2*(1+v))
1958
+ fy = self._mat_yield/1e6
1959
+ gammaM = self._Plate.mat_factor
1960
+ t = self._Plate.t
1961
+ s = self._Plate.spacing
1962
+ l = self._Plate.span * 1000
1963
+
1964
+ sig_x1 = self._Plate.sigma_x1 * self._stress_load_factor
1965
+ sig_x2 = self._Plate.sigma_x2 * self._stress_load_factor
1966
+
1967
+ sig_y1 = self._Plate.sigma_y1 * self._stress_load_factor
1968
+ sig_y2 = self._Plate.sigma_y2 * self._stress_load_factor
1969
+
1970
+ Lg = self._Plate.girder_lg*1000
1971
+
1972
+ stf_pl_data = dict()
1973
+
1974
+ sxsd = unstf_pl_data['sxsd']
1975
+ #sxsd = 0 if self._method == 2 else unstf_pl_data['sxsd']
1976
+ sy1sd = 0 if self.get_method() == 2 else unstf_pl_data['sy1sd']
1977
+
1978
+ sysd = 0 if self.get_method() == 2 else unstf_pl_data['sysd']
1979
+ tsd = self._Plate.tau_xy * self._stress_load_factor
1980
+ psd = self._lat_press * self._lat_load_factor
1981
+ psd_min_adj = psd if self._min_lat_press_adj_span is None else\
1982
+ self._min_lat_press_adj_span*self._lat_load_factor
1983
+ shear_ratio_long = 1
1984
+ shear_ratio_trans = 1
1985
+
1986
+ #Pnt.7: Buckling of stiffened plates
1987
+ Vsd = psd*s*l/2
1988
+ tw_req = Vsd*gammaM*math.sqrt(3)/(fy*self._Stiffener.hw)
1989
+ Anet = (self._Stiffener.hw + self._Stiffener.tf) * self._Stiffener.tw# + self._Stiffener.b*self._Stiffener.tf
1990
+ Vrd = Anet*fy/(gammaM*math.sqrt(3))
1991
+ Vsd_div_Vrd = Vsd/Vrd
1992
+
1993
+ stf_pl_data['UF Shear force'] = Vsd_div_Vrd
1994
+ if optimizing and Vsd_div_Vrd > 1:
1995
+ return ['UF Shear force', Vsd_div_Vrd]
1996
+
1997
+ # 7.2 Forces in idealised stiffened plate
1998
+ Iy = Is = self._Stiffener.get_moment_of_intertia()*1000**4
1999
+
2000
+ stf_pl_data['Is'] = Is
2001
+ kc = 0 if t*s == 0 else 2*(1+math.sqrt(1+10.9*Is/(math.pow(t,3)*s)))
2002
+ mc = 13.3 if self._stf_end_support == 'Continuous' else 8.9
2003
+
2004
+ # 7.3 Effective plate width
2005
+ syR = unstf_pl_data['syR']
2006
+
2007
+ Cys = 0.5*(math.sqrt(4-3*math.pow(sysd/fy,2))+sysd/fy)
2008
+
2009
+ alphap = 0 if t*E == 0 else 0.525 * (s / t) * math.sqrt(fy / E) # reduced plate slenderness, checked not calculated with ex
2010
+ Cxs = (alphap - 0.22) / math.pow(alphap, 2) if alphap > 0.673 else 1
2011
+ stf_pl_data['alphap'] = alphap
2012
+ stf_pl_data['Cxs'] = Cxs
2013
+ if sysd < 0:
2014
+ Cys = min(Cys, 1)
2015
+ else:
2016
+ if s / t <= 120:
2017
+ ci = 0 if t == 0 else 1-s / 120 / t
2018
+ else:
2019
+ ci = 0
2020
+
2021
+ cys_chk = 1 - math.pow(sysd / syR, 2) + ci * ((sxsd * sysd) / (Cxs * fy * syR))
2022
+ Cys =0 if cys_chk < 0 else math.sqrt(cys_chk)
2023
+
2024
+ stf_pl_data['Cys_comp'] = Cys
2025
+
2026
+ se_div_s = Cxs * Cys
2027
+ se = s * se_div_s
2028
+
2029
+ zp = self._Stiffener.get_cross_section_centroid_with_effective_plate(se=se/1000)*1000 - t / 2 # ch7.5.1 page 19
2030
+ zt = (self._Stiffener.hw+self._Stiffener.tf) - zp + t/2
2031
+
2032
+ Iy = self._Stiffener.get_moment_of_intertia(efficent_se=se/1000)*1000**4
2033
+
2034
+ Weff = 0.0001 if zt == 0 else Iy/zt
2035
+ Co= 0 if kc*E*t*s == 0 else Weff*fy*mc/(kc*E*math.pow(t,2)*s)
2036
+ Po = 0 if all([sig_y1 < 0, sig_y2 < 0]) else (0.6+0.4*shear_ratio_trans)*Co*sy1sd \
2037
+ if shear_ratio_trans >-1.5 else 0
2038
+
2039
+ qsd_press = (psd+abs(Po))*s
2040
+ qsd_opposite = abs(Po)*s if psd < Po else 0
2041
+
2042
+ '''
2043
+ 1 Overpressure on Stiffener Side
2044
+ 2 Overpressure on Plate Side
2045
+ 3 Overpr. may occur on both sides
2046
+ '''
2047
+
2048
+ qsd_plate_side = qsd_opposite if self._overpressure_side == 'stiffener side' else qsd_press
2049
+ qsd_stf_side = qsd_opposite if self._overpressure_side == 'plate side' else qsd_press
2050
+ kl = unstf_pl_data['kl']
2051
+
2052
+ tcrl = 0 if s == 0 else kl*0.904*E*math.pow(t/s,2)
2053
+
2054
+ if l<= Lg:
2055
+ kg = 0 if Lg == 0 else 5.34+4*math.pow(l/Lg,2)
2056
+ else:
2057
+ kg = 0 if Lg == 0 else 5.34*math.pow(l / Lg, 2)+4
2058
+
2059
+ tcrg = 0 if l == 0 else kg*0.904*E*math.pow(t/l,2)
2060
+
2061
+ if self._tension_field_action == 'allowed' and tsd>(tcrl/gammaM):
2062
+ ttf = tsd-tcrg
2063
+ else:
2064
+ ttf = 0
2065
+
2066
+ As = self._Stiffener.tw*self._Stiffener.hw + self._Stiffener.b*self._Stiffener.tf
2067
+
2068
+ NSd = sxsd*(As+s*t)+ttf*s*t
2069
+
2070
+ #7.4 Resistance of plate between stiffeners
2071
+ ksp = math.sqrt(1-3*math.pow(tsd/fy,2)) if tsd < (fy/math.sqrt(3)) else 0
2072
+ syrd_unstf = unstf_pl_data['syRd'] * ksp
2073
+ tsd_7_4 = fy/(math.sqrt(3)*gammaM)
2074
+ uf_stf_panel_res_bet_plate = max([sysd/syrd_unstf if all([syrd_unstf >0, sysd > 0]) else 0, tsd/tsd_7_4])
2075
+ stf_pl_data['UF Plate resistance'] = uf_stf_panel_res_bet_plate
2076
+ if optimizing and uf_stf_panel_res_bet_plate > 1:
2077
+ return ['UF Plate resistance', uf_stf_panel_res_bet_plate]
2078
+ #7.5 Characteristic buckling strength of stiffeners
2079
+
2080
+ fEpx = 0 if s == 0 else 3.62*E*math.pow(t/s,2) # eq 7.42, checked, ok
2081
+ fEpy = 0 if s == 0 else 0.9*E*math.pow(t/s,2) # eq 7.43, checked, ok
2082
+ fEpt = 0 if s == 0 else 5.0*E*math.pow(t/s,2) # eq 7.44, checked, ok
2083
+ c = 0 if l == 0 else 2-(s/l) # eq 7.41, checked, ok
2084
+
2085
+ sjSd = math.sqrt(
2086
+ math.pow(max([sxsd, 0]), 2) + math.pow(max([sysd, 0]), 2) - max([sxsd, 0]) * max([sysd, 0]) +
2087
+ 3 * math.pow(tsd, 2)) # eq 7.38, ok
2088
+
2089
+ alphae = math.sqrt( (fy/sjSd) * math.pow(math.pow(max([sxsd, 0])/fEpx, c)+
2090
+ math.pow(max([sysd, 0])/fEpy, c)+
2091
+ math.pow(abs(tsd)/fEpt, c), 1/c)) # eq 7.40
2092
+
2093
+
2094
+
2095
+ fep = fy / math.sqrt(1+math.pow(alphae,4)) # eq 7.39
2096
+ eta = min(sjSd/fep, 1) # eq. 7.377
2097
+
2098
+ C = 0 if self._Stiffener.tw == 0 else (self._Stiffener.hw / s) * math.pow(t / self._Stiffener.tw, 3) * \
2099
+ math.sqrt((1 - eta)) # e 7.36, checked ok
2100
+
2101
+ beta = (3*C+0.2)/(C+0.2) # eq 7.35
2102
+ It = self._Stiffener.get_torsional_moment_venant(efficient_flange=False)
2103
+ Ipo = self._Stiffener.get_polar_moment()
2104
+ Iz = self._Stiffener.get_Iz_moment_of_inertia()
2105
+
2106
+ def red_prop():
2107
+ tw_red =max(0,self._Stiffener.tw*(1-Vsd_div_Vrd))
2108
+ Atot_red = As+se*t-self._Stiffener.hw*(self._Stiffener.tw - tw_red )
2109
+ It_red = self._Stiffener.get_torsional_moment_venant(reduced_tw=tw_red, efficient_flange=False)
2110
+ Ipo_red = self._Stiffener.get_polar_moment(reduced_tw=tw_red )
2111
+ #Iz = self._Stiffener.get_Iz_moment_of_inertia(reduced_tw=tw)
2112
+ #Iz_red = self._Stiffener.get_moment_of_intertia(efficent_se=se/1000, reduced_tw=tw_red)
2113
+ Iy_red = self._Stiffener.get_moment_of_intertia(efficent_se=se / 1000, reduced_tw=tw_red) * 1000 ** 4
2114
+ zp_red = self._Stiffener.get_cross_section_centroid_with_effective_plate(se / 1000, reduced_tw=tw_red ) \
2115
+ * 1000 - t / 2 # ch7.5.1 page 19
2116
+ zt_red = (self._Stiffener.hw + self._Stiffener.tf) - zp_red + t/2 # ch 7.5.1 page 19
2117
+ Wes_red = 0.0001 if zt_red == 0 else Iy_red/zt_red
2118
+ Wep_red = 0.0001 if zp_red == 0 else Iy_red/zp_red
2119
+ return {'tw':tw_red , 'Atot': Atot_red , 'It': It_red , 'Ipo': Ipo_red , 'zp': zp_red ,
2120
+ 'zt': zt_red , 'Wes': Wes_red , 'Wep': Wep_red, 'Iy': Iy_red}
2121
+
2122
+ hs = self._Stiffener.hw / 2 if self._Stiffener.get_stiffener_type() == 'FB' else \
2123
+ self._Stiffener.hw + self._Stiffener.tf / 2
2124
+
2125
+ def lt_params(lT):
2126
+
2127
+ if Ipo*lT>0:
2128
+ fET = beta*G*It/Ipo+math.pow(math.pi,2)*E*math.pow(hs,2)*Iz/(Ipo*math.pow(lT,2)) #NOTE, beta was missed from above, added. 23.08.2022
2129
+ else:
2130
+ fET = 0.001
2131
+ alphaT = 0 if fET == 0 else math.sqrt(fy/fET)
2132
+ mu = 0.35*(alphaT-0.6)
2133
+ fT_div_fy = (1+mu+math.pow(alphaT,2)-math.sqrt(math.pow(1+mu+math.pow(alphaT,2),2)-
2134
+ 4*math.pow(alphaT,2)))/(2*math.pow(alphaT,2))
2135
+ fT = fy*fT_div_fy if alphaT > 0.6 else fy
2136
+ #print(fET, alphaT, mu, fT)
2137
+ return {'fEt': fET, 'alphaT': alphaT, 'mu': mu, 'fT_div_fy': fT_div_fy, 'fT': fT}
2138
+
2139
+
2140
+ zp = self._Stiffener.get_cross_section_centroid_with_effective_plate(se/1000)*1000 - t / 2 # ch7.5.1 page 19
2141
+ zt = (self._Stiffener.hw + self._Stiffener.tf) - zp + t/2 # ch 7.5.1 page 19
2142
+ fr = fy
2143
+
2144
+ if Vsd_div_Vrd < 0.5:
2145
+ Wes = 0.0001 if zt == 0 else Iy/zt
2146
+ Wep = 0.0001 if zp == 0 else Iy/zp
2147
+ Ae = As + se * t
2148
+ else:
2149
+ red_param = red_prop()
2150
+ Wes = red_param['Wes']
2151
+ Wep = red_param['Wep']
2152
+ Ae = red_param['Atot']
2153
+
2154
+ Wmin = min([Wes, Wep])
2155
+ pf = 0.0001 if l*s*gammaM == 0 else 12*Wmin*fy/(math.pow(l,2)*s*gammaM)
2156
+
2157
+ if self._buckling_length_factor_stf is None:
2158
+ if self._stf_end_support == 'Continuous':
2159
+ lk = l*(1-0.5*abs(psd_min_adj/pf))
2160
+
2161
+ else:
2162
+ lk = l
2163
+ else:
2164
+ lk = self._buckling_length_factor_stf * l
2165
+ ie = 0.0001 if As+se*t == 0 else math.sqrt(Iy/(As+se*t))
2166
+ fE = 0.0001 if lk == 0 else math.pow(math.pi,2)*E*math.pow(ie/lk,2)
2167
+
2168
+
2169
+ fk_dict = dict()
2170
+ fr_dict = dict()
2171
+ #Plate side
2172
+ zp = zp
2173
+ fr = fy
2174
+ fr_dict['plate'] = fr
2175
+ alpha = math.sqrt(fr/fE)
2176
+ mu = 0 if ie == 0 else (0.34+0.08*zp/ie)*(alpha-0.2)
2177
+ fk_div_fr = (1+mu+math.pow(alpha,2)-math.sqrt(math.pow(1+mu+math.pow(alpha,2),2)-4*math.pow(alpha,2)))/(2*math.pow(alpha,2))
2178
+ fk = fk_div_fr*fr if alpha > 0.2 else fr
2179
+ fk_dict['plate'] = fk
2180
+ #Stiffener side
2181
+
2182
+ for lT in [int(l if self._stf_dist_between_lateral_supp is None else self._stf_dist_between_lateral_supp),
2183
+ int(0.4*l if self._stf_dist_between_lateral_supp is None else self._stf_dist_between_lateral_supp),
2184
+ int(0.8*l if self._stf_dist_between_lateral_supp is None else self._stf_dist_between_lateral_supp)]:
2185
+ params = lt_params(lT)
2186
+ fr = params['fT'] if params['alphaT']>0.6 else fy
2187
+ fr_dict[lT] = fr
2188
+ alpha = math.sqrt(fr / fE)
2189
+ mu = 0 if ie == 0 else (0.34 + 0.08 * zt / ie) * (alpha - 0.2)
2190
+ fk_div_fr = (1 + mu + math.pow(alpha, 2) - math.sqrt(
2191
+ math.pow(1 + mu + math.pow(alpha, 2), 2) - 4 * math.pow(alpha, 2))) / (2 * math.pow(alpha, 2))
2192
+ fk = fk_div_fr * fr if alpha > 0.2 else fr
2193
+ fk_dict[lT] = fk
2194
+
2195
+ #7.7.3 Resistance parameters for stiffeners
2196
+
2197
+ NRd = 0.0001 if gammaM == 0 else Ae * (fy / gammaM) # eq7.65, checked ok
2198
+ NksRd = Ae * (fk_dict[int(l if self._stf_dist_between_lateral_supp is None else self._stf_dist_between_lateral_supp)] / gammaM) #eq7.66
2199
+ NkpRd = Ae * (fk_dict['plate'] / gammaM) # checked ok
2200
+
2201
+ Ms1Rd = Wes * (fr_dict[int(0.4*l if self._stf_dist_between_lateral_supp is None else
2202
+ self._stf_dist_between_lateral_supp)] / gammaM) # ok
2203
+ Ms2Rd = Wes * (fr_dict[int(0.8*l if self._stf_dist_between_lateral_supp is None else
2204
+ self._stf_dist_between_lateral_supp)] / gammaM) # eq7.69 checked ok
2205
+
2206
+ MstRd = Wes*(fy/gammaM) #eq7.70 checked ok
2207
+ MpRd = Wep*(fy/gammaM) #eq7.71 checked ok
2208
+
2209
+ Ne = ((math.pow(math.pi,2))*E*Ae)/(math.pow(lk/ie,2))# eq7.72 , checked ok
2210
+
2211
+ #7.6 Resistance of stiffened panels to shear stresses
2212
+ Ip = math.pow(t,3)*s/10.9
2213
+ tcrs = (36 * E / (s * t * math.pow(l, 2))) * ((Ip * math.pow(Is, 3)) ** 0.25)
2214
+ tRdy = fy/math.sqrt(3)/gammaM
2215
+ tRdl = tcrl/gammaM
2216
+ tRds = tcrs/gammaM
2217
+ tRd = min([tRdy,tRdl,tRds])
2218
+
2219
+
2220
+ u = 0 if all([tsd>(tcrl/gammaM), self._tension_field_action == 'allowed']) else math.pow(tsd/tRd, 2)
2221
+ zstar = zp
2222
+ if self._stf_end_support != 'Continuous':
2223
+ #Lateral pressure on plate side:
2224
+ #7.7.2 Simple supported stiffener (sniped stiffeners)
2225
+
2226
+ #Lateral pressure on plate side:
2227
+ stf_pl_data['UF Stiffener side'] = 0
2228
+ stf_pl_data['UF Plate side'] = 0
2229
+ uf_7_58 = NSd/NksRd-2*NSd/NRd +((qsd_plate_side*math.pow(l,2)/8)+NSd*zstar)/(MstRd*(1-NSd/Ne))+u
2230
+ uf_7_59 = NSd/NkpRd+((qsd_plate_side*math.pow(l,2)/8)+NSd*zstar)/(MpRd*(1-NSd/Ne))+u
2231
+ uf_max_simp_pl = max([uf_7_58, uf_7_59])
2232
+ stf_pl_data['UF simply supported plate side'] = uf_max_simp_pl
2233
+
2234
+ #Lateral pressure on stiffener side:
2235
+
2236
+ uf_7_60 = NSd/NksRd+((qsd_stf_side*math.pow(l,2)/8)-NSd*zstar)/(Ms2Rd*(1-NSd/Ne))+u
2237
+ uf_7_61 = NSd/NkpRd-2*NSd/NRd+((qsd_stf_side*math.pow(l,2)/8)-NSd*zstar)/(MpRd*(1-NSd/Ne))+u
2238
+
2239
+ test_qsd_l = qsd_stf_side*math.pow(l,2)/8 >= NSd*zstar
2240
+ uf_7_62 = NSd/NksRd-2*NSd/NRd+(NSd*zstar-(qsd_stf_side*math.pow(l,2)/8))/(MstRd*(1-NSd/Ne))+u
2241
+ uf_7_63 = NSd/NkpRd+(NSd*zstar-(qsd_stf_side*math.pow(l,2)/8))/(MpRd*(1-NSd/Ne))+u
2242
+
2243
+ uf_max_simp_stf = max([0,uf_7_62,uf_7_63]) if not test_qsd_l else max([0,uf_7_60,uf_7_61])
2244
+ stf_pl_data['UF simply supported stf side'] = uf_max_simp_stf
2245
+ else:
2246
+ stf_pl_data['UF simply supported stf side'] = 0
2247
+ stf_pl_data['UF simply supported plate side'] = 0
2248
+ #7.7.1 Continuous stiffeners
2249
+
2250
+ M1Sd_pl = abs(qsd_plate_side)*math.pow(l,2)/self._km3
2251
+ M2Sd_pl = abs(qsd_plate_side)*math.pow(l,2)/self._km2
2252
+ M1Sd_stf = abs(qsd_stf_side) * math.pow(l, 2) / self._km3
2253
+ M2Sd_stf = abs(qsd_stf_side) * math.pow(l, 2) / self._km2
2254
+ M1Sd_max = max([M1Sd_pl, M1Sd_stf])
2255
+ M2Sd_max = max([M2Sd_pl, M2Sd_stf])
2256
+ # Lateral pressure on plate side:
2257
+ #print(M1Sd_pl, M2Sd_pl, M1Sd_stf,M2Sd_stf, qsd_stf_side, qsd_plate_side)
2258
+ from scipy.optimize import minimize
2259
+ def iteration_min_uf_pl_side(x):
2260
+ eq7_50 = NSd/NksRd+(M1Sd_pl-NSd*x)/(Ms1Rd*(1-NSd/Ne))+u
2261
+ eq7_51 = NSd/NkpRd-2*NSd/NRd +(M1Sd_pl-NSd*x)/(MpRd*(1-NSd/Ne))+u
2262
+ eq7_52 = NSd/NksRd-2*NSd/NRd+(M2Sd_pl+NSd*x)/(MstRd*(1-NSd/Ne))+u
2263
+ eq7_53 = NSd/NkpRd+(M2Sd_pl+NSd*x)/(MpRd*(1-NSd/Ne))+u
2264
+ #print(zstar, eq7_50, eq7_51,eq7_52,eq7_53,max([eq7_50, eq7_51,eq7_52,eq7_53]))
2265
+ return max(eq7_50, eq7_51, eq7_52, eq7_53)
2266
+ res_iter_pl = minimize(iteration_min_uf_pl_side, 0, bounds=[[-zt+self._Stiffener.tf/2,zp]])
2267
+
2268
+ if type(res_iter_pl.fun) == list:
2269
+ stf_pl_data['UF Plate side'] = res_iter_pl.fun[0]
2270
+ else:
2271
+ stf_pl_data['UF Plate side'] = res_iter_pl.fun
2272
+
2273
+ # Lateral pressure on stiffener side:
2274
+
2275
+ # max_lfs = []
2276
+ # ufs = []
2277
+
2278
+ def iteration_min_uf_stf_side(x):
2279
+ eq7_54 = NSd/NksRd-2*NSd/NRd +(M1Sd_stf+NSd*x)/(MstRd*(1-NSd/Ne))+u
2280
+ eq7_55 = NSd/NkpRd+(M1Sd_stf+NSd*x)/(MpRd*(1-NSd/Ne))+u
2281
+ eq7_56 = NSd/NksRd+(M2Sd_stf-NSd*x)/(Ms2Rd*(1-NSd/Ne))+u
2282
+ eq7_57 = NSd/NkpRd-2*NSd/NRd+(M2Sd_stf-NSd*x)/(MpRd*(1-NSd/Ne))+u
2283
+ return max(eq7_54, eq7_55, eq7_56, eq7_57)
2284
+
2285
+ res_iter_stf = minimize(iteration_min_uf_stf_side, 0, bounds=[[-zt+self._Stiffener.tf/2,zp]])
2286
+
2287
+ if type(res_iter_stf.fun) == list:
2288
+ stf_pl_data['UF Stiffener side'] = res_iter_stf.fun[0]
2289
+ else:
2290
+ stf_pl_data['UF Stiffener side'] = res_iter_stf.fun
2291
+
2292
+ return stf_pl_data
2293
+
2294
+ def girder(self, unstf_pl_data = None, stf_pl_data = None, optmizing = False):
2295
+ '''
2296
+ Buckling of girder.
2297
+ '''
2298
+
2299
+ girder_data = dict()
2300
+
2301
+ E = self._E / 1e6
2302
+ v = self._v
2303
+ G = E/(2*(1+v))
2304
+ fy = self._mat_yield/1e6
2305
+ gammaM = self._Plate.mat_factor
2306
+ t = self._Plate.t
2307
+ s = self._Plate.spacing
2308
+ l = self._Plate.span * 1000
2309
+ hw = self._Girder.hw
2310
+
2311
+ tsd = self._Plate.tau_xy * self._stress_load_factor
2312
+ psd = self._lat_press
2313
+
2314
+
2315
+ sig_x1 = self._Plate.sigma_x1 * self._stress_load_factor
2316
+ sig_x2 = self._Plate.sigma_x2 * self._stress_load_factor
2317
+
2318
+ sig_y1 = self._Plate.sigma_y1 * self._stress_load_factor
2319
+ sig_y2 = self._Plate.sigma_y2 * self._stress_load_factor
2320
+
2321
+ sxsd = unstf_pl_data['sxsd']
2322
+ #sxsd = 0 if self._method == 2 else unstf_pl_data['sxsd']
2323
+
2324
+ sy1sd = unstf_pl_data['sy1sd']
2325
+
2326
+ #sysd = 0 if self.get_method() == 2 else unstf_pl_data['sysd']
2327
+ sysd = unstf_pl_data['sysd']
2328
+ tsd = self._Plate.tau_xy * self._stress_load_factor
2329
+ psd = self._lat_press * self._lat_load_factor
2330
+ psd_min_adj = psd if self._min_lat_press_adj_span is None else\
2331
+ self._min_lat_press_adj_span*self._lat_load_factor
2332
+
2333
+ Lg = self._Plate.girder_lg*1000
2334
+
2335
+ Ltg = Lg if self._girder_dist_between_lateral_supp == None else self._girder_dist_between_lateral_supp
2336
+ Lp = 0 if self._panel_length_Lp is None else self._panel_length_Lp
2337
+
2338
+ #Pnt.8: Buckling of Girders
2339
+ #7.8 Check for shear force
2340
+ Vsd = psd*l*Lg/2
2341
+
2342
+ tw_req = Vsd*gammaM*math.sqrt(3)/(fy*self._Girder.hw)
2343
+ Anet = self._Girder.hw * self._Girder.tw + self._Girder.tw*self._Girder.tf
2344
+ Vrd = Anet*fy/(gammaM*math.sqrt(3))
2345
+
2346
+ Vsd_div_Vrd = Vsd/Vrd
2347
+ girder_data['UF shear force'] = Vsd_div_Vrd
2348
+ if optmizing and Vsd_div_Vrd > 1:
2349
+ return ['UF shear force', Vsd_div_Vrd]
2350
+
2351
+ CHK_account_for_interaction = Vsd < 0.5*Vrd
2352
+
2353
+ #8.2 Girder forces
2354
+ As = self._Stiffener.tw*self._Stiffener.hw + self._Stiffener.b*self._Stiffener.tf
2355
+ Ag = self._Girder.tw*self._Girder.hw + self._Girder.b*self._Girder.tf
2356
+
2357
+
2358
+ #sysd = 0 if self.get_method() == 2 else unstf_pl_data['sysd']
2359
+ NySd = sysd*(Ag+l*t)
2360
+
2361
+ Is = stf_pl_data['Is']
2362
+
2363
+ tcel = 18*E/(t*math.pow(l,2))*math.pow(t*Is/s, 0.75)
2364
+ tceg = 0 if Lp == 0 else tcel*math.pow(l,2)/math.pow(Lp,2)
2365
+
2366
+ alpha_t1 = 0 if Lp == 0 else math.sqrt(0.6*fy/tceg)
2367
+ alpha_t2 = math.sqrt(0.6*fy/tcel)
2368
+
2369
+ tcrg = 0.6*fy/math.pow(alpha_t1,2) if alpha_t1 > 1 else 0.6*fy
2370
+ tcrl = 0.6*fy/math.pow(alpha_t2,2) if alpha_t2 > 1 else 0.6*fy
2371
+
2372
+ tcrg = tcrg if self._stf_end_support == 'Continuous' else 0
2373
+
2374
+ #8.4 Effective width of girders
2375
+
2376
+ #Method 1:
2377
+ alphap = stf_pl_data['alphap']
2378
+ Cxs = stf_pl_data['Cxs']
2379
+ fkx = Cxs*fy
2380
+ CxG = math.sqrt(1-math.pow(sxsd/fkx,2)) if sxsd<fkx else 0
2381
+ if 4-math.pow(Lg/l,2) != 0:
2382
+ CyG_tens = 1 if Lg > 2*l else Lg/(l*math.sqrt(4-math.pow(Lg/l,2)))
2383
+ else:
2384
+ CyG_tens = 1
2385
+ CyG_comp = 0 if l*alphap == 0 else stf_pl_data['Cys_comp']
2386
+ CyG = min([1,CyG_tens]) if sy1sd<0 else min([1, CyG_comp])
2387
+ CtG = math.sqrt(1-3*math.pow(tsd/fy,2)) if tsd<fy/math.sqrt(3) else 0
2388
+ le_div_l_method1 = CxG*CyG*CtG
2389
+ le_method1 = l*le_div_l_method1
2390
+
2391
+ lim_sniped_or_cont = 0.3*Lg if self._girder_end_support == 'Continuous' else 0.4*Lg
2392
+ tot_min_lim = min([le_method1, lim_sniped_or_cont])
2393
+
2394
+
2395
+ #Method 2:
2396
+ CxG = math.sqrt(1-math.pow(sxsd/fy,2))
2397
+ alphaG = 0 if E*t == 0 else 0.525*l/t*math.sqrt(fy/E)
2398
+ CyG = (alphaG-0.22)/math.pow(alphaG,2) if alphaG>0.673 else 1
2399
+ CtG = math.sqrt(1-3*math.pow(tsd/fy,2)) if tsd<fy/math.sqrt(3) else 0
2400
+ le_div_l_method2 = CxG*CyG*CtG
2401
+ le_method2 = le_div_l_method2*l
2402
+
2403
+ eff_width_sec_mod = tot_min_lim if self.get_method() == 1 else le_method2
2404
+ eff_width_other_calc = le_method1 if self.get_method() == 1 else le_method2
2405
+
2406
+ le = eff_width_other_calc
2407
+
2408
+ AtotG = Ag + le * t
2409
+
2410
+ Iy = self._Girder.get_moment_of_intertia(efficent_se=le / 1000) * 1000 ** 4
2411
+ zp = self._Girder.get_cross_section_centroid_with_effective_plate(le / 1000) * 1000 - t / 2 # ch7.5.1 page 19
2412
+ zt = (t / 2 + self._Girder.hw + self._Girder.tf) - zp # ch 7.5.1 page 19
2413
+ #
2414
+ def red_prop():
2415
+ twG =max(0,self._Girder.tw*(1-Vsd_div_Vrd))
2416
+
2417
+ le = eff_width_other_calc
2418
+
2419
+ AtotG = Ag+le*t-self._Girder.hw*(self._Girder.tw - twG)
2420
+ Ipo = self._Girder.get_polar_moment(reduced_tw=twG)
2421
+ IzG = self._Girder.get_Iz_moment_of_inertia(reduced_tw=twG)
2422
+ Iy = self._Girder.get_moment_of_intertia(efficent_se=le/1000, reduced_tw=twG)*1000**4
2423
+
2424
+ zp = self._Girder.get_cross_section_centroid_with_effective_plate(le / 1000, reduced_tw=twG) * 1000 - t / 2 # ch7.5.1 page 19
2425
+ zt = (t / 2 + self._Girder.hw + self._Girder.tf) - zp # ch 7.5.1 page 19
2426
+ WeG = 0.0001 if zt == 0 else Iy / zt
2427
+ Wep = 0.0001 if zp == 0 else Iy / zp
2428
+ #print('In reduced', 'zp',zp,'zt',zt,'WeG',WeG,'Wep',Wep, 'Iy', Iy)
2429
+ return {'tw':twG, 'Atot': AtotG, 'Ipo': Ipo, 'IzG': IzG, 'zp': zp, 'zt': zt, 'WeG': WeG, 'Wep': Wep}
2430
+
2431
+ if Vsd_div_Vrd < 0.5:
2432
+ WeG = 0.0001 if zt == 0 else Iy/zt
2433
+ Wep = 0.0001 if zp == 0 else Iy/zp
2434
+ AeG = Ag+eff_width_other_calc*t
2435
+ else:
2436
+ red_param = red_prop()
2437
+ WeG = red_param['WeG']
2438
+ Wep = red_param['Wep']
2439
+ AeG = red_param['Atot']
2440
+
2441
+ # #from: 7.7.3 Resistance parameters for stiffeners
2442
+ Wmin = min([WeG, Wep])
2443
+ pf = 0.0001 if l*s*gammaM == 0 else 12*Wmin*fy/(math.pow(l,2)*s*gammaM)
2444
+
2445
+ lk = Lg
2446
+ LGk = lk if self._buckling_length_factor_girder is None else lk*self._buckling_length_factor_girder
2447
+
2448
+ #ie = 0 if Vsd_div_Vrd<0.5 else math.sqrt(Iy/AtotG)
2449
+ ie = math.sqrt(Iy / AtotG)
2450
+ fE = 0 if LGk == 0 else math.pow(math.pi,2)*E*math.pow(ie/LGk,2)
2451
+
2452
+ # 8.2 Girder forces, cont
2453
+ alphaG = 0 if fE == 0 else math.sqrt(fy/fE)
2454
+ Q = 0 if alphaG-0.2<0 else min([1, alphaG-0.2])
2455
+ C_for_tsd_trg = Q*(7-5*math.pow(s/l,2))*math.pow((tsd-tcrg)/tcrl,2)
2456
+ C = C_for_tsd_trg if tsd>tcrg else 0
2457
+ p0lim = 0.02*(t+As/s)/l*(sxsd+C*tsd)
2458
+ p0calc = 0 if s*self._Girder.hw*Lg*E*l==0 else 0.4*(t+As/s)/(self._Girder.hw*(1-s/Lg))*fy/E*math.pow(Lg/l,2)\
2459
+ *(sxsd+C*tsd)
2460
+ p0_compression = max([p0lim,p0calc])
2461
+ p0_tension = 0 if s*Lg*self._Girder.hw*E*l==0 else 0.4*(t+As/s)/(self._Girder.hw*(l-s/Lg))*gammaM/E\
2462
+ *math.pow(Lg/l,2)*(C*tsd)
2463
+ p0 = p0_tension if sxsd<0 else p0_compression
2464
+
2465
+ qSd_pressure = (psd+p0_tension)*l if sxsd<0 else (psd+p0_compression)*l
2466
+ qsd_oppsite = p0*l if psd<p0 else 0
2467
+ qSd_plate_side = qsd_oppsite if self._overpressure_side == 'stiffener side' else qSd_pressure
2468
+ qSd_girder_side = qsd_oppsite if self._overpressure_side == 'plate side' else qSd_pressure
2469
+
2470
+ #8.5 Torsional buckling of girders
2471
+ Af = self._Girder.tf*self._Girder.b
2472
+ Aw = self._Girder.hw*self._Girder.tw
2473
+ Iz = self._Girder.get_Iz_moment_of_inertia()
2474
+
2475
+ b = max([self._Girder.b, self._Girder.tw])
2476
+ C = 0.55 if self._Girder.get_stiffener_type() in ['T', 'FB'] else 1.1
2477
+ LGT0 = b*C*math.sqrt(E*Af/(fy*(Af+Aw/3))) #TODO can add a automatic check/message if torsional buckling shall be considered
2478
+ girder_data['Torsional buckling'] = 'Torsional buckling to be considered' if Ltg >LGT0 else \
2479
+ "Torsional buckling need not to be considered"
2480
+ def lt_params(LTG):
2481
+ fETG = math.pow(math.pi, 2)*E*Iz/((Af+Aw/3)*math.pow(LTG, 2))
2482
+ alphaTG = math.sqrt(fy/fETG)
2483
+ mu = 0.35*(alphaTG-0.6)
2484
+ fT_div_fy = (1 + mu + math.pow(alphaTG, 2) - math.sqrt(
2485
+ math.pow(1 + mu + math.pow(alphaTG, 2), 2) - 4 * math.pow(alphaTG, 2))) / (2 * math.pow(alphaTG, 2))
2486
+ fT = fT_div_fy*fy if alphaTG>0.6 else fy
2487
+ return {'fETG': fETG, 'alphaT': alphaTG, 'mu': mu, 'fT_div_fy': fT_div_fy, 'fT': fT}
2488
+
2489
+ fk_dict = dict()
2490
+ fr_dict = dict()
2491
+ for lT in ['plate', Ltg, 0.4*Lg, 0.8*Lg]:
2492
+ if lT != 'plate':
2493
+ params = lt_params(lT)
2494
+ fr = params['fT'] if params['alphaT']>0.6 else fy
2495
+ alpha = math.sqrt(fr / fE)
2496
+ mu = 0 if ie == 0 else (0.34 + 0.08 * zt / ie) * (alpha - 0.2)
2497
+ else:
2498
+ fr = fy
2499
+ alpha = math.sqrt(fr / fE)
2500
+ mu = 0 if ie == 0 else (0.34 + 0.08 * zp / ie) * (alpha - 0.2)
2501
+ fr_dict[lT] = fr
2502
+ fk_div_fr = (1 + mu + math.pow(alpha, 2) - math.sqrt(
2503
+ math.pow(1 + mu + math.pow(alpha, 2), 2) - 4 * math.pow(alpha, 2))) / (2 * math.pow(alpha, 2))
2504
+ fk = fk_div_fr * fr if alpha > 0.2 else fr
2505
+ fk_dict[lT] = fk
2506
+
2507
+ # #7.7.3 Resistance parameters for stiffeners
2508
+
2509
+ NRd = 0.0001 if gammaM == 0 else AeG * (fy / gammaM) # eq7.65, checked ok
2510
+
2511
+ NksRd = AeG * (fk_dict[Ltg] / gammaM) #eq7.66
2512
+ NkpRd = AeG * (fk_dict['plate'] / gammaM) # checked ok
2513
+ MsRd = WeG*fr_dict[Ltg]/gammaM
2514
+ Ms1Rd = WeG * (fr_dict[0.4*Lg] / gammaM) # ok
2515
+ Ms2Rd = WeG * (fr_dict[0.8*Lg] / gammaM) # eq7.69 checked ok
2516
+
2517
+ MstRd = WeG*(fy/gammaM) #eq7.70 checked ok
2518
+ MpRd = Wep*(fy/gammaM) #eq7.71 checked ok
2519
+
2520
+ NE = ((math.pow(math.pi,2))*E*AeG)/(math.pow(LGk/ie,2))# eq7.72 , checked ok
2521
+ # print(fr_dict)
2522
+ # print(fk_dict)
2523
+ # print('WeG', WeG, 'Wep', Wep)
2524
+ # print('NRd',NRd, 'NksRd',NksRd, 'NkpRd',NkpRd,'MsRd', MsRd,'MstRd', MstRd, 'Ms1Rd', Ms1Rd, 'Ms2Rd', Ms2Rd, 'MstRd', MstRd, 'MpRd', MpRd, 'Ne', Ne)
2525
+
2526
+ #7.7 Interaction formulas for axial compression and lateral pressure
2527
+ #7.7.2 Simple supported girder (sniped girders)
2528
+ if self._girder_end_support != 'Continuous':
2529
+ u = 0
2530
+ zstar = zp
2531
+ girder_data['UF Cont. plate side'] = 0
2532
+ girder_data['UF Cont. girder side'] = 0
2533
+
2534
+ # Lateral pressure on plate side:
2535
+ uf_7_58 = NySd/NksRd-2*NySd/NRd +((qSd_plate_side*math.pow(Lg, 2)/8)+NySd*zstar)/(MstRd*(1-NySd/NE))+u
2536
+ uf_7_59 = NySd/NkpRd+((qSd_plate_side*math.pow(Lg, 2)/8)+NySd*zstar)/(MpRd*(1-NySd/NE))+u
2537
+
2538
+ max_uf_simp_plate = max([0,uf_7_58,uf_7_59])
2539
+ girder_data['UF Simplified plate side'] = max_uf_simp_plate
2540
+
2541
+ #Lateral pressure on girder side:
2542
+ uf_7_60 = NySd/NksRd+((qSd_girder_side*math.pow(Lg, 2)/8)-NySd*zstar)/(Ms2Rd*(1-NySd/NE))+u
2543
+ uf_7_61 = NySd/NkpRd-2*NySd/NRd+((qSd_girder_side*math.pow(Lg, 2)/8)-NySd*zstar)/(MpRd*(1-NySd/NE))+u
2544
+
2545
+ CHK_qSd_NSd = qSd_girder_side*math.pow(Lg, 2)/8 < NySd*zstar
2546
+
2547
+ uf_7_62 = NySd/NksRd-2*NySd/NRd+(NySd*zstar-(qSd_girder_side*math.pow(Lg, 2)/8))/(MstRd*(1-NySd/NE))+u
2548
+ uf_7_63 = NySd/NkpRd+(NySd*zstar-(qSd_girder_side*math.pow(Lg, 2)/8))/(MpRd*(1-NySd/NE))+u
2549
+
2550
+ max_uf_simp_stiffener = max([0,uf_7_60,uf_7_61]) if CHK_qSd_NSd else max([0,uf_7_60,uf_7_61, uf_7_62,uf_7_63])
2551
+ girder_data['UF Simplified girder side'] = max_uf_simp_stiffener
2552
+ else:
2553
+ u = 0
2554
+ girder_data['UF Simplified girder side'] = 0
2555
+ girder_data['UF Simplified plate side'] = 0
2556
+ #7.7.1 Continuous stiffeners
2557
+ M1Sd_pl = abs(qSd_plate_side)*math.pow(Lg, 2)/12
2558
+ M2Sd_pl = abs(qSd_plate_side)*math.pow(Lg, 2)/24
2559
+
2560
+ M1Sd_stf = abs(qSd_girder_side)*math.pow(Lg, 2)/12
2561
+ M2Sd_stf = abs(qSd_girder_side)*math.pow(Lg, 2)/24
2562
+ # #Lateral pressure on plate side:
2563
+ def iter_plate(zstar):
2564
+ uf_7_48 = NySd/NksRd+(M1Sd_pl-NySd*zstar)/(Ms1Rd*(1-NySd/NE))+u
2565
+ uf_7_49 = NySd/NkpRd-2*NySd/NRd +(M1Sd_pl-NySd*zstar)/(MpRd*(1-NySd/NE))+u
2566
+ uf_7_50 = NySd/NksRd-2*NySd/NRd+(M2Sd_pl+NySd*zstar)/(MstRd*(1-NySd/NE))+u
2567
+ uf_7_51 = NySd/NkpRd+(M2Sd_pl+NySd*zstar)/(MpRd*(1-NySd/NE))+u
2568
+ return max([uf_7_48, uf_7_49, uf_7_50, uf_7_51])
2569
+
2570
+ res_iter_pl = minimize(iter_plate, 0, bounds=[[-zt + self._Girder.tf / 2, zp]])
2571
+
2572
+ if type(res_iter_pl.fun) == list:
2573
+ girder_data['UF Cont. plate side'] = res_iter_pl.fun[0]
2574
+ else:
2575
+ girder_data['UF Cont. plate side'] = res_iter_pl.fun
2576
+ # Lateral pressure on girder side:
2577
+ def iter_girder(zstar):
2578
+ uf_7_52 = NySd/NksRd-2*NySd/NRd +(M1Sd_stf +NySd*zstar)/(MstRd*(1-NySd/NE))+u
2579
+ uf_7_53 = NySd/NkpRd+(M1Sd_stf +NySd*zstar)/(MpRd*(1-NySd/NE))+u
2580
+ uf_7_54 = NySd/NksRd+(M2Sd_stf-NySd*zstar)/(Ms2Rd*(1-NySd/NE))+u
2581
+ uf_7_55 = NySd/NkpRd-2*NySd/NRd+(M2Sd_stf-NySd*zstar)/(MpRd*(1-NySd/NE))+u
2582
+ return max([uf_7_52, uf_7_53 ,uf_7_54 ,uf_7_55])
2583
+
2584
+ res_iter_girder = minimize(iter_girder, 0, bounds=[[-zt + self._Girder.tf / 2, zp]])
2585
+
2586
+ if type(res_iter_girder.fun) == list:
2587
+ girder_data['UF Cont. girder side'] = res_iter_girder.fun[0]
2588
+ else:
2589
+ girder_data['UF Cont. girder side'] = res_iter_girder.fun
2590
+
2591
+ return girder_data
2592
+
2593
+ def local_buckling(self, optimizing = False):
2594
+ '''
2595
+ Checks for girders and stiffeners
2596
+ '''
2597
+ fy = self._mat_yield
2598
+ if self._Stiffener is not None:
2599
+ max_web_stf = 42*self._Stiffener.tw*math.sqrt(235/fy) if self._Stiffener.get_stiffener_type() != 'FB' else 0
2600
+ max_flange_stf = (14 if self._fab_method_stiffener == 'welded' else 15) * self._Stiffener.tf *math.sqrt(235/fy)
2601
+ else:
2602
+ max_web_stf = 0
2603
+ max_flange_stf = 0
2604
+
2605
+ if self._Girder is not None:
2606
+ max_web_girder = 42*self._Girder.tw*math.sqrt(235/fy) if self._Girder.get_stiffener_type() != 'FB' else 0
2607
+ max_flange_girder = (14 if self._fab_method_girder == 'welded' else 15) * self._Girder.tf *math.sqrt(235/fy)
2608
+ else:
2609
+ max_web_girder = 0
2610
+ max_flange_girder = 0
2611
+
2612
+ return {'Stiffener': [max_web_stf, max_flange_stf], 'Girder': [max_web_girder, max_flange_girder]}
2613
+
2614
+ # def get_tuple(self):
2615
+ # ''' Return a tuple of the plate stiffener'''
2616
+ # return (self.Plate.get_s(), self.Plate.get_pl_thk(), self.Stiffener.get_web_thk(), self.Stiffener.get_web_thk(),
2617
+ # self.Stiffener.get_fl_w(), self.Stiffener.get_fl_thk(), self.Plate.span, self.Plate.girder_lg,
2618
+ # self.Stiffener.get_stiffener_type())
2619
+
2620
+ def get_one_line_string_mixed(self):
2621
+ ''' Returning a one line string. '''
2622
+ return 'pl_'+str(round(self.Plate.s, 1))+'x'+str(round(self.Plate.t,1))+' stf_'+\
2623
+ self.Stiffener.get_stiffener_type()+\
2624
+ str(round(self.Stiffener.hw,1))+'x'+str(round(self.Stiffener.tw,1))+'+'\
2625
+ +str(round(self.Stiffener.b,1))+'x'+\
2626
+ str(round(self.Stiffener.tf,1))
2627
+
2628
+ def get_extended_string_mixed(self):
2629
+ ''' Some more information returned. '''
2630
+ return 'span: '+str(round(self.Plate.span,4))+' structure type: '+ self.Stiffener.get_structure_type() + ' stf. type: ' + \
2631
+ self.Stiffener.get_stiffener_type() + ' pressure side: ' + self.Plate.overpressure_side
2632
+
2633
+ class Shell():
2634
+ '''
2635
+ Small class to contain shell properties.
2636
+ '''
2637
+ def __init__(self, main_dict: dict = None):
2638
+ super(Shell, self).__init__()
2639
+ '''
2640
+ shell_dict = {'plate_thk': [self._new_shell_thk.get() / 1000, 'm'],
2641
+ 'radius': [self._new_shell_radius.get() / 1000, 'm'],
2642
+ 'distance between rings, l': [self._new_shell_dist_rings.get() / 1000, 'm'],
2643
+ 'length of shell, L': [self._new_shell_length.get() / 1000, 'm'],
2644
+ 'tot cyl length, Lc': [self._new_shell_tot_length.get() / 1000, 'm'],
2645
+ 'eff. buckling lenght factor': [self._new_shell_k_factor.get() / 1000, 'm'],
2646
+ 'mat_yield': [self._new_shell_yield.get() *1e6, 'Pa']}
2647
+ '''
2648
+ if main_dict is None:
2649
+ self._thk = None
2650
+ self._mat_yield = None
2651
+ self._radius = None
2652
+ self._dist_between_rings = None
2653
+ self._length_of_shell = None
2654
+ self._tot_cyl_length = None
2655
+ self._k_factor = None
2656
+ else:
2657
+ self._thk = main_dict['plate_thk'][0]
2658
+ self._mat_yield = main_dict['mat_yield'][0]
2659
+ self._radius = main_dict['radius'][0]
2660
+ self._dist_between_rings = main_dict['distance between rings, l'][0]
2661
+ self._length_of_shell = main_dict['length of shell, L'][0]
2662
+ self._tot_cyl_length = main_dict['tot cyl length, Lc'][0]
2663
+ self._k_factor = main_dict['eff. buckling lenght factor'][0]
2664
+
2665
+ # For conical
2666
+ self._cone_r1 = None
2667
+ self._cone_r2 = None
2668
+ self._cone_alpha = None
2669
+ @property
2670
+ def Lc(self):
2671
+ return self._tot_cyl_length
2672
+ @Lc.setter
2673
+ def Lc(self, val):
2674
+ self._tot_cyl_length = val
2675
+ @property
2676
+ def thk(self):
2677
+ return self._thk
2678
+ @thk.setter
2679
+ def thk(self, val):
2680
+ self._thk = val
2681
+ @property
2682
+ def radius(self):
2683
+ return self._radius
2684
+ @radius.setter
2685
+ def radius(self, val):
2686
+ self._radius = val
2687
+ @property
2688
+ def dist_between_rings(self):
2689
+ return self._dist_between_rings
2690
+ @dist_between_rings.setter
2691
+ def dist_between_rings(self, val):
2692
+ self._dist_between_rings = val
2693
+ @property
2694
+ def length_of_shell(self):
2695
+ return self._length_of_shell
2696
+ @length_of_shell.setter
2697
+ def length_of_shell(self, val):
2698
+ self._length_of_shell = val
2699
+ @property
2700
+ def tot_cyl_length(self):
2701
+ return self._tot_cyl_length
2702
+ @tot_cyl_length.setter
2703
+ def tot_cyl_length(self, val):
2704
+ self._tot_cyl_length = val
2705
+ @property
2706
+ def k_factor(self):
2707
+ return self._k_factor
2708
+ @k_factor.setter
2709
+ def k_factor(self, val):
2710
+ self._k_factor = val
2711
+ def get_Zl(self):
2712
+ L = self.tot_cyl_length*1000
2713
+ Zl = math.pow(L,2)*math.sqrt(1-math.pow(0.3,2))/(self._radius*1000 * self._thk*1000) if self._thk*self._radius else 0
2714
+ return Zl
2715
+
2716
+ def get_effective_width_shell_plate(self):
2717
+ return 1.56*math.sqrt(self._radius * self._thk)/(1+12*self.thk/self._radius)
2718
+
2719
+ def get_main_properties(self):
2720
+ main_data = {'plate_thk': [self._thk, 'm'],
2721
+ 'radius': [self._radius, 'm'],
2722
+ 'distance between rings, l': [self._dist_between_rings, 'm'],
2723
+ 'length of shell, L': [self._length_of_shell, 'm'],
2724
+ 'tot cyl length, Lc': [self._tot_cyl_length, 'm'],
2725
+ 'eff. buckling lenght factor': [self._k_factor, 'm'],
2726
+ 'mat_yield': [self._mat_yield, 'Pa']}
2727
+ return main_data
2728
+
2729
+ def set_main_properties(self, main_dict):
2730
+
2731
+ self._thk = main_dict['plate_thk'][0]
2732
+ self._mat_yield = main_dict['mat_yield'][0]
2733
+ self._radius = main_dict['radius'][0]
2734
+ self._dist_between_rings = main_dict['distance between rings, l'][0]
2735
+ self._length_of_shell = main_dict['length of shell, L'][0]
2736
+ self._tot_cyl_length = main_dict['tot cyl length, Lc'][0]
2737
+ self._k_factor = main_dict['eff. buckling lenght factor'][0]
2738
+
2739
+ class CylinderAndCurvedPlate():
2740
+ '''
2741
+ Buckling of cylinders and curved plates.
2742
+ Geomeries
2743
+ Selections for: Type of Structure Geometry:
2744
+ geomeries = {1:'Unstiffened shell (Force input)', 2:'Unstiffened panel (Stress input)',
2745
+ 3:'Longitudinal Stiffened shell (Force input)',
2746
+ 4:'Longitudinal Stiffened panel (Stress input)',
2747
+ 5:'Ring Stiffened shell (Force input)',
2748
+ 6:'Ring Stiffened panel (Stress input)',
2749
+ 7:'Orthogonally Stiffened shell (Force input)',
2750
+ 8:'Orthogonally Stiffened panel (Stress input)'}
2751
+
2752
+ '''
2753
+
2754
+ geomeries = {11:'Flat plate, stiffened',10: 'Flat plate, unstiffened', 12: 'Flat plate, stiffened with girder',
2755
+ 1:'Unstiffened shell (Force input)', 2:'Unstiffened panel (Stress input)',
2756
+ 3:'Longitudinal Stiffened shell (Force input)', 4:'Longitudinal Stiffened panel (Stress input)',
2757
+ 5:'Ring Stiffened shell (Force input)', 6:'Ring Stiffened panel (Stress input)',
2758
+ 7:'Orthogonally Stiffened shell (Force input)', 8:'Orthogonally Stiffened panel (Stress input)'}
2759
+ geomeries_map = dict()
2760
+ for key, value in geomeries.items():
2761
+ geomeries_map[value] = key
2762
+
2763
+ geomeries_map_no_input_spec = dict()
2764
+ for key, value in geomeries.items():
2765
+ this_str = value.replace(' (Stress input)', '')
2766
+ this_str = this_str.replace(' (Force input)', '')
2767
+ geomeries_map_no_input_spec[this_str] = key
2768
+
2769
+ def __init__(self, main_dict = None, shell: Shell = None, long_stf: Structure = None, ring_stf: Structure = None,
2770
+ ring_frame: Structure = None):
2771
+ super(CylinderAndCurvedPlate, self).__init__()
2772
+
2773
+ if all([main_dict is None, shell is None, long_stf is None, ring_stf is None]):
2774
+ self._sasd= None
2775
+ self._smsd= None
2776
+ self._tTsd= None
2777
+ self._tQsd= None
2778
+ self._psd = None
2779
+ self._shsd= None
2780
+ self._geometry= None
2781
+ self._mat_factor= None
2782
+ self._delta0 = None
2783
+ self._fab_method_ring_stf= None
2784
+ self._fab_method_ring_girder= None
2785
+ self._E = None
2786
+ self._v = None
2787
+ self._mat_yield= None
2788
+ self._length_between_girders= None
2789
+ self._panel_spacing= None
2790
+ self.__ring_stiffener_excluded= None
2791
+ self.__ring_frame_excluded= None
2792
+ self._end_cap_pressure_included= None
2793
+ self._uls_or_als= None
2794
+
2795
+ else:
2796
+ self._sasd = main_dict['sasd'][0]
2797
+ self._smsd = main_dict['smsd'][0]
2798
+ self._tTsd = abs(main_dict['tTsd'][0])
2799
+ self._tQsd= main_dict['tQsd'][0]
2800
+ self._psd = main_dict['psd'][0]
2801
+ self._shsd = main_dict['shsd'][0]
2802
+ self._geometry = main_dict['geometry'][0]
2803
+ self._mat_factor = main_dict['material factor'][0]
2804
+ self._delta0 = main_dict['delta0'][0]
2805
+ self._fab_method_ring_stf = main_dict['fab method ring stf'][0]
2806
+ self._fab_method_ring_girder = main_dict['fab method ring girder'][0]
2807
+ self._E = main_dict['E-module'][0]
2808
+ self._v = main_dict['poisson'][0]
2809
+ self._mat_yield = main_dict['mat_yield'][0]
2810
+ self._length_between_girders = main_dict['length between girders'][0]
2811
+ self._panel_spacing = main_dict['panel spacing, s'][0]
2812
+ self.__ring_stiffener_excluded = main_dict['ring stf excluded'][0]
2813
+ self.__ring_frame_excluded = main_dict['ring frame excluded'][0]
2814
+ self._end_cap_pressure_included = main_dict['end cap pressure'][0]
2815
+ self._uls_or_als = main_dict['ULS or ALS'][0]
2816
+
2817
+ self._Shell = shell
2818
+ self._LongStf = long_stf
2819
+ self._RingStf = ring_stf
2820
+ self._RingFrame = ring_frame
2821
+
2822
+
2823
+
2824
+ def __str__(self):
2825
+ '''
2826
+ Returning all properties.
2827
+ '''
2828
+
2829
+ long_string = 'N/A' if self._LongStf is None else self._LongStf.get_beam_string()
2830
+ ring_string = 'N/A' if self._RingStf is None else self._RingStf.get_beam_string()
2831
+ frame_string = 'N/A' if self._RingFrame is None else self._RingFrame.get_beam_string()
2832
+ s = max([self._Shell.dist_between_rings, 2*math.pi*self._Shell.radius])*1000 if self._LongStf == None else \
2833
+ self._LongStf.spacing
2834
+
2835
+ return \
2836
+ str(
2837
+ '\n Cylinder radius: ' + str(round(self._Shell.radius,3)) + ' meters' +
2838
+ '\n Cylinder thickness: ' + str(self._Shell.thk*1000)+' mm'+
2839
+ '\n Distance between rings, l: ' + str(self._Shell.dist_between_rings*1000)+' mm'+
2840
+ '\n Length of shell, L: ' + str(self._Shell.length_of_shell*1000)+' mm'+
2841
+ '\n Total cylinder lenght: ' + str(self._Shell.tot_cyl_length*1000)+' mm'+
2842
+ '\n Eff. Buckling length factor: ' + str(self._Shell.k_factor)+
2843
+ '\n Material yield: ' + str(self._mat_yield/1e6)+' MPa'+
2844
+ '\n Spacing/panel circ., s: ' + str(s) + ' mm' +
2845
+ '\n Longitudinal stiffeners: ' + long_string+
2846
+ '\n Ring stiffeners ' + ring_string+
2847
+ '\n Ring frames/girders: ' + frame_string+
2848
+ '\n Design axial stress/force: ' + str(self._sasd/1e6)+' MPa'+
2849
+ '\n Design bending stress/moment: ' + str(self._smsd/1e6)+' MPa'+
2850
+ '\n Design tosional stress/moment: ' + str(self._tTsd/1e6)+' MPa'+
2851
+ '\n Design shear stress/force: ' + str(self._tQsd/1e6)+' MPa'+
2852
+ '\n Design lateral pressure ' + str(self._psd/1e6)+' MPa'+
2853
+ '\n Additional hoop stress ' + str(self._shsd/1e6)+' MPa')
2854
+
2855
+ @property
2856
+ def uls_or_als(self):
2857
+ return self._uls_or_als
2858
+ @uls_or_als.setter
2859
+ def uls_or_als(self, val):
2860
+ self._uls_or_als = val
2861
+ @property
2862
+ def fab_method_ring_girder(self):
2863
+ return self._fab_method_ring_girder
2864
+ @fab_method_ring_girder.setter
2865
+ def fab_method_ring_girder(self, val):
2866
+ self._fab_method_ring_girder = val
2867
+
2868
+ @property
2869
+ def fab_method_ring_stf(self):
2870
+ return self._fab_method_ring_stf
2871
+ @fab_method_ring_stf.setter
2872
+ def fab_method_ring_stf(self, val):
2873
+ self._fab_method_ring_stf = val
2874
+ @property
2875
+ def end_cap_pressure_included(self):
2876
+ return self._end_cap_pressure_included
2877
+ @end_cap_pressure_included.setter
2878
+ def end_cap_pressure_included(self, val):
2879
+ self._end_cap_pressure_included = val
2880
+ @property
2881
+ def delta0(self):
2882
+ return self._delta0
2883
+ @delta0.setter
2884
+ def delta0(self, val):
2885
+ self._delta0 = val
2886
+ @property
2887
+ def mat_factor(self):
2888
+ return self._mat_factor
2889
+ @mat_factor.setter
2890
+ def mat_factor(self, val):
2891
+ self._mat_factor = val
2892
+ @property
2893
+ def E(self):
2894
+ return self._E
2895
+ @E.setter
2896
+ def E(self, val):
2897
+ self._E = val
2898
+ @property
2899
+ def v(self):
2900
+ return self._v
2901
+ @v.setter
2902
+ def v(self, val):
2903
+ self._v = val
2904
+ @property
2905
+ def mat_yield(self):
2906
+ return self._mat_yield
2907
+ @mat_yield.setter
2908
+ def mat_yield(self, val):
2909
+ self._mat_yield = val
2910
+ @property
2911
+ def sasd(self):
2912
+ return self._sasd
2913
+ @sasd.setter
2914
+ def sasd(self, val):
2915
+ self._sasd = val
2916
+ @property
2917
+ def smsd(self):
2918
+ return self._smsd
2919
+ @smsd.setter
2920
+ def smsd(self, val):
2921
+ self._smsd = val
2922
+ @property
2923
+ def tTsd(self):
2924
+ return abs(self._tTsd)
2925
+ @tTsd.setter
2926
+ def tTsd(self, val):
2927
+ self._tTsd = abs(val)
2928
+ @property
2929
+ def tQsd(self):
2930
+ return self._tQsd
2931
+ @tQsd.setter
2932
+ def tQsd(self, val):
2933
+ self._tQsd = val
2934
+ @property
2935
+ def psd(self):
2936
+ return self._psd
2937
+ @psd.setter
2938
+ def psd(self, val):
2939
+ self._psd = val
2940
+ @property
2941
+ def shsd(self):
2942
+ return self._shsd
2943
+ @shsd.setter
2944
+ def shsd(self, val):
2945
+ self._shsd = val
2946
+ @property
2947
+ def panel_spacing(self):
2948
+ return self._panel_spacing
2949
+ @panel_spacing.setter
2950
+ def panel_spacing(self, val):
2951
+ self._panel_spacing = val
2952
+
2953
+ @property
2954
+ def ShellObj(self):
2955
+ return self._Shell
2956
+ @ShellObj.setter
2957
+ def ShellObj(self, val):
2958
+ self._Shell = val
2959
+ @property
2960
+ def LongStfObj(self):
2961
+ return self._LongStf
2962
+ @LongStfObj.setter
2963
+ def LongStfObj(self, val):
2964
+ self._LongStf = val
2965
+ @property
2966
+ def RingStfObj(self):
2967
+ return self._RingStf
2968
+ @RingStfObj.setter
2969
+ def RingStfObj(self, val):
2970
+ self._RingStf = val
2971
+ @property
2972
+ def RingFrameObj(self):
2973
+ return self._RingFrame
2974
+ @RingFrameObj.setter
2975
+ def RingFrameObj(self, val):
2976
+ self._RingFrame = val
2977
+
2978
+ @property
2979
+ def geometry(self):
2980
+ return self._geometry
2981
+ @geometry.setter
2982
+ def geometry(self, val):
2983
+ self._geometry = val
2984
+ @property
2985
+ def length_between_girders(self):
2986
+ return self._length_between_girders
2987
+ @length_between_girders.setter
2988
+ def length_between_girders(self, val):
2989
+ self._length_between_girders = val
2990
+ @property
2991
+ def _ring_stiffener_excluded(self):
2992
+ return self.__ring_stiffener_excluded
2993
+ @_ring_stiffener_excluded.setter
2994
+ def _ring_stiffener_excluded(self, val):
2995
+ self.__ring_stiffener_excluded = val
2996
+ @property
2997
+ def _ring_frame_excluded(self):
2998
+ return self.__ring_frame_excluded
2999
+ @_ring_frame_excluded.setter
3000
+ def _ring_frame_excluded(self, val):
3001
+ self.__ring_frame_excluded = val
3002
+
3003
+ def get_utilization_factors(self, optimizing = False, empty_result_dict = False):
3004
+ '''
3005
+ If optimizing running time must be reduced.
3006
+ '''
3007
+ # Local buckling of stiffeners
3008
+
3009
+ results = {'Unstiffened shell': None,
3010
+ 'Longitudinal stiffened shell': None,
3011
+ 'Ring stiffened shell': None,
3012
+ 'Heavy ring frame': None,
3013
+ 'Column stability check': None,
3014
+ 'Column stability UF': None,
3015
+ 'Stiffener check': None,
3016
+ 'Stiffener check detailed': None,
3017
+ 'Weight': None}
3018
+
3019
+ if empty_result_dict:
3020
+ return results
3021
+ data_shell_buckling = self.shell_buckling()
3022
+ unstiffend_shell, column_buckling_data = None, None
3023
+ # UF for unstiffened shell
3024
+ unstiffend_shell = self.unstiffened_shell(shell_data=data_shell_buckling)
3025
+
3026
+ s = self._panel_spacing*1000 if self._LongStf is None else self._LongStf.spacing
3027
+
3028
+ if any([self._geometry in [1, 5], s > self._Shell.dist_between_rings*1000]):
3029
+ uf_unstf_shell = unstiffend_shell['UF unstiffened circular cylinder']
3030
+ results['Unstiffened shell'] = uf_unstf_shell
3031
+ else:
3032
+ uf_unstf_shell = unstiffend_shell['UF unstiffened curved panel']
3033
+ results['Unstiffened shell'] = uf_unstf_shell
3034
+
3035
+ if optimizing:
3036
+ if uf_unstf_shell > 1:
3037
+ return False, 'UF unstiffened', results
3038
+
3039
+ # UF for longitudinal stiffened shell
3040
+
3041
+ if self._geometry in [3,4,7,8]:
3042
+ if self._LongStf is not None:
3043
+ column_buckling_data= self.column_buckling(unstf_shell_data=unstiffend_shell,
3044
+ shell_bukcling_data=data_shell_buckling)
3045
+ long_stf_shell = self.longitudinally_stiffened_shell(column_buckling_data=column_buckling_data,
3046
+ unstiffened_shell=unstiffend_shell)
3047
+
3048
+ results['Column stability check'] = column_buckling_data['Column stability check']
3049
+ results['Column stability UF'] = column_buckling_data['Column stability UF']
3050
+ results['Need to check column buckling'] = column_buckling_data['Need to check column buckling']
3051
+ results['Stiffener check'] = column_buckling_data['stiffener check']
3052
+ results['Stiffener check detailed'] = column_buckling_data['stiffener check detailed']
3053
+ if self._geometry in [3,4,7,8] and long_stf_shell['fksd'] > 0:
3054
+ results['Longitudinal stiffened shell'] = long_stf_shell['sjsd_used']/long_stf_shell['fksd']\
3055
+ if self._geometry in [3,4,7,8] else 0
3056
+
3057
+ if optimizing:
3058
+ if not results['Column stability check']:
3059
+ return False, 'Column stability', results
3060
+ elif False in results['Stiffener check'].values():
3061
+ return False, 'Stiffener check', results
3062
+ elif results['Longitudinal stiffened shell'] > 1:
3063
+ return False, 'UF longitudinal stiffeners', results
3064
+
3065
+ if self._geometry in [5,6,7,8]:
3066
+ # UF for panel ring buckling
3067
+ ring_stf_shell = None
3068
+ if self._RingStf is not None:
3069
+ column_buckling_data = column_buckling_data if column_buckling_data is not None \
3070
+ else self.column_buckling( unstf_shell_data=unstiffend_shell,
3071
+ shell_bukcling_data=data_shell_buckling)
3072
+ ring_stf_shell = self.ring_stiffened_shell(data_shell_buckling=data_shell_buckling,
3073
+ column_buckling_data=column_buckling_data)
3074
+ results['Column stability check'] = column_buckling_data['Column stability check']
3075
+ results['Column stability UF'] = column_buckling_data['Column stability UF']
3076
+ results['Need to check column buckling'] = column_buckling_data['Need to check column buckling']
3077
+ results['Stiffener check'] = column_buckling_data['stiffener check']
3078
+ results['Stiffener check detailed'] = column_buckling_data['stiffener check detailed']
3079
+ results['Ring stiffened shell'] = ring_stf_shell[0]
3080
+
3081
+
3082
+
3083
+ if optimizing:
3084
+ if not results['Column stability check']:
3085
+ return False, 'Column stability', results
3086
+ elif False in results['Stiffener check'].values():
3087
+ return False, 'Stiffener check', results
3088
+ elif results['Ring stiffened shell'] > 1:
3089
+ return False, 'UF ring stiffeners', results
3090
+
3091
+ # UF for ring frame
3092
+ if self._geometry in [5, 6, 7, 8]:
3093
+ if self._RingFrame is not None:
3094
+ column_buckling_data = column_buckling_data if column_buckling_data is not None \
3095
+ else self.column_buckling( unstf_shell_data=unstiffend_shell,
3096
+ shell_bukcling_data=data_shell_buckling)
3097
+ ring_stf_shell = ring_stf_shell if ring_stf_shell is not None else\
3098
+ self.ring_stiffened_shell(data_shell_buckling=data_shell_buckling,
3099
+ column_buckling_data=column_buckling_data)
3100
+ results['Column stability check'] = column_buckling_data['Column stability check']
3101
+ results['Column stability UF'] = column_buckling_data['Column stability UF']
3102
+ results['Need to check column buckling'] = column_buckling_data['Need to check column buckling']
3103
+ results['Stiffener check'] = column_buckling_data['stiffener check']
3104
+ results['Stiffener check detailed'] = column_buckling_data['stiffener check detailed']
3105
+ results['Heavy ring frame'] = ring_stf_shell[1]
3106
+
3107
+ if optimizing:
3108
+ if not results['Column stability check']:
3109
+ return False, 'Column stability', results
3110
+ elif False in results['Stiffener check'].values():
3111
+ return False, 'Stiffener check', results
3112
+ elif results['Heavy ring frame'] > 1:
3113
+ return False, 'UF ring frame', results
3114
+
3115
+ if optimizing:
3116
+ return True, 'Check OK', results
3117
+
3118
+ # print('Results for geometry', self._geometry)
3119
+ # print('UF',uf_unstf_shell, uf_long_stf, uf_ring_stf, uf_ring_frame)
3120
+ # print('Stiffeners', stiffener_check)
3121
+
3122
+ return results
3123
+
3124
+ def set_main_properties(self, main_dict):
3125
+ self._sasd = main_dict['sasd'][0]
3126
+ self._smsd = main_dict['smsd'][0]
3127
+ self._tTsd = abs(main_dict['tTsd'][0])
3128
+ self._tQsd= main_dict['tQsd'][0]
3129
+ self._psd = main_dict['psd'][0]
3130
+ self._shsd = main_dict['shsd'][0]
3131
+ self._geometry = main_dict['geometry'][0]
3132
+ self._mat_factor = main_dict['material factor'][0]
3133
+ self._delta0 = main_dict['delta0'][0]
3134
+ self._fab_method_ring_stf = main_dict['fab method ring stf'][0]
3135
+ self._fab_method_ring_girder = main_dict['fab method ring girder'][0]
3136
+ self._E = main_dict['E-module'][0]
3137
+ self._v = main_dict['poisson'][0]
3138
+ self._mat_yield = main_dict['mat_yield'][0]
3139
+ self._length_between_girders = main_dict['length between girders'][0]
3140
+ self._panel_spacing = main_dict['panel spacing, s'][0]
3141
+ self.__ring_stiffener_excluded = main_dict['ring stf excluded'][0]
3142
+ self.__ring_frame_excluded = main_dict['ring frame excluded'][0]
3143
+ self._end_cap_pressure_included = main_dict['end cap pressure'][0]
3144
+ self._uls_or_als = main_dict['ULS or ALS'][0]
3145
+
3146
+ def shell_buckling(self):
3147
+ '''
3148
+ Main sheet to calculate cylinder buckling.
3149
+ '''
3150
+ stucture_objects = {'Unstiffened':self._Shell, 'Long Stiff.': self._LongStf, 'Ring Stiffeners': self._RingStf,
3151
+ 'Heavy ring Frame': self._RingFrame}
3152
+ stf_type = ['T', 'FB', 'T']
3153
+ assert self._Shell.dist_between_rings is not None, 'Input missing: self._Shell.dist_between_rings'
3154
+ assert self._Shell.radius is not None, 'Input missing: self._Shell.radius'
3155
+ assert self._Shell.thk is not None, 'Input missing: self._Shell.thk'
3156
+
3157
+ l = self._Shell.dist_between_rings*1000
3158
+ r = self._Shell.radius*1000
3159
+ t = self._Shell.thk*1000
3160
+
3161
+ parameters, cross_sec_data = list(), list()
3162
+ for idx, obj in stucture_objects.items():
3163
+ if obj is None:
3164
+ cross_sec_data.append([np.nan, np.nan, np.nan, np.nan, np.nan])
3165
+ if idx not in ['Unstiffened', 'Long Stiff.']:
3166
+ parameters.append([np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan])
3167
+ continue
3168
+ if idx != 'Unstiffened':
3169
+ hs = obj.hw/2 if stf_type =='FB' else obj.hw + obj.tf/2
3170
+ It = obj.get_torsional_moment_venant()
3171
+ se = self._Shell.get_effective_width_shell_plate()
3172
+
3173
+ Ipo = obj.get_polar_moment()
3174
+ Iz = obj.get_Iz_moment_of_inertia()
3175
+
3176
+ Iy = obj.get_moment_of_intertia(efficent_se=se, tf1=self._Shell.thk)*1000**4
3177
+
3178
+ cross_sec_data.append([hs, It, Iz, Ipo, Iy])
3179
+
3180
+ A = obj.get_cross_section_area(include_plate=False)*math.pow(1000,2)
3181
+ beta = l/(1.56*math.sqrt(r*t))
3182
+ leo = (l/beta) * ((math.cosh(2*beta)-math.cos(2*beta))/(math.sinh(2*beta)+math.sin(2*beta)))
3183
+
3184
+ assert self._sasd is not None, 'Input missing: self._sasd'
3185
+ assert self._smsd is not None, 'Input missing: self._smsd'
3186
+
3187
+
3188
+ worst_axial_comb = min(self._sasd/1e6 - self._smsd/1e6, self._sasd/1e6 + self._smsd/1e6)
3189
+ sxsd_used = worst_axial_comb
3190
+
3191
+ if idx == 'Long Stiff.':
3192
+ zp = obj.get_cross_section_centroid_with_effective_plate(include_plate=False) * 1000
3193
+ h_tot = obj.hw + obj.tf
3194
+ zt = h_tot -zp
3195
+ else:
3196
+ se = self._Shell.get_effective_width_shell_plate()
3197
+ zp = obj.get_cross_section_centroid_with_effective_plate(se=se, tf1=self._Shell.thk) * 1000 # ch7.5.1 page 19
3198
+ h_tot = self._Shell.thk*1000 + obj.hw + obj.tf
3199
+ zt = h_tot -zp
3200
+
3201
+ if idx not in ['Unstiffened', 'Long Stiff.']: # Parameters
3202
+ alpha = A/(leo*t)
3203
+ zeta = max([0, 2*(math.sinh(beta)*math.cos(beta)+math.cosh(beta)*math.sin(beta))/
3204
+ (math.sinh(2*beta)+math.sin(2*beta))])
3205
+ rf = r - t / 2 - (obj.hw + obj.tf)
3206
+
3207
+ r0 = zt + rf
3208
+ parameters.append([alpha, beta, leo, zeta, rf, r0, zt])
3209
+
3210
+ sxsd, shsd, shRsd, tsd = list(), list(), list(), list()
3211
+
3212
+ for idx, obj in stucture_objects.items():
3213
+ if obj is None:
3214
+ shRsd.append(np.nan)
3215
+ continue
3216
+ assert self._psd is not None, 'Input missing: self._psd'
3217
+
3218
+ if idx == 'Unstiffened':
3219
+ shsd.append((self._psd/1e6)*r/t + self._shsd/1e6)
3220
+ sxsd.append(self._sasd/1e6+self._smsd/1e6 if self._geometry in [2,6] else
3221
+ min([self._sasd/1e6, self._sasd/1e6-self._smsd/1e6, self._sasd/1e6+self._smsd/1e6]))
3222
+ tsd.append(self._tTsd/1e6 + self._tQsd/1e6)
3223
+ elif idx == 'Long Stiff.':
3224
+ assert +self._shsd is not None, 'Input missing: self._shsd'
3225
+ assert +self._tTsd is not None, 'Input missing: self._tTsd'
3226
+ assert +self._tQsd is not None, 'Input missing: self._tQsd'
3227
+
3228
+ if stucture_objects['Ring Stiffeners'] == None:
3229
+ shsd.append(shsd[0]+self._shsd/1e6)
3230
+ else:
3231
+ shsd_ring = ((self._psd/1e6)*r/t)-parameters[0][0]*parameters[0][3]/(parameters[0][0]+1)*\
3232
+ ((self._psd/1e6)*r/t-0.3*sxsd[0])
3233
+ shsd.append(shsd_ring + self._shsd/1e6)
3234
+
3235
+ if self._geometry in [3,4,7,8]:
3236
+ sxsd.append(sxsd_used)
3237
+ else:
3238
+ sxsd.append(sxsd[0])
3239
+
3240
+ tsd.append(self._tTsd/1e6 + self._tQsd/1e6)
3241
+
3242
+ elif idx == 'Ring Stiffeners':
3243
+ rf = parameters[0][4]
3244
+ shsd_ring = ((self._psd / 1e6) * r / t) - parameters[0][0] * parameters[0][3] / (parameters[0][0] + 1) * \
3245
+ ((self._psd / 1e6) * r / t - 0.3 * sxsd[0])
3246
+ shsd.append(np.nan if stucture_objects['Ring Stiffeners'] == None else shsd_ring)
3247
+ shRsd.append(((self._psd/1e6)*r/t-0.3*sxsd[0])*(1/(1+parameters[0][0]))*(r/rf))
3248
+ if self._geometry > 4:
3249
+ sxsd.append(sxsd[0])
3250
+ tsd.append(tsd[0])
3251
+ else:
3252
+ sxsd.append(np.nan)
3253
+ tsd.append(np.nan)
3254
+
3255
+ else:
3256
+ rf = parameters[1][4]
3257
+ shsd.append(((self._psd/1e6)*r/t)-parameters[1][0]*parameters[1][3]/(parameters[1][0]+1)*
3258
+ ((self._psd/1e6)*r/t-0.3*self._sasd/1e6))
3259
+ shRsd.append(((self._psd/1e6)*r/t-0.3*self._sasd/1e6)*(1/(1+parameters[1][0]))*(r/rf))
3260
+ if self._geometry > 4:
3261
+ sxsd.append(sxsd[0])
3262
+ tsd.append(tsd[0])
3263
+ else:
3264
+ sxsd.append(np.nan)
3265
+ tsd.append(np.nan)
3266
+
3267
+ sxsd = np.array(sxsd)
3268
+ shsd = np.array(shsd)
3269
+ tsd = np.array(np.abs(tsd))
3270
+ sjsd = np.sqrt(sxsd**2 - sxsd*shsd + shsd**2+3*tsd**2)
3271
+
3272
+ return {'sjsd': sjsd, 'parameters': parameters, 'cross section data': cross_sec_data,
3273
+ 'shRsd': shRsd, 'shsd': shsd, 'sxsd': sxsd}
3274
+
3275
+ def unstiffened_shell(self, conical = False, shell_data = None):
3276
+
3277
+ E = self._E/1e6
3278
+ t = self._Shell.thk*1000
3279
+
3280
+ # get correct s
3281
+
3282
+ s = min([self._Shell.dist_between_rings, 2*math.pi*self._Shell.radius])*1000 if self._LongStf == None else \
3283
+ self._LongStf.spacing
3284
+ v = self._v
3285
+ r = self._Shell.radius*1000
3286
+ l = self._Shell.dist_between_rings * 1000
3287
+ fy = self._mat_yield/1e6
3288
+ sasd = self._sasd/1e6
3289
+ smsd = self._smsd/1e6
3290
+
3291
+ tsd = abs(self._tTsd/1e6+self._tQsd/1e6)
3292
+
3293
+ psd = self._psd/1e6
3294
+
3295
+ if self._RingStf is None:
3296
+ shsd = shell_data['shsd'][0]
3297
+ else:
3298
+ shsd = shell_data['shsd'][1]
3299
+
3300
+ provide_data = dict()
3301
+
3302
+
3303
+ '''
3304
+ Selections for: Type of Structure Geometry:
3305
+ 1 Unstiffened shell (Force input)
3306
+ 2 Unstiffened panel (Stress input)
3307
+ 3 Longitudinal Stiffened shell (Force input)
3308
+ 4 Longitudinal Stiffened panel (Stress input)
3309
+ 5 Ring Stiffened shell (Force input)
3310
+ 6 Ring Stiffened panel (Stress input)
3311
+ 7 Orthogonally Stiffened shell (Force input)
3312
+ 8 Orthogonally Stiffened panel (Stress input)
3313
+ Selected:
3314
+ 3 Longitudinal Stiffened shell (Force input)
3315
+ '''
3316
+ # Pnt. 3.3 Unstifffed curved panel
3317
+ geometry = self._geometry
3318
+
3319
+ if geometry in [2,6]:
3320
+ sxsd = sasd+smsd
3321
+ else:
3322
+ sxsd = min(sasd, sasd+smsd, sasd-smsd)
3323
+
3324
+ if smsd < 0:
3325
+ smsd = abs(smsd)
3326
+ sm0sd = abs(smsd)
3327
+
3328
+ else:
3329
+ if geometry in [2, 6]:
3330
+ smsd = 0
3331
+ sm0sd = 0
3332
+ else:
3333
+ smsd = smsd
3334
+ sm0sd = smsd
3335
+
3336
+ sjsd = math.sqrt(math.pow(sxsd,2) - sxsd*shsd + math.pow(shsd,2) + 3 * math.pow(tsd, 2)) # (3.2.3)
3337
+
3338
+ Zs = (math.pow(s, 2) / (r * t)) * math.sqrt(1 - math.pow(v, 2)) # The curvature parameter Zs (3.3.3)
3339
+
3340
+ def table_3_1(chk):
3341
+ psi = {'Axial stress': 4, 'Shear stress': 5.34+4*math.pow(s/l, 2),
3342
+ 'Circumferential compression': math.pow(1+math.pow(s/l, 2), 2)} # ψ
3343
+ epsilon = {'Axial stress': 0.702*Zs, 'Shear stress': 0.856*math.sqrt(s/l)*math.pow(Zs, 3/4),
3344
+ 'Circumferential compression': 1.04*(s/l)*math.sqrt(Zs)} # ξ
3345
+ rho = {'Axial stress': 0.5*math.pow(1+(r/(150*t)), -0.5), 'Shear stress': 0.6,
3346
+ 'Circumferential compression': 0.6}
3347
+ return psi[chk], epsilon[chk], rho[chk]
3348
+ vals = list()
3349
+
3350
+ for chk in ['Axial stress', 'Shear stress', 'Circumferential compression']:
3351
+ psi, epsilon, rho = table_3_1(chk=chk)
3352
+ C = psi * math.sqrt(1 + math.pow(rho * epsilon / psi, 2)) # (3.4.2) (3.6.4)
3353
+ fE = C*(math.pow(math.pi, 2)*E/(12*(1-math.pow(v,2)))) *math.pow(t/s,2)
3354
+ #print(chk, 'C', C, 'psi', psi,'epsilon', epsilon,'rho' ,rho, 'fE', fE)
3355
+ vals.append(fE)
3356
+
3357
+ fEax, fEshear, fEcirc = vals
3358
+ sa0sd = -sxsd if sxsd < 0 else 0
3359
+ sh0sd = -shsd if shsd < 0 else 0 # Maximium allowable stress from iteration.
3360
+
3361
+ if any([val == 0 for val in vals]):
3362
+ lambda_s_pow = 0
3363
+ else:
3364
+ lambda_s_pow = (fy/sjsd) * (sa0sd/fEax + sh0sd/fEcirc + tsd/fEshear)
3365
+
3366
+ lambda_s = math.sqrt(lambda_s_pow)
3367
+ fks = fy/math.sqrt(1+math.pow(lambda_s,4 ))
3368
+
3369
+ provide_data['fks - Unstifffed curved panel'] = fks
3370
+ if lambda_s < 0.5:
3371
+ gammaM = self._mat_factor
3372
+ else:
3373
+ if self._mat_factor == 1.1:
3374
+ if lambda_s > 1:
3375
+ gammaM = 1.4
3376
+ else:
3377
+ gammaM = 0.8+0.6*lambda_s
3378
+ elif self._mat_factor == 1.15:
3379
+ if lambda_s > 1:
3380
+ gammaM = 1.45
3381
+ else:
3382
+ gammaM = 0.85+0.6*lambda_s
3383
+ else:
3384
+ if lambda_s > 1:
3385
+ gammaM = 1.45 * (self._mat_factor/1.15)
3386
+ else:
3387
+ gammaM = 0.85+0.6*lambda_s * (self._mat_factor/1.15)
3388
+ if self._uls_or_als == 'ALS':
3389
+ gammaM = gammaM/self._mat_factor
3390
+ provide_data['gammaM Unstifffed panel'] = gammaM
3391
+ fksd = fks/gammaM
3392
+ provide_data['fksd - Unstifffed curved panel'] = fksd
3393
+ uf = sjsd/fksd
3394
+
3395
+ provide_data['UF unstiffened curved panel'] = uf
3396
+ provide_data['gammaM curved panel'] = gammaM
3397
+ sjsd_max = math.sqrt(math.pow(sasd+smsd,2)-(sasd+smsd)*shsd+math.pow(shsd,2)+3*math.pow(tsd,2))
3398
+
3399
+ uf_max = self._mat_factor* sjsd_max/fy
3400
+
3401
+
3402
+ def iter_table_1():
3403
+ found, sasd_iter, count, this_val, logger = False, 0.001 if uf > 1 else sasd, 0, 0, list()
3404
+
3405
+ while not found:
3406
+ # Iteration
3407
+ sigmsd_iter = smsd if geometry in [2,6] else min([-smsd, smsd])
3408
+ siga0sd_iter = 0 if sasd_iter >= 0 else -sasd_iter # (3.2.4)
3409
+ sigm0sd_iter = 0 if sigmsd_iter >= 0 else -sigmsd_iter # (3.2.5)
3410
+ sigh0sd_iter = 0 if shsd>= 0 else -shsd # (3.2.6)
3411
+
3412
+ sjsd_iter = math.sqrt(math.pow(sasd_iter+sigmsd_iter, 2) - (sasd_iter+sigmsd_iter)*shsd + math.pow(shsd, 2)+
3413
+ 3*math.pow(tsd, 2)) #(3.2.3)
3414
+ lambdas_iter = math.sqrt((fy / sjsd_iter) * ((siga0sd_iter+sigm0sd_iter)/fEax+ sigh0sd_iter/fEcirc+tsd/fEshear)) # (3.2.2)
3415
+
3416
+ gammaM_iter = 1 # As taken in the DNVGL sheets
3417
+ fks_iter = fy / math.sqrt(1 + math.pow(lambdas_iter,4))
3418
+ fksd_iter = fks_iter / gammaM_iter
3419
+ #print('sjsd', sjsd_iter, 'fksd', fksd_iter, 'fks', fks, 'gammaM', gammaM_iter, 'lambdas_iter', lambdas_iter)
3420
+ this_val = sjsd_iter/fksd_iter
3421
+ logger.append(0 if this_val > 1 else siga0sd_iter)
3422
+ if this_val > 1.0 or count == 1e6:
3423
+ found = True
3424
+ count += 1
3425
+ if this_val >0.98:
3426
+ sasd_iter -= 0.5
3427
+ elif this_val > 0.95:
3428
+ sasd_iter -= 1
3429
+ elif this_val > 0.9:
3430
+ sasd_iter -= 2
3431
+ elif this_val > 0.7:
3432
+ sasd_iter -= 10
3433
+ else:
3434
+ sasd_iter -= 20
3435
+
3436
+ #print(sasd_iter, this_val)
3437
+
3438
+ return 0 if len(logger) == 1 else max([logger[-2],0])
3439
+
3440
+ provide_data['max axial stress - 3.3 Unstifffed curved panel'] = iter_table_1()
3441
+
3442
+
3443
+ # Pnt. 3.4 Unstifffed circular cylinders
3444
+ Zl = (math.pow(l, 2)/(r*t)) * math.sqrt(1 - math.pow(v, 2)) #(3.4.3) (3.6.5)
3445
+ provide_data['Zl'] = Zl
3446
+ def table_3_2(chk):
3447
+ psi = {'Axial stress': 1, 'Bending': 1,
3448
+ 'Torsion and shear force': 5.34,
3449
+ 'Lateral pressure': 4, 'Hydrostatic pressure': 2} # ψ
3450
+
3451
+ zeta= {'Axial stress': 0.702*Zl, 'Bending': 0.702*Zl,
3452
+ 'Torsion and shear force': 0.856* math.pow(Zl, 3/4),'Lateral pressure': 1.04*math.sqrt(Zl),
3453
+ 'Hydrostatic pressure': 1.04*math.sqrt(Zl)} # ξ
3454
+
3455
+ rho = {'Axial stress': 0.5*math.pow(1+(r/(150*t)), -0.5), 'Bending': 0.5*math.pow(1+(r/(300*t)), -0.5),
3456
+ 'Torsion and shear force': 0.6,
3457
+ 'Lateral pressure': 0.6, 'Hydrostatic pressure': 0.6}
3458
+ return psi[chk], zeta[chk], rho[chk]
3459
+
3460
+ vals = list()
3461
+ for chk in ['Axial stress', 'Bending', 'Torsion and shear force',
3462
+ 'Lateral pressure','Hydrostatic pressure']:
3463
+ psi, zeta, rho = table_3_2(chk=chk)
3464
+ C = psi * math.sqrt(1 + math.pow(rho * zeta / psi, 2)) # (3.4.2) (3.6.4)
3465
+ fE = C*math.pow(math.pi,2)*E / (12*(1-math.pow(v,2))) * math.pow(t/l,2)
3466
+ #print(chk, 'C', C, 'psi', psi,'epsilon', epsilon,'rho' ,rho, 'fE', fE)
3467
+ vals.append(fE)
3468
+
3469
+
3470
+
3471
+ fEax, fEbend, fEtors, fElat, fEhyd = vals
3472
+
3473
+ provide_data['fEax - Unstifffed circular cylinders'] = fEax
3474
+
3475
+ test1 = 3.85 * math.sqrt(r / t)
3476
+ test2 = 2.25 * math.sqrt(r / t)
3477
+ test_l_div_r = l/r
3478
+ provide_data['fEh - Unstifffed circular cylinders - Psi=4'] = 0.25*E*math.pow(t/r,2) if test_l_div_r > test2 else fElat
3479
+ if l / r > test1:
3480
+ fEt_used = 0.25 * E * math.pow(t / r, 3 / 2) # (3.4.4)
3481
+ else:
3482
+ fEt_used = fEtors
3483
+
3484
+ if l / r > test2:
3485
+ fEh_used = 0.25 * E * math.pow(t / r, 2)
3486
+ else:
3487
+ fEh_used = fElat if self._end_cap_pressure_included == 'not included in axial stresses' else fEhyd
3488
+
3489
+ sjsd = math.sqrt(math.pow(sxsd,2) - sxsd*shsd + math.pow(shsd,2) + 3 * math.pow(tsd, 2)) # (3.2.3)
3490
+
3491
+ sa0sd = -sasd if sasd < 0 else 0
3492
+ sh0sd = -shsd if shsd < 0 else 0
3493
+
3494
+
3495
+ if any([fEax == 0, fEbend == 0, fEt_used == 0, fEh_used == 0, sjsd == 0]):
3496
+ lambda_s_pow = 0
3497
+ else:
3498
+ lambda_s_pow = (fy/sjsd) * (sa0sd/fEax + sm0sd/fEbend + sh0sd/fEh_used + tsd/fEt_used)
3499
+
3500
+ lambda_s = math.sqrt(lambda_s_pow)
3501
+ fks = fy/math.sqrt(1+math.pow(lambda_s,4 ))
3502
+
3503
+ provide_data['fks - Unstifffed circular cylinders'] = fks
3504
+
3505
+ if lambda_s < 0.5:
3506
+ gammaM = self._mat_factor
3507
+ else:
3508
+ if self._mat_factor == 1.1:
3509
+ if lambda_s > 1:
3510
+ gammaM = 1.4
3511
+ else:
3512
+ gammaM = 0.8+0.6*lambda_s
3513
+ elif self._mat_factor == 1.15:
3514
+ if lambda_s > 1:
3515
+ gammaM = 1.45
3516
+ else:
3517
+ gammaM = 0.85+0.6*lambda_s
3518
+ else:
3519
+ if lambda_s > 1:
3520
+ gammaM = 1.45 * (self._mat_factor/1.15)
3521
+ else:
3522
+ gammaM = 0.85+0.6*lambda_s * (self._mat_factor/1.15)
3523
+ if self._uls_or_als == 'ALS':
3524
+ gammaM = gammaM/self._mat_factor
3525
+
3526
+ fksd = fks/gammaM
3527
+ provide_data['fksd - Unstifffed circular cylinders'] = fksd
3528
+ uf = sjsd/fksd
3529
+
3530
+ provide_data['UF unstiffened circular cylinder'] = uf
3531
+ provide_data['gammaM circular cylinder'] = gammaM
3532
+ #print('UF', uf, 'Unstifffed circular cylinders')
3533
+ def iter_table_2():
3534
+ found, sasd_iter, count, this_val, logger = False, 0 if uf > 1 else sasd, 0, 0, list()
3535
+ while not found:
3536
+ # Iteration
3537
+ sigmsd_iter = smsd if geometry in [2, 6] else min([-smsd, smsd])
3538
+ siga0sd_iter = 0.00001 if sasd_iter >= 0 else -sasd_iter # (3.2.4)
3539
+ sigm0sd_iter = 0.00001 if sigmsd_iter >= 0 else -sigmsd_iter # (3.2.5)
3540
+ sigh0sd_iter = 0.00001 if shsd >= 0 else -shsd # (3.2.6)
3541
+ sjsd_iter = math.sqrt(
3542
+ math.pow(sasd_iter + sigmsd_iter, 2) - (sasd_iter + sigmsd_iter) * shsd + math.pow(shsd, 2) +
3543
+ 3 * math.pow(tsd, 2)) # (3.2.3)
3544
+ if sjsd_iter == 0:
3545
+ sjsd_iter = 0.00001
3546
+ lambdas_iter = math.sqrt((fy/sjsd_iter) * (siga0sd_iter/fEax + sigm0sd_iter/fEbend +
3547
+ sigh0sd_iter/fElat + tsd/fEtors))
3548
+ gammaM_iter = 1 # As taken in the DNVGL sheets
3549
+ fks_iter = fy / math.sqrt(1 + math.pow(lambdas_iter, 4))
3550
+ fksd_iter = fks_iter / gammaM_iter
3551
+ # print('sjsd', sjsd_iter, 'fksd', fksd_iter, 'fks', fks, 'gammaM', gammaM_iter, 'lambdas_iter', lambdas_iter)
3552
+
3553
+ this_val = sjsd_iter / fksd_iter
3554
+ logger.append(sasd_iter)
3555
+
3556
+ if this_val > 1.0 or count == 1e6:
3557
+ found = True
3558
+ count += 1
3559
+
3560
+ if this_val >0.98:
3561
+ sasd_iter -= 0.5
3562
+ elif this_val > 0.95:
3563
+ sasd_iter -= 1
3564
+ elif this_val > 0.9:
3565
+ sasd_iter -= 2
3566
+ elif this_val > 0.7:
3567
+ sasd_iter -= 10
3568
+ else:
3569
+ sasd_iter -= 20
3570
+
3571
+ return 0 if len(logger) == 1 else max(logger[-2],0)
3572
+
3573
+ provide_data['max axial stress - 3.4.2 Shell buckling'] = iter_table_2()
3574
+ provide_data['shsd'] = shsd
3575
+ return provide_data
3576
+
3577
+ def ring_stiffened_shell(self, data_shell_buckling = None, column_buckling_data = None):
3578
+
3579
+ E = self._E/1e6
3580
+ t = self._Shell.thk*1000
3581
+ s = min([self._Shell.dist_between_rings, 2*math.pi*self._Shell.radius])*1000 if self._LongStf == None else \
3582
+ self._LongStf.spacing
3583
+
3584
+ r = self._Shell.radius*1000
3585
+ l = self._Shell.dist_between_rings * 1000
3586
+ fy = self._mat_yield/1e6
3587
+
3588
+ L = self._Shell.tot_cyl_length*1000
3589
+ LH = L
3590
+ sasd = self._sasd/1e6
3591
+ smsd = self._smsd/1e6
3592
+ tsd = abs(self._tTsd/1e6 + self._tQsd/1e6) # MAYBE MAYBE NOT.
3593
+ psd = self._psd/1e6
3594
+
3595
+ data_shell_buckling = self.shell_buckling() if data_shell_buckling == None else data_shell_buckling
3596
+
3597
+ #Pnt. 3.5: Ring stiffened shell
3598
+
3599
+ # Pnt. 3.5.2.1 Requirement for cross-sectional area:
3600
+ #Zl = self._Shell.get_Zl()
3601
+
3602
+ Zl = math.pow(l, 2) * math.sqrt(1 - math.pow(self._v, 2)) / (r * t) if r * t > 0 else 0
3603
+ Areq = np.nan if Zl == 0 else (2/math.pow(Zl,2)+0.06)*l*t
3604
+ Areq = np.array([Areq, Areq])
3605
+ Astf = np.nan if self._RingStf is None else self._RingStf.get_cross_section_area(include_plate=False)*1000**2
3606
+ Aframe = np.nan if self._RingFrame is None else \
3607
+ self._RingFrame.get_cross_section_area(include_plate=False) * 1000 ** 2
3608
+ A = np.array([Astf, Aframe])
3609
+
3610
+ uf_cross_section = Areq/A
3611
+
3612
+ #Pnt. 3.5.2.3 Effective width calculation of shell plate
3613
+ lef = 1.56*math.sqrt(r*t)/(1+12*t/r)
3614
+ lef_used = np.array([min([lef, LH]), min([lef, LH])])
3615
+
3616
+ #Pnt. 3.5.2.4 Required Ix for Shell subject to axial load
3617
+ A_long_stf = 0 if self._LongStf is None else self._LongStf.get_cross_section_area(include_plate=False)*1000**2
3618
+ alfaA = 0 if s*t <= 0 else A_long_stf/(s*t)
3619
+
3620
+
3621
+ r0 = np.array([data_shell_buckling['parameters'][0][5], data_shell_buckling['parameters'][1][5]])
3622
+
3623
+ worst_ax_comp = min([sasd+smsd, sasd-smsd])
3624
+
3625
+ Ixreq = np.array([abs(worst_ax_comp) * t * (1 + alfaA) * math.pow(r0[0], 4) / (500 * E * l),
3626
+ abs(worst_ax_comp) * t * (1 + alfaA) * math.pow(r0[1], 4) / (500 * E * l)])
3627
+
3628
+ #Pnt. 3.5.2.5 Required Ixh for shell subjected to torsion and/or shear:
3629
+ Ixhreq = np.array([math.pow(tsd / E, (8 / 5)) * math.pow(r0[0] / L, 1 / 5) * L * r0[0] * t * l,
3630
+ math.pow(tsd / E, (8 / 5)) * math.pow(r0[1] / L, 1 / 5) * L * r0[1] * t * l])
3631
+
3632
+ #Pnt. 3.5.2.6 Simplified calculation of Ih for shell subjected to external pressure
3633
+ zt = np.array([data_shell_buckling['parameters'][0][6],data_shell_buckling['parameters'][1][6]])
3634
+ rf = np.array([data_shell_buckling['parameters'][0][4], data_shell_buckling['parameters'][1][4]])
3635
+
3636
+ delta0 = r*self._delta0
3637
+
3638
+ fb_ring_req_val = np.array([0 if self._RingStf is None else 0.4*self._RingStf.tw*math.sqrt(E/fy),
3639
+ 0 if self._RingFrame is None else 0.4*self._RingFrame.tw*math.sqrt(E/fy)])
3640
+ # if self._RingStf.get_stiffener_type() == 'FB':
3641
+ # fb_ring_req = fb_ring_req_val[0] > self._RingStf.hw
3642
+ # else:
3643
+ # fb_ring_req = np.NaN
3644
+
3645
+ flanged_rf_req_h_val = np.array([0 if self._RingStf is None else 1.35*self._RingStf.tw*math.sqrt(E/fy),
3646
+ 0 if self._RingFrame is None else 1.35*self._RingFrame.tw*math.sqrt(E/fy)])
3647
+ # if self._RingFrame.get_stiffener_type() != 'FB':
3648
+ # flanged_rf_req_h = flanged_rf_req_h_val[1] > self._RingFrame.hw
3649
+ # else:
3650
+ # flanged_rf_req_h = np.NaN
3651
+
3652
+ flanged_rf_req_b_val = np.array([0 if self._RingStf is None else 7*self._RingStf.hw/math.sqrt(10+E*self._RingStf.hw/(fy*r)),
3653
+ 0 if self._RingFrame is None else 7*self._RingFrame.hw/math.sqrt(10+E*self._RingFrame.hw/(fy*r))])
3654
+ # if self._RingFrame.get_stiffener_type() != 'FB':
3655
+ # flanged_rf_req_b = flanged_rf_req_b_val[1] > self._RingFrame.b
3656
+ # else:
3657
+ # flanged_rf_req_b = np.NaN
3658
+
3659
+ if self._RingStf is not None:
3660
+ spf_stf = self._RingStf.hw/fb_ring_req_val[0] if self._RingStf.get_stiffener_type() == 'FB' \
3661
+ else max([flanged_rf_req_b_val[0]/self._RingStf.b, self._RingStf.hw/flanged_rf_req_h_val[0]])
3662
+ else:
3663
+ spf_stf = 0
3664
+
3665
+ if self._RingFrame is not None:
3666
+ spf_frame = self._RingFrame.hw / fb_ring_req_val[1]if self._RingFrame.get_stiffener_type() == 'FB' \
3667
+ else max([flanged_rf_req_b_val[1] / self._RingFrame.b,self._RingFrame.hw / flanged_rf_req_h_val[1]])
3668
+ else:
3669
+ spf_frame = 0
3670
+
3671
+ Stocky_profile_factor = np.array([spf_stf, spf_frame])
3672
+
3673
+ fT = column_buckling_data['fT_dict']
3674
+ fT = np.array([fT['Ring Stiff.'] if Stocky_profile_factor[0] > 1 else fy,
3675
+ fT['Ring Girder'] if Stocky_profile_factor[1] > 1 else fy])
3676
+
3677
+ fr_used = np.array([fT[0] if self._fab_method_ring_stf == 1 else 0.9 * fT[0],
3678
+ fT[1] if self._fab_method_ring_girder == 1 else 0.9 * fT[1]])
3679
+ shRsd = [abs(val) for val in data_shell_buckling['shRsd']]
3680
+
3681
+ Ih = np.array([0 if E*r0[idx]*(fr_used[idx]/2-shRsd[idx]) == 0 else abs(psd)*r*math.pow(r0[idx],2)*l/(3*E)*
3682
+ (1.5+3*E*zt[idx]*delta0/(math.pow(r0[idx],2)
3683
+ *(fr_used[idx]/2-shRsd[idx])))
3684
+ for idx in [0,1]])
3685
+
3686
+ # Pnt. 3.5.2.2 Moment of inertia:
3687
+ IR = [Ih[idx] + Ixhreq[idx] + Ixreq[idx] if all([psd <= 0, Ih[idx] > 0]) else Ixhreq[idx] + Ixreq[idx]
3688
+ for idx in [0,1]]
3689
+ Iy = [data_shell_buckling['cross section data'][idx+1][4] for idx in [0,1]]
3690
+
3691
+ uf_moment_of_inertia = list()
3692
+ for idx in [0,1]:
3693
+
3694
+ if Iy[idx] > 0:
3695
+ uf_moment_of_inertia.append(9.999 if fr_used[idx] < 2*shRsd[idx] else IR[idx]/Iy[idx])
3696
+ else:
3697
+ uf_moment_of_inertia.append(0)
3698
+
3699
+ # Pnt. 3.5.2.7 Refined calculation of external pressure
3700
+ # parameters.append([alpha, beta, leo, zeta, rf, r0, zt])
3701
+ I = Iy
3702
+ Ihmax = [max(0, I[idx]-Ixhreq[idx]-Ixreq[idx]) for idx in [0,1]]
3703
+ leo = [data_shell_buckling['parameters'][idx][2] for idx in [0,1]]
3704
+ Ar = A
3705
+ ih2 = [0 if Ar[idx]+leo[idx]*t == 0 else Ihmax[idx]/(Ar[idx]+leo[idx]*t) for idx in [0,1]]
3706
+ alfa = [0 if l*t == 0 else 12*(1-math.pow(0.3,2))*Ihmax[idx]/(l*math.pow(t,3)) for idx in [0,1]]
3707
+ betta = [data_shell_buckling['parameters'][idx][0] for idx in [0,1]]
3708
+ ZL = [math.pow(L,2)/r/t*math.sqrt(1-math.pow(0.3,2)) for idx in [0,1]]
3709
+
3710
+ C1 = [2*(1+alfa[idx])/(1+betta[idx])*(math.sqrt(1+0.27*ZL[idx]/math.sqrt(1+alfa[idx]))-alfa[idx]/(1+alfa[idx]))
3711
+ for idx in [0,1]]
3712
+
3713
+ C2 = [2*math.sqrt(1+0.27*ZL[idx]) for idx in [0,1]]
3714
+
3715
+ my = [0 if ih2[idx]*r*leo[idx]*C1[idx] == 0 else
3716
+ zt[idx]*delta0*rf[idx]*l/(ih2[idx]*r*leo[idx])*(1-C2[idx]/C1[idx])*1/(1-0.3/2) for idx in [0,1]]
3717
+
3718
+ fE = np.array([C1[idx]*math.pow(math.pi,2)*E/(12*(1-math.pow(0.3,2)))*(math.pow(t/L,2)) if L > 0
3719
+ else 0.1 for idx in [0,1]])
3720
+
3721
+ fr = np.array(fT)
3722
+ lambda_2 = fr/fE
3723
+ lambda_ = np.sqrt(lambda_2)
3724
+
3725
+ fk = [0 if lambda_2[idx] == 0 else fr[idx]*(1+my[idx]+lambda_2[idx]-math.sqrt(math.pow(1+my[idx]+lambda_2[idx],2)-
3726
+ 4*lambda_2[idx]))/(2*lambda_2[idx])
3727
+ for idx in [0,1]]
3728
+ gammaM = self._mat_factor # LRFD
3729
+ fkd = [fk[idx]/gammaM for idx in [0,1]]
3730
+ psd = np.array([0.75*fk[idx]*t*rf[idx]*(1+betta[idx])/(gammaM*math.pow(r,2)*(1-0.3/2)) for idx in [0,1]])
3731
+
3732
+ uf_refined = abs((self._psd/1e6))/psd
3733
+
3734
+ return np.max([uf_cross_section, uf_moment_of_inertia, uf_refined], axis=0)
3735
+
3736
+ def longitudinally_stiffened_shell(self, column_buckling_data = None, unstiffened_shell = None):
3737
+
3738
+ h = self._Shell.thk*1000 + self._LongStf.hw + self._LongStf.tf
3739
+
3740
+ hw = self._LongStf.hw
3741
+ tw = self._LongStf.tw
3742
+ b = self._LongStf.b
3743
+ tf = self._LongStf.tf
3744
+
3745
+ E = self._E/1e6
3746
+ t = self._Shell.thk*1000
3747
+ s = max([self._Shell.dist_between_rings, 2*math.pi*self._Shell.radius])*1000 if self._LongStf == None else \
3748
+ self._LongStf.spacing
3749
+ v = self._v
3750
+ r = self._Shell.radius*1000
3751
+ l = self._Shell.dist_between_rings * 1000
3752
+ fy = self._mat_yield/1e6
3753
+
3754
+ L = self._Shell.tot_cyl_length*1000
3755
+ LH = L
3756
+ sasd = self._sasd/1e6
3757
+ smsd = self._smsd/1e6
3758
+ tsd = abs(self._tTsd/1e6 + self._tQsd/1e6)
3759
+ psd = self._psd/1e6
3760
+ shsd = unstiffened_shell['shsd']
3761
+
3762
+ #print(h, hw, tw, b, tf, s, r, l, L, sasd, smsd, shsd)
3763
+ lightly_stf = s/t > math.sqrt(r/t)
3764
+ provide_data = dict()
3765
+
3766
+ '''
3767
+ Selections for: Type of Structure Geometry:
3768
+ 1 Unstiffened shell (Force input)
3769
+ 2 Unstiffened panel (Stress input)
3770
+ 3 Longitudinal Stiffened shell (Force input)
3771
+ 4 Longitudinal Stiffened panel (Stress input)
3772
+ 5 Ring Stiffened shell (Force input)
3773
+ 6 Ring Stiffened panel (Stress input)
3774
+ 7 Orthogonally Stiffened shell (Force input)
3775
+ 8 Orthogonally Stiffened panel (Stress input)
3776
+ Selected:
3777
+ 3 Longitudinal Stiffened shell (Force input)
3778
+ '''
3779
+ # Pnt. 3.3 Unstifffed curved panel
3780
+ geometry = self._geometry
3781
+ data = unstiffened_shell if unstiffened_shell is not None else self.unstiffened_shell()
3782
+
3783
+ if geometry == 1:
3784
+ fks = data['fks - Unstifffed circular cylinders']
3785
+ else:
3786
+ fks = data['fks - Unstifffed curved panel']
3787
+
3788
+ sxSd =min([sasd+smsd, sasd-smsd])
3789
+
3790
+
3791
+ sjsd = math.sqrt(math.pow(sxSd,2) - sxSd*shsd + math.pow(shsd,2) + 3 * math.pow(tsd, 2))
3792
+
3793
+ Se = (fks*abs(sxSd) / (sjsd*fy))*s
3794
+
3795
+ # Moment of inertia
3796
+ As = A = hw*tw + b*tf # checked
3797
+
3798
+ num_stf = math.floor(2*math.pi*r/s)
3799
+
3800
+ e= (hw*tw*(hw/2) + b*tf*(hw+tf/2)) / (hw*tw+b*tw)
3801
+ Istf = h*math.pow(tw,3)/12 + tf*math.pow(b, 3)/12
3802
+
3803
+ dist_stf = r - t / 2 - e
3804
+ Istf_tot = 0
3805
+ angle = 0
3806
+ for stf_no in range(num_stf):
3807
+ Istf_tot += Istf + As*math.pow(dist_stf*math.cos(angle),2)
3808
+ angle += 2*math.pi/num_stf
3809
+ # Ishell = (math.pi/4) * ( math.pow(r+t/2,4) - math.pow(r-t/2,4))
3810
+ # Itot = Ishell + Istf_tot # Checked
3811
+
3812
+ Iy = self._LongStf.get_moment_of_intertia(efficent_se=Se/1000, tf1=self._Shell.thk)*1000**4
3813
+
3814
+ alpha = 12*(1-math.pow(v,2))*Iy/(s*math.pow(t,3))
3815
+ Zl = (math.pow(l, 2)/(r*t)) * math.sqrt(1-math.pow(v,2))
3816
+
3817
+ #|1print('Zl', Zl, 'alpha', alpha, 'Isef', Iy, 'Se', Se, 'sjsd', sjsd, 'sxsd', sxSd, 'fks', fks, 'As', As)
3818
+ # Table 3-3
3819
+
3820
+
3821
+ def table_3_3(chk):
3822
+ psi = {'Axial stress': 0 if Se == 0 else (1+alpha) / (1+A/(Se*t)),
3823
+ 'Torsion and shear stress': 5.54+1.82*math.pow(l/s, 4/3) * math.pow(alpha, 1/3),
3824
+ 'Lateral Pressure': 2*(1+math.sqrt(1+alpha))} # ψ
3825
+ epsilon = {'Axial stress': 0.702*Zl,
3826
+ 'Torsion and shear stress': 0.856*math.pow(Zl, 3/4),
3827
+ 'Lateral Pressure': 1.04*math.sqrt(Zl)} # ξ
3828
+ rho = {'Axial stress': 0.5,
3829
+ 'Torsion and shear stress': 0.6,
3830
+ 'Lateral Pressure': 0.6}
3831
+ return psi[chk], epsilon[chk], rho[chk]
3832
+
3833
+ vals = list()
3834
+ for chk in ['Axial stress', 'Torsion and shear stress','Lateral Pressure']:
3835
+ psi, epsilon, rho = table_3_3(chk=chk)
3836
+
3837
+ C = 0 if psi == 0 else psi * math.sqrt(1 + math.pow(rho * epsilon / psi, 2)) # (3.4.2) (3.6.4)
3838
+ fE = C * ((math.pow(math.pi, 2) * E) / (12 * (1 - math.pow(v, 2)))) * math.pow(t / l,2)
3839
+ vals.append(fE)
3840
+ #print(chk, 'C', C, 'psi', psi,'epsilon', epsilon,'rho' ,rho, 'fE', fE)
3841
+ fEax, fEtors, fElat = vals
3842
+
3843
+ #Torsional Buckling can be excluded as possible failure if:
3844
+ if self._LongStf._stiffener_type == 'FB':
3845
+ chk_fb = hw <= 0.4*tw*math.sqrt(E/fy)
3846
+
3847
+ data_col_buc = column_buckling_data
3848
+
3849
+ fy_used = fy if data_col_buc['lambda_T'] <= 0.6 else data_col_buc['fT']
3850
+
3851
+ sasd = sasd*(A+s*t)/(A+Se*t) if A+Se*t>0 else 0
3852
+ smsd = smsd * (A + s * t) / (A + Se * t) if A + Se * t > 0 else 0
3853
+
3854
+ sa0sd = -sasd if sasd < 0 else 0
3855
+ sm0sd = -smsd if smsd < 0 else 0
3856
+ sh0sd = -shsd if shsd < 0 else 0
3857
+ #print('fy_used', fy_used,'sasd', sasd,'shsd', shsd, 'tsd', tsd)
3858
+ sjsd_panels = math.sqrt(math.pow(sasd+smsd,2)-(sasd+smsd)*shsd + math.pow(shsd,2)+ 3*math.pow(tsd,2))
3859
+
3860
+ worst_axial_comb = min(sasd-smsd,sasd+smsd)
3861
+ sjsd_shells = math.sqrt(math.pow(worst_axial_comb,2)-worst_axial_comb*shsd +math.pow(shsd,2)+3*math.pow(tsd,2))
3862
+ sxsd_used = worst_axial_comb
3863
+ provide_data['sxsd_used'] = sxsd_used
3864
+ sjsd_used = sjsd_panels if self._geometry in [2,6] else sjsd_shells
3865
+ provide_data['sjsd_used'] = sjsd_used
3866
+
3867
+ lambda_s2_panel = fy_used/sjsd_panels*((sa0sd+sm0sd)/fEax+sh0sd/fElat+tsd/fEtors) if\
3868
+ sjsd_panels*fEax*fEtors*fElat>0 else 0
3869
+
3870
+ lambda_s2_shell = fy_used/sjsd_shells*(max(0,-worst_axial_comb)/fEax+sh0sd/fElat+tsd/fEtors) if\
3871
+ sjsd_shells*fEax*fEtors*fElat>0 else 0
3872
+
3873
+ shell_type = 2 if self._geometry in [1,5] else 1
3874
+ lambda_s = math.sqrt(lambda_s2_panel) if shell_type == 1 else math.sqrt(lambda_s2_shell)
3875
+
3876
+ fks = fy_used/math.sqrt(1+math.pow(lambda_s,4))
3877
+
3878
+ #print('tsd',tsd, 'sasd', sasd, 'sjsd panels', sjsd_panels, 'fy_used', fy_used, 'lambda_T',data_col_buc['lambda_T'] )
3879
+ if lambda_s < 0.5:
3880
+ gammaM = self._mat_factor
3881
+ else:
3882
+ if self._mat_factor == 1.1:
3883
+ if lambda_s > 1:
3884
+ gammaM = 1.4
3885
+ else:
3886
+ gammaM = 0.8+0.6*lambda_s
3887
+ elif self._mat_factor == 1.15:
3888
+ if lambda_s > 1:
3889
+ gammaM = 1.45
3890
+ else:
3891
+ gammaM = 0.85+0.6*lambda_s
3892
+ else:
3893
+ if lambda_s > 1:
3894
+ gammaM = 1.45 * (self._mat_factor/1.15)
3895
+ else:
3896
+ gammaM = 0.85+0.6*lambda_s * (self._mat_factor/1.15)
3897
+
3898
+ if self._uls_or_als == 'ALS':
3899
+ gammaM = gammaM/self._mat_factor
3900
+
3901
+ # Design buckling strength:
3902
+ fksd = fks/gammaM
3903
+ provide_data['fksd'] = fksd
3904
+ # print(sjsd_panels, sjsd_shells, fksd)
3905
+ # print('fksd', fksd, 'fks', fks, 'gammaM', gammaM, 'lambda_s', lambda_s, 'lambda_s^2 panel',
3906
+ # lambda_s2_panel, 'sjsd', sjsd_used, 'worst_axial_comb',worst_axial_comb, 'sm0sd',sm0sd)
3907
+ #print(' ')
3908
+ return provide_data
3909
+
3910
+ @staticmethod
3911
+ def get_Itot(hw, tw, b, tf, r, s, t):
3912
+
3913
+ h = t+hw+tf
3914
+ As = hw*tw + b*tf # checked
3915
+ if As != 0:
3916
+
3917
+ num_stf = math.floor(2*math.pi*r/s)
3918
+ e= (hw*tw*(hw/2) + b*tf*(hw+tf/2)) / (hw*tw+b*tw)
3919
+ Istf = h*math.pow(tw,3)/12 + tf*math.pow(b, 3)/12
3920
+ dist_stf = r - t / 2 - e
3921
+ Istf_tot = 0
3922
+ angle = 0
3923
+ for stf_no in range(num_stf):
3924
+ Istf_tot += Istf + As*math.pow(dist_stf*math.cos(angle),2)
3925
+ angle += 2*math.pi/num_stf
3926
+ else:
3927
+ Istf_tot = 0
3928
+ Ishell = (math.pi/4) * ( math.pow(r+t/2,4) - math.pow(r-t/2,4))
3929
+ Itot = Ishell + Istf_tot # Checked
3930
+
3931
+ return Itot
3932
+
3933
+ def column_buckling(self,shell_bukcling_data = None, unstf_shell_data = None):
3934
+
3935
+ geometry = self._geometry
3936
+ provide_data = dict()
3937
+ G = 80769.2
3938
+
3939
+ if self._LongStf is None:
3940
+ h = self._Shell.thk*1000
3941
+ else:
3942
+ h = self._Shell.thk*1000 + self._LongStf.hw + self._LongStf.tf
3943
+
3944
+ hw = 0 if self._LongStf is None else self._LongStf.hw
3945
+ tw = 0 if self._LongStf is None else self._LongStf.tw
3946
+ b = 0 if self._LongStf is None else self._LongStf.b
3947
+ tf = 0 if self._LongStf is None else self._LongStf.tf
3948
+
3949
+ E = self._E/1e6
3950
+ t = self._Shell.thk*1000
3951
+ s = max([self._Shell.dist_between_rings, 2*math.pi*self._Shell.radius])*1000 if self._LongStf == None else \
3952
+ self._LongStf.spacing
3953
+ v = self._v
3954
+ r = self._Shell.radius*1000
3955
+ l = self._Shell.dist_between_rings * 1000
3956
+ fy = self._mat_yield/1e6
3957
+
3958
+ L = self._Shell.tot_cyl_length*1000
3959
+ LH = L
3960
+ Lc = max([L, LH])
3961
+
3962
+ sasd = self._sasd/1e6
3963
+ smsd = self._smsd/1e6
3964
+ tsd = abs(self._tTsd/1e6 + self._tQsd/1e6)
3965
+ psd = self._psd/1e6
3966
+ shsd = psd * r / t
3967
+ #print(t,h, hw, tw, b, tf, s, r, l, L, sasd, smsd, tsd, shsd)
3968
+ shell_buckling_data = self.shell_buckling(unstiffened_cylinder=unstf_shell_data) if\
3969
+ shell_bukcling_data is None else shell_bukcling_data
3970
+ data = self.unstiffened_shell() if unstf_shell_data is None else unstf_shell_data
3971
+
3972
+ idx = 1
3973
+ param_map = {'Ring Stiff.': 0,'Ring Girder': 1}
3974
+ fT_dict = dict()
3975
+ for key, obj in {'Longitudinal stiff.': self._LongStf, 'Ring Stiff.': self._RingStf,
3976
+ 'Ring Girder': self._RingFrame}.items():
3977
+ if obj is None:
3978
+ idx += 1
3979
+ continue
3980
+ gammaM = data['gammaM circular cylinder'] if self._geometry > 2 else \
3981
+ data['gammaM curved panel']
3982
+ sjsd = shell_buckling_data['sjsd'][idx-1]
3983
+
3984
+ this_s = 0 if self._LongStf is None else self._LongStf.spacing
3985
+ if any([self._geometry in [1, 5], this_s > (self._Shell.dist_between_rings * 1000)]):
3986
+ fksd = data['fksd - Unstifffed circular cylinders']
3987
+ else:
3988
+ fksd = data['fksd - Unstifffed curved panel']
3989
+
3990
+ fks = fksd * gammaM
3991
+ eta = sjsd/fks
3992
+ hw = obj.hw
3993
+ tw = obj.tw
3994
+
3995
+ if key == 'Longitudinal stiff.':
3996
+ s_or_leo = obj.spacing
3997
+ lT = l
3998
+ else:
3999
+ s_or_leo = shell_buckling_data['parameters'][param_map[key]][2]
4000
+ lT = math.pi*math.sqrt(r*hw)
4001
+
4002
+ C = hw/s_or_leo*math.pow(t/tw,3)*math.sqrt(1-min([1,eta])) if s_or_leo*tw>0 else 0
4003
+
4004
+ beta = (3*C+0.2)/(C+0.2)
4005
+
4006
+ #parameters.append([alpha, beta, leo, zeta])
4007
+ hs, It, Iz, Ipo, Iy = shell_buckling_data['cross section data'][idx - 1]
4008
+ if obj.get_stiffener_type() == 'FB':
4009
+ Af = obj.tf * obj.b
4010
+ Aw = obj.hw * obj.tw
4011
+ fEt = beta * (Aw + math.pow(obj.tf / obj.tw, 2) * Af) / (Aw + 3 * Af) * G * math.pow(obj.tw / hw,
4012
+ 2) + math.pow(
4013
+ math.pi, 2) \
4014
+ * E * Iz / ((Aw / 3 + Af) * math.pow(lT, 2))
4015
+
4016
+ else:
4017
+ hs, It, Iz, Ipo, Iy = shell_buckling_data['cross section data'][idx-1]
4018
+ fEt = beta * G * It / Ipo + math.pow(math.pi, 2) * E * math.pow(hs, 2) * Iz / (Ipo * math.pow(lT, 2))
4019
+ #print(key, 'hs', hs, 'It', It, 'Iz', Iz, 'Ipo', Ipo, 'Iy', Iy)
4020
+
4021
+ lambdaT = math.sqrt(fy/fEt)
4022
+
4023
+ mu = 0.35*(lambdaT-0.6)
4024
+ fT = (1+mu+math.pow(lambdaT,2)-math.sqrt(math.pow(1+mu+math.pow(lambdaT,2),2)-4*math.pow(lambdaT,2)))\
4025
+ /(2*math.pow(lambdaT,2))*fy if lambdaT > 0.6 else fy
4026
+
4027
+ # General
4028
+
4029
+ if key == 'Longitudinal stiff.':
4030
+ #print('Column buckling', 'fET', fEt, 'mu', mu, 'lambdaT', lambdaT, 'hs', hs, 'It', It, 'Iz', Iz ,'Ipo', Ipo)
4031
+ provide_data['lambda_T'] = lambdaT
4032
+ provide_data['fT'] = fT
4033
+ fT_dict[key] = fT
4034
+ idx += 1
4035
+ # if key == 'Ring Stiff.':
4036
+ # print(hs, It, Iz, Ipo, Iy)
4037
+ # print('hello')
4038
+ provide_data['fT_dict'] = fT_dict
4039
+
4040
+ # Moment of inertia
4041
+ As = A = hw*tw + b*tf # checked
4042
+
4043
+ num_stf = math.floor(2*math.pi*r/s)
4044
+
4045
+ Atot = As*num_stf + 2*math.pi*r*t
4046
+
4047
+ e= (hw*tw*(hw/2) + b*tf*(hw+tf/2)) / (hw*tw+b*tw)
4048
+ Istf = h*math.pow(tw,3)/12 + tf*math.pow(b, 3)/12
4049
+
4050
+ dist_stf = r - t / 2 - e
4051
+ Istf_tot = 0
4052
+ angle = 0
4053
+ for stf_no in range(num_stf):
4054
+ Istf_tot += Istf + As*math.pow(dist_stf*math.cos(angle),2)
4055
+ angle += 2*math.pi/num_stf
4056
+
4057
+ Ishell = (math.pi/4) * ( math.pow(r+t/2,4) - math.pow(r-t/2,4))
4058
+ Itot = Ishell + Istf_tot # Checked
4059
+
4060
+ k_factor = self._Shell.k_factor
4061
+ col_test =math.pow(k_factor*Lc/math.sqrt(Itot/Atot),2) >= 2.5*E/fy
4062
+
4063
+ provide_data['Need to check column buckling'] = col_test
4064
+ # print("Column buckling should be assessed") if col_test else \
4065
+ # print("Column buckling does not need to be checked")
4066
+
4067
+
4068
+ #Sec. 3.8.2 Column buckling strength:
4069
+
4070
+ fEa = data['fEax - Unstifffed circular cylinders']
4071
+ #fEa = any([geometry in [1,5], s > l])
4072
+ fEh = data['fEh - Unstifffed circular cylinders - Psi=4']
4073
+
4074
+ # Special case: calculation of fak for unstiffened shell:
4075
+
4076
+ # General case:
4077
+
4078
+ use_fac = 1 if geometry < 3 else 2
4079
+
4080
+ if use_fac == 1:
4081
+ a = 1 + math.pow(fy, 2) / math.pow(fEa, 2)
4082
+ b = ((2 * math.pow(fy, 2) / (fEa * fEh)) - 1) * shsd
4083
+ c = math.pow(shsd, 2) + math.pow(fy, 2) * math.pow(shsd, 2) / math.pow(fEh, 2) - math.pow(fy, 2)
4084
+ fak = 0 if b == 0 else (b + math.sqrt(math.pow(b, 2) - 4 * a * c)) / (2 * a)
4085
+ elif any([geometry in [1,5], s > l]):
4086
+ fak = data['max axial stress - 3.4.2 Shell buckling']
4087
+ else:
4088
+ fak = data['max axial stress - 3.3 Unstifffed curved panel']
4089
+
4090
+ i = Itot/Atot
4091
+ fE = 0.0001 if Lc*k_factor == 0 else E*math.sqrt(math.pi*i / (Lc * k_factor))
4092
+
4093
+ Lambda_ = 0 if fE == 0 else math.sqrt(fak/fE)
4094
+
4095
+ fkc = (1-0-28*math.pow(Lambda_,2))*fak if Lambda_ <= 1.34 else fak/math.pow(Lambda_,2)
4096
+ gammaM = data['gammaM curved panel'] #self._mat_factor # Check
4097
+
4098
+ fakd = fak/gammaM
4099
+ fkcd = fkc/gammaM
4100
+
4101
+ sa0sd = -sasd if sasd<0 else 0
4102
+
4103
+ if fakd*fkcd > 0:
4104
+ stab_uf = sa0sd/fkcd + (abs(smsd) / (1-sa0sd/fE))/fakd
4105
+ stab_chk = stab_uf <= 1
4106
+ else:
4107
+ stab_uf = 10
4108
+ stab_chk = True
4109
+
4110
+ #print("Stability requirement satisfied") if stab_chk else print("Not acceptable")
4111
+ # Sec. 3.9 Torsional buckling: moved to the top
4112
+
4113
+ # Stiffener check
4114
+
4115
+ stf_req_h = list()
4116
+ for idx, obj in enumerate([self._LongStf, self._RingStf, self._RingFrame]):
4117
+ if obj is None:
4118
+ stf_req_h.append(np.nan)
4119
+ else:
4120
+ stf_req_h.append(0.4*obj.tw*math.sqrt(E/fy) if obj.get_stiffener_type() == 'FB'
4121
+ else 1.35*obj.tw*math.sqrt(E/fy))
4122
+
4123
+ stf_req_h = np.array(stf_req_h)
4124
+
4125
+ stf_req_b = list()
4126
+ for idx, obj in enumerate([self._LongStf, self._RingStf, self._RingFrame]):
4127
+ if obj is None:
4128
+ stf_req_b.append(np.nan)
4129
+ else:
4130
+ stf_req_b.append(np.nan if obj.get_stiffener_type() == 'FB' else 0.4*obj.tf*math.sqrt(E/fy))
4131
+
4132
+ bf = list()
4133
+ for idx, obj in enumerate([self._LongStf, self._RingStf, self._RingFrame]):
4134
+ if obj is None:
4135
+ bf.append(np.nan)
4136
+ elif obj.get_stiffener_type() == 'FB':
4137
+ bf.append(obj.b)
4138
+ elif obj.get_stiffener_type() == 'T':
4139
+ bf.append((obj.b-obj.tw)/2)
4140
+ else:
4141
+ bf.append(obj.b-obj.tw)
4142
+ bf = np.array(bf)
4143
+
4144
+ hw_div_tw = list()
4145
+ for idx, obj in enumerate([self._RingStf, self._RingFrame]):
4146
+ if obj is None:
4147
+ hw_div_tw.append(np.nan)
4148
+ else:
4149
+ hw_div_tw.append(obj.hw/obj.tw)
4150
+ hw_div_tw = np.array(hw_div_tw)
4151
+
4152
+ #parameters - [alpha, beta, leo, zeta, rf, r0, zt]
4153
+
4154
+ req_hw_div_tw = list()
4155
+ for idx, obj in enumerate([self._RingStf, self._RingFrame]):
4156
+ if obj is None:
4157
+ req_hw_div_tw.append(np.nan)
4158
+ else:
4159
+ #print(shell_buckling_data['parameters'][idx][4],obj.tw, obj.hw, E, obj.hw, obj.b, obj.tf, fy)
4160
+ to_append = np.nan if obj.b*obj.tf == 0 else 2/3*math.sqrt(shell_buckling_data['parameters'][idx][4]
4161
+ *(obj.tw*obj.hw)*E/
4162
+ (obj.hw*obj.b*obj.tf*fy))
4163
+ req_hw_div_tw.append(to_append)
4164
+ req_hw_div_tw = np.array(req_hw_div_tw)
4165
+
4166
+ ef_div_tw = list()
4167
+ for idx, obj in enumerate([self._RingStf, self._RingFrame]):
4168
+ if obj is None:
4169
+ ef_div_tw.append(np.nan)
4170
+ else:
4171
+ ef_div_tw.append(obj.get_flange_eccentricity())
4172
+ ef_div_tw = np.array(ef_div_tw)
4173
+
4174
+ ef_div_tw_req = list()
4175
+ for idx, obj in enumerate([self._RingStf, self._RingFrame]):
4176
+ if obj is None:
4177
+ ef_div_tw_req.append(np.nan)
4178
+ else:
4179
+ ef_div_tw_req.append(np.nan if obj.b*obj.tf == 0 else
4180
+ 1/3*shell_buckling_data['parameters'][idx][4]/obj.hw*obj.hw*obj.tw/(obj.b*obj.tf))
4181
+ ef_div_tw_req = np.array(ef_div_tw_req)
4182
+
4183
+ #
4184
+ # print(stf_req_h , '>', np.array([np.nan if self._LongStf is None else self._LongStf.hw,
4185
+ # np.nan if self._RingStf is None else self._RingStf.hw,
4186
+ # np.nan if self._RingFrame is None else self._RingFrame.hw]))
4187
+ # print(stf_req_b , '>', bf)
4188
+ # print(hw_div_tw , '<', req_hw_div_tw)
4189
+ # print(ef_div_tw , '<', ef_div_tw_req)
4190
+
4191
+ chk1 = stf_req_h>np.array([np.nan if self._LongStf is None else self._LongStf.hw,
4192
+ np.nan if self._RingStf is None else self._RingStf.hw,
4193
+ np.nan if self._RingFrame is None else self._RingFrame.hw])
4194
+ chk1 = [np.nan if np.isnan(val) else chk1[idx] for idx, val in enumerate(stf_req_h)]
4195
+
4196
+ chk2 = stf_req_b > bf
4197
+ chk2 = [np.nan if np.isnan(val) else chk2[idx] for idx, val in enumerate(stf_req_b)]
4198
+
4199
+ chk3= hw_div_tw < req_hw_div_tw
4200
+ chk3 = [np.nan if np.isnan(val) else chk3[idx] for idx, val in enumerate(req_hw_div_tw)]
4201
+
4202
+ chk4 = ef_div_tw < ef_div_tw_req
4203
+ chk4 = [np.nan if np.isnan(val) else chk4[idx] for idx, val in enumerate(ef_div_tw_req)]
4204
+
4205
+ provide_data['stiffener check'] = {'longitudinal':all([chk1[0], chk2[0]]),
4206
+ 'ring stiffener': None if self._RingStf is None else
4207
+ all([chk1[1],chk2[1],chk3[0],chk4[0]]),
4208
+ 'ring frame': None if self._RingFrame is None else
4209
+ True}
4210
+ #all([chk1[2],chk2[2],chk3[1],chk4[1]])} SKIP check for girders
4211
+ provide_data['stiffener check detailed'] = {'longitudinal':'Web height < ' + str(round(stf_req_h[0],1)) if not chk1[0]
4212
+ else '' + ' ' + 'flange width < ' +str(round(stf_req_b[0],1)) if not chk2[0] else ' ',
4213
+ 'ring stiffener': None if self._RingStf is None
4214
+ else 'Web height < ' + str(round(stf_req_h[1],1)) if not chk1[1]
4215
+ else '' + ' ' + 'flange width < ' +str(round(stf_req_b[1],1)) if not chk2[1]
4216
+ else ' ' + ' ' + 'hw/tw >= ' + str(round(req_hw_div_tw[0],1))
4217
+ if not chk3[0]
4218
+ else ''+ ' ' + 'ef/tw >= ' + str(round(ef_div_tw_req[0],1))
4219
+ if not chk4[0]
4220
+ else '',
4221
+ 'ring frame': None if self._RingFrame is None
4222
+ else 'Web height < ' + str(round(stf_req_h[2],1)) if not chk1[2]
4223
+ else '' + ' ' + 'flange width < ' +str(round(stf_req_b[2],1)) if not chk2[2]
4224
+ else ' ' + ' ' + 'hw/tw >= ' + str(round(req_hw_div_tw[1],1))
4225
+ if not chk3[1]
4226
+ else ''+ ' ' + 'ef/tw >= ' + str(round(ef_div_tw_req[1],1))
4227
+ if not chk4[1]
4228
+ else ''}
4229
+
4230
+ provide_data['Column stability check'] = stab_chk
4231
+ provide_data['Column stability UF'] = stab_uf
4232
+
4233
+ return provide_data
4234
+
4235
+ def get_all_properties(self):
4236
+ all_data = {'Main class': self.get_main_properties(),
4237
+ 'Shell': self._Shell.get_main_properties(),
4238
+ 'Long. stf.': None if self._LongStf is None else self._LongStf.get_structure_prop(),
4239
+ 'Ring stf.': None if self._RingStf is None else self.RingStfObj.get_structure_prop(),
4240
+ 'Ring frame': None if self._RingFrame is None else self._RingFrame.get_structure_prop()}
4241
+ return all_data
4242
+
4243
+ def set_all_properties(self, all_prop_dict): # TODO ensure that this is set when optimizing and saving.
4244
+ all_data = {'Main class': self.set_main_properties(all_prop_dict['Main class']),
4245
+ 'Shell': self._Shell.set_main_properties(all_prop_dict['Shell']),
4246
+ 'Long. stf.': None if self._LongStf is None else
4247
+ self._LongStf.set_main_properties(all_prop_dict['Long. stf.']),
4248
+ 'Ring stf.': None if self._RingStf is None else
4249
+ self.RingStfObj.set_main_properties(all_prop_dict['Ring stf.']),
4250
+ 'Ring frame': None if self._RingFrame is None else
4251
+ self._RingFrame.set_main_properties(all_prop_dict['Ring frame'])}
4252
+ return all_data
4253
+
4254
+ def get_main_properties(self):
4255
+ main_dict = {'sasd': [self._sasd, 'Pa'],
4256
+ 'smsd': [self._smsd, 'Pa'],
4257
+ 'tTsd': [abs(self._tTsd), 'Pa'],
4258
+ 'tQsd': [self._tQsd, 'Pa'],
4259
+ 'psd': [self._psd, 'Pa'],
4260
+ 'shsd': [self._shsd, 'Pa'],
4261
+ 'geometry': [self._geometry, ''],
4262
+ 'material factor': [self._mat_factor, ''],
4263
+ 'delta0': [self._delta0, ''],
4264
+ 'fab method ring stf': [self._fab_method_ring_stf, '-'],
4265
+ 'fab method ring girder': [self._fab_method_ring_girder, '-'],
4266
+ 'E-module': [self._E, 'Pa'],
4267
+ 'poisson': [self._v, '-'],
4268
+ 'mat_yield': [self._mat_yield, 'Pa'],
4269
+ 'length between girders': [self._length_between_girders, 'm'],
4270
+ 'panel spacing, s': [self._panel_spacing, 'm'],
4271
+ 'ring stf excluded': [self.__ring_stiffener_excluded, ''],
4272
+ 'ring frame excluded': [self.__ring_frame_excluded, ''],
4273
+ 'end cap pressure': [self._end_cap_pressure_included, ''],
4274
+ 'ULS or ALS':[self._uls_or_als, '']}
4275
+
4276
+ return main_dict
4277
+
4278
+ def set_stresses_and_pressure(self, val):
4279
+ self._sasd = val['sasd']
4280
+ self._smsd = val['smsd']
4281
+ self._tTsd = abs(val['tTsd'])
4282
+ self._tQsd= val['tQsd']
4283
+ self._psd = val['psd']
4284
+ self._shsd = val['shsd']
4285
+
4286
+ def get_x_opt(self):
4287
+ '''
4288
+ shell (0.02, 2.5, 5, 5, 10, nan, nan, nan),
4289
+ long (0.875, nan, 0.3, 0.01, 0.1, 0.01, nan, stiffener_type)),
4290
+ ring (nan, nan, 0.3, 0.01, 0.1, 0.01, nan, stiffener_type)),
4291
+ ring (nan, nan, 0.7, 0.02, 0.2, 0.02, nan, stiffener_type))]
4292
+
4293
+ (self._spacing, self._plate_th, self._web_height, self._web_th, self._flange_width,
4294
+ self._flange_th, self._span, self._girder_lg, self._stiffener_type)
4295
+ '''
4296
+ shell = [self._Shell.thk, self._Shell.radius, self._Shell.dist_between_rings, self._Shell.length_of_shell,
4297
+ self._Shell.tot_cyl_length, np.nan, np.nan, np.nan]
4298
+ if self._LongStf is not None:
4299
+ long = [self._LongStf.spacing/1000, np.nan, self._LongStf.hw/1000, self._LongStf.tw/1000, self._LongStf.b/1000,
4300
+ self._LongStf.tf/1000, np.nan, self._LongStf.stiffener_type]
4301
+ else:
4302
+ long = [0 for dummy in range(8)]
4303
+
4304
+ if self._RingStf is not None:
4305
+ ring_stf = [self._RingStf.s/1000, np.nan, self._RingStf.hw/1000, self._RingStf.tw/1000, self._RingStf.b/1000,
4306
+ self._RingStf.tf/1000, np.nan, self._RingStf.stiffener_type]
4307
+ else:
4308
+ ring_stf = [0 for dummy in range(8)]
4309
+
4310
+ if self._RingFrame is not None:
4311
+ ring_fr = [self._RingFrame.s/1000, np.nan, self._RingFrame.hw/1000, self._RingFrame.tw/1000, self._RingFrame.b/1000,
4312
+ self._RingFrame.tf/1000, np.nan, self._RingFrame.stiffener_type]
4313
+ else:
4314
+ ring_fr = [0 for dummy in range(8)]
4315
+
4316
+ return [shell, long, ring_stf, ring_fr]
4317
+
4318
+ class CalcFatigue(Structure):
4319
+ '''
4320
+ This Class does the calculations for the plate fields.
4321
+ Input is a structure object (getters from the Structure Class)
4322
+ '''
4323
+ def __init__(self, main_dict: dict, fatigue_dict: dict=None):
4324
+ super(CalcFatigue, self).__init__(main_dict, fatigue_dict)
4325
+ if fatigue_dict is not None:
4326
+ self._sn_curve = fatigue_dict['SN-curve']
4327
+ self._acc = fatigue_dict['Accelerations']
4328
+ self._weibull = fatigue_dict['Weibull']
4329
+ self._period = fatigue_dict['Period']
4330
+ self._k_factor = fatigue_dict['SCF']
4331
+ self._corr_loc = fatigue_dict['CorrLoc']
4332
+ self._no_of_cycles = fatigue_dict['n0']
4333
+ self._design_life = fatigue_dict['Design life']
4334
+ self._fraction = fatigue_dict['Fraction']
4335
+ self._case_order = fatigue_dict['Order']
4336
+ try:
4337
+ self._dff = fatigue_dict['DFF']
4338
+ except KeyError:
4339
+ self._dff = 2
4340
+
4341
+ self.fatigue_dict = fatigue_dict
4342
+
4343
+ def get_sn_curve(self):
4344
+ return self._sn_curve
4345
+
4346
+ def __get_sigma_ext(self, int_press):
4347
+ return -0.5*int_press* ((self._spacing / (self._plate_th))**2) * (self._k_factor/1000**2)
4348
+
4349
+ def __get_sigma_int(self, ext_press):
4350
+ return 0.5*ext_press*((self._spacing/(self._plate_th))**2) * (self._k_factor/1000**2)
4351
+
4352
+ def __get_range(self, idx, int_press, ext_press):
4353
+ return 2*math.sqrt(math.pow(self.__get_sigma_ext(ext_press), 2) +
4354
+ math.pow(self.__get_sigma_int(int_press), 2) +
4355
+ 2*self._corr_loc[idx]*self.__get_sigma_ext(ext_press)
4356
+ *self.__get_sigma_int(int_press))
4357
+
4358
+ def __get_stress_fraction(self,idx, int_press, ext_press):
4359
+ return self.__get_range(idx, int_press, ext_press) / \
4360
+ math.pow(math.log(self._no_of_cycles), 1/self._weibull[idx])
4361
+
4362
+ def __get_gamma1(self,idx):
4363
+ return math.exp(gammaln(snc.get_paramter(self._sn_curve,'m1')/self._weibull[idx] + 1))
4364
+
4365
+ def __get_gamma2(self,idx):
4366
+ return math.exp(gammaln(snc.get_paramter(self._sn_curve, 'm2') / self._weibull[idx] + 1))
4367
+
4368
+ def get_damage_slope1(self, idx, curve, int_press=0, ext_press=0):
4369
+ m1, log_a1, k, slope = snc.get_paramter(curve,'m1'), snc.get_paramter(curve,'log a1'),\
4370
+ snc.get_paramter(curve,'k'), snc.get_paramter(curve,'slope')
4371
+ cycles = self._design_life*365*24*3600/self._period[idx]
4372
+ thk_eff = math.log10(max(1,self._plate_th/0.025)) * k
4373
+ slope_ch = math.exp( math.log( math.pow(10, log_a1-m1*thk_eff)/slope) / m1)
4374
+ gamma1 = self.__get_gamma1(idx)
4375
+ weibull = self._weibull[idx]
4376
+ stress_frac = self.__get_stress_fraction(idx, int_press, ext_press)
4377
+ # print('Internal pressure: ', int_press)
4378
+ # print('External pressure: ', ext_press)
4379
+ # finding GAMMADIST
4380
+ if stress_frac == 0:
4381
+ return 0
4382
+
4383
+ x, alpha = math.pow(slope_ch/stress_frac, weibull),1 + m1/weibull
4384
+ gamma_val = gammadist.cdf(x,alpha)
4385
+ return cycles / math.pow(10, log_a1-m1*thk_eff) * math.pow(stress_frac, m1)*gamma1*(1-gamma_val)\
4386
+ *self._fraction[idx]
4387
+
4388
+ def get_damage_slope2(self, idx, curve, int_press, ext_press):
4389
+ m2, log_m2, k, slope = snc.get_paramter(curve,'m2'), snc.get_paramter(curve,'log a2'),\
4390
+ snc.get_paramter(curve,'k'), snc.get_paramter(curve,'slope')
4391
+ cycles = self._design_life*365*24*3600/self._period[idx]
4392
+ thk_eff = math.log10(max(1,self._plate_th/25)) * k
4393
+ slope_ch = math.exp( math.log( math.pow(10, log_m2-m2*thk_eff)/slope) / m2)
4394
+ gammm2 = self.__get_gamma2(idx)
4395
+ weibull = self._weibull[idx]
4396
+ stress_frac = self.__get_stress_fraction(idx, int_press, ext_press)
4397
+
4398
+ # finding GAMMADIST
4399
+ if stress_frac == 0:
4400
+ return 0
4401
+ x, alpha = math.pow(slope_ch/stress_frac, weibull),1 + m2/weibull
4402
+ gamma_val = gammadist.cdf(x,alpha)
4403
+
4404
+ return cycles / math.pow(10, log_m2-m2*thk_eff) * math.pow(stress_frac, m2)*gammm2*(gamma_val)\
4405
+ *self._fraction[idx]
4406
+
4407
+ def get_total_damage(self, int_press=(0, 0, 0), ext_press=(0, 0, 0)):
4408
+ damage = 0
4409
+
4410
+ for idx in range(3):
4411
+ if self._fraction[idx] != 0 and self._period[idx] != 0:
4412
+ damage += self.get_damage_slope1(idx,self._sn_curve, int_press[idx], ext_press[idx]) + \
4413
+ self.get_damage_slope2(idx,self._sn_curve, int_press[idx], ext_press[idx])
4414
+
4415
+ return damage
4416
+
4417
+ def set_commmon_properties(self, fatigue_dict: dict):
4418
+ ''' Setting the fatiuge properties. '''
4419
+ #self._sn_curve, self.fatigue_dict['SN-curve'] = fatigue_dict['SN-curve'], fatigue_dict['SN-curve']
4420
+ self._acc, self.fatigue_dict['Accelerations'] = fatigue_dict['Accelerations'], fatigue_dict['Accelerations']
4421
+ #self._weibull, self.fatigue_dict['Weibull'] = fatigue_dict['Weibull'], fatigue_dict['Weibull']
4422
+ #self._period, self.fatigue_dict['Period'] = fatigue_dict['Period'], fatigue_dict['Period']
4423
+ #self._k_factor, self.fatigue_dict['SCF'] = fatigue_dict['SCF'], fatigue_dict['SCF']
4424
+ #self._corr_loc, self.fatigue_dict['CorrLoc'] = fatigue_dict['CorrLoc'], fatigue_dict['CorrLoc']
4425
+ self._no_of_cycles, self.fatigue_dict['n0'] = fatigue_dict['n0'], fatigue_dict['n0']
4426
+ self._design_life, self.fatigue_dict['Design life'] = fatigue_dict['Design life'], fatigue_dict['Design life']
4427
+ self._fraction, self.fatigue_dict['Fraction'] = fatigue_dict['Fraction'], fatigue_dict['Fraction']
4428
+ #self._case_order, self.fatigue_dict['Order'] = fatigue_dict['Order'], fatigue_dict['Order']
4429
+ self._dff, self.fatigue_dict['DFF'] = fatigue_dict['DFF'], fatigue_dict['DFF']
4430
+
4431
+
4432
+ def set_fatigue_properties(self, fatigue_dict: dict):
4433
+ ''' Setting the fatiuge properties. '''
4434
+ self._sn_curve, self.fatigue_dict['SN-curve'] = fatigue_dict['SN-curve'], fatigue_dict['SN-curve']
4435
+ self._acc, self.fatigue_dict['Accelerations'] = fatigue_dict['Accelerations'], fatigue_dict['Accelerations']
4436
+ self._weibull, self.fatigue_dict['Weibull'] = fatigue_dict['Weibull'], fatigue_dict['Weibull']
4437
+ self._period, self.fatigue_dict['Period'] = fatigue_dict['Period'], fatigue_dict['Period']
4438
+ self._k_factor, self.fatigue_dict['SCF'] = fatigue_dict['SCF'], fatigue_dict['SCF']
4439
+ self._corr_loc, self.fatigue_dict['CorrLoc'] = fatigue_dict['CorrLoc'], fatigue_dict['CorrLoc']
4440
+ self._no_of_cycles, self.fatigue_dict['n0'] = fatigue_dict['n0'], fatigue_dict['n0']
4441
+ self._design_life, self.fatigue_dict['Design life'] = fatigue_dict['Design life'], fatigue_dict['Design life']
4442
+ self._fraction, self.fatigue_dict['Fraction'] = fatigue_dict['Fraction'], fatigue_dict['Fraction']
4443
+ self._case_order, self.fatigue_dict['Order'] = fatigue_dict['Order'], fatigue_dict['Order']
4444
+ self._dff, self.fatigue_dict['DFF'] = fatigue_dict['DFF'], fatigue_dict['DFF']
4445
+
4446
+ def get_fatigue_properties(self):
4447
+ ''' Returning properties as a dictionary '''
4448
+ return self.fatigue_dict
4449
+
4450
+ def get_accelerations(self):
4451
+ ''' Returning tuple of accelerattions.'''
4452
+ return self._acc
4453
+
4454
+ def get_dff(self):
4455
+ return self._dff
4456
+
4457
+ def get_design_life(self):
4458
+ return self._design_life
4459
+
4460
+ class PULSpanel():
4461
+ '''
4462
+ Takes care of puls runs
4463
+ '''
4464
+ def __init__(self, run_dict: dict = {}, puls_acceptance: float = 0.87, puls_sheet_location: str = None):
4465
+ super(PULSpanel, self).__init__()
4466
+
4467
+ self._all_to_run = run_dict
4468
+ self._run_results = {}
4469
+ self._puls_acceptance = puls_acceptance
4470
+ self._puls_sheet_location = puls_sheet_location
4471
+ self._all_uf = {'buckling': list(), 'ultimate': list()}
4472
+
4473
+ @property
4474
+ def all_uf(self):
4475
+ return self._all_uf
4476
+
4477
+ @property
4478
+ def puls_acceptance(self):
4479
+ return self._puls_acceptance
4480
+
4481
+ @puls_acceptance.setter
4482
+ def puls_acceptance(self, val):
4483
+ self._puls_acceptance = val
4484
+
4485
+ @property
4486
+ def puls_sheet_location(self):
4487
+ return self._puls_sheet_location
4488
+
4489
+ @puls_sheet_location.setter
4490
+ def puls_sheet_location(self, val):
4491
+ self._puls_sheet_location = val
4492
+
4493
+ def set_all_to_run(self, val):
4494
+ self._all_to_run = val
4495
+
4496
+ def get_all_to_run(self):
4497
+ return self._all_to_run
4498
+
4499
+ def get_run_results(self):
4500
+ return self._run_results
4501
+
4502
+ def set_run_results(self, val):
4503
+ self._run_results = val
4504
+ for key in self._run_results.keys():
4505
+ if any([key == 'sheet location',type(self._run_results[key]['Buckling strength']) != dict,
4506
+ type(self._run_results[key]['Ultimate capacity']) != dict]):
4507
+ continue
4508
+
4509
+ if all([type(self._run_results[key]['Buckling strength']['Actual usage Factor'][0]) == float,
4510
+ type(self._run_results[key]['Ultimate capacity']['Actual usage Factor'][0]) == float]):
4511
+ self._all_uf['buckling'].append(self._run_results[key]['Buckling strength']['Actual usage Factor'][0])
4512
+ self._all_uf['ultimate'].append(self._run_results[key]['Ultimate capacity']['Actual usage Factor'][0])
4513
+ self._all_uf['buckling'] = np.unique(self._all_uf['buckling']).tolist()
4514
+ self._all_uf['ultimate'] = np.unique(self._all_uf['ultimate']).tolist()
4515
+
4516
+ def run_all(self, store_results = False):
4517
+ '''
4518
+ Returning following results.:
4519
+
4520
+ Identification: name of line/run
4521
+ Plate geometry: dict_keys(['Length of panel', 'Stiffener spacing', 'Plate thick.'])
4522
+ Primary stiffeners: dict_keys(['Number of stiffeners', 'Stiffener type', 'Stiffener boundary', 'Stiff. Height',
4523
+ 'Web thick.', 'Flange width', 'Flange thick.', 'Flange ecc.', 'Tilt angle'])
4524
+ Secondary stiffeners. dict_keys(['Number of sec. stiffeners', 'Secondary stiffener type', 'Stiffener boundary',
4525
+ 'Stiff. Height', 'Web thick.', 'Flange width', 'Flange thick.'])
4526
+ Model imperfections. dict_keys(['Imp. level', 'Plate', 'Stiffener', 'Stiffener tilt'])
4527
+ Material: dict_keys(['Modulus of elasticity', "Poisson's ratio", 'Yield stress plate', 'Yield stress stiffener'])
4528
+ Aluminium prop: dict_keys(['HAZ pattern', 'HAZ red. factor'])
4529
+ Applied loads: dict_keys(['Axial stress', 'Trans. stress', 'Shear stress', 'Pressure (fixed)'])
4530
+ Bound cond.: dict_keys(['In-plane support'])
4531
+ Global elastic buckling: dict_keys(['Axial stress', 'Trans. Stress', 'Trans. stress', 'Shear stress'])
4532
+ Local elastic buckling: dict_keys(['Axial stress', 'Trans. Stress', 'Trans. stress', 'Shear stress'])
4533
+ Ultimate capacity: dict_keys(['Actual usage Factor', 'Allowable usage factor', 'Status'])
4534
+ Failure modes: dict_keys(['Plate buckling', 'Global stiffener buckling', 'Torsional stiffener buckling',
4535
+ 'Web stiffener buckling'])
4536
+ Buckling strength: dict_keys(['Actual usage Factor', 'Allowable usage factor', 'Status'])
4537
+ Local geom req (PULS validity limits): dict_keys(['Plate slenderness', 'Web slend', 'Web flange ratio',
4538
+ 'Flange slend ', 'Aspect ratio'])
4539
+ CSR-Tank requirements (primary stiffeners): dict_keys(['Plating', 'Web', 'Web-flange', 'Flange', 'stiffness'])
4540
+
4541
+ :return:
4542
+ '''
4543
+ import excel_inteface as pulsxl
4544
+
4545
+ iterator = self._all_to_run
4546
+
4547
+ newfile = self._puls_sheet_location
4548
+
4549
+ my_puls = pulsxl.ExcelInterface(newfile, visible=False)
4550
+ #my_puls.set_multiple_rows(20, iterator)
4551
+ run_sp, run_up = my_puls.set_multiple_rows_batch(iterator)
4552
+ my_puls.calculate_panels(sp=run_sp, up=run_up)
4553
+ #all_results = my_puls.get_all_results()
4554
+ all_results = my_puls.get_all_results_batch(sp = run_sp, up=run_up)
4555
+
4556
+ for id, data in all_results.items():
4557
+ self._run_results[id] = data
4558
+
4559
+ my_puls.close_book(save=False)
4560
+
4561
+ self._all_uf = {'buckling': list(), 'ultimate': list()}
4562
+ for key in self._run_results.keys():
4563
+ try:
4564
+ if all([type(self._run_results[key]['Buckling strength']['Actual usage Factor'][0]) == float,
4565
+ type(self._run_results[key]['Ultimate capacity']['Actual usage Factor'][0]) == float]):
4566
+ self._all_uf['buckling'].append(self._run_results[key]['Buckling strength']
4567
+ ['Actual usage Factor'][0])
4568
+ self._all_uf['ultimate'].append(self._run_results[key]['Ultimate capacity']
4569
+ ['Actual usage Factor'][0])
4570
+ except TypeError:
4571
+ print('Got a type error. Life will go on. Key for PULS run results was', key)
4572
+ print(self._run_results[key])
4573
+ self._all_uf['buckling'] = np.unique(self._all_uf['buckling']).tolist()
4574
+ self._all_uf['ultimate'] = np.unique(self._all_uf['ultimate']).tolist()
4575
+ if store_results:
4576
+ store_path = os.path.dirname(os.path.abspath(__file__))+'\\PULS\\Result storage\\'
4577
+ with open(store_path+datetime.datetime.now().strftime("%Y%m%d-%H%M%S")+'_UP.json', 'w') as file:
4578
+ file.write(json.dumps(all_results, ensure_ascii=False))
4579
+ return all_results
4580
+
4581
+ def get_utilization(self, line, method, acceptance = 0.87):
4582
+ if line in self._run_results.keys():
4583
+ if method == 'buckling':
4584
+ if type(self._run_results[line]['Buckling strength']['Actual usage Factor'][0]) == str or \
4585
+ self._run_results[line]['Buckling strength']['Actual usage Factor'][0] is None:
4586
+ return None
4587
+ return self._run_results[line]['Buckling strength']['Actual usage Factor'][0]/acceptance
4588
+ else:
4589
+ if type(self._run_results[line]['Ultimate capacity']['Actual usage Factor'][0]) == str or \
4590
+ self._run_results[line]['Buckling strength']['Actual usage Factor'][0] is None:
4591
+ return None
4592
+ return self._run_results[line]['Ultimate capacity']['Actual usage Factor'][0]/acceptance
4593
+ else:
4594
+ return None
4595
+
4596
+ def get_puls_line_results(self, line):
4597
+ if line not in self._run_results.keys():
4598
+ return None
4599
+ else:
4600
+ return self._run_results[line]
4601
+
4602
+ def get_string(self, line, uf = 0.87):
4603
+ '''
4604
+ :param line:
4605
+ :return:
4606
+ '''
4607
+
4608
+ results = self._run_results[line]
4609
+ loc_geom = 'Ok' if all([val[0] == 'Ok' for val in results['Local geom req (PULS validity limits)']
4610
+ .values()]) else 'Not ok'
4611
+ csr_geom = 'Ok' if all([val[0] == 'Ok' for val in results['CSR-Tank requirements (primary stiffeners)']
4612
+ .values()]) else 'Not ok'
4613
+
4614
+ ret_str = 'PULS results\n\n' +\
4615
+ 'Ultimate capacity usage factor: ' + str(results['Ultimate capacity']['Actual usage Factor'][0]/uf)+'\n'+\
4616
+ 'Buckling strength usage factor: ' + str(results['Buckling strength']['Actual usage Factor'][0]/uf)+'\n'+\
4617
+ 'Local geom req (PULS validity limits): ' + loc_geom + '\n'+\
4618
+ 'CSR-Tank requirements (primary stiffeners): ' + csr_geom
4619
+ return ret_str
4620
+
4621
+ def result_changed(self, id):
4622
+ if id in self._run_results.keys():
4623
+ self._run_results.pop(id)
4624
+
4625
+ def generate_random_results(self, batch_size: int = 1000, stf_type: str = None):
4626
+ '''
4627
+ Genrate random results based on user input.
4628
+ :return:
4629
+ '''
4630
+
4631
+ '''
4632
+ Running iterator:
4633
+ run_dict_one = {'line3': {'Identification': 'line3', 'Length of panel': 4000.0, 'Stiffener spacing': 700.0,
4634
+ 'Plate thickness': 18.0, 'Number of primary stiffeners': 10, 'Stiffener type (L,T,F)': 'T',
4635
+ 'Stiffener boundary': 'C', 'Stiff. Height': 400.0, 'Web thick.': 12.0, 'Flange width': 200.0,
4636
+ 'Flange thick.': 20.0, 'Tilt angle': 0, 'Number of sec. stiffeners': 0,
4637
+ 'Modulus of elasticity': 210000.0, "Poisson's ratio": 0.3, 'Yield stress plate': 355.0,
4638
+ 'Yield stress stiffener': 355.0, 'Axial stress': 101.7, 'Trans. stress 1': 100.0,
4639
+ 'Trans. stress 2': 100.0, 'Shear stress': 5.0, 'Pressure (fixed)': 0.41261,
4640
+ 'In-plane support': 'Int'}}
4641
+ '''
4642
+ run_dict = {}
4643
+
4644
+ profiles = hlp.helper_read_section_file('bulb_anglebar_tbar_flatbar.csv')
4645
+ if stf_type is not None:
4646
+ new_profiles = list()
4647
+ for stf in profiles:
4648
+ if stf['stf_type'][0] == stf_type:
4649
+ new_profiles.append(stf)
4650
+ profiles = new_profiles
4651
+ lengths = np.arange(2000,6000,100)
4652
+ spacings = np.arange(500,900,10)
4653
+ thks = np.arange(10,25,1)
4654
+ axstress =transsress1 = transsress2 = shearstress = np.arange(-200,210,10) #np.concatenate((np.arange(-400,-200,10), np.arange(210,410,10)))
4655
+
4656
+ pressures = np.arange(0,0.45,0.01)
4657
+ now = time.time()
4658
+ yields = np.array([235,265,315,355,355,355,355,390,420,460])
4659
+ for idx in range(batch_size):
4660
+ ''' Adding 'Stiffener type (L,T,F)': self.stf_type, 'Stiffener boundary': 'C',
4661
+ 'Stiff. Height': self.stf_web_height*1000, 'Web thick.': self.stf_web_thk*1000,
4662
+ 'Flange width': self.stf_flange_width*1000, 'Flange thick.': self.stf_flange_thk*1000}'''
4663
+
4664
+ this_id = 'run_' + str(idx) + datetime.datetime.now().strftime("%Y%m%d-%H%M%S")
4665
+ this_stf = random.choice(profiles)
4666
+
4667
+ if random.choice([True, False]):
4668
+ boundary = 'Int'
4669
+ else:
4670
+ boundary = random.choice(['GL', 'GT'])
4671
+ if random.choice([True, True, True, False]):
4672
+ stf_boundary = 'C'
4673
+ else:
4674
+ stf_boundary = 'S'
4675
+ #boundary = 'Int'
4676
+ #stf_boundary = 'C'
4677
+
4678
+
4679
+ yieldstress = np.random.choice(yields)
4680
+ if random.choice([True, True, True, False]):
4681
+ transstress1 = np.random.choice(transsress1) # Using same value for trans1 and trans 2
4682
+ transstress2 = transstress1
4683
+ else:
4684
+ transstress1 = np.random.choice(transsress1)
4685
+ transstress2 = np.random.choice(transsress2)
4686
+
4687
+ # run_dict[this_id] = {'Identification': this_id, 'Length of panel': np.random.choice(lengths),
4688
+ # 'Stiffener spacing': np.random.choice(spacings),
4689
+ # 'Plate thickness': np.random.choice(thks), 'Number of primary stiffeners': 10,
4690
+ # 'Stiffener type (L,T,F)': 'F' if this_stf['stf_type'][0] == 'FB' else this_stf['stf_type'][0],
4691
+ # 'Stiffener boundary': stf_boundary,
4692
+ # 'Stiff. Height': this_stf['stf_web_height'][0]*1000,
4693
+ # 'Web thick.': this_stf['stf_web_thk'][0]*1000,
4694
+ # 'Flange width': 0 if this_stf['stf_type'][0] == 'F'
4695
+ # else this_stf['stf_flange_width'][0]*1000,
4696
+ # 'Flange thick.': 0 if this_stf['stf_type'][0] == 'F'
4697
+ # else this_stf['stf_flange_thk'][0]*1000,
4698
+ # 'Tilt angle': 0, 'Number of sec. stiffeners': 0,
4699
+ # 'Modulus of elasticity': 210000, "Poisson's ratio": 0.3,
4700
+ # 'Yield stress plate':yieldstress, 'Yield stress stiffener': yieldstress,
4701
+ # 'Axial stress': 0 if boundary == 'GT' else np.random.choice(axstress),
4702
+ # 'Trans. stress 1': 0 if boundary == 'GL' else transstress1,
4703
+ # 'Trans. stress 2': 0 if boundary == 'GL' else transstress2,
4704
+ # 'Shear stress': np.random.choice(shearstress),
4705
+ # 'Pressure (fixed)': 0 if stf_boundary == 'S' else np.random.choice(pressures),
4706
+ # 'In-plane support': boundary, 'sp or up': 'SP'}
4707
+
4708
+ same_ax = np.random.choice(axstress)
4709
+ lengths = np.arange(100, 6000, 100)
4710
+ spacings = np.arange(100, 26000, 100)
4711
+ thks = np.arange(10, 50, 1)
4712
+ boundary = random.choice(['GL', 'GT'])
4713
+
4714
+ if np.random.choice([True,False,False,False]):
4715
+ support = ['SS','SS','SS','SS']
4716
+ elif np.random.choice([True,False,False,False]):
4717
+ support = ['CL','CL','CL','CL']
4718
+ else:
4719
+ support = [np.random.choice(['SS', 'CL']),np.random.choice(['SS', 'CL']),
4720
+ np.random.choice(['SS', 'CL']),np.random.choice(['SS', 'CL'])]
4721
+ if np.random.choice([True,False]):
4722
+ press = 0
4723
+ else:
4724
+ press = np.random.choice(pressures)
4725
+ run_dict[this_id] = {'Identification': this_id, 'Length of plate': np.random.choice(lengths),
4726
+ 'Width of c': np.random.choice(spacings),
4727
+ 'Plate thickness': np.random.choice(thks),
4728
+ 'Modulus of elasticity': 210000, "Poisson's ratio": 0.3,
4729
+ 'Yield stress plate':yieldstress,
4730
+ 'Axial stress 1': 0 if boundary == 'GT' else same_ax,
4731
+ 'Axial stress 2': 0 if boundary == 'GT' else same_ax,
4732
+ 'Trans. stress 1': 0 if boundary == 'GL' else transstress1,
4733
+ 'Trans. stress 2': 0 if boundary == 'GL' else transstress2,
4734
+ 'Shear stress': np.random.choice(shearstress), 'Pressure (fixed)': press,
4735
+ 'In-plane support': boundary,
4736
+ 'Rot left': support[0], 'Rot right': support[1],
4737
+ 'Rot upper': support[2], 'Rot lower': support[3],
4738
+ 'sp or up': 'UP'}
4739
+
4740
+ self._all_to_run = run_dict
4741
+ self.run_all(store_results=True)
4742
+ print('Time to run', batch_size, 'batches:', time.time() - now)
4743
+
4744
+ def main():
4745
+ import example_data as ex
4746
+ # PULS = PULSpanel(ex.run_dict, puls_sheet_location=r'C:\Github\ANYstructure\ANYstructure\PULS\PulsExcel_new - Copy (1).xlsm')
4747
+ # PULS.run_all_multi()
4748
+ # PULS = PULSpanel(puls_sheet_location=r'C:\Github\ANYstructure\PULS\PulsExcel_new - generator.xlsm')
4749
+ # for dummy in range(100):
4750
+ # PULS.generate_random_results(batch_size=10000)
4751
+ # import example_data as test
4752
+ # from multiprocessing import Process
4753
+ #
4754
+ # queue = multiprocessing.SimpleQueue()
4755
+ # tasks = ['a', 'b', 'c']
4756
+ # for name in tasks:
4757
+ # p = Process(target=f, args=(name,queue))
4758
+ # p.start()
4759
+ #
4760
+ # for task in tasks:
4761
+ # print(queue.get())
4762
+
4763
+
4764
+ # print('Fatigue test: ')
4765
+ # my_test = CalcFatigue(test.obj_dict, test.fat_obj_dict)
4766
+ # print('Total damage: ',my_test.get_total_damage(int_press=(0,0,0), ext_press=(50000, 60000,0)))
4767
+ # print('')
4768
+ # print('Buckling test: ')
4769
+ #
4770
+ # my_buc = test.get_structure_calc_object()
4771
+ #
4772
+ # #print(my_buc.calculate_buckling_all(design_lat_press=100))
4773
+ # print(my_buc.calculate_slamming_plate(1000000))
4774
+ # print(my_buc.calculate_slamming_stiffener(1000000))
4775
+ # print(my_buc.get_net_effective_plastic_section_modulus())
4776
+
4777
+ #my_test.get_total_damage(int_press=(0, 0, 0), ext_press=(0, 40000, 0))
4778
+
4779
+ for example in [CalcScantlings(ex.obj_dict)]:#, CalcScantlings(ex.obj_dict2), CalcScantlings(ex.obj_dict_L)]:
4780
+
4781
+ my_test = example
4782
+ # my_test = CalcFatigue(example, ex.fat_obj_dict2)
4783
+ # my_test.get_total_damage(int_press=(0, 0, 0), ext_press=(0, 40000, 0))
4784
+ # print('Total damage: ', my_test.get_total_damage(int_press=(0, 0, 0), ext_press=(0, 40000, 0)))
4785
+ # #print(my_test.get_fatigue_properties())
4786
+ # pressure = 200
4787
+ # # print(my_test.buckling_local_stiffener())
4788
+ # # print('SHEAR CENTER: ',my_test.get_shear_center())
4789
+ # # print('SECTION MOD: ',my_test.get_section_modulus())
4790
+ # # print('SECTION MOD FLANGE: ', my_test.get_section_modulus()[0])
4791
+ # # print('SHEAR AREA: ', my_test.get_shear_area())
4792
+ # # print('PLASTIC SECTION MOD: ',my_test.get_plasic_section_modulus())
4793
+ # # print('MOMENT OF INTERTIA: ',my_test.get_moment_of_intertia())
4794
+ # # print('WEIGHT', my_test.get_weight())
4795
+ # # print('PROPERTIES', my_test.get_structure_prop())
4796
+ # # print('CROSS AREA', my_test.get_cross_section_area())
4797
+ # # print()
4798
+ # #
4799
+ # # print('EFFICIENT MOMENT OF INTERTIA: ',my_test.get_moment_of_intertia(efficent_se=my_test.get_plate_efficent_b(
4800
+ # # design_lat_press=pressure)))
4801
+ # # print('Se: ',my_test.calculate_buckling_all(design_lat_press=pressure,checked_side='s'))
4802
+ # # print('Se: ', my_test.calculate_buckling_all(design_lat_press=pressure, checked_side='p'))
4803
+ # # print('MINIMUM PLATE THICKNESS',my_test.get_dnv_min_thickness(pressure))
4804
+ # # print('MINIMUM SECTION MOD.', my_test.get_dnv_min_section_modulus(pressure))
4805
+ # print()
4806
+ # #my_test.cyl_buckling_long_sft_shell()
4807
+ #
4808
+ #
4809
+ #Structure(ex.obj_dict_cyl_ring)
4810
+ #Structure(ex.obj_dict_cyl_heavy_ring)
4811
+ # my_cyl = CylinderAndCurvedPlate(main_dict = ex.shell_main_dict2, shell= Shell(ex.shell_dict),
4812
+ # long_stf= None,#Structure(ex.obj_dict_cyl_long2),
4813
+ # ring_stf = Structure(ex.obj_dict_cyl_ring2),
4814
+ # ring_frame= None)#Structure(ex.obj_dict_cyl_heavy_ring2))
4815
+ # print(my_cyl.get_utilization_factors())
4816
+
4817
+ # Prescriptive buckling UPDATED
4818
+ Plate = CalcScantlings(ex.obj_dict)
4819
+ Stiffener = CalcScantlings(ex.obj_dict)
4820
+ Girder = CalcScantlings(ex.obj_dict_heavy)
4821
+ PreBuc = AllStructure(Plate = Plate, Stiffener = Stiffener, Girder = Girder,
4822
+ main_dict=ex.prescriptive_main_dict)
4823
+
4824
+
4825
+ print(PreBuc)
4826
+
4827
+ cylinder = CylinderAndCurvedPlate()
4828
+ #print(Girder)
4829
+ #PreBuc.lat_press = 0.412197
4830
+ #print(Plate)
4831
+ # print(Plate)
4832
+ #print(Stiffener)
4833
+ # print(Girder)
4834
+ #print(PreBuc.get_main_properties())
4835
+ #print(PreBuc.plate_buckling())
4836
+
4837
+ if __name__ == '__main__':
4838
+ main()