1use super::constants::N_S_EQ;
4use super::geometry::{
5 angle_centroid, built_h_centroid_y, lip_channel_centroid_z, plastic_modulus_strips,
6 rect_torsion_j, tee_centroid,
7};
8use super::types::SectionShape;
9
10impl SectionShape {
11 pub fn calc_area(&self) -> f64 {
13 match *self {
14 SectionShape::SteelH {
15 height,
16 width,
17 web_thick,
18 flange_thick,
19 } => 2.0 * width * flange_thick + (height - 2.0 * flange_thick) * web_thick,
20 SectionShape::SteelBox {
21 height,
22 width,
23 thick,
24 ..
25 } => width * height - (width - 2.0 * thick) * (height - 2.0 * thick),
26 SectionShape::SteelAngle {
27 leg_a,
28 leg_b,
29 thick,
30 } => thick * (leg_a + leg_b - thick),
31 SectionShape::SteelChannel {
32 height,
33 width,
34 web_thick,
35 flange_thick,
36 } => 2.0 * width * flange_thick + (height - 2.0 * flange_thick) * web_thick,
37 SectionShape::SteelTee {
38 height,
39 width,
40 web_thick,
41 flange_thick,
42 } => width * flange_thick + (height - flange_thick) * web_thick,
43 SectionShape::SteelPipe { outer_dia, thick } => {
44 let r = outer_dia / 2.0;
45 let ri = r - thick;
46 std::f64::consts::PI * (r * r - ri * ri)
47 }
48 SectionShape::SteelFlatBar { width, thick } => width * thick,
49 SectionShape::SteelRoundBar { dia } => std::f64::consts::PI * dia * dia / 4.0,
50 SectionShape::SteelLipChannel {
51 height,
52 width,
53 lip,
54 thick,
55 } => {
56 let (_, area) = lip_channel_centroid_z(height, width, lip, thick);
57 area
58 }
59 SectionShape::SteelBuiltH {
60 height,
61 upper_width,
62 upper_thick,
63 lower_width,
64 lower_thick,
65 web_thick,
66 } => {
67 let (_, area) = built_h_centroid_y(
68 height,
69 upper_width,
70 upper_thick,
71 lower_width,
72 lower_thick,
73 web_thick,
74 );
75 area
76 }
77 SectionShape::RcRect { b, d, .. } => b * d,
78 SectionShape::RcCircle { d, .. } => std::f64::consts::PI * d * d / 4.0,
79 SectionShape::SrcRect { b, d, .. } => b * d,
81 SectionShape::CftBox {
82 height,
83 width,
84 thick,
85 } => width * height - (width - 2.0 * thick) * (height - 2.0 * thick),
86 SectionShape::CftPipe { outer_dia, thick } => {
87 let r = outer_dia / 2.0;
88 let ri = r - thick;
89 std::f64::consts::PI * (r * r - ri * ri)
90 }
91 SectionShape::RcWall { thickness, .. } | SectionShape::RcSlab { thickness } => {
93 thickness * 1000.0
94 }
95 }
96 }
97
98 pub fn plastic_modulus_strong(&self) -> Option<f64> {
107 match *self {
108 SectionShape::SteelH {
109 height,
110 width,
111 web_thick,
112 flange_thick,
113 } => Some(
114 width * flange_thick * (height - flange_thick)
115 + web_thick * (height - 2.0 * flange_thick).powi(2) / 4.0,
116 ),
117 SectionShape::SteelBox {
118 height,
119 width,
120 thick,
121 ..
122 } => Some(
123 width * height * height / 4.0
124 - (width - 2.0 * thick) * (height - 2.0 * thick).powi(2) / 4.0,
125 ),
126 SectionShape::SteelPipe { outer_dia, thick } => {
127 Some((outer_dia.powi(3) - (outer_dia - 2.0 * thick).powi(3)) / 6.0)
128 }
129 SectionShape::SteelRoundBar { dia } => Some(dia.powi(3) / 6.0),
131 SectionShape::SteelFlatBar { width, thick } => Some(width * thick * thick / 4.0),
133 SectionShape::SteelChannel {
135 height,
136 width,
137 web_thick,
138 flange_thick,
139 } => Some(plastic_modulus_strips(&[
140 (0.0, flange_thick, width),
141 (flange_thick, height - flange_thick, web_thick),
142 (height - flange_thick, height, width),
143 ])),
144 SectionShape::SteelTee {
146 height,
147 width,
148 web_thick,
149 flange_thick,
150 } => Some(plastic_modulus_strips(&[
151 (0.0, height - flange_thick, web_thick),
152 (height - flange_thick, height, width),
153 ])),
154 SectionShape::SteelBuiltH {
156 height,
157 upper_width,
158 upper_thick,
159 lower_width,
160 lower_thick,
161 web_thick,
162 } => Some(plastic_modulus_strips(&[
163 (0.0, lower_thick, lower_width),
164 (lower_thick, height - upper_thick, web_thick),
165 (height - upper_thick, height, upper_width),
166 ])),
167 SectionShape::SteelLipChannel {
170 height,
171 width,
172 lip,
173 thick,
174 } => Some(plastic_modulus_strips(&[
175 (0.0, height, thick),
176 (0.0, thick, width - thick),
177 (height - thick, height, width - thick),
178 (thick, lip, thick),
179 (height - lip, height - thick, thick),
180 ])),
181 SectionShape::SteelAngle {
184 leg_a,
185 leg_b,
186 thick,
187 } => Some(plastic_modulus_strips(&[
188 (0.0, leg_a, thick),
189 (0.0, thick, leg_b - thick),
190 ])),
191 _ => None,
192 }
193 }
194
195 pub fn calc_iy(&self) -> f64 {
197 match *self {
198 SectionShape::SteelH {
199 height,
200 width,
201 web_thick,
202 flange_thick,
203 } => {
204 let hw = height - 2.0 * flange_thick;
205 (width * height.powi(3) - (width - web_thick) * hw.powi(3)) / 12.0
206 }
207 SectionShape::SteelBox {
208 height,
209 width,
210 thick,
211 ..
212 } => {
213 let hi = height - 2.0 * thick;
214 (width * height.powi(3) - (width - 2.0 * thick) * hi.powi(3)) / 12.0
215 }
216 SectionShape::SteelAngle {
217 leg_a,
218 leg_b,
219 thick,
220 } => {
221 let (_, cy, _) = angle_centroid(leg_a, leg_b, thick);
222 let a1 = leg_a * thick;
223 let y1 = leg_a / 2.0;
224 let a2 = (leg_b - thick) * thick;
225 let y2 = thick / 2.0;
226 let i1 = thick * leg_a.powi(3) / 12.0;
227 let i2 = (leg_b - thick) * thick.powi(3) / 12.0;
228 (i1 + a1 * (y1 - cy).powi(2)) + (i2 + a2 * (y2 - cy).powi(2))
229 }
230 SectionShape::SteelChannel {
231 height,
232 width,
233 web_thick,
234 flange_thick,
235 } => {
236 let hw = height - 2.0 * flange_thick;
237 (width * height.powi(3) - (width - web_thick) * hw.powi(3)) / 12.0
238 }
239 SectionShape::SteelTee {
240 height,
241 width,
242 web_thick,
243 flange_thick,
244 } => {
245 let y_bar = tee_centroid(height, width, web_thick, flange_thick);
246 let a_f = width * flange_thick;
247 let a_w = (height - flange_thick) * web_thick;
248 let i_f = width * flange_thick.powi(3) / 12.0
249 + a_f * (height - flange_thick / 2.0 - y_bar).powi(2);
250 let i_w = web_thick * (height - flange_thick).powi(3) / 12.0
251 + a_w * ((height - flange_thick) / 2.0 - y_bar).powi(2);
252 i_f + i_w
253 }
254 SectionShape::SteelPipe { outer_dia, thick } => {
255 let r = outer_dia / 2.0;
256 let ri = r - thick;
257 std::f64::consts::PI / 4.0 * (r.powi(4) - ri.powi(4))
258 }
259 SectionShape::SteelFlatBar { width, thick } => width * thick.powi(3) / 12.0,
261 SectionShape::SteelRoundBar { dia } => std::f64::consts::PI * dia.powi(4) / 64.0,
262 SectionShape::SteelLipChannel {
264 height,
265 width,
266 lip,
267 thick,
268 } => {
269 let t = thick;
270 let i_web = t * height.powi(3) / 12.0;
272 let a_f = (width - t) * t;
274 let off_f = (height - t) / 2.0;
275 let i_f = (width - t) * t.powi(3) / 12.0 + a_f * off_f.powi(2);
276 let a_l = t * (lip - t);
278 let off_l = (height - lip - t) / 2.0;
279 let i_l = t * (lip - t).powi(3) / 12.0 + a_l * off_l.powi(2);
280 i_web + 2.0 * i_f + 2.0 * i_l
281 }
282 SectionShape::SteelBuiltH {
284 height,
285 upper_width,
286 upper_thick,
287 lower_width,
288 lower_thick,
289 web_thick,
290 } => {
291 let (y_bar, _) = built_h_centroid_y(
292 height,
293 upper_width,
294 upper_thick,
295 lower_width,
296 lower_thick,
297 web_thick,
298 );
299 let hw = (height - upper_thick - lower_thick).max(0.0);
300 let a_uf = upper_width * upper_thick;
301 let y_uf = height - upper_thick / 2.0;
302 let i_uf = upper_width * upper_thick.powi(3) / 12.0 + a_uf * (y_uf - y_bar).powi(2);
303 let a_lf = lower_width * lower_thick;
304 let y_lf = lower_thick / 2.0;
305 let i_lf = lower_width * lower_thick.powi(3) / 12.0 + a_lf * (y_lf - y_bar).powi(2);
306 let a_w = web_thick * hw;
307 let y_w = lower_thick + hw / 2.0;
308 let i_w = web_thick * hw.powi(3) / 12.0 + a_w * (y_w - y_bar).powi(2);
309 i_uf + i_lf + i_w
310 }
311 SectionShape::RcRect { b, d, .. } => b * d.powi(3) / 12.0,
312 SectionShape::RcCircle { d, .. } => std::f64::consts::PI * d.powi(4) / 64.0,
313 SectionShape::SrcRect {
314 b,
315 d,
316 steel_height,
317 steel_width,
318 steel_web_thick,
319 steel_flange_thick,
320 ..
321 } => {
322 let i_c = b * d.powi(3) / 12.0;
323 let hw = steel_height - 2.0 * steel_flange_thick;
324 let i_s = (steel_width * steel_height.powi(3)
325 - (steel_width - steel_web_thick) * hw.powi(3))
326 / 12.0;
327 i_c + (N_S_EQ - 1.0) * i_s
328 }
329 SectionShape::CftBox {
330 height,
331 width,
332 thick,
333 } => {
334 let hi = height - 2.0 * thick;
335 (width * height.powi(3) - (width - 2.0 * thick) * hi.powi(3)) / 12.0
336 }
337 SectionShape::CftPipe { outer_dia, thick } => {
338 let r = outer_dia / 2.0;
339 let ri = r - thick;
340 std::f64::consts::PI / 4.0 * (r.powi(4) - ri.powi(4))
341 }
342 SectionShape::RcWall { thickness, .. } | SectionShape::RcSlab { thickness } => {
343 1000.0 * thickness.powi(3) / 12.0
344 }
345 }
346 }
347
348 pub fn calc_iz(&self) -> f64 {
350 match *self {
351 SectionShape::SteelH {
352 height,
353 width,
354 web_thick,
355 flange_thick,
356 } => {
357 let hw = height - 2.0 * flange_thick;
358 (2.0 * flange_thick * width.powi(3) + hw * web_thick.powi(3)) / 12.0
359 }
360 SectionShape::SteelBox {
361 height,
362 width,
363 thick,
364 ..
365 } => {
366 let wi = width - 2.0 * thick;
367 (height * width.powi(3) - (height - 2.0 * thick) * wi.powi(3)) / 12.0
368 }
369 SectionShape::SteelAngle {
370 leg_a,
371 leg_b,
372 thick,
373 } => {
374 let (cx, _, _) = angle_centroid(leg_a, leg_b, thick);
375 let a1 = leg_a * thick;
376 let z1 = thick / 2.0;
377 let a2 = (leg_b - thick) * thick;
378 let z2 = thick + (leg_b - thick) / 2.0;
379 let i1 = leg_a * thick.powi(3) / 12.0;
380 let i2 = thick * (leg_b - thick).powi(3) / 12.0;
381 (i1 + a1 * (z1 - cx).powi(2)) + (i2 + a2 * (z2 - cx).powi(2))
382 }
383 SectionShape::SteelChannel {
384 height,
385 width,
386 web_thick,
387 flange_thick,
388 } => {
389 let hw = height - 2.0 * flange_thick;
390 let a_f = width * flange_thick;
391 let a_w = hw * web_thick;
392 let a_total = 2.0 * a_f + a_w;
393 let z_bar = if a_total > 0.0 {
394 (2.0 * a_f * width / 2.0 + a_w * web_thick / 2.0) / a_total
395 } else {
396 0.0
397 };
398 let i_f = flange_thick * width.powi(3) / 12.0 + a_f * (width / 2.0 - z_bar).powi(2);
400 let i_w = hw * web_thick.powi(3) / 12.0 + a_w * (web_thick / 2.0 - z_bar).powi(2);
401 2.0 * i_f + i_w
402 }
403 SectionShape::SteelTee {
404 height,
405 width,
406 web_thick,
407 flange_thick,
408 } => {
409 let iz = flange_thick * width.powi(3) / 12.0;
410 let iz_w = (height - flange_thick) * web_thick.powi(3) / 12.0;
411 iz + iz_w
412 }
413 SectionShape::SteelPipe { .. } => self.calc_iy(),
414 SectionShape::SteelFlatBar { width, thick } => thick * width.powi(3) / 12.0,
416 SectionShape::SteelRoundBar { .. } => self.calc_iy(),
417 SectionShape::SteelLipChannel {
419 height,
420 width,
421 lip,
422 thick,
423 } => {
424 let t = thick;
425 let (z_bar, _) = lip_channel_centroid_z(height, width, lip, thick);
426 let a_web = t * height;
428 let i_web = height * t.powi(3) / 12.0 + a_web * (t / 2.0 - z_bar).powi(2);
429 let a_f = (width - t) * t;
431 let z_f = (t + width) / 2.0;
432 let i_f = t * (width - t).powi(3) / 12.0 + a_f * (z_f - z_bar).powi(2);
433 let a_l = t * (lip - t);
435 let z_l = width - t / 2.0;
436 let i_l = (lip - t) * t.powi(3) / 12.0 + a_l * (z_l - z_bar).powi(2);
437 i_web + 2.0 * i_f + 2.0 * i_l
438 }
439 SectionShape::SteelBuiltH {
441 height,
442 upper_width,
443 upper_thick,
444 lower_width,
445 lower_thick,
446 web_thick,
447 } => {
448 let hw = (height - upper_thick - lower_thick).max(0.0);
449 upper_thick * upper_width.powi(3) / 12.0
450 + lower_thick * lower_width.powi(3) / 12.0
451 + hw * web_thick.powi(3) / 12.0
452 }
453 SectionShape::RcRect { b, d, .. } => d * b.powi(3) / 12.0,
454 SectionShape::RcCircle { .. } => self.calc_iy(),
455 SectionShape::SrcRect {
456 b,
457 d,
458 steel_height,
459 steel_width,
460 steel_web_thick,
461 steel_flange_thick,
462 ..
463 } => {
464 let i_c = d * b.powi(3) / 12.0;
465 let hw = steel_height - 2.0 * steel_flange_thick;
466 let i_s = (2.0 * steel_flange_thick * steel_width.powi(3)
467 + hw * steel_web_thick.powi(3))
468 / 12.0;
469 i_c + (N_S_EQ - 1.0) * i_s
470 }
471 SectionShape::CftBox {
472 height,
473 width,
474 thick,
475 } => {
476 let wi = width - 2.0 * thick;
477 (height * width.powi(3) - (height - 2.0 * thick) * wi.powi(3)) / 12.0
478 }
479 SectionShape::CftPipe { .. } => self.calc_iy(),
480 SectionShape::RcWall { .. } | SectionShape::RcSlab { .. } => self.calc_iy(),
482 }
483 }
484
485 pub fn calc_j(&self) -> f64 {
487 match *self {
488 SectionShape::SteelH {
489 height,
490 width,
491 web_thick,
492 flange_thick,
493 } => {
494 (2.0 * width * flange_thick.powi(3)
495 + (height - 2.0 * flange_thick) * web_thick.powi(3))
496 / 3.0
497 }
498 SectionShape::SteelBox {
499 height,
500 width,
501 thick,
502 ..
503 } => {
504 let a0 = (height - thick) * (width - thick);
505 let perim = 2.0 * (height + width - 2.0 * thick);
506 4.0 * a0 * a0 * thick / perim
507 }
508 SectionShape::SteelAngle {
509 leg_a,
510 leg_b,
511 thick,
512 } => ((leg_a + leg_b - thick) * thick.powi(3)) / 3.0,
513 SectionShape::SteelChannel {
514 height,
515 width,
516 web_thick,
517 flange_thick,
518 } => {
519 (2.0 * width * flange_thick.powi(3)
520 + (height - 2.0 * flange_thick) * web_thick.powi(3))
521 / 3.0
522 }
523 SectionShape::SteelTee {
524 height,
525 width,
526 web_thick,
527 flange_thick,
528 } => (width * flange_thick.powi(3) + (height - flange_thick) * web_thick.powi(3)) / 3.0,
529 SectionShape::SteelPipe { outer_dia, thick } => {
530 let r = outer_dia / 2.0;
531 let ri = r - thick;
532 std::f64::consts::PI / 2.0 * (r.powi(4) - ri.powi(4))
533 }
534 SectionShape::SteelFlatBar { width, thick } => rect_torsion_j(width, thick),
536 SectionShape::SteelRoundBar { dia } => std::f64::consts::PI * dia.powi(4) / 32.0,
537 SectionShape::SteelLipChannel {
539 height,
540 width,
541 lip,
542 thick,
543 } => {
544 let len = height + 2.0 * (width - thick) + 2.0 * (lip - thick);
545 len * thick.powi(3) / 3.0
546 }
547 SectionShape::SteelBuiltH {
549 height,
550 upper_width,
551 upper_thick,
552 lower_width,
553 lower_thick,
554 web_thick,
555 } => {
556 let hw = (height - upper_thick - lower_thick).max(0.0);
557 (upper_width * upper_thick.powi(3)
558 + lower_width * lower_thick.powi(3)
559 + hw * web_thick.powi(3))
560 / 3.0
561 }
562 SectionShape::RcRect { b, d, .. } => rect_torsion_j(b, d),
563 SectionShape::RcCircle { d, .. } => std::f64::consts::PI * d.powi(4) / 32.0,
564 SectionShape::SrcRect { b, d, .. } => rect_torsion_j(b, d),
567 SectionShape::CftBox {
568 height,
569 width,
570 thick,
571 } => {
572 let a0 = (height - thick) * (width - thick);
573 let perim = 2.0 * (height + width - 2.0 * thick);
574 4.0 * a0 * a0 * thick / perim
575 }
576 SectionShape::CftPipe { outer_dia, thick } => {
577 let r = outer_dia / 2.0;
578 let ri = r - thick;
579 std::f64::consts::PI / 2.0 * (r.powi(4) - ri.powi(4))
580 }
581 SectionShape::RcWall { thickness, .. } | SectionShape::RcSlab { thickness } => {
582 1000.0 * thickness.powi(3) / 3.0
583 }
584 }
585 }
586
587 pub fn calc_axial_stiffness_area(&self) -> f64 {
594 match *self {
595 SectionShape::SrcRect {
596 b,
597 d,
598 steel_height,
599 steel_width,
600 steel_web_thick,
601 steel_flange_thick,
602 ..
603 } => {
604 let s_a = 2.0 * steel_width * steel_flange_thick
605 + (steel_height - 2.0 * steel_flange_thick) * steel_web_thick;
606 b * d + (N_S_EQ - 1.0) * s_a
607 }
608 _ => self.calc_area(),
609 }
610 }
611}