ocs-calculators 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (136) hide show
  1. package/CHANGELOG.md +45 -4
  2. package/README.md +47 -5
  3. package/README_EN.md +11 -5
  4. package/dist/ampacity/index.cjs +17 -0
  5. package/dist/ampacity/index.cjs.map +1 -0
  6. package/dist/ampacity/index.d.cts +68 -0
  7. package/dist/ampacity/index.d.ts +68 -0
  8. package/dist/ampacity/index.js +17 -0
  9. package/dist/ampacity/index.js.map +1 -0
  10. package/dist/chunk-3ERFRRHZ.cjs +119 -0
  11. package/dist/chunk-3ERFRRHZ.cjs.map +1 -0
  12. package/dist/chunk-4UU7WA7N.cjs +107 -0
  13. package/dist/chunk-4UU7WA7N.cjs.map +1 -0
  14. package/dist/chunk-5INEDXRY.cjs +69 -0
  15. package/dist/chunk-5INEDXRY.cjs.map +1 -0
  16. package/dist/chunk-5Q6IASB2.cjs +101 -0
  17. package/dist/chunk-5Q6IASB2.cjs.map +1 -0
  18. package/dist/chunk-746H65EQ.js +91 -0
  19. package/dist/chunk-746H65EQ.js.map +1 -0
  20. package/dist/chunk-CVA4EH2K.js +102 -0
  21. package/dist/chunk-CVA4EH2K.js.map +1 -0
  22. package/dist/chunk-DGO2DCO5.cjs +19 -0
  23. package/dist/chunk-DGO2DCO5.cjs.map +1 -0
  24. package/dist/chunk-FVESJBUD.cjs +95 -0
  25. package/dist/chunk-FVESJBUD.cjs.map +1 -0
  26. package/dist/chunk-GN6QNOUL.js +91 -0
  27. package/dist/chunk-GN6QNOUL.js.map +1 -0
  28. package/dist/chunk-IFVYGNT3.js +107 -0
  29. package/dist/chunk-IFVYGNT3.js.map +1 -0
  30. package/dist/chunk-IUENDAAJ.js +67 -0
  31. package/dist/chunk-IUENDAAJ.js.map +1 -0
  32. package/dist/chunk-J2UXRMTU.cjs +126 -0
  33. package/dist/chunk-J2UXRMTU.cjs.map +1 -0
  34. package/dist/chunk-KOSC6EA3.js +101 -0
  35. package/dist/chunk-KOSC6EA3.js.map +1 -0
  36. package/dist/chunk-LDSV3U4M.js +69 -0
  37. package/dist/chunk-LDSV3U4M.js.map +1 -0
  38. package/dist/chunk-MZBQ4546.cjs +102 -0
  39. package/dist/chunk-MZBQ4546.cjs.map +1 -0
  40. package/dist/chunk-NBFOB2PI.cjs +91 -0
  41. package/dist/chunk-NBFOB2PI.cjs.map +1 -0
  42. package/dist/chunk-NBHEOJ5A.cjs +88 -0
  43. package/dist/chunk-NBHEOJ5A.cjs.map +1 -0
  44. package/dist/chunk-P6KUGPHD.cjs +91 -0
  45. package/dist/chunk-P6KUGPHD.cjs.map +1 -0
  46. package/dist/chunk-QTPXTDGY.js +119 -0
  47. package/dist/chunk-QTPXTDGY.js.map +1 -0
  48. package/dist/chunk-RPKDEFSJ.cjs +78 -0
  49. package/dist/chunk-RPKDEFSJ.cjs.map +1 -0
  50. package/dist/chunk-RVG3LEZQ.js +95 -0
  51. package/dist/chunk-RVG3LEZQ.js.map +1 -0
  52. package/dist/chunk-RVP3IU2L.cjs +67 -0
  53. package/dist/chunk-RVP3IU2L.cjs.map +1 -0
  54. package/dist/chunk-UO2PHBC3.js +126 -0
  55. package/dist/chunk-UO2PHBC3.js.map +1 -0
  56. package/dist/chunk-VAHQDIMW.js +88 -0
  57. package/dist/chunk-VAHQDIMW.js.map +1 -0
  58. package/dist/chunk-WPMKM6NL.js +78 -0
  59. package/dist/chunk-WPMKM6NL.js.map +1 -0
  60. package/dist/chunk-YHDO6XVM.js +19 -0
  61. package/dist/chunk-YHDO6XVM.js.map +1 -0
  62. package/dist/copper/index.cjs +12 -0
  63. package/dist/copper/index.cjs.map +1 -0
  64. package/dist/copper/index.d.cts +57 -0
  65. package/dist/copper/index.d.ts +57 -0
  66. package/dist/copper/index.js +12 -0
  67. package/dist/copper/index.js.map +1 -0
  68. package/dist/curve-stagger/index.cjs +17 -0
  69. package/dist/curve-stagger/index.cjs.map +1 -0
  70. package/dist/curve-stagger/index.d.cts +77 -0
  71. package/dist/curve-stagger/index.d.ts +77 -0
  72. package/dist/curve-stagger/index.js +17 -0
  73. package/dist/curve-stagger/index.js.map +1 -0
  74. package/dist/dropper/index.cjs +15 -0
  75. package/dist/dropper/index.cjs.map +1 -0
  76. package/dist/dropper/index.d.cts +84 -0
  77. package/dist/dropper/index.d.ts +84 -0
  78. package/dist/dropper/index.js +15 -0
  79. package/dist/dropper/index.js.map +1 -0
  80. package/dist/force/index.cjs +17 -0
  81. package/dist/force/index.cjs.map +1 -0
  82. package/dist/force/index.d.cts +69 -0
  83. package/dist/force/index.d.ts +69 -0
  84. package/dist/force/index.js +17 -0
  85. package/dist/force/index.js.map +1 -0
  86. package/dist/icing/index.cjs +9 -0
  87. package/dist/icing/index.cjs.map +1 -0
  88. package/dist/icing/index.d.cts +43 -0
  89. package/dist/icing/index.d.ts +43 -0
  90. package/dist/icing/index.js +9 -0
  91. package/dist/icing/index.js.map +1 -0
  92. package/dist/index.cjs +162 -1220
  93. package/dist/index.cjs.map +1 -1
  94. package/dist/index.d.cts +47 -775
  95. package/dist/index.d.ts +47 -775
  96. package/dist/index.js +108 -1063
  97. package/dist/index.js.map +1 -1
  98. package/dist/stroke/index.cjs +19 -0
  99. package/dist/stroke/index.cjs.map +1 -0
  100. package/dist/stroke/index.d.cts +63 -0
  101. package/dist/stroke/index.d.ts +63 -0
  102. package/dist/stroke/index.js +19 -0
  103. package/dist/stroke/index.js.map +1 -0
  104. package/dist/tension/index.cjs +19 -0
  105. package/dist/tension/index.cjs.map +1 -0
  106. package/dist/tension/index.d.cts +85 -0
  107. package/dist/tension/index.d.ts +85 -0
  108. package/dist/tension/index.js +19 -0
  109. package/dist/tension/index.js.map +1 -0
  110. package/dist/types-C2OanO8N.d.cts +33 -0
  111. package/dist/types-C2OanO8N.d.ts +33 -0
  112. package/dist/voltage-drop/index.cjs +12 -0
  113. package/dist/voltage-drop/index.cjs.map +1 -0
  114. package/dist/voltage-drop/index.d.cts +40 -0
  115. package/dist/voltage-drop/index.d.ts +40 -0
  116. package/dist/voltage-drop/index.js +12 -0
  117. package/dist/voltage-drop/index.js.map +1 -0
  118. package/dist/wavespeed/index.cjs +17 -0
  119. package/dist/wavespeed/index.cjs.map +1 -0
  120. package/dist/wavespeed/index.d.cts +58 -0
  121. package/dist/wavespeed/index.d.ts +58 -0
  122. package/dist/wavespeed/index.js +17 -0
  123. package/dist/wavespeed/index.js.map +1 -0
  124. package/dist/wear/index.cjs +13 -0
  125. package/dist/wear/index.cjs.map +1 -0
  126. package/dist/wear/index.d.cts +55 -0
  127. package/dist/wear/index.d.ts +55 -0
  128. package/dist/wear/index.js +13 -0
  129. package/dist/wear/index.js.map +1 -0
  130. package/dist/wind/index.cjs +15 -0
  131. package/dist/wind/index.cjs.map +1 -0
  132. package/dist/wind/index.d.cts +66 -0
  133. package/dist/wind/index.d.ts +66 -0
  134. package/dist/wind/index.js +15 -0
  135. package/dist/wind/index.js.map +1 -0
  136. package/package.json +64 -3
