squid_n_core/section_shape/
composite.rs1use super::constants::{E_STEEL, KAPPA_RC, NU_CONCRETE, NU_STEEL};
8use super::geometry::{h_web_shear_area, rect_torsion_j};
9use super::material::concrete_young_modulus;
10use super::types::SectionShape;
11
12#[derive(Clone, Copy, Debug, PartialEq)]
17pub struct CompositeProps {
18 pub area_ax: f64,
20 pub iy: f64,
21 pub iz: f64,
22 pub j: f64,
23 pub as_y: f64,
24 pub as_z: f64,
25}
26
27impl SectionShape {
28 pub fn src_equivalent_props(&self, ec: f64, nu_c: f64) -> Option<CompositeProps> {
37 let SectionShape::SrcRect {
38 b,
39 d,
40 steel_height: sh,
41 steel_width: sw,
42 steel_web_thick: tw,
43 steel_flange_thick: tf,
44 ..
45 } = *self
46 else {
47 return None;
48 };
49 if ec <= 0.0 {
50 return None;
51 }
52 let ns = E_STEEL / ec;
53 let ngs = ns * (1.0 + nu_c) / (1.0 + NU_STEEL);
54
55 let s_a = 2.0 * sw * tf + (sh - 2.0 * tf) * tw;
56 let hw = sh - 2.0 * tf;
57 let s_iy = (sw * sh.powi(3) - (sw - tw) * hw.powi(3)) / 12.0;
58 let s_iz = (2.0 * tf * sw.powi(3) + hw * tw.powi(3)) / 12.0;
59 let s_j = (2.0 * sw * tf.powi(3) + hw * tw.powi(3)) / 3.0;
60
61 let rc_as = b * d / KAPPA_RC;
62 Some(CompositeProps {
63 area_ax: b * d + (ns - 1.0) * s_a,
64 iy: b * d.powi(3) / 12.0 + (ns - 1.0) * s_iy,
65 iz: d * b.powi(3) / 12.0 + (ns - 1.0) * s_iz,
66 j: rect_torsion_j(b, d) + ngs * s_j,
67 as_y: rc_as + (ngs - 1.0) * 2.0 * sw * tf,
68 as_z: rc_as + (ngs - 1.0) * h_web_shear_area(sh, tw),
69 })
70 }
71
72 pub fn cft_equivalent_props(&self, es: f64, nu_s: f64, fc: f64) -> Option<CompositeProps> {
82 let ec = concrete_young_modulus(fc);
83 if ec <= 0.0 || es <= 0.0 {
84 return None;
85 }
86 let core = self.cft_core_props()?;
87 if core.area <= 0.0 {
90 return None;
91 }
92 let n = es / ec;
93 let ngs = n * (1.0 + NU_CONCRETE) / (1.0 + nu_s);
94 let (s_as_y, s_as_z) = match *self {
97 SectionShape::CftBox { thick: t, .. } => {
98 (2.0 * t * core.inner_width, 2.0 * t * core.inner_height)
99 }
100 SectionShape::CftPipe { .. } => {
101 let a = self.calc_area() / 2.0;
102 (a, a)
103 }
104 _ => unreachable!("cft_core_props が Some を返した非 CFT 断面"),
106 };
107 Some(CompositeProps {
108 area_ax: self.calc_area() + core.area / n,
109 iy: self.calc_iy() + core.iy / n,
110 iz: self.calc_iz() + core.iz / n,
111 j: self.calc_j() + core.j / ngs,
112 as_y: s_as_y + core.area / KAPPA_RC / ngs,
113 as_z: s_as_z + core.area / KAPPA_RC / ngs,
114 })
115 }
116}
117
118#[derive(Clone, Copy, Debug, PartialEq)]
124pub struct CftCoreProps {
125 pub inner_width: f64,
127 pub inner_height: f64,
129 pub area: f64,
131 pub iy: f64,
133 pub iz: f64,
135 pub j: f64,
137}
138
139impl SectionShape {
140 pub fn cft_core_props(&self) -> Option<CftCoreProps> {
148 match *self {
149 SectionShape::CftBox {
150 height: h,
151 width: w,
152 thick: t,
153 } => {
154 let bi = (w - 2.0 * t).max(0.0);
155 let hi = (h - 2.0 * t).max(0.0);
156 Some(CftCoreProps {
157 inner_width: bi,
158 inner_height: hi,
159 area: bi * hi,
160 iy: bi * hi.powi(3) / 12.0,
161 iz: hi * bi.powi(3) / 12.0,
162 j: rect_torsion_j(bi, hi),
163 })
164 }
165 SectionShape::CftPipe { outer_dia, thick } => {
166 let di = (outer_dia - 2.0 * thick).max(0.0);
167 let i = std::f64::consts::PI * di.powi(4) / 64.0;
168 Some(CftCoreProps {
169 inner_width: di,
170 inner_height: di,
171 area: std::f64::consts::PI * di * di / 4.0,
172 iy: i,
173 iz: i,
174 j: std::f64::consts::PI * di.powi(4) / 32.0,
176 })
177 }
178 _ => None,
179 }
180 }
181}