Skip to main content

squid_n_core/
rc_wall_capacity.rs

1//! RC 造耐震壁の終局せん断強度 Qu と開口低減率(非線形解析・保有水平耐力用)。
2//!
3//! # 位置付け
4//! `squid-n-element`(Layer 3)・`squid-n-solver`(Layer 4)は
5//! `squid-n-design-jp`(Layer 5)に依存できない(循環依存になる)ため、耐震壁の
6//! せん断終局強度の本体を Layer 0 の本モジュールへ置き、
7//! `squid_n_design_jp::rc::wall_nonlinear` は本モジュールへ委譲する
8//! ([`crate::rc_capacity`](梁・柱)と同じ構成)。
9//!
10//! これにより、プッシュオーバーで**耐震壁をせん断終局強度で頭打ちにする**
11//! (壁エレメントの面内せん断を弾完全塑性とする)ことができる。従来は壁要素が
12//! 線形弾性のままで、押し込むほど際限なく水平力を負担し、崩壊機構が形成されず
13//! 保有水平耐力 Qu を過大評価していた(危険側)。
14//!
15//! # 準拠する規準・出典
16//! - 終局せん断強度 Qu(荒川mean式系・耐震壁): 2007年版建築物の構造関係技術基準
17//!   解説書 P.281-282, 638-639/日本建築学会「鉄筋コンクリート終局強度設計に関する
18//!   資料」P.132。
19//! - 開口低減率 r(**耐力用**): 同 資料 P.132、平19国交告第594号第1。
20
21/// 耐震壁の終局せん断強度算定の入力(SI 系: 長さ [mm]・面積 [mm²]・応力 [N/mm²])。
22#[derive(Clone, Copy, Debug)]
23pub struct RcWallShearInput {
24    /// コンクリート設計基準強度 Fc [N/mm²]。
25    pub fc: f64,
26    /// 等価壁厚 te [mm](I 形断面を等価長方形に置換した幅。壁厚 t の 1.5 倍以下)。
27    pub te: f64,
28    /// 壁厚 t [mm](pwh = Pwh·t/te の換算に用いる)。
29    pub t: f64,
30    /// 付帯柱を含めた耐震壁の全長 D [mm]。
31    pub d_wall: f64,
32    /// 圧縮側柱のせい Dc [mm](有効せい d = D − Dc/2)。付帯柱がない場合は 0。
33    pub dc_compression: f64,
34    /// 引張側柱の主筋断面積 at [mm²](pte = 100·at/(te·d) の分子)。
35    pub tension_column_at: f64,
36    /// 水平せん断補強筋(横筋)の材料強度 σwh [N/mm²]。
37    pub sigma_wh: f64,
38    /// 横筋比 Pwh(小数。pwh = Pwh·t/te、1.2% 上限)。
39    pub pwh_ratio: f64,
40    /// 全断面積に対する平均軸方向応力度 σ0 = N/A [N/mm²](圧縮正)。
41    pub sigma_0: f64,
42    /// せん断スパン比 M/(Q·D)(適用範囲 1.0〜3.0 にクランプ)。
43    pub shear_span_ratio: f64,
44    /// 高強度せん断補強筋を用いる場合 true(Qu 係数 0.053→0.068)。
45    pub high_strength_shear_rebar: bool,
46    /// 開口(`(l0, h0, h, lw)`。l0・h0: 開口幅・高さ、h: 壁の上下梁中心間高さ、
47    /// lw: 付帯柱中心間距離)。`None` は無開口(r=1)。
48    pub opening: Option<(f64, f64, f64, f64)>,
49}
50
51/// 耐震壁の**耐力**用開口低減率 r2(無次元)。
52///
53/// ```text
54/// r2 = 1 − max(r0, l0/lw, h0/h),   r0 = √(h0·l0/(h·lw))
55/// ```
56///
57/// 平19国交告第594号第1 の「耐力壁のせん断耐力の低減率」。一次設計(許容応力度)
58/// の開口低減にも同一式を用いる(参照実装マニュアルの係数 1.1 は採らない)。
59/// **剛性**の低減率 `r1 = 1 − 1.25·r0`
60/// (`squid_n_element::factory::wall_opening_reduction`)とは**別式**であり、
61/// 取り違えてはならない(耐力側に r1 を使うと開口の影響を過小評価する=危険側)。
62///
63/// 無開口(`opening == None`)は 1.0。極端な開口では 0 にクランプする。
64pub fn wall_opening_reduction_strength(opening: Option<(f64, f64, f64, f64)>) -> f64 {
65    match opening {
66        Some((l0, h0, h, lw)) if h > 0.0 && lw > 0.0 => {
67            let r0 = (h0 * l0 / (h * lw)).max(0.0).sqrt();
68            let reduce = r0.max(l0 / lw).max(h0 / h);
69            (1.0 - reduce).clamp(0.0, 1.0)
70        }
71        _ => 1.0,
72    }
73}
74
75/// 開口周比 r0 = √(h0·l0/(h·l))。`h`・`l` が 0 以下なら 0。
76pub fn wall_opening_ratio_r0(h0: f64, l0: f64, h: f64, l: f64) -> f64 {
77    if h <= 0.0 || l <= 0.0 {
78        return 0.0;
79    }
80    ((h0 * l0) / (h * l)).max(0.0).sqrt()
81}
82
83/// 耐震壁の**剛性**用開口低減率 r1 = 1 − 1.25·r0(平19国交告第594号第1)。
84///
85/// **耐力**用の r2 = 1−max(r0, l0/lw, h0/h)([`wall_opening_reduction_strength`])
86/// とは別式。剛性側に r2 を、耐力側に r1 を使う取り違えをしないこと。
87/// 負になる場合は 0 にクランプする。
88pub fn wall_opening_reduction_stiffness(r0: f64) -> f64 {
89    (1.0 - 1.25 * r0.max(0.0)).max(0.0)
90}
91
92/// 耐震壁の終局せん断強度 Qu [N](荒川mean式系。技術基準解説書 P.638-639)。
93///
94/// ```text
95/// Qu = { k·pte^0.23·(Fc+18)/denom + 0.85·√(σwh·pwh) + 0.1·σ0 }·te·j·r
96/// ```
97/// - `k = 0.053`(既定。denom = M/(Q·D)+0.12)/`0.068`(高強度せん断補強筋。
98///   denom = √(M/(Q·D)+0.12))
99/// - `pte = 100·at/(te·d)` \[%\](等価引張鉄筋比)、`d = D − Dc/2`、`j = 7/8·d`
100/// - `M/(Q·D)` は適用範囲 1.0〜3.0 にクランプ、`pwh` は 1.2% 上限、
101///   `σ0` は 0〜0.4Fc にクランプ(引張は 0)
102/// - 開口低減 r は**耐力用** [`wall_opening_reduction_strength`] を乗じる
103///
104/// 不正入力(Fc・te・D・at のいずれかが 0 以下、または d ≤ 0)は 0.0 を返す。
105pub fn wall_shear_ultimate(inp: &RcWallShearInput) -> f64 {
106    let d = inp.d_wall - inp.dc_compression / 2.0;
107    if inp.fc <= 0.0
108        || inp.te <= 0.0
109        || inp.d_wall <= 0.0
110        || inp.tension_column_at <= 0.0
111        || d <= 0.0
112    {
113        return 0.0;
114    }
115    let pte = 100.0 * inp.tension_column_at / (inp.te * d);
116    let j = 7.0 / 8.0 * d;
117    let shear_span_ratio = inp.shear_span_ratio.clamp(1.0, 3.0);
118    let k = if inp.high_strength_shear_rebar {
119        0.068
120    } else {
121        0.053
122    };
123    let pwh = if inp.te > 0.0 {
124        (inp.pwh_ratio.max(0.0) * inp.t / inp.te).min(0.012)
125    } else {
126        0.0
127    };
128    let denom = if inp.high_strength_shear_rebar {
129        (shear_span_ratio + 0.12).sqrt()
130    } else {
131        shear_span_ratio + 0.12
132    };
133    let concrete_term = k * pte.powf(0.23) * (inp.fc + 18.0) / denom;
134    let hoop_term = 0.85 * (pwh * inp.sigma_wh).max(0.0).sqrt();
135    let sigma_0 = inp.sigma_0.clamp(0.0, 0.4 * inp.fc);
136    let axial_term = 0.1 * sigma_0;
137    let r = wall_opening_reduction_strength(inp.opening);
138    (concrete_term + hoop_term + axial_term) * inp.te * j * r
139}
140
141#[cfg(test)]
142mod tests {
143    use super::*;
144
145    fn sample() -> RcWallShearInput {
146        RcWallShearInput {
147            fc: 24.0,
148            te: 200.0,
149            t: 200.0,
150            d_wall: 4000.0,
151            dc_compression: 0.0,
152            tension_column_at: 1000.0,
153            sigma_wh: 295.0,
154            pwh_ratio: 0.0025,
155            sigma_0: 0.0,
156            shear_span_ratio: 1.0,
157            high_strength_shear_rebar: false,
158            opening: None,
159        }
160    }
161
162    /// 開口低減(耐力用)は r2 = 1 − max(r0, l0/lw, h0/h)。
163    /// 剛性用の r1 = 1 − 1.25·r0 とは別式であることを固定する。
164    #[test]
165    fn test_opening_reduction_strength_uses_max_rule() {
166        // l0=1000, h0=1000, h=3000, lw=4000
167        // r0 = √(1000·1000/(3000·4000)) = √0.08333 = 0.288675
168        // l0/lw = 0.25、h0/h = 0.33333 → max = 0.33333
169        let r = wall_opening_reduction_strength(Some((1000.0, 1000.0, 3000.0, 4000.0)));
170        assert!((r - (1.0 - 1.0 / 3.0)).abs() < 1e-9, "r={}", r);
171        // 剛性用 r1 = 1 − 1.25·0.288675 = 0.6392 とは一致しない。
172        let r1 = 1.0 - 1.25 * (1.0f64 / 12.0).sqrt();
173        assert!((r - r1).abs() > 1e-3, "耐力用 r2 と剛性用 r1 は別式");
174    }
175
176    #[test]
177    fn test_opening_reduction_none_is_one() {
178        assert!((wall_opening_reduction_strength(None) - 1.0).abs() < 1e-12);
179    }
180
181    /// 開口低減は Qu に線形に乗る。
182    #[test]
183    fn test_qu_scales_with_opening_reduction() {
184        let mut inp = sample();
185        let qu0 = wall_shear_ultimate(&inp);
186        inp.opening = Some((1000.0, 1000.0, 3000.0, 4000.0));
187        let r = wall_opening_reduction_strength(inp.opening);
188        let qu1 = wall_shear_ultimate(&inp);
189        assert!(
190            (qu1 - qu0 * r).abs() < 1e-6,
191            "qu1={} qu0*r={}",
192            qu1,
193            qu0 * r
194        );
195    }
196
197    /// 軸圧縮は Qu を増やし、0.4Fc で頭打ちになる。
198    #[test]
199    fn test_qu_axial_term_clamped() {
200        let mut inp = sample();
201        let q0 = wall_shear_ultimate(&inp);
202        inp.sigma_0 = 5.0;
203        let q1 = wall_shear_ultimate(&inp);
204        assert!(q1 > q0);
205        inp.sigma_0 = 100.0; // 0.4Fc = 9.6 でクランプ
206        let q2 = wall_shear_ultimate(&inp);
207        let mut inp_c = sample();
208        inp_c.sigma_0 = 0.4 * 24.0;
209        assert!((q2 - wall_shear_ultimate(&inp_c)).abs() < 1e-9);
210    }
211
212    #[test]
213    fn test_qu_invalid_inputs_are_zero() {
214        let mut inp = sample();
215        inp.tension_column_at = 0.0;
216        assert_eq!(wall_shear_ultimate(&inp), 0.0);
217        let mut inp = sample();
218        inp.fc = 0.0;
219        assert_eq!(wall_shear_ultimate(&inp), 0.0);
220    }
221
222    /// 代表値の手計算照合(無開口・軸力なし・M/(QD)=1.0)。
223    #[test]
224    fn test_qu_matches_handcalc() {
225        let inp = sample();
226        let d: f64 = 4000.0;
227        let pte: f64 = 100.0 * 1000.0 / (200.0 * d);
228        let j = 7.0 / 8.0 * d;
229        let concrete = 0.053 * pte.powf(0.23) * (24.0 + 18.0) / (1.0 + 0.12);
230        let hoop = 0.85 * (0.0025f64 * 295.0).sqrt();
231        let expect = (concrete + hoop) * 200.0 * j;
232        assert!(
233            (wall_shear_ultimate(&inp) - expect).abs() < 1e-6,
234            "{} vs {}",
235            wall_shear_ultimate(&inp),
236            expect
237        );
238    }
239}