package/CHANGELOG.md CHANGED
@@ -3,6 +3,29 @@
3
3
  本文件格式遵循 [Keep a Changelog](https://keepachangelog.com/zh-CN/1.1.0/),
4
4
  版本号遵循[语义化版本](https://semver.org/lang/zh-CN/)。
5
5
 
6
+ ## [0.1.2] - 2026-09-06
7
+
8
+ ### 新增
9
+
10
+ - **子路径导入**:支持 `import 'ocs-calculators/wind'` 等按模块导入,
11
+ 构建改为多入口 + ESM splitting,利于打包工具 tree-shaking
12
+ - `CONTRIBUTING.md`(贡献指南,含与站点 `calc-core.js` 的同步政策)与
13
+ `SECURITY.md`(安全与公式纠错报告流程)
14
+ - README 增加同步政策章节与子路径导入示例
15
+
16
+ ## [0.1.1] - 2026-09-05
17
+
18
+ ### 修复
19
+
20
+ - **补回 `wind`(风偏限界校验)与 `wear`(接触线磨耗率)两个模块的源码**。
21
+ 0.1.0 的 npm 包 dist 中已包含二者,但对应源码目录(`src/wind/`、`src/wear/`)
22
+ 未一并提交,导致从仓库克隆后 `typecheck` / `build` 失败。0.1.1 起仓库与
23
+ 发布包内容一致。
24
+
25
+ ### 新增
26
+
27
+ - `wind` / `wear` 模块单元测试(站点默认输入、物理性质与输入校验)
28
+
6
29
  ## [0.1.0] - 2026-08-31
7
30
 
8
31
  首个公开版本。覆盖思维接触网百科全部 12 个在线计算器。
@@ -89,12 +112,30 @@
89
112
  - 跨中弛度抛物线近似 `f = gl²/(8T)`
90
113
  - 当量跨距归算 `l_D = √(Σlᵢ³/Σlᵢ)`
91
114
  - 覆冰荷载冰筒模型 `g_ice = ρ_ice·g₀·π·b·(d+b)`
92
- - 15 个单元测试,逐行回归站点已发布的输出表(张力误差 ≤ 0.02%)
115
+ - 15 个单元测试,逐行回归站点已发布的输出表
93
116
  - `wire-specs.ts` 线材参数预设(CTHM-120 / CTHM-150 / CTHA-120)
94
117
  - `CalculatorMeta` 元信息规范:公式、依据标准、适用范围、免责声明
95
118
  - `DISCLAIMER.md` 工程免责声明
96
119
 
97
- ### 待确认
120
+ ## 自重口径确认记录
121
+
122
+ 线材自重取值口径已于 2026-08-31 确认并统一,原「待确认」项关闭。
98
123
 
99
- - 线材自重取值口径:标称密度 8.94 g/cm³ 反算得 g ≈ 10.524 N/m
100
- 站点输出表反算得 g 10.62 N/m(+0.9%)。当前采用后者以复现站点输出。
124
+ - **结论**:线密度取标准「参考单位质量」表值,CTHM-120 1082 kg/km
125
+ 自重 `g = 1.082 × 9.81 = 10.61442 N/m`。
126
+ - **口径根因**:标准的 8.94 g/cm³ 是配「计算截面」用的,不是配「标称截面」。
127
+ `CT 120|标称 120|计算截面 121|参考单位质量 1082 kg/km`,
128
+ 121 × 8.94 × 1e-3 = 1.08174 ≈ 1.082 kg/m。
129
+ 早期用标称截面 120 推算得 1.0728 kg/m(g ≈ 10.524 N/m),偏低约 0.86%。
130
+ - **依据**:TB/T 2810-2017(纯铜)、TB/T 2821-2017(铜银)规格尺寸表;
131
+ 与站点 `/calculator/tension/` 预设 `rho=1.082`、表单默认值 `10.61`、
132
+ 本库 `TB2809_WIRE_PARAMS.unitWeightKgPerKm = 1082` 三处同源。
133
+ - **废弃值**:回归表反算出的魔数 `10.6222`(偏高约 0.07%)已替换。
134
+ 该反算之所以偏差,是因为 g 在状态方程中仅以 `g²l²EA/24` 项出现(量级 0.006 kN),
135
+ 而 `αEA·Δt` 项有 15 kN——g 偏差 1% 只让张力变化约 0.001%,弛度则随 g 线性变化,
136
+ 张力逐位一致对 g 的约束极弱。
137
+ - **代码变更**:`wire-specs.ts` 预设改用标准参考单位质量表值,
138
+ 新增 `calculatedSectionMM2` / `STANDARD_UNIT_WEIGHT_KG_PER_KM` /
139
+ `unitWeightToKgPerM`;`deriveLinearMassKgPerM` 文档注明须传计算截面。
140
+ `tension.test.ts` 回归常量改为 10.61442,0℃ 行弛度期望值由 0.261 修正为 0.260
141
+ (该行原为站点旧版本输出快照中的孤点)。
package/README.md CHANGED
@@ -8,7 +8,7 @@
8
8
  [English](./README_EN.md) | 简体中文
9
9
 
10
10
  ![npm version](https://img.shields.io/npm/v/ocs-calculators)
11
- ![CI](https://github.com/showhoo/ocs-calculators/actions/workflows/ci.yml/badge.svg)
11
+ [![CI](https://github.com/showhoo/ocs-calculators/actions/workflows/ci.yml/badge.svg)](https://github.com/showhoo/ocs-calculators/actions/workflows/ci.yml)
12
12
  ![license](https://img.shields.io/npm/l/ocs-calculators)
13
13
  ![dependencies](https://img.shields.io/badge/dependencies-0-brightgreen)
14
14
 
@@ -39,7 +39,7 @@ const curve = tensionCurve(
39
39
  {
40
40
  baseTensionKN: 20,
41
41
  baseTempDegC: -20,
42
- weightPerLengthNPerM: 10.6222,
42
+ weightPerLengthNPerM: 10.61442,
43
43
  spanM: 55,
44
44
  elasticModulusGPa: 120,
45
45
  crossSectionMM2: 120,
@@ -62,6 +62,13 @@ for (const p of curve) {
62
62
 
63
63
  上面这段输出与 <https://www.itswe.com/calculator/tension/> 在线计算器完全一致,测试用例里做了逐行回归。
64
64
 
65
+ 也支持按模块子路径导入(利于打包工具做 tree-shaking):
66
+
67
+ ```ts
68
+ import { windClearanceCheck } from 'ocs-calculators/wind';
69
+ import { wearRatio } from 'ocs-calculators/wear';
70
+ ```
71
+
65
72
  ## 12 个计算器(全部实现)
66
73
 
67
74
  对应 <https://www.itswe.com/Category:tools> 的 12 个在线计算器,全部已实现并逐项回归。
@@ -109,6 +116,18 @@ console.log(tensionMeta.scope); // 适用范围:跨距 20~90 m、E 50~20
109
116
  console.log(tensionMeta.disclaimer); // 免责声明
110
117
  ```
111
118
 
119
+ ## 与站点实现的同步政策
120
+
121
+ 本仓库是 [itswe.com](https://www.itswe.com) 在线计算器的公式算法层,同步基准为站点资产
122
+ [`calculator/assets/calc-core.js`](https://www.itswe.com/calculator/assets/calc-core.js):
123
+
124
+ - `src/` 中每个模块的公式与默认参数,以 `calc-core.js` 对应实现为准;
125
+ - 站点侧公式变更时,本仓库同步更新并补充/修订对应测试;
126
+ - 本仓库的公式变更同样会回流站点,两边的计算结果保持一致;
127
+ - `meta.ts` 中的参考依据(标准号 + 年份)随两侧更新同步修订。
128
+
129
+ 当前同步状态:`calc-core.js` 与 `src/` 一致(2026-09-05 校验,152 项测试全绿)。
130
+
112
131
  ## ⚠️ 免责声明
113
132
 
114
133
  **本库所有计算结果仅供参考,不构成工程设计、施工或验收依据。**
@@ -119,11 +138,26 @@ console.log(tensionMeta.disclaimer); // 免责声明
119
138
 
120
139
  详见 [DISCLAIMER.md](./DISCLAIMER.md)。
121
140
 
122
- ## 开放问题
141
+ ## 自重口径(已确认)
123
142
 
124
- **线材自重的取值口径待确认。** 站点页面注明"参考单位质量按密度 8.94 g/cm³ 计",据此 CTHM-120 应为 1.0728 kg/m(g ≈ 10.524 N/m)。但由站点已发布的输出表反算,实际使用的 g ≈ 10.62 N/m(≈ 1.083 kg/m),比标称值高约 0.9%,疑似计入了吊弦、线夹、接头的等效附加荷载。
143
+ 线密度取标准「参考单位质量」表值,而非由截面推算。标准表分两列,
144
+ `CT 120|标称截面 120|计算截面 121|参考单位质量 1082 kg/km`,
145
+ 注「参考单位质量按密度 8.94 g/cm³ 计算」——这个 8.94 g/cm³ 是配**计算截面**
146
+ (把尺寸公差计入后的截面)用的,不是配标称截面:
147
+ `121 × 8.94 × 1e-3 = 1.08174 ≈ 1.082 kg/m`。
125
148
 
126
- 本库回归测试采用反算值(10.6222 N/m)以复现站点输出。确认口径后我们会统一,欢迎在 issue 里说明。
149
+ 因此 CTHM-120 自重 `g = 1.082 × 9.81 = 10.61442 N/m`,
150
+ 与站点 `/calculator/tension/` 的预设 `rho=1.082`、表单默认值 `10.61`、
151
+ 以及本库 `TB2809_WIRE_PARAMS` 的 `1082` 三处同源。
152
+
153
+ 依据:TB/T 2810-2017(纯铜)、TB/T 2821-2017(铜银)规格尺寸表。
154
+
155
+ 早期版本按标称截面 120 推算得 `1.0728 kg/m`(g ≈ 10.524 N/m),比标准值低约 0.86%,
156
+ 另有一版用回归表反算出魔数 `10.6222`,偏高约 0.07%,两者均已废弃。
157
+
158
+ 顺带说明为什么仅靠回归表约不动 g:g 在状态方程里以 `g²l²EA/24` 项出现,
159
+ 量级只有 0.006 kN,而 `αEA·Δt` 项有 15 kN。g 偏差 1% 只让张力变化约 0.001%,
160
+ 弛度则随 g 线性变化。所以张力逐位一致对 g 的约束极弱,必须回到标准表确认口径。
127
161
 
128
162
  ## 新增一个计算器
129
163
 
@@ -142,11 +176,19 @@ src/<模块名>/
142
176
  2. `meta.ts` 必须写全 `formula` / `references` / `scope` / `disclaimer`
143
177
  3. 测试的期望值取自站点在线计算器,容差 1%(站点输出经过显示取整)
144
178
 
179
+ 完整约定与同步政策见 [CONTRIBUTING.md](./CONTRIBUTING.md)。
180
+
145
181
  ## 相关项目
146
182
 
147
183
  - [ocs-wiki-content](https://github.com/showhoo/ocs-wiki-content) — 504 条词条快照与结构化数据(规划中)
148
184
  - [itswe](https://github.com/showhoo/itswe) — 站点介绍与建站文档(规划中)
149
185
 
186
+ ## 赞助
187
+
188
+ 本项目的开发与维护感谢以下赞助者的支持:
189
+
190
+ **[河南创为铁路器材有限公司](https://www.chuangwit.com)**
191
+
150
192
  ## 授权
151
193
 
152
194
  - **代码**:[MIT](./LICENSE)
package/README_EN.md CHANGED
@@ -8,7 +8,7 @@
8
8
  [简体中文](./README.md) | English
9
9
 
10
10
  ![npm version](https://img.shields.io/npm/v/ocs-calculators)
11
- ![CI](https://github.com/showhoo/ocs-calculators/actions/workflows/ci.yml/badge.svg)
11
+ [![CI](https://github.com/showhoo/ocs-calculators/actions/workflows/ci.yml/badge.svg)](https://github.com/showhoo/ocs-calculators/actions/workflows/ci.yml)
12
12
  ![license](https://img.shields.io/npm/l/ocs-calculators)
13
13
  ![dependencies](https://img.shields.io/badge/dependencies-0-brightgreen)
14
14
 
@@ -46,7 +46,7 @@ const curve = tensionCurve(
46
46
  {
47
47
  baseTensionKN: 20,
48
48
  baseTempDegC: -20,
49
- weightPerLengthNPerM: 10.6222,
49
+ weightPerLengthNPerM: 10.61442,
50
50
  spanM: 55,
51
51
  elasticModulusGPa: 120,
52
52
  crossSectionMM2: 120,
@@ -78,9 +78,9 @@ This matches <https://www.itswe.com/calculator/tension/> exactly.
78
78
  | ✅ Available | Ampacity and thermal stability | `ampacity` |
79
79
  | ✅ Available | Dropper length | `dropper` |
80
80
  | ✅ Available | Wind deflection clearance | `wind` |
81
- | 📋 Planned | Contact wire wear | `wear` |
82
- | 📋 Planned | Copper weight | `copper` |
83
- | 📋 Planned | Compensation stroke | `stroke` |
81
+ | Available | Contact wire wear | `wear` |
82
+ | Available | Copper weight | `copper` |
83
+ | Available | Compensation stroke | `stroke` |
84
84
  | ✅ Available | Wave propagation speed | `wavespeed` |
85
85
  | ✅ Available | Voltage drop | `voltage-drop` |
86
86
  | ✅ Available | Curve stagger | `curve-stagger` |
@@ -133,6 +133,12 @@ src/<module>/
133
133
  └── <module>.test.ts # expected values taken from the online calculator
134
134
  ```
135
135
 
136
+ ## Sponsors
137
+
138
+ Development and maintenance of this project is supported by:
139
+
140
+ **[Henan Chuangwei Railway Equipment Co., Ltd.](https://www.chuangwit.com)** (河南创为铁路器材有限公司)
141
+
136
142
  ## License
137
143
 
138
144
  Code: [MIT](./LICENSE). Companion wiki content: CC BY-SA 4.0.
@@ -0,0 +1,17 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
+
3
+
4
+
5
+
6
+
7
+
8
+ var _chunkNBFOB2PIcjs = require('../chunk-NBFOB2PI.cjs');
9
+
10
+
11
+
12
+
13
+
14
+
15
+
16
+ exports.DEFAULT_BASE_AMBIENT_TEMP_DEG_C = _chunkNBFOB2PIcjs.DEFAULT_BASE_AMBIENT_TEMP_DEG_C; exports.ampacityDeratingFactor = _chunkNBFOB2PIcjs.ampacityDeratingFactor; exports.ampacityMeta = _chunkNBFOB2PIcjs.ampacityMeta; exports.deratedAmpacityA = _chunkNBFOB2PIcjs.deratedAmpacityA; exports.shortCircuitCheck = _chunkNBFOB2PIcjs.shortCircuitCheck; exports.shortCircuitMinSectionMM2 = _chunkNBFOB2PIcjs.shortCircuitMinSectionMM2;
17
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/home/runner/work/ocs-calculators/ocs-calculators/dist/ampacity/index.cjs"],"names":[],"mappings":"AAAA;AACE;AACA;AACA;AACA;AACA;AACA;AACF,yDAA8B;AAC9B;AACE;AACA;AACA;AACA;AACA;AACA;AACF,+aAAC","file":"/home/runner/work/ocs-calculators/ocs-calculators/dist/ampacity/index.cjs"}
@@ -0,0 +1,68 @@
1
+ import { C as CalculatorMeta } from '../types-C2OanO8N.cjs';
2
+
3
+ declare const ampacityMeta: CalculatorMeta;
4
+
5
+ /** 基准环境温度 T₀,℃(TB/T 2809-2017 标准环境) */
6
+ declare const DEFAULT_BASE_AMBIENT_TEMP_DEG_C = 25;
7
+ /** 载流量环境温度修正输入 */
8
+ interface AmpacityDeratingInput {
9
+ /** 基准载流量 I₀,A(标准环境 T₀ 下的持续载流量) */
10
+ readonly baseAmpacityA: number;
11
+ /** 最高允许工作温度 Tmax,℃(铜 95、铜合金 150) */
12
+ readonly maxAllowedTempDegC: number;
13
+ /** 最不利实际环境温度 Ta,℃ */
14
+ readonly ambientTempDegC: number;
15
+ /** 基准环境温度 T₀,℃。缺省 25 ℃ */
16
+ readonly baseAmbientTempDegC?: number;
17
+ }
18
+ interface AmpacityDeratingResult {
19
+ /** 修正系数,无量纲 */
20
+ readonly deratingFactor: number;
21
+ /** 修正后载流量 I(Ta),A */
22
+ readonly deratedAmpacityA: number;
23
+ }
24
+ /**
25
+ * 环境温度修正系数:√((Tmax − Ta) / (Tmax − T₀))。
26
+ *
27
+ * Ta 越接近允许温度,系数越小;Ta = T₀ 时为 1;Ta > Tmax 无解,直接抛错。
28
+ */
29
+ declare function ampacityDeratingFactor(input: AmpacityDeratingInput): number;
30
+ /**
31
+ * 修正后载流量:I(Ta) = I₀·√((Tmax − Ta)/(Tmax − T₀)),A。
32
+ *
33
+ * ⚠️ 修正式仅覆盖环境温度项;高海拔、隧道、日照叠加场景须另行叠加修正。
34
+ */
35
+ declare function deratedAmpacityA(input: AmpacityDeratingInput): number;
36
+ /** 热稳定校核判定结果 */
37
+ type ThermalStabilityVerdict = 'pass' | 'fail' | 'not-assessed';
38
+ interface ShortCircuitCheckInput {
39
+ /** 短路电流 I_k,kA(热稳定等效值,由供电计算给出) */
40
+ readonly shortCircuitCurrentKA: number;
41
+ /** 全切除时间 t_k,s */
42
+ readonly clearingTimeS: number;
43
+ /** 热稳定系数 C,A·√s/mm²(设计输入) */
44
+ readonly thermalCoefficientC: number;
45
+ /** 拟选截面,mm²。传 null 则仅输出最小截面,不判定 */
46
+ readonly selectedSectionMM2: number | null;
47
+ }
48
+ interface ShortCircuitCheckResult {
49
+ /** 最小热稳截面 S_min = I_k·√t_k / C,mm² */
50
+ readonly minSectionMM2: number;
51
+ readonly selectedSectionMM2: number | null;
52
+ /** 拟选截面判定 */
53
+ readonly verdict: ThermalStabilityVerdict;
54
+ }
55
+ /**
56
+ * 短路热稳定最小截面:S_min = I_k·√t_k / C,mm²。
57
+ *
58
+ * @param shortCircuitCurrentKA 短路电流,kA
59
+ * @param clearingTimeS 切除时间,s
60
+ * @param thermalCoefficientC 热稳定系数,A·√s/mm²
61
+ */
62
+ declare function shortCircuitMinSectionMM2(shortCircuitCurrentKA: number, clearingTimeS: number, thermalCoefficientC: number): number;
63
+ /**
64
+ * 短路热稳定校核:给出最小截面,并在提供拟选截面时判定是否满足 S ≥ S_min。
65
+ */
66
+ declare function shortCircuitCheck(input: ShortCircuitCheckInput): ShortCircuitCheckResult;
67
+
68
+ export { type AmpacityDeratingInput, type AmpacityDeratingResult, DEFAULT_BASE_AMBIENT_TEMP_DEG_C, type ShortCircuitCheckInput, type ShortCircuitCheckResult, type ThermalStabilityVerdict, ampacityDeratingFactor, ampacityMeta, deratedAmpacityA, shortCircuitCheck, shortCircuitMinSectionMM2 };
@@ -0,0 +1,68 @@
1
+ import { C as CalculatorMeta } from '../types-C2OanO8N.js';
2
+
3
+ declare const ampacityMeta: CalculatorMeta;
4
+
5
+ /** 基准环境温度 T₀,℃(TB/T 2809-2017 标准环境) */
6
+ declare const DEFAULT_BASE_AMBIENT_TEMP_DEG_C = 25;
7
+ /** 载流量环境温度修正输入 */
8
+ interface AmpacityDeratingInput {
9
+ /** 基准载流量 I₀,A(标准环境 T₀ 下的持续载流量) */
10
+ readonly baseAmpacityA: number;
11
+ /** 最高允许工作温度 Tmax,℃(铜 95、铜合金 150) */
12
+ readonly maxAllowedTempDegC: number;
13
+ /** 最不利实际环境温度 Ta,℃ */
14
+ readonly ambientTempDegC: number;
15
+ /** 基准环境温度 T₀,℃。缺省 25 ℃ */
16
+ readonly baseAmbientTempDegC?: number;
17
+ }
18
+ interface AmpacityDeratingResult {
19
+ /** 修正系数,无量纲 */
20
+ readonly deratingFactor: number;
21
+ /** 修正后载流量 I(Ta),A */
22
+ readonly deratedAmpacityA: number;
23
+ }
24
+ /**
25
+ * 环境温度修正系数:√((Tmax − Ta) / (Tmax − T₀))。
26
+ *
27
+ * Ta 越接近允许温度,系数越小;Ta = T₀ 时为 1;Ta > Tmax 无解,直接抛错。
28
+ */
29
+ declare function ampacityDeratingFactor(input: AmpacityDeratingInput): number;
30
+ /**
31
+ * 修正后载流量:I(Ta) = I₀·√((Tmax − Ta)/(Tmax − T₀)),A。
32
+ *
33
+ * ⚠️ 修正式仅覆盖环境温度项;高海拔、隧道、日照叠加场景须另行叠加修正。
34
+ */
35
+ declare function deratedAmpacityA(input: AmpacityDeratingInput): number;
36
+ /** 热稳定校核判定结果 */
37
+ type ThermalStabilityVerdict = 'pass' | 'fail' | 'not-assessed';
38
+ interface ShortCircuitCheckInput {
39
+ /** 短路电流 I_k,kA(热稳定等效值,由供电计算给出) */
40
+ readonly shortCircuitCurrentKA: number;
41
+ /** 全切除时间 t_k,s */
42
+ readonly clearingTimeS: number;
43
+ /** 热稳定系数 C,A·√s/mm²(设计输入) */
44
+ readonly thermalCoefficientC: number;
45
+ /** 拟选截面,mm²。传 null 则仅输出最小截面,不判定 */
46
+ readonly selectedSectionMM2: number | null;
47
+ }
48
+ interface ShortCircuitCheckResult {
49
+ /** 最小热稳截面 S_min = I_k·√t_k / C,mm² */
50
+ readonly minSectionMM2: number;
51
+ readonly selectedSectionMM2: number | null;
52
+ /** 拟选截面判定 */
53
+ readonly verdict: ThermalStabilityVerdict;
54
+ }
55
+ /**
56
+ * 短路热稳定最小截面:S_min = I_k·√t_k / C,mm²。
57
+ *
58
+ * @param shortCircuitCurrentKA 短路电流,kA
59
+ * @param clearingTimeS 切除时间,s
60
+ * @param thermalCoefficientC 热稳定系数,A·√s/mm²
61
+ */
62
+ declare function shortCircuitMinSectionMM2(shortCircuitCurrentKA: number, clearingTimeS: number, thermalCoefficientC: number): number;
63
+ /**
64
+ * 短路热稳定校核:给出最小截面,并在提供拟选截面时判定是否满足 S ≥ S_min。
65
+ */
66
+ declare function shortCircuitCheck(input: ShortCircuitCheckInput): ShortCircuitCheckResult;
67
+
68
+ export { type AmpacityDeratingInput, type AmpacityDeratingResult, DEFAULT_BASE_AMBIENT_TEMP_DEG_C, type ShortCircuitCheckInput, type ShortCircuitCheckResult, type ThermalStabilityVerdict, ampacityDeratingFactor, ampacityMeta, deratedAmpacityA, shortCircuitCheck, shortCircuitMinSectionMM2 };
@@ -0,0 +1,17 @@
1
+ import {
2
+ DEFAULT_BASE_AMBIENT_TEMP_DEG_C,
3
+ ampacityDeratingFactor,
4
+ ampacityMeta,
5
+ deratedAmpacityA,
6
+ shortCircuitCheck,
7
+ shortCircuitMinSectionMM2
8
+ } from "../chunk-746H65EQ.js";
9
+ export {
10
+ DEFAULT_BASE_AMBIENT_TEMP_DEG_C,
11
+ ampacityDeratingFactor,
12
+ ampacityMeta,
13
+ deratedAmpacityA,
14
+ shortCircuitCheck,
15
+ shortCircuitMinSectionMM2
16
+ };
17
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,119 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});// src/tension/meta.ts
2
+ var tensionMeta = {
3
+ name: "\u5F20\u529B-\u6E29\u5EA6\u5B89\u88C5\u66F2\u7EBF",
4
+ nameEn: "Tension-Temperature Installation Curve",
5
+ summary: "\u6309\u5F20\u529B-\u6E29\u5EA6\u72B6\u6001\u65B9\u7A0B\u6C42\u89E3\u5404\u6E29\u5EA6\u6863\u7684\u65BD\u5DE5\u5F20\u529B\u4E0E\u5F1B\u5EA6\uFF0C\u751F\u6210\u5B89\u88C5\u66F2\u7EBF\u8868\uFF1B\u652F\u6301\u5F53\u91CF\u8DE8\u8DDD\uFF08\u591A\u8DE8\u951A\u6BB5\uFF09\u4E0E\u8986\u51B0\u5DE5\u51B5\u6821\u6838\u3002",
6
+ formula: [
7
+ "\u72B6\u6001\u65B9\u7A0B\uFF1AT\u2082 \u2212 g\u2082\xB2l\xB2EA/(24T\u2082\xB2) = T\u2081 \u2212 g\u2081\xB2l\xB2EA/(24T\u2081\xB2) \u2212 \u03B1EA(t\u2082 \u2212 t\u2081)",
8
+ "\u8DE8\u4E2D\u5F1B\u5EA6\uFF08\u629B\u7269\u7EBF\u8FD1\u4F3C\uFF09\uFF1Af = gl\xB2/(8T)",
9
+ "\u5F53\u91CF\u8DE8\u8DDD\uFF1Al_D = \u221A(\u03A3l\u1D62\xB3 / \u03A3l\u1D62)",
10
+ "\u8986\u51B0\u8377\u8F7D\uFF08\u51B0\u7B52\u6A21\u578B\uFF09\uFF1Ag_ice = \u03C1_ice \xB7 g\u2080 \xB7 \u03C0 \xB7 b \xB7 (d + b)"
11
+ ],
12
+ references: [
13
+ "TB 10009-2016\u300A\u94C1\u8DEF\u7535\u529B\u7275\u5F15\u4F9B\u7535\u8BBE\u8BA1\u89C4\u8303\u300B\u2014\u2014 \u4EC5\u89C4\u5B9A\u63A5\u89E6\u7EBF\u6700\u5C0F\u5F20\u529B\u3001\u5F20\u529B\u786E\u5B9A\u539F\u5219\u4E0E\u5F20\u529B\u5DEE\u9650\u503C\uFF0C\u4E0D\u542B\u5F20\u529B-\u6E29\u5EA6\u72B6\u6001\u65B9\u7A0B\u672C\u8EAB",
14
+ "\u5F20\u529B-\u6E29\u5EA6\u72B6\u6001\u65B9\u7A0B\u4E3A\u901A\u7528\u67D4\u7D22\u72B6\u6001\u65B9\u7A0B\uFF0C\u5177\u4F53\u5F62\u5F0F\u4EE5\u8BBE\u8BA1\u6587\u4EF6\u53CA\u63A5\u89E6\u7F51\u8BBE\u8BA1\u6559\u6750/\u624B\u518C\u4E3A\u51C6",
15
+ "\u7EBF\u6750 E / \u03B1 / \u7EBF\u5BC6\u5EA6\u4E3A\u6807\u79F0\u53C2\u8003\u503C\uFF0C\u5B9E\u9645\u4EE5\u4EA7\u54C1\u6280\u672F\u6761\u4EF6\u4E3A\u51C6"
16
+ ],
17
+ scope: [
18
+ "\u5F39\u6027\u6A21\u91CF E\uFF1A50 ~ 200 GPa",
19
+ "\u622A\u9762\u79EF A\uFF1A50 ~ 250 mm\xB2",
20
+ "\u8DE8\u8DDD l\uFF1A20 ~ 90 m",
21
+ "\u5F1B\u5EA6\u91C7\u7528\u629B\u7269\u7EBF\u8FD1\u4F3C\uFF0C\u4E0D\u9002\u7528\u4E8E\u5927\u5F1B\u5EA6\uFF08f/l > 1/10\uFF09\u5DE5\u51B5",
22
+ "\u8986\u51B0\u6A21\u578B\u4E3A\u5747\u5300\u51B0\u7B52\u5047\u8BBE\uFF0C\u4E0D\u8003\u8651\u4E0D\u5747\u5300\u8986\u51B0\u4E0E\u8131\u51B0\u8DF3\u8DC3"
23
+ ],
24
+ disclaimer: "\u672C\u5DE5\u5177\u7ED3\u679C\u4EC5\u4F9B\u53C2\u8003\uFF0C\u5DE5\u7A0B\u5E94\u7528\u4EE5\u8BBE\u8BA1\u6587\u4EF6\u4E3A\u51C6\u3002\u8BE6\u89C1 DISCLAIMER.md\u3002",
25
+ online: "https://www.itswe.com/calculator/tension/"
26
+ };
27
+
28
+ // src/tension/index.ts
29
+ function sagM(weightPerLengthNPerM, spanM, tensionN) {
30
+ if (!(tensionN > 0)) {
31
+ throw new RangeError(`\u5F20\u529B\u5FC5\u987B\u4E3A\u6B63\u6570\uFF0C\u6536\u5230 ${tensionN} N`);
32
+ }
33
+ return weightPerLengthNPerM * spanM * spanM / (8 * tensionN);
34
+ }
35
+ function equivalentSpanM(spansM) {
36
+ if (spansM.length === 0) {
37
+ throw new RangeError("\u8DE8\u8DDD\u6570\u7EC4\u4E0D\u80FD\u4E3A\u7A7A");
38
+ }
39
+ let sumCubed = 0;
40
+ let sum = 0;
41
+ for (const s of spansM) {
42
+ if (!(s > 0)) {
43
+ throw new RangeError(`\u8DE8\u8DDD\u5FC5\u987B\u4E3A\u6B63\u6570\uFF0C\u6536\u5230 ${s}`);
44
+ }
45
+ sumCubed += s * s * s;
46
+ sum += s;
47
+ }
48
+ return Math.sqrt(sumCubed / sum);
49
+ }
50
+ function stateCoefficientK(weightPerLengthNPerM, spanM, elasticModulusGPa, crossSectionMM2) {
51
+ const ePa = elasticModulusGPa * 1e9;
52
+ const aM2 = crossSectionMM2 * 1e-6;
53
+ return weightPerLengthNPerM * weightPerLengthNPerM * spanM * spanM * ePa * aM2 / 24;
54
+ }
55
+ function solveTensionN(K, targetN) {
56
+ const hOf = (t) => t - K / (t * t) - targetN;
57
+ let lo = Math.max(targetN, 1e-9);
58
+ let hi = lo + 1;
59
+ let guard = 0;
60
+ while (hOf(hi) < 0 && guard++ < 200) {
61
+ hi = lo + (hi - lo) * 2;
62
+ if (!Number.isFinite(hi)) break;
63
+ }
64
+ let iterations = 0;
65
+ for (let i = 0; i < 200; i++) {
66
+ iterations = i + 1;
67
+ const mid = 0.5 * (lo + hi);
68
+ if (hOf(mid) < 0) {
69
+ lo = mid;
70
+ } else {
71
+ hi = mid;
72
+ }
73
+ if (hi - lo <= 1e-12 * Math.max(1, hi)) break;
74
+ }
75
+ const tensionN = 0.5 * (lo + hi);
76
+ return { tensionN, iterations, residualN: hOf(tensionN) };
77
+ }
78
+ function tensionAt(input) {
79
+ const T1N = input.baseTensionKN * 1e3;
80
+ if (!(T1N > 0)) {
81
+ throw new RangeError(`\u57FA\u51C6\u5F20\u529B\u5FC5\u987B\u4E3A\u6B63\u6570\uFF0C\u6536\u5230 ${input.baseTensionKN} kN`);
82
+ }
83
+ if (!(input.spanM > 0)) {
84
+ throw new RangeError(`\u8DE8\u8DDD\u5FC5\u987B\u4E3A\u6B63\u6570\uFF0C\u6536\u5230 ${input.spanM} m`);
85
+ }
86
+ const K = stateCoefficientK(
87
+ input.weightPerLengthNPerM,
88
+ input.spanM,
89
+ input.elasticModulusGPa,
90
+ input.crossSectionMM2
91
+ );
92
+ const ePa = input.elasticModulusGPa * 1e9;
93
+ const aM2 = input.crossSectionMM2 * 1e-6;
94
+ const alphaEA = input.expansionPerDegC * ePa * aM2;
95
+ const fBase = T1N - K / (T1N * T1N);
96
+ const target = fBase - alphaEA * (input.targetTempDegC - input.baseTempDegC);
97
+ const { tensionN, iterations, residualN } = solveTensionN(K, target);
98
+ return {
99
+ targetTempDegC: input.targetTempDegC,
100
+ tensionKN: tensionN / 1e3,
101
+ sagM: sagM(input.weightPerLengthNPerM, input.spanM, tensionN),
102
+ iterations,
103
+ residualN
104
+ };
105
+ }
106
+ function tensionCurve(base, tempsDegC) {
107
+ return tempsDegC.map((t) => tensionAt({ ...base, targetTempDegC: t }));
108
+ }
109
+
110
+
111
+
112
+
113
+
114
+
115
+
116
+
117
+
118
+ exports.tensionMeta = tensionMeta; exports.sagM = sagM; exports.equivalentSpanM = equivalentSpanM; exports.stateCoefficientK = stateCoefficientK; exports.solveTensionN = solveTensionN; exports.tensionAt = tensionAt; exports.tensionCurve = tensionCurve;
119
+ //# sourceMappingURL=chunk-3ERFRRHZ.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/home/runner/work/ocs-calculators/ocs-calculators/dist/chunk-3ERFRRHZ.cjs","../src/tension/meta.ts","../src/tension/index.ts"],"names":[],"mappings":"AAAA;ACEO,IAAM,YAAA,EAA8B;AAAA,EACzC,IAAA,EAAM,mDAAA;AAAA,EACN,MAAA,EAAQ,wCAAA;AAAA,EACR,OAAA,EACE,2TAAA;AAAA,EACF,OAAA,EAAS;AAAA,IACP,6KAAA;AAAA,IACA,yFAAA;AAAA,IACA,+EAAA;AAAA,IACA;AAAA,EACF,CAAA;AAAA,EACA,UAAA,EAAY;AAAA,IACV,yUAAA;AAAA,IACA,8OAAA;AAAA,IACA;AAAA,EACF,CAAA;AAAA,EACA,KAAA,EAAO;AAAA,IACL,8CAAA;AAAA,IACA,2CAAA;AAAA,IACA,+BAAA;AAAA,IACA,0IAAA;AAAA,IACA;AAAA,EACF,CAAA;AAAA,EACA,UAAA,EAAY,sKAAA;AAAA,EACZ,MAAA,EAAQ;AACV,CAAA;ADDA;AACA;AEmBO,SAAS,IAAA,CACd,oBAAA,EACA,KAAA,EACA,QAAA,EACQ;AACR,EAAA,GAAA,CAAI,CAAA,CAAE,SAAA,EAAW,CAAA,CAAA,EAAI;AACnB,IAAA,MAAM,IAAI,UAAA,CAAW,CAAA,6DAAA,EAAc,QAAQ,CAAA,EAAA,CAAI,CAAA;AAAA,EACjD;AACA,EAAA,OAAQ,qBAAA,EAAuB,MAAA,EAAQ,MAAA,EAAA,CAAU,EAAA,EAAI,QAAA,CAAA;AACvD;AAOO,SAAS,eAAA,CAAgB,MAAA,EAAmC;AACjE,EAAA,GAAA,CAAI,MAAA,CAAO,OAAA,IAAW,CAAA,EAAG;AACvB,IAAA,MAAM,IAAI,UAAA,CAAW,kDAAU,CAAA;AAAA,EACjC;AACA,EAAA,IAAI,SAAA,EAAW,CAAA;AACf,EAAA,IAAI,IAAA,EAAM,CAAA;AACV,EAAA,IAAA,CAAA,MAAW,EAAA,GAAK,MAAA,EAAQ;AACtB,IAAA,GAAA,CAAI,CAAA,CAAE,EAAA,EAAI,CAAA,CAAA,EAAI;AACZ,MAAA,MAAM,IAAI,UAAA,CAAW,CAAA,6DAAA,EAAc,CAAC,CAAA,CAAA;AACtC,IAAA;AACoB,IAAA;AACb,IAAA;AACT,EAAA;AAC+B,EAAA;AACjC;AAgBU;AACwB,EAAA;AACF,EAAA;AACqD,EAAA;AACrF;AAY+D;AACR,EAAA;AAEtB,EAAA;AACjB,EAAA;AACF,EAAA;AACyB,EAAA;AACb,IAAA;AACI,IAAA;AAC5B,EAAA;AAEiB,EAAA;AACa,EAAA;AACX,IAAA;AACO,IAAA;AACN,IAAA;AACX,MAAA;AACA,IAAA;AACA,MAAA;AACP,IAAA;AACwC,IAAA;AAC1C,EAAA;AAE6B,EAAA;AAC2B,EAAA;AAC1D;AAOmE;AAC/B,EAAA;AAClB,EAAA;AACO,IAAA;AACvB,EAAA;AACwB,EAAA;AACa,IAAA;AACrC,EAAA;AAEU,EAAA;AACF,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACR,EAAA;AACsC,EAAA;AACF,EAAA;AACW,EAAA;AAEhB,EAAA;AACgC,EAAA;AAEI,EAAA;AAE5D,EAAA;AACiB,IAAA;AACA,IAAA;AACsC,IAAA;AAC5D,IAAA;AACA,IAAA;AACF,EAAA;AACF;AAQmB;AACoD,EAAA;AACvE;AFzE6F;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"/home/runner/work/ocs-calculators/ocs-calculators/dist/chunk-3ERFRRHZ.cjs","sourcesContent":[null,"import type { CalculatorMeta } from '../types';\n\nexport const tensionMeta: CalculatorMeta = {\n name: '张力-温度安装曲线',\n nameEn: 'Tension-Temperature Installation Curve',\n summary:\n '按张力-温度状态方程求解各温度档的施工张力与弛度,生成安装曲线表;支持当量跨距(多跨锚段)与覆冰工况校核。',\n formula: [\n '状态方程:T₂ − g₂²l²EA/(24T₂²) = T₁ − g₁²l²EA/(24T₁²) − αEA(t₂ − t₁)',\n '跨中弛度(抛物线近似):f = gl²/(8T)',\n '当量跨距:l_D = √(Σlᵢ³ / Σlᵢ)',\n '覆冰荷载(冰筒模型):g_ice = ρ_ice · g₀ · π · b · (d + b)',\n ],\n references: [\n 'TB 10009-2016《铁路电力牵引供电设计规范》—— 仅规定接触线最小张力、张力确定原则与张力差限值,不含张力-温度状态方程本身',\n '张力-温度状态方程为通用柔索状态方程,具体形式以设计文件及接触网设计教材/手册为准',\n '线材 E / α / 线密度为标称参考值,实际以产品技术条件为准',\n ],\n scope: [\n '弹性模量 E:50 ~ 200 GPa',\n '截面积 A:50 ~ 250 mm²',\n '跨距 l:20 ~ 90 m',\n '弛度采用抛物线近似,不适用于大弛度(f/l > 1/10)工况',\n '覆冰模型为均匀冰筒假设,不考虑不均匀覆冰与脱冰跳跃',\n ],\n disclaimer: '本工具结果仅供参考,工程应用以设计文件为准。详见 DISCLAIMER.md。',\n online: 'https://www.itswe.com/calculator/tension/',\n};\n","export { tensionMeta } from './meta';\n\n/** 单个温度档的输入参数 */\nexport interface TensionPointInput {\n /** 基准工况张力 T₁,kN */\n readonly baseTensionKN: number;\n /** 基准温度 t₁,℃ */\n readonly baseTempDegC: number;\n /** 目标温度 t₂,℃ */\n readonly targetTempDegC: number;\n /** 单位自重荷载 g,N/m(覆冰工况传自重与冰重的组合值) */\n readonly weightPerLengthNPerM: number;\n /** 计算跨距 l,m(多跨锚段传当量跨距 l_D) */\n readonly spanM: number;\n /** 弹性模量 E,GPa */\n readonly elasticModulusGPa: number;\n /** 截面积 A,mm² */\n readonly crossSectionMM2: number;\n /** 线膨胀系数 α,1/℃ */\n readonly expansionPerDegC: number;\n}\n\n/** 安装曲线公共参数(不含目标温度) */\nexport type TensionCurveInput = Omit<TensionPointInput, 'targetTempDegC'>;\n\n/** 单个温度档的计算结果 */\nexport interface TensionResult {\n /** 目标温度 t₂,℃ */\n readonly targetTempDegC: number;\n /** 该温度下的张力 T₂,kN */\n readonly tensionKN: number;\n /** 跨中弛度 f,m(抛物线近似) */\n readonly sagM: number;\n /** 求解迭代次数 */\n readonly iterations: number;\n /** 状态方程残差,N(用于校验收敛,应接近 0) */\n readonly residualN: number;\n}\n\n/**\n * 跨中弛度,抛物线近似:f = gl²/(8T)\n * @param weightPerLengthNPerM 单位自重荷载 g,N/m\n * @param spanM 跨距 l,m\n * @param tensionN 张力 T,N\n * @returns 弛度 f,m\n */\nexport function sagM(\n weightPerLengthNPerM: number,\n spanM: number,\n tensionN: number,\n): number {\n if (!(tensionN > 0)) {\n throw new RangeError(`张力必须为正数,收到 ${tensionN} N`);\n }\n return (weightPerLengthNPerM * spanM * spanM) / (8 * tensionN);\n}\n\n/**\n * 当量跨距(多跨锚段归算):l_D = √(Σlᵢ³ / Σlᵢ)\n * @param spansM 各跨跨距,m\n * @returns 当量跨距 l_D,m\n */\nexport function equivalentSpanM(spansM: readonly number[]): number {\n if (spansM.length === 0) {\n throw new RangeError('跨距数组不能为空');\n }\n let sumCubed = 0;\n let sum = 0;\n for (const s of spansM) {\n if (!(s > 0)) {\n throw new RangeError(`跨距必须为正数,收到 ${s}`);\n }\n sumCubed += s * s * s;\n sum += s;\n }\n return Math.sqrt(sumCubed / sum);\n}\n\n/**\n * 覆冰荷载(均匀冰筒模型)与 icing 模块共用 `src/common/ice.ts`,\n * 由根 index 统一导出,此处不再重复定义。\n */\n\n/**\n * 状态方程系数 K = g²l²EA/24,单位 N³。\n * 使状态方程可写成 F(T) = T − K/T² 的紧凑形式。\n */\nexport function stateCoefficientK(\n weightPerLengthNPerM: number,\n spanM: number,\n elasticModulusGPa: number,\n crossSectionMM2: number,\n): number {\n const ePa = elasticModulusGPa * 1e9;\n const aM2 = crossSectionMM2 * 1e-6;\n return (weightPerLengthNPerM * weightPerLengthNPerM * spanM * spanM * ePa * aM2) / 24;\n}\n\n/**\n * 求解状态方程 T − K/T² = target 的正根。\n *\n * h(T) = T − K/T² − target 在 T > 0 上严格单调递增(h′ = 1 + 2K/T³ > 0),\n * 因此用二分法必定收敛。又由 T = target + K/T² 可知 T > target,\n * 可直接取 target 作为下界,bracket 很紧。\n */\nexport function solveTensionN(\n K: number,\n targetN: number,\n): { tensionN: number; iterations: number; residualN: number } {\n const hOf = (t: number): number => t - K / (t * t) - targetN;\n\n let lo = Math.max(targetN, 1e-9);\n let hi = lo + 1;\n let guard = 0;\n while (hOf(hi) < 0 && guard++ < 200) {\n hi = lo + (hi - lo) * 2;\n if (!Number.isFinite(hi)) break;\n }\n\n let iterations = 0;\n for (let i = 0; i < 200; i++) {\n iterations = i + 1;\n const mid = 0.5 * (lo + hi);\n if (hOf(mid) < 0) {\n lo = mid;\n } else {\n hi = mid;\n }\n if (hi - lo <= 1e-12 * Math.max(1, hi)) break;\n }\n\n const tensionN = 0.5 * (lo + hi);\n return { tensionN, iterations, residualN: hOf(tensionN) };\n}\n\n/**\n * 求某一温度档的张力与弛度。\n *\n * 状态方程:T₂ − g²l²EA/(24T₂²) = T₁ − g²l²EA/(24T₁²) − αEA(t₂ − t₁)\n */\nexport function tensionAt(input: TensionPointInput): TensionResult {\n const T1N = input.baseTensionKN * 1000;\n if (!(T1N > 0)) {\n throw new RangeError(`基准张力必须为正数,收到 ${input.baseTensionKN} kN`);\n }\n if (!(input.spanM > 0)) {\n throw new RangeError(`跨距必须为正数,收到 ${input.spanM} m`);\n }\n\n const K = stateCoefficientK(\n input.weightPerLengthNPerM,\n input.spanM,\n input.elasticModulusGPa,\n input.crossSectionMM2,\n );\n const ePa = input.elasticModulusGPa * 1e9;\n const aM2 = input.crossSectionMM2 * 1e-6;\n const alphaEA = input.expansionPerDegC * ePa * aM2;\n\n const fBase = T1N - K / (T1N * T1N);\n const target = fBase - alphaEA * (input.targetTempDegC - input.baseTempDegC);\n\n const { tensionN, iterations, residualN } = solveTensionN(K, target);\n\n return {\n targetTempDegC: input.targetTempDegC,\n tensionKN: tensionN / 1000,\n sagM: sagM(input.weightPerLengthNPerM, input.spanM, tensionN),\n iterations,\n residualN,\n };\n}\n\n/**\n * 批量求解多个温度档,生成安装曲线表。\n */\nexport function tensionCurve(\n base: TensionCurveInput,\n tempsDegC: readonly number[],\n): TensionResult[] {\n return tempsDegC.map((t) => tensionAt({ ...base, targetTempDegC: t }));\n}\n"]}
@@ -0,0 +1,107 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } }// src/curve-stagger/meta.ts
2
+ var curveStaggerMeta = {
3
+ name: "\u66F2\u7EBF\u62C9\u51FA\u503C\u6821\u6838",
4
+ nameEn: "Curve Stagger Clearance Check",
5
+ summary: "\u8BA1\u7B97\u66F2\u7EBF\u533A\u6BB5\u8DE8\u4E2D\u7EFC\u5408\u504F\u79FB\uFF08\u62C9\u51FA\u503C\u5747\u503C\u3001\u66F2\u7EBF\u77E2\u5EA6\u3001\u98CE\u504F\u7684\u7EC4\u5408\uFF09\uFF0C\u4E0E\u53D7\u7535\u5F13\u5BB9\u8BB8\u504F\u79FB\u6BD4\u8F83\u7ED9\u51FA\u5224\u5B9A\u3002",
6
+ formula: [
7
+ "\u5E73\u5747\u62C9\u51FA\u503C\uFF1A\u0101 = (a\u2081 + a\u2082) / 2",
8
+ "\u66F2\u7EBF\u77E2\u5EA6\uFF1Ac = l\xB2 / (8R)\uFF08\u76F4\u7EBF\u6BB5 R = \u221E \u65F6 c = 0\uFF09",
9
+ "\u8D85\u9AD8\u6A2A\u79FB\uFF1A\u03B4 = H\xB7h / l\u2080",
10
+ "\u8DE8\u4E2D\u98CE\u504F\uFF1Ap_w = (\xBD\xB7\u03C1\xB7v\xB2\xB7d\xB7\u03B1) \xB7 l\xB2 / (8T)\uFF08\u53D6\u98CE\u5411\u5782\u76F4\u7EBF\u8DEF\u7684\u6700\u4E0D\u5229\u5DE5\u51B5\uFF09",
11
+ "\u7EFC\u5408\u504F\u79FB\uFF1Ae = max(|\u0101 + c|, |\u0101 \u2212 c|) + p_w \u2264 [e]"
12
+ ],
13
+ references: [
14
+ "\u4F9D\u636E\u672C\u7AD9 \u62C9\u51FA\u503C\u8BBE\u8BA1 \u6761\u76EE",
15
+ "\u98CE\u504F\u53D6\u98CE\u5411\u5782\u76F4\u7EBF\u8DEF\u7684\u6700\u4E0D\u5229\u5DE5\u51B5\uFF08sin\xB2\u03B8 = 1\uFF09",
16
+ "\u5BB9\u8BB8\u504F\u79FB [e] \u6309\u53D7\u7535\u5F13\u52A8\u6001\u5305\u7EDC\u7EBF\u53D6\u503C\uFF0C\u4EE5\u8BBE\u8BA1\u6587\u4EF6\u4E3A\u51C6"
17
+ ],
18
+ scope: [
19
+ "\u66F2\u7EBF\u534A\u5F84 R\uFF1A0 ~ 20000 m\uFF08\u76F4\u7EBF\u4F20 0 \u6216 Infinity\uFF09",
20
+ "\u8DE8\u8DDD l\uFF1A20 ~ 80 m",
21
+ "\u62C9\u51FA\u503C a\u2081/a\u2082\uFF1A\u22120.6 ~ 0.6 m\uFF08\u66F2\u7EBF\u5185\u4FA7\u4E3A\u6B63\uFF09",
22
+ "\u98CE\u901F v\uFF1A0 ~ 60 m/s",
23
+ "\u7EBF\u7D22\u76F4\u5F84 d\uFF1A1 ~ 30 mm",
24
+ "\u98CE\u8F7D\u4F53\u578B\u7CFB\u6570 \u03B1\uFF1A0.5 ~ 2",
25
+ "\u5F20\u529B T\uFF1A5 ~ 40 kN",
26
+ "\u6ED1\u677F\u9762\u8DDD\u8F68\u9762 H\uFF1A4 ~ 8 m\uFF1B\u5916\u8F68\u8D85\u9AD8 h\uFF1A0 ~ 0.25 m\uFF1B\u8F68\u8DDD l\u2080 \u9ED8\u8BA4 1.435 m",
27
+ "\u26A0\uFE0F \u7AD9\u70B9\u6E90\u7801\u7684 JSDoc \u5199\u660E\u7EFC\u5408\u504F\u79FB\u542B\u8D85\u9AD8\u6A2A\u79FB\u9879 \u2213\u03B4\uFF0C\u4F46\u5B9E\u73B0\u4E2D \u03B4 \u4EC5\u8BA1\u7B97\u8FD4\u56DE\u3001\u672A\u53C2\u4E0E e \u7684\u5408\u6210\u3002\u672C\u5E93\u6309\u5B9E\u73B0\u884C\u4E3A\u5BF9\u9F50\uFF0C\u8BE6\u89C1\u6D4B\u8BD5\u4E2D\u7684\u8BF4\u660E"
28
+ ],
29
+ disclaimer: "\u672C\u5DE5\u5177\u7ED3\u679C\u4EC5\u4F9B\u53C2\u8003\uFF0C\u5DE5\u7A0B\u5E94\u7528\u4EE5\u8BBE\u8BA1\u6587\u4EF6\u4E3A\u51C6\u3002\u8BE6\u89C1 DISCLAIMER.md\u3002",
30
+ online: "https://www.itswe.com/calculator/curve-stagger/"
31
+ };
32
+
33
+ // src/curve-stagger/index.ts
34
+ var STANDARD_GAUGE_M = 1.435;
35
+ var DEFAULT_PANTOGRAPH_HEIGHT_M = 6;
36
+ function versineM(spanM, curveRadiusM) {
37
+ if (!(spanM > 0)) {
38
+ throw new RangeError(`\u8DE8\u8DDD\u5FC5\u987B\u4E3A\u6B63\u6570\uFF0C\u6536\u5230 ${spanM} m`);
39
+ }
40
+ if (!(curveRadiusM > 0) || !Number.isFinite(curveRadiusM)) {
41
+ return 0;
42
+ }
43
+ return spanM * spanM / (8 * curveRadiusM);
44
+ }
45
+ function cantShiftM(cantM, pantographHeightM = DEFAULT_PANTOGRAPH_HEIGHT_M, gaugeM = STANDARD_GAUGE_M) {
46
+ if (!(cantM >= 0)) {
47
+ throw new RangeError(`\u5916\u8F68\u8D85\u9AD8\u4E0D\u80FD\u4E3A\u8D1F\uFF0C\u6536\u5230 ${cantM} m`);
48
+ }
49
+ if (!(pantographHeightM > 0)) {
50
+ throw new RangeError(`\u6ED1\u677F\u9762\u8DDD\u8F68\u9762\u5FC5\u987B\u4E3A\u6B63\u6570\uFF0C\u6536\u5230 ${pantographHeightM} m`);
51
+ }
52
+ if (!(gaugeM > 0)) {
53
+ throw new RangeError(`\u8F68\u8DDD\u5FC5\u987B\u4E3A\u6B63\u6570\uFF0C\u6536\u5230 ${gaugeM} m`);
54
+ }
55
+ return pantographHeightM * cantM / gaugeM;
56
+ }
57
+ function curveStaggerCheck(input) {
58
+ const { spanM, stagger1M, stagger2M, wireDiameterM, dragCoefficient, tensionN } = input;
59
+ if (!(tensionN > 0)) {
60
+ throw new RangeError(`\u5F20\u529B\u5FC5\u987B\u4E3A\u6B63\u6570\uFF0C\u6536\u5230 ${tensionN} N`);
61
+ }
62
+ if (!(wireDiameterM > 0)) {
63
+ throw new RangeError(`\u7EBF\u7D22\u76F4\u5F84\u5FC5\u987B\u4E3A\u6B63\u6570\uFF0C\u6536\u5230 ${wireDiameterM} m`);
64
+ }
65
+ if (!(dragCoefficient > 0)) {
66
+ throw new RangeError(`\u98CE\u8F7D\u4F53\u578B\u7CFB\u6570\u5FC5\u987B\u4E3A\u6B63\u6570\uFF0C\u6536\u5230 ${dragCoefficient}`);
67
+ }
68
+ if (!(input.windSpeedMPerS >= 0)) {
69
+ throw new RangeError(`\u98CE\u901F\u4E0D\u80FD\u4E3A\u8D1F\uFF0C\u6536\u5230 ${input.windSpeedMPerS} m/s`);
70
+ }
71
+ if (!(input.allowableOffsetM > 0)) {
72
+ throw new RangeError(`\u5BB9\u8BB8\u504F\u79FB\u5FC5\u987B\u4E3A\u6B63\u6570\uFF0C\u6536\u5230 ${input.allowableOffsetM} m`);
73
+ }
74
+ const meanStaggerM = (stagger1M + stagger2M) / 2;
75
+ const c = versineM(spanM, input.curveRadiusM);
76
+ const delta = cantShiftM(
77
+ _nullishCoalesce(input.cantM, () => ( 0)),
78
+ _nullishCoalesce(input.pantographHeightM, () => ( DEFAULT_PANTOGRAPH_HEIGHT_M)),
79
+ _nullishCoalesce(input.gaugeM, () => ( STANDARD_GAUGE_M))
80
+ );
81
+ const rhoAir = 1.225;
82
+ const windLoadNPerM = 0.5 * rhoAir * input.windSpeedMPerS * input.windSpeedMPerS * wireDiameterM * dragCoefficient;
83
+ const pw = windLoadNPerM * spanM * spanM / (8 * tensionN);
84
+ const offsetPlusM = Math.abs(meanStaggerM + c) + pw;
85
+ const offsetMinusM = Math.abs(meanStaggerM - c) + pw;
86
+ const maxOffsetM = Math.max(offsetPlusM, offsetMinusM);
87
+ return {
88
+ meanStaggerM,
89
+ versineM: c,
90
+ cantShiftM: delta,
91
+ windOffsetM: pw,
92
+ offsetPlusM,
93
+ offsetMinusM,
94
+ maxOffsetM,
95
+ passes: maxOffsetM <= input.allowableOffsetM
96
+ };
97
+ }
98
+
99
+
100
+
101
+
102
+
103
+
104
+
105
+
106
+ exports.curveStaggerMeta = curveStaggerMeta; exports.STANDARD_GAUGE_M = STANDARD_GAUGE_M; exports.DEFAULT_PANTOGRAPH_HEIGHT_M = DEFAULT_PANTOGRAPH_HEIGHT_M; exports.versineM = versineM; exports.cantShiftM = cantShiftM; exports.curveStaggerCheck = curveStaggerCheck;
107
+ //# sourceMappingURL=chunk-4UU7WA7N.cjs.map