Skip to main content

squid_n_core/
rc_rebar_geom.rs

1//! RC 配筋幾何の共通算定(断面検定・非線形解析・終局検定・MN/ファイバ配置の単一情報源)。
2//!
3//! - [`rebar_layer_clear`] — 段間あき k'
4//! - [`rebar_layer_spacing`] — 段の中心間距離 s
5//! - [`rebar_layer_depth_from_edge`] — 縁 → 第 n 段中心までの距離
6//! - [`tension_dt`] — 引張縁 → 引張筋重心までの距離 dt
7//! - [`rebar_tension_dt`] — せい方向主筋(`main_x`)の dt
8//! - [`tension_effective_depth`] — 有効せい d_eff = D − dt
9//! - [`pw_ratio`] — せん断補強筋比 pw
10
11use crate::section_shape::{BarSet, RcRebar, ShearBar};
12
13/// 多段配筋の段間あき k' [mm](RC 配筋指針: `max(25, 1.5・dia)`)。
14pub fn rebar_layer_clear(main: &BarSet) -> f64 {
15    25.0_f64.max(1.5 * main.dia)
16}
17
18/// 多段配筋の段中心間距離 s = dia + k' [mm]。
19pub fn rebar_layer_spacing(main: &BarSet) -> f64 {
20    main.dia + rebar_layer_clear(main)
21}
22
23/// 縁から第 `layer` 段(0 始まり)の主筋中心までの距離 [mm]。
24///
25/// 1 段目(layer=0)は k1 = cover + shear.dia + main.dia/2。
26/// 2 段目以降は中心間距離 [`rebar_layer_spacing`] だけ内側へ進む。
27/// MN 曲面・非線形ファイバの主筋点配置と、検定用 [`tension_dt`] が同じ座標規約を使う。
28pub fn rebar_layer_depth_from_edge(cover: f64, shear_dia: f64, main: &BarSet, layer: u32) -> f64 {
29    let k1 = cover + shear_dia + main.dia / 2.0;
30    if layer == 0 {
31        return k1;
32    }
33    k1 + layer as f64 * rebar_layer_spacing(main)
34}
35
36/// 引張縁 → 引張筋重心までの距離 dt [mm]。
37///
38/// 各段の本数が等しいと仮定し、[`rebar_layer_depth_from_edge`] で置いた各段中心の
39/// 平均とする。1 段なら k1、2 段なら (k1+k2)/2、一般に
40/// `dt = k1 + (layers-1)/2・s`(RC 配筋指針の 2 段式に一致)。
41pub fn tension_dt(cover: f64, shear_dia: f64, main: &BarSet) -> f64 {
42    let layers = main.layers.max(1);
43    if layers == 1 {
44        return rebar_layer_depth_from_edge(cover, shear_dia, main, 0);
45    }
46    let d0 = rebar_layer_depth_from_edge(cover, shear_dia, main, 0);
47    let d_last = rebar_layer_depth_from_edge(cover, shear_dia, main, layers - 1);
48    0.5 * (d0 + d_last)
49}
50
51/// 断面の主筋(せい方向 `main_x`)の引張筋重心位置 dt [mm]。
52pub fn rebar_tension_dt(rebar: &RcRebar) -> f64 {
53    tension_dt(rebar.cover, rebar.shear.dia, &rebar.main_x)
54}
55
56/// 有効せい d_eff = D − dt [mm](dt は [`tension_dt`] と同規約)。
57pub fn tension_effective_depth(d: f64, cover: f64, shear_dia: f64, main: &BarSet) -> f64 {
58    (d - tension_dt(cover, shear_dia, main)).max(0.0)
59}
60
61/// 有効せい d_eff = D − dt [mm](dt は [`rebar_tension_dt`] と同規約)。
62pub fn rebar_effective_depth(d: f64, rebar: &RcRebar) -> f64 {
63    (d - rebar_tension_dt(rebar)).max(0.0)
64}
65
66/// せん断補強筋比 pw = (legs・π/4・dia²) / (b・pitch)。pitch<=0 のときは 0。
67pub fn pw_ratio(shear: &ShearBar, b: f64) -> f64 {
68    if shear.pitch <= 0.0 || b <= 0.0 {
69        return 0.0;
70    }
71    crate::section_shape::shear_legs_area(shear) / (b * shear.pitch)
72}
73
74#[cfg(test)]
75mod tests {
76    use super::*;
77    use crate::section_shape::ShearBar;
78
79    fn rebar(layers: u32) -> RcRebar {
80        let main = BarSet {
81            count: 6,
82            dia: 25.0,
83            layers,
84        };
85        RcRebar {
86            main_x: main.clone(),
87            main_y: main,
88            shear: ShearBar {
89                dia: 10.0,
90                pitch: 100.0,
91                legs: 2,
92            },
93            cover: 40.0,
94        }
95    }
96
97    #[test]
98    fn test_tension_dt_single_layer() {
99        let bar = BarSet {
100            count: 4,
101            dia: 22.0,
102            layers: 1,
103        };
104        let dt = tension_dt(40.0, 10.0, &bar);
105        assert!((dt - (40.0 + 10.0 + 11.0)).abs() < 1e-9);
106    }
107
108    #[test]
109    fn test_tension_dt_two_layers() {
110        let bar = BarSet {
111            count: 8,
112            dia: 22.0,
113            layers: 2,
114        };
115        let cover = 40.0;
116        let shear_dia = 10.0;
117        let k1 = cover + shear_dia + bar.dia / 2.0;
118        let k_prime = 25.0_f64.max(1.5 * bar.dia);
119        let k2 = k1 + bar.dia / 2.0 + k_prime + bar.dia / 2.0;
120        let expected = (k1 + k2) / 2.0;
121        let dt = tension_dt(cover, shear_dia, &bar);
122        assert!((dt - expected).abs() < 1e-6);
123    }
124
125    #[test]
126    fn test_rebar_tension_dt_considers_layers() {
127        let k1 = 40.0 + 10.0 + 25.0 / 2.0;
128        assert!((rebar_tension_dt(&rebar(1)) - k1).abs() < 1e-9);
129
130        let two = rebar_tension_dt(&rebar(2));
131        assert!((two - (k1 + 62.5 / 2.0)).abs() < 1e-9, "dt(2段)={two}");
132        assert!(two > k1);
133
134        let r = rebar(2);
135        assert!((two - tension_dt(r.cover, r.shear.dia, &r.main_x)).abs() < 1e-12);
136    }
137
138    #[test]
139    fn test_layer_depth_matches_tension_dt_average() {
140        let bar = BarSet {
141            count: 4,
142            dia: 13.0, // 細い筋: k'=25 > 1.5φ(旧 2.5φ とは段間隔が違う)
143            layers: 2,
144        };
145        let cover = 40.0;
146        let shear = 10.0;
147        let d0 = rebar_layer_depth_from_edge(cover, shear, &bar, 0);
148        let d1 = rebar_layer_depth_from_edge(cover, shear, &bar, 1);
149        let s = rebar_layer_spacing(&bar);
150        assert!((s - (13.0 + 25.0)).abs() < 1e-12);
151        assert!((d1 - d0 - s).abs() < 1e-12);
152        assert!((tension_dt(cover, shear, &bar) - 0.5 * (d0 + d1)).abs() < 1e-12);
153    }
154
155    #[test]
156    fn test_pw_ratio_zero_pitch() {
157        let shear = ShearBar {
158            dia: 10.0,
159            pitch: 0.0,
160            legs: 2,
161        };
162        assert_eq!(pw_ratio(&shear, 400.0), 0.0);
163    }
164}