Skip to main content

squid_n_core/
units.rs

1pub const GRAVITY_MM_S2: f64 = 9_806.65;
2
3/// コンクリートの種類(単位体積重量表の行。固定荷重の自重算定に用いる)。
4/// 許容応力度低減(軽量1種・2種は普通コンクリートの 0.9 倍。技術基準解説書)にも用いる。
5#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
6pub enum ConcreteClass {
7    #[default]
8    Normal,
9    Lightweight1,
10    Lightweight2,
11}
12
13/// コンクリート系構造の区分(γC/γRC/γSRC の列に対応)。
14#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
15pub enum ConcreteComposition {
16    /// 無筋(気乾単位体積重量 γC)
17    Plain,
18    /// 鉄筋コンクリート(γRC = γC + 1.0)
19    #[default]
20    Rc,
21    /// 鉄骨鉄筋コンクリート(γSRC = γC + 2.0)
22    Src,
23}
24
25/// コンクリートの単位体積重量 [kN/m³]。
26/// 固定荷重の単位体積重量表(設計基準強度 Fc・種類・構造区分ごと)による。
27/// 軽量コンクリートで表の範囲を超える Fc は最上段の値で頭打ちとする。
28pub fn concrete_unit_weight_kn_m3(fc: f64, class: ConcreteClass, comp: ConcreteComposition) -> f64 {
29    let gamma_c = match class {
30        ConcreteClass::Normal => {
31            if fc <= 36.0 {
32                23.0
33            } else if fc <= 48.0 {
34                23.5
35            } else if fc <= 120.0 {
36                24.0
37            } else {
38                24.5
39            }
40        }
41        ConcreteClass::Lightweight1 => {
42            if fc <= 27.0 {
43                19.0
44            } else {
45                20.0
46            }
47        }
48        ConcreteClass::Lightweight2 => 17.0,
49    };
50    // 軽量1種 27<Fc≦36 は γRC=22.0(+2.0)と表の増分が他と異なるため個別に扱う。
51    match (class, comp) {
52        (ConcreteClass::Lightweight1, ConcreteComposition::Rc) if fc > 27.0 => 22.0,
53        (ConcreteClass::Lightweight1, ConcreteComposition::Src) if fc > 27.0 => 23.0,
54        (_, ConcreteComposition::Plain) => gamma_c,
55        (_, ConcreteComposition::Rc) => gamma_c + 1.0,
56        (_, ConcreteComposition::Src) => gamma_c + 2.0,
57    }
58}
59
60/// 鋼材の単位体積重量 [kN/m³](固定荷重: γs = 77 kN/m³)。
61pub const STEEL_UNIT_WEIGHT_KN_M3: f64 = 77.0;
62
63/// 鋼材の単位重量 [t/m³](数量積算の慣用値)。
64///
65/// 積算分野では鋼材比重 7.85 を用いるのが慣用であり、固定荷重の
66/// γs = 77 kN/m³([`STEEL_UNIT_WEIGHT_KN_M3`]。質量換算 ≒7.8518 t/m³)とは
67/// 約 0.02% の系統差がある。荷重・質量は 77 kN/m³、数量積算は 7.85 t/m³ を
68/// それぞれ正とする分野別の慣用値として使い分ける(仕様)。
69pub const STEEL_UNIT_WEIGHT_TAKEOFF_T_M3: f64 = 7.85;
70
71pub mod to_internal {
72    pub fn length_m(m: f64) -> f64 {
73        m * 1_000.0
74    }
75    pub fn force_kn(kn: f64) -> f64 {
76        kn * 1_000.0
77    }
78    /// バネ定数 kN/mm → N/mm。
79    pub fn stiffness_kn_per_mm(kn_per_mm: f64) -> f64 {
80        kn_per_mm * 1_000.0
81    }
82    /// 粘性係数 C0 [kN·(s/mm)^α] → [N·(s/mm)^α]。
83    pub fn viscous_c0_kn(c0_kn: f64) -> f64 {
84        c0_kn * 1_000.0
85    }
86    pub fn line_load_kn_per_m(v: f64) -> f64 {
87        v
88    }
89    pub fn area_load_kn_per_m2(v: f64) -> f64 {
90        v / 1_000.0
91    }
92    pub fn stress_n_per_mm2(v: f64) -> f64 {
93        v
94    }
95    pub fn mass_density_g_per_cm3(v: f64) -> f64 {
96        v * 1.0e-9
97    }
98    pub fn unit_weight_kn_per_m3(v: f64) -> f64 {
99        v * 1.0e-6
100    }
101    pub fn weight_n_to_mass(w_n: f64) -> f64 {
102        w_n / super::GRAVITY_MM_S2
103    }
104    /// 単位体積重量 [kN/m³] → 質量密度 [ton/mm³](内部単位系 N-mm-s)。
105    /// 例: γRC=24.0 kN/m³ → 2.4473e-9 ton/mm³。
106    pub fn mass_density_from_unit_weight_kn_m3(v: f64) -> f64 {
107        unit_weight_kn_per_m3(v) / super::GRAVITY_MM_S2
108    }
109}
110
111/// 内部単位系(N-mm)から表示用の単位への換算と、その単位ラベル。
112///
113/// **どの量をどの単位で見せるか**は日本の構造設計の慣例で決まっており(力は kN、
114/// 断面性能は cm 系、応力度は N/mm² など)、量ごとに異なる。その慣例をここに 1 つ
115/// だけ置き、画面ごとに違う単位で同じ量を表示することを防ぐ。
116///
117/// 値の関数とラベル定数は**分離**している。軸ラベル(`"層せん断力 [kN]"`)だけ
118/// 要る場面と、値だけ要る場面の双方があるためである。小数桁は規約化しない
119/// (一覧表では `{:.0}`、詳細表示では `{:.2}` のような使い分けが正当なため)。
120pub mod to_display {
121    /// 力の表示単位ラベル。
122    pub const LABEL_FORCE: &str = "kN";
123    /// モーメントの表示単位ラベル。
124    pub const LABEL_MOMENT: &str = "kN·m";
125    /// 長さ(階高・建物高さ・スパン)の表示単位ラベル。
126    pub const LABEL_LENGTH: &str = "m";
127    /// 断面寸法・鉄筋径・変位の表示単位ラベル(内部単位のまま)。
128    pub const LABEL_LENGTH_MM: &str = "mm";
129    /// 応力度・材料強度の表示単位ラベル(内部単位のまま)。
130    pub const LABEL_STRESS: &str = "N/mm²";
131    /// 断面積の表示単位ラベル。
132    pub const LABEL_AREA: &str = "cm²";
133    /// 断面二次モーメント・ねじり定数の表示単位ラベル。
134    pub const LABEL_INERTIA: &str = "cm⁴";
135    /// 断面係数の表示単位ラベル。
136    pub const LABEL_MODULUS: &str = "cm³";
137    /// 断面二次半径の表示単位ラベル。
138    pub const LABEL_RADIUS: &str = "cm";
139    /// 線剛性・バネ定数の表示単位ラベル。
140    pub const LABEL_STIFFNESS: &str = "kN/mm";
141    /// 面荷重(床・雑壁)の表示単位ラベル。
142    pub const LABEL_AREA_LOAD: &str = "kN/m²";
143    /// 単位幅あたりモーメント(スラブ検定など)の表示単位ラベル。
144    pub const LABEL_MOMENT_PER_WIDTH: &str = "kN·m/m";
145    /// 粘性係数 C0 の表示単位ラベル(マクスウェルダンパー)。
146    pub const LABEL_VISCOUS_C0: &str = "kN·(s/mm)^α";
147
148    /// 力 N → kN。重量・せん断力・軸力に用いる。
149    pub fn force_kn(n: f64) -> f64 {
150        n / 1_000.0
151    }
152
153    /// モーメント N·mm → kN·m。
154    pub fn moment_kn_m(n_mm: f64) -> f64 {
155        n_mm / 1.0e6
156    }
157
158    /// 長さ mm → m。階高・建物高さ・スパンに用いる。
159    pub fn length_m(mm: f64) -> f64 {
160        mm / 1_000.0
161    }
162
163    /// バネ定数 N/mm → kN/mm。
164    pub fn stiffness_kn_per_mm(n_per_mm: f64) -> f64 {
165        n_per_mm / 1_000.0
166    }
167
168    /// 面荷重 N/mm² → kN/m²。
169    pub fn area_load_kn_per_m2(n_per_mm2: f64) -> f64 {
170        n_per_mm2 * 1_000.0
171    }
172
173    /// 単位幅あたりモーメント N·mm/mm → kN·m/m。
174    pub fn moment_kn_m_per_m(n_mm_per_mm: f64) -> f64 {
175        n_mm_per_mm / 1_000.0
176    }
177
178    /// 粘性係数 C0 N·(s/mm)^α → kN·(s/mm)^α。
179    pub fn viscous_c0_kn(c0_n: f64) -> f64 {
180        c0_n / 1_000.0
181    }
182
183    /// 断面積 mm² → cm²(JIS 形鋼表の慣例)。
184    pub fn area_cm2(mm2: f64) -> f64 {
185        mm2 / 1.0e2
186    }
187
188    /// 断面二次モーメント・ねじり定数 mm⁴ → cm⁴(同上)。
189    pub fn inertia_cm4(mm4: f64) -> f64 {
190        mm4 / 1.0e4
191    }
192
193    /// 断面係数(弾性・塑性)mm³ → cm³(同上)。
194    pub fn modulus_cm3(mm3: f64) -> f64 {
195        mm3 / 1.0e3
196    }
197
198    /// 断面二次半径 mm → cm(同上)。
199    pub fn radius_cm(mm: f64) -> f64 {
200        mm / 1.0e1
201    }
202}
203
204#[cfg(test)]
205mod tests {
206    use super::*;
207    use approx::assert_relative_eq;
208
209    #[test]
210    fn test_unit_conversions() {
211        assert_relative_eq!(to_internal::length_m(6.0), 6000.0, max_relative = 1e-12);
212        assert_relative_eq!(
213            to_internal::line_load_kn_per_m(10.0),
214            10.0,
215            max_relative = 1e-12
216        );
217        assert_relative_eq!(to_internal::force_kn(50.0), 50000.0, max_relative = 1e-12);
218        assert_relative_eq!(
219            to_internal::stiffness_kn_per_mm(10.0),
220            10000.0,
221            max_relative = 1e-12
222        );
223        assert_relative_eq!(
224            to_display::stiffness_kn_per_mm(10000.0),
225            10.0,
226            max_relative = 1e-12
227        );
228        assert_relative_eq!(
229            to_display::area_load_kn_per_m2(0.0029),
230            2.9,
231            max_relative = 1e-12
232        );
233        assert_relative_eq!(
234            to_internal::area_load_kn_per_m2(2.9),
235            0.0029,
236            max_relative = 1e-12
237        );
238        assert_relative_eq!(
239            to_display::moment_kn_m_per_m(5000.0),
240            5.0,
241            max_relative = 1e-12
242        );
243        assert_relative_eq!(to_display::viscous_c0_kn(1000.0), 1.0, max_relative = 1e-12);
244        assert_relative_eq!(
245            to_internal::viscous_c0_kn(1.0),
246            1000.0,
247            max_relative = 1e-12
248        );
249        assert_relative_eq!(
250            to_internal::stress_n_per_mm2(24.0),
251            24.0,
252            max_relative = 1e-12
253        );
254        assert_relative_eq!(
255            to_internal::mass_density_g_per_cm3(2.4),
256            2.4e-9,
257            max_relative = 1e-12
258        );
259        assert_relative_eq!(
260            to_internal::unit_weight_kn_per_m3(24.0),
261            2.4e-5,
262            max_relative = 1e-12
263        );
264        assert_relative_eq!(
265            to_internal::weight_n_to_mass(1.0e6),
266            101.971_621_297_792_82,
267            max_relative = 1e-12
268        );
269    }
270
271    #[test]
272    fn test_concrete_unit_weight_table() {
273        use ConcreteClass::*;
274        use ConcreteComposition::*;
275        // 普通コンクリート(単位体積重量表の代表値)
276        assert_eq!(concrete_unit_weight_kn_m3(24.0, Normal, Plain), 23.0);
277        assert_eq!(concrete_unit_weight_kn_m3(24.0, Normal, Rc), 24.0);
278        assert_eq!(concrete_unit_weight_kn_m3(24.0, Normal, Src), 25.0);
279        assert_eq!(concrete_unit_weight_kn_m3(42.0, Normal, Rc), 24.5);
280        assert_eq!(concrete_unit_weight_kn_m3(60.0, Normal, Rc), 25.0);
281        assert_eq!(concrete_unit_weight_kn_m3(100.0, Normal, Rc), 25.0);
282        assert_eq!(concrete_unit_weight_kn_m3(150.0, Normal, Rc), 25.5);
283        // 軽量コンクリート
284        assert_eq!(concrete_unit_weight_kn_m3(24.0, Lightweight1, Rc), 20.0);
285        assert_eq!(concrete_unit_weight_kn_m3(30.0, Lightweight1, Rc), 22.0);
286        assert_eq!(concrete_unit_weight_kn_m3(30.0, Lightweight1, Src), 23.0);
287        assert_eq!(concrete_unit_weight_kn_m3(21.0, Lightweight2, Rc), 18.0);
288    }
289
290    #[test]
291    fn test_mass_density_from_unit_weight() {
292        // γRC=24 kN/m³ → 24e-6 N/mm³ / 9806.65 mm/s² ≈ 2.4473e-9 t/mm³
293        let rho = to_internal::mass_density_from_unit_weight_kn_m3(24.0);
294        assert_relative_eq!(rho, 24.0e-6 / GRAVITY_MM_S2, max_relative = 1e-12);
295        assert!((rho - 2.4473e-9).abs() / rho < 1e-3);
296    }
297}