Skip to main content

squid_n_core/section_shape/
composite.rs

1//! SRC/CFT の複合換算断面性能。
2//!
3//! - [`CompositeProps`] — 複合換算後の断面性能
4//! - [`SectionShape::src_equivalent_props`] — SRC の等価断面性能
5//! - [`SectionShape::cft_equivalent_props`] — CFT の等価断面性能
6
7use 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/// SRC/CFT の複合換算断面性能(要素剛性用。各種合成構造設計指針)。
13///
14/// いずれも要素に割り当てた材料(SRC はコンクリート、CFT は鋼管)を基準とした
15/// 等価値。質量算定用の断面積(`calc_area`)とは区別して用いること。
16#[derive(Clone, Copy, Debug, PartialEq)]
17pub struct CompositeProps {
18    /// 軸剛性用断面積 [mm²]
19    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    /// SRC 断面の等価断面性能を、実際のヤング係数比 ns=Es/Ec から算定する
29    /// (各種合成構造設計指針: An=rcAn+sAn·(ns−1)、Ie=rcIe+sIe·(ns−1)、
30    /// As=rcAs+sAs·(ngs−1)、J=cJ+(sG/cG)·sJ)。
31    ///
32    /// `ec`/`nu_c`: 要素材料(コンクリート)のヤング係数・ポアソン比。
33    /// 鉄骨は Es=`E_STEEL`・νs=0.3 とする。ngs=ns·(1+νc)/(1+νs)。
34    /// SrcRect 以外、または ec≤0 では None(呼び出し側は `to_section` の
35    /// 既定値=N_S_EQ 固定へフォールバックする)。
36    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    /// CFT 断面(CftBox/CftPipe)の等価断面性能を鋼管基準で算定する
73    /// (各種合成構造設計指針: SRC 柱に準じる累加(CFT もこれに準じる)を鋼基準の
74    /// 1/n 換算で適用。J は S 柱の J=(sG/cG)·sJ+cJ を鋼基準 J=sJ+cJ/ngs に換算)。
75    ///
76    /// `es`/`nu_s`: 要素材料(鋼管)のヤング係数・ポアソン比、
77    /// `fc`: 充填コンクリート強度(`Material.fc`)。
78    /// Ec は `concrete_young_modulus`(γ=23)・νc=0.2 とする。
79    /// CftBox/CftPipe 以外、または Ec≤0 では None(鋼管のみの既定値へ
80    /// フォールバック)。
81    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        // 内法が消える(板厚が過大な)断面は充填コンクリートを累加できないため、
88        // 鋼管のみの既定値へフォールバックする。
89        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        // 鋼管のせん断有効断面積: 角形は加力方向に平行な 2 枚の板、
95        // 円形は全断面の 1/2(薄肉円管の慣用)。
96        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            // `cft_core_props` が Some を返すのは CFT 断面のみ。
105            _ => 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/// CFT 断面の**充填コンクリート部分**(鋼管の内法で囲まれる部分)の諸元。
119///
120/// 剛性側([`SectionShape::cft_equivalent_props`]。等価断面性能の累加)と
121/// 耐力側(`squid-n-design-jp` の CFT 軸終局検定)が同じ値を使うために切り出す。
122/// 片方だけ式を直せば静かに食い違うため、算定はここ 1 か所に置く。
123#[derive(Clone, Copy, Debug, PartialEq)]
124pub struct CftCoreProps {
125    /// 内法幅 [mm](角形は `幅 − 2t`、円形は内法径 `外径 − 2t`)。
126    pub inner_width: f64,
127    /// 内法せい [mm](角形は `せい − 2t`、円形は内法径)。
128    pub inner_height: f64,
129    /// 充填コンクリートの断面積 [mm²]。
130    pub area: f64,
131    /// 強軸(せい方向まわり)の断面二次モーメント [mm⁴]。
132    pub iy: f64,
133    /// 弱軸(幅方向まわり)の断面二次モーメント [mm⁴]。円形は `iy` と同値。
134    pub iz: f64,
135    /// St.Venant ねじり定数 [mm⁴]。
136    pub j: f64,
137}
138
139impl SectionShape {
140    /// CFT 断面(`CftBox`/`CftPipe`)の充填コンクリート部分の諸元。
141    /// CFT 以外の形状は `None`。
142    ///
143    /// 内法寸法は 0 で下限クランプするため、板厚が過大で内法が消える断面では
144    /// `area` が 0 になる(=充填コンクリートが効かない)。呼び出し側が
145    /// 「鋼管のみへフォールバックする」か「充填ゼロのまま続行する」かを選べるよう、
146    /// ここでは `None` にせず 0 を返す。
147    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                    // 中実円のねじり定数は極断面二次モーメント Ip = 2·I。
175                    j: std::f64::consts::PI * di.powi(4) / 32.0,
176                })
177            }
178            _ => None,
179        }
180    }
181}