ocs-calculators 0.1.0 → 0.1.1

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.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,19 @@
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.1] - 2026-09-05
7
+
8
+ ### 修复
9
+
10
+ - **补回 `wind`(风偏限界校验)与 `wear`(接触线磨耗率)两个模块的源码**。
11
+ 0.1.0 的 npm 包 dist 中已包含二者,但对应源码目录(`src/wind/`、`src/wear/`)
12
+ 未一并提交,导致从仓库克隆后 `typecheck` / `build` 失败。0.1.1 起仓库与
13
+ 发布包内容一致。
14
+
15
+ ### 新增
16
+
17
+ - `wind` / `wear` 模块单元测试(站点默认输入、物理性质与输入校验)
18
+
6
19
  ## [0.1.0] - 2026-08-31
7
20
 
8
21
  首个公开版本。覆盖思维接触网百科全部 12 个在线计算器。
@@ -89,12 +102,30 @@
89
102
  - 跨中弛度抛物线近似 `f = gl²/(8T)`
90
103
  - 当量跨距归算 `l_D = √(Σlᵢ³/Σlᵢ)`
91
104
  - 覆冰荷载冰筒模型 `g_ice = ρ_ice·g₀·π·b·(d+b)`
92
- - 15 个单元测试,逐行回归站点已发布的输出表(张力误差 ≤ 0.02%)
105
+ - 15 个单元测试,逐行回归站点已发布的输出表
93
106
  - `wire-specs.ts` 线材参数预设(CTHM-120 / CTHM-150 / CTHA-120)
94
107
  - `CalculatorMeta` 元信息规范:公式、依据标准、适用范围、免责声明
95
108
  - `DISCLAIMER.md` 工程免责声明
96
109
 
97
- ### 待确认
110
+ ## 自重口径确认记录
111
+
112
+ 线材自重取值口径已于 2026-08-31 确认并统一,原「待确认」项关闭。
98
113
 
99
- - 线材自重取值口径:标称密度 8.94 g/cm³ 反算得 g ≈ 10.524 N/m
100
- 站点输出表反算得 g 10.62 N/m(+0.9%)。当前采用后者以复现站点输出。
114
+ - **结论**:线密度取标准「参考单位质量」表值,CTHM-120 1082 kg/km
115
+ 自重 `g = 1.082 × 9.81 = 10.61442 N/m`。
116
+ - **口径根因**:标准的 8.94 g/cm³ 是配「计算截面」用的,不是配「标称截面」。
117
+ `CT 120|标称 120|计算截面 121|参考单位质量 1082 kg/km`,
118
+ 121 × 8.94 × 1e-3 = 1.08174 ≈ 1.082 kg/m。
119
+ 早期用标称截面 120 推算得 1.0728 kg/m(g ≈ 10.524 N/m),偏低约 0.86%。
120
+ - **依据**:TB/T 2810-2017(纯铜)、TB/T 2821-2017(铜银)规格尺寸表;
121
+ 与站点 `/calculator/tension/` 预设 `rho=1.082`、表单默认值 `10.61`、
122
+ 本库 `TB2809_WIRE_PARAMS.unitWeightKgPerKm = 1082` 三处同源。
123
+ - **废弃值**:回归表反算出的魔数 `10.6222`(偏高约 0.07%)已替换。
124
+ 该反算之所以偏差,是因为 g 在状态方程中仅以 `g²l²EA/24` 项出现(量级 0.006 kN),
125
+ 而 `αEA·Δt` 项有 15 kN——g 偏差 1% 只让张力变化约 0.001%,弛度则随 g 线性变化,
126
+ 张力逐位一致对 g 的约束极弱。
127
+ - **代码变更**:`wire-specs.ts` 预设改用标准参考单位质量表值,
128
+ 新增 `calculatedSectionMM2` / `STANDARD_UNIT_WEIGHT_KG_PER_KM` /
129
+ `unitWeightToKgPerM`;`deriveLinearMassKgPerM` 文档注明须传计算截面。
130
+ `tension.test.ts` 回归常量改为 10.61442,0℃ 行弛度期望值由 0.261 修正为 0.260
131
+ (该行原为站点旧版本输出快照中的孤点)。
package/README.md CHANGED
@@ -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,
@@ -119,11 +119,26 @@ console.log(tensionMeta.disclaimer); // 免责声明
119
119
 
120
120
  详见 [DISCLAIMER.md](./DISCLAIMER.md)。
121
121
 
122
- ## 开放问题
122
+ ## 自重口径(已确认)
123
123
 
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%,疑似计入了吊弦、线夹、接头的等效附加荷载。
124
+ 线密度取标准「参考单位质量」表值,而非由截面推算。标准表分两列,
125
+ `CT 120|标称截面 120|计算截面 121|参考单位质量 1082 kg/km`,
126
+ 注「参考单位质量按密度 8.94 g/cm³ 计算」——这个 8.94 g/cm³ 是配**计算截面**
127
+ (把尺寸公差计入后的截面)用的,不是配标称截面:
128
+ `121 × 8.94 × 1e-3 = 1.08174 ≈ 1.082 kg/m`。
125
129
 
126
- 本库回归测试采用反算值(10.6222 N/m)以复现站点输出。确认口径后我们会统一,欢迎在 issue 里说明。
130
+ 因此 CTHM-120 自重 `g = 1.082 × 9.81 = 10.61442 N/m`,
131
+ 与站点 `/calculator/tension/` 的预设 `rho=1.082`、表单默认值 `10.61`、
132
+ 以及本库 `TB2809_WIRE_PARAMS` 的 `1082` 三处同源。
133
+
134
+ 依据:TB/T 2810-2017(纯铜)、TB/T 2821-2017(铜银)规格尺寸表。
135
+
136
+ 早期版本按标称截面 120 推算得 `1.0728 kg/m`(g ≈ 10.524 N/m),比标准值低约 0.86%,
137
+ 另有一版用回归表反算出魔数 `10.6222`,偏高约 0.07%,两者均已废弃。
138
+
139
+ 顺带说明为什么仅靠回归表约不动 g:g 在状态方程里以 `g²l²EA/24` 项出现,
140
+ 量级只有 0.006 kN,而 `αEA·Δt` 项有 15 kN。g 偏差 1% 只让张力变化约 0.001%,
141
+ 弛度则随 g 线性变化。所以张力逐位一致对 g 的约束极弱,必须回到标准表确认口径。
127
142
 
128
143
  ## 新增一个计算器
129
144
 
@@ -147,6 +162,12 @@ src/<模块名>/
147
162
  - [ocs-wiki-content](https://github.com/showhoo/ocs-wiki-content) — 504 条词条快照与结构化数据(规划中)
148
163
  - [itswe](https://github.com/showhoo/itswe) — 站点介绍与建站文档(规划中)
149
164
 
165
+ ## 赞助
166
+
167
+ 本项目的开发与维护感谢以下赞助者的支持:
168
+
169
+ **[河南创为铁路器材有限公司](https://www.chuangwit.com)**
170
+
150
171
  ## 授权
151
172
 
152
173
  - **代码**:[MIT](./LICENSE)
package/README_EN.md CHANGED
@@ -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.
package/dist/index.cjs CHANGED
@@ -33,11 +33,11 @@ __export(index_exports, {
33
33
  G0: () => G0,
34
34
  IACS_RESISTIVITY_OHM_MM2_PER_M: () => IACS_RESISTIVITY_OHM_MM2_PER_M,
35
35
  MIN_MARGIN_MM: () => MIN_MARGIN_MM,
36
- NOMINAL_SECTION_MM2: () => NOMINAL_SECTION_MM2,
37
36
  REFERENCE_DENSITY_G_PER_CM3: () => REFERENCE_DENSITY_G_PER_CM3,
38
37
  REF_TARGET_COEFF: () => REF_TARGET_COEFF,
39
38
  REF_TARGET_OFFSET_N: () => REF_TARGET_OFFSET_N,
40
39
  STANDARD_GAUGE_M: () => STANDARD_GAUGE_M,
40
+ STANDARD_UNIT_WEIGHT_KG_PER_KM: () => STANDARD_UNIT_WEIGHT_KG_PER_KM,
41
41
  TB2809_AMPACITY_A: () => TB2809_AMPACITY_A,
42
42
  TB2809_WIRE_PARAMS: () => TB2809_WIRE_PARAMS,
43
43
  TRANSMISSION_RATIOS: () => TRANSMISSION_RATIOS,
@@ -65,7 +65,6 @@ __export(index_exports, {
65
65
  kmHToMPerS: () => kmHToMPerS,
66
66
  maxParabolaSagM: () => maxParabolaSagM,
67
67
  naturalFrequencyHz: () => naturalFrequencyHz,
68
- nominalSectionMM2: () => nominalSectionMM2,
69
68
  parabolaSagM: () => parabolaSagM,
70
69
  referenceTargetForceN: () => referenceTargetForceN,
71
70
  requiredStrokeMM: () => requiredStrokeMM,
@@ -82,6 +81,7 @@ __export(index_exports, {
82
81
  tensionAt: () => tensionAt,
83
82
  tensionCurve: () => tensionCurve,
84
83
  tensionMeta: () => tensionMeta,
84
+ unitWeightToKgPerM: () => unitWeightToKgPerM,
85
85
  versineM: () => versineM,
86
86
  voltageDropCheck: () => voltageDropCheck,
87
87
  voltageDropMeta: () => voltageDropMeta,
@@ -136,6 +136,14 @@ function iceLoadNPerM(params) {
136
136
 
137
137
  // src/data/wire-specs.ts
138
138
  var REFERENCE_DENSITY_G_PER_CM3 = 8.94;
139
+ var STANDARD_UNIT_WEIGHT_KG_PER_KM = {
140
+ cthm120: 1082,
141
+ cthm150: 1350,
142
+ ctha120: 1070
143
+ };
144
+ function unitWeightToKgPerM(kgPerKm) {
145
+ return kgPerKm / 1e3;
146
+ }
139
147
  function deriveLinearMassKgPerM(crossSectionMM2, densityGPerCm3 = REFERENCE_DENSITY_G_PER_CM3) {
140
148
  return crossSectionMM2 * 1e-6 * densityGPerCm3 * 1e3;
141
149
  }
@@ -146,27 +154,30 @@ var WIRE_PRESETS = [
146
154
  name: "CTHM-120\uFF08\u94DC\u9541 120\uFF09",
147
155
  nameEn: "CTHM-120 (CuMg 120 mm\xB2)",
148
156
  crossSectionMM2: 120,
157
+ calculatedSectionMM2: 121,
149
158
  elasticModulusGPa: 120,
150
159
  expansionPerDegC: COPPER_ALLOY_ALPHA_PER_DEG_C,
151
- linearMassKgPerM: deriveLinearMassKgPerM(120)
160
+ linearMassKgPerM: unitWeightToKgPerM(STANDARD_UNIT_WEIGHT_KG_PER_KM.cthm120)
152
161
  },
153
162
  {
154
163
  id: "cthm150",
155
164
  name: "CTHM-150\uFF08\u94DC\u9541 150\uFF09",
156
165
  nameEn: "CTHM-150 (CuMg 150 mm\xB2)",
157
166
  crossSectionMM2: 150,
167
+ calculatedSectionMM2: 151,
158
168
  elasticModulusGPa: 120,
159
169
  expansionPerDegC: COPPER_ALLOY_ALPHA_PER_DEG_C,
160
- linearMassKgPerM: deriveLinearMassKgPerM(150)
170
+ linearMassKgPerM: unitWeightToKgPerM(STANDARD_UNIT_WEIGHT_KG_PER_KM.cthm150)
161
171
  },
162
172
  {
163
173
  id: "ctha120",
164
174
  name: "CTHA-120\uFF08\u94DC\u94F6 120\uFF09",
165
175
  nameEn: "CTHA-120 (CuAg 120 mm\xB2)",
166
176
  crossSectionMM2: 120,
177
+ calculatedSectionMM2: 121,
167
178
  elasticModulusGPa: 120,
168
179
  expansionPerDegC: COPPER_ALLOY_ALPHA_PER_DEG_C,
169
- linearMassKgPerM: deriveLinearMassKgPerM(120)
180
+ linearMassKgPerM: unitWeightToKgPerM(STANDARD_UNIT_WEIGHT_KG_PER_KM.ctha120)
170
181
  }
171
182
  ];
172
183
  function findWirePreset(id) {
@@ -480,13 +491,7 @@ var windMeta = {
480
491
  // src/wind/index.ts
481
492
  var AIR_DENSITY_KG_PER_M3 = 1.225;
482
493
  function windLoadNPerM(params) {
483
- const {
484
- windSpeedMPerS,
485
- windAngleDeg,
486
- wireDiameterMM,
487
- dragCoefficient,
488
- airDensityKgPerM3
489
- } = params;
494
+ const { windSpeedMPerS, windAngleDeg, wireDiameterMM, dragCoefficient, airDensityKgPerM3 } = params;
490
495
  if (!(windSpeedMPerS >= 0)) {
491
496
  throw new RangeError(`\u98CE\u901F\u4E0D\u80FD\u4E3A\u8D1F\uFF0C\u6536\u5230 ${windSpeedMPerS} m/s`);
492
497
  }
@@ -497,9 +502,7 @@ function windLoadNPerM(params) {
497
502
  throw new RangeError(`\u98CE\u8F7D\u4F53\u578B\u7CFB\u6570\u5FC5\u987B\u4E3A\u6B63\u6570\uFF0C\u6536\u5230 ${dragCoefficient}`);
498
503
  }
499
504
  if (!(windAngleDeg >= 0 && windAngleDeg <= 180)) {
500
- throw new RangeError(
501
- `\u98CE\u5411\u4E0E\u7EBF\u8DEF\u5939\u89D2\u5E94\u4E3A 0 ~ 180\xB0\uFF0C\u6536\u5230 ${windAngleDeg}\xB0`
502
- );
505
+ throw new RangeError(`\u98CE\u5411\u4E0E\u7EBF\u8DEF\u5939\u89D2\u5E94\u4E3A 0 ~ 180\xB0\uFF0C\u6536\u5230 ${windAngleDeg}\xB0`);
503
506
  }
504
507
  const rho = airDensityKgPerM3 ?? AIR_DENSITY_KG_PER_M3;
505
508
  if (!(rho > 0)) {
@@ -719,14 +722,6 @@ var wearMeta = {
719
722
 
720
723
  // src/wear/index.ts
721
724
  var DEFAULT_REPLACEMENT_THRESHOLD_PERCENT = 20;
722
- var NOMINAL_SECTION_MM2 = {
723
- "CTHM-120": 120,
724
- "CTHM-150": 150,
725
- "CTHA-120": 120,
726
- "CTHA-150": 150,
727
- "CTHS-120": 120,
728
- "CTHS-150": 150
729
- };
730
725
  function sectionFromDiameterMM2(diameterMM) {
731
726
  if (!(diameterMM > 0)) {
732
727
  throw new RangeError(`\u6B8B\u5F84\u5FC5\u987B\u4E3A\u6B63\u6570\uFF0C\u6536\u5230 ${diameterMM} mm`);
@@ -762,9 +757,6 @@ function wearRatio(input) {
762
757
  verdict: wearPercent > thresholdPercent ? "replace" : "keep"
763
758
  };
764
759
  }
765
- function nominalSectionMM2(model) {
766
- return NOMINAL_SECTION_MM2[model];
767
- }
768
760
 
769
761
  // src/copper/meta.ts
770
762
  var copperMeta = {
@@ -1259,11 +1251,11 @@ function icingCheck(input) {
1259
1251
  G0,
1260
1252
  IACS_RESISTIVITY_OHM_MM2_PER_M,
1261
1253
  MIN_MARGIN_MM,
1262
- NOMINAL_SECTION_MM2,
1263
1254
  REFERENCE_DENSITY_G_PER_CM3,
1264
1255
  REF_TARGET_COEFF,
1265
1256
  REF_TARGET_OFFSET_N,
1266
1257
  STANDARD_GAUGE_M,
1258
+ STANDARD_UNIT_WEIGHT_KG_PER_KM,
1267
1259
  TB2809_AMPACITY_A,
1268
1260
  TB2809_WIRE_PARAMS,
1269
1261
  TRANSMISSION_RATIOS,
@@ -1291,7 +1283,6 @@ function icingCheck(input) {
1291
1283
  kmHToMPerS,
1292
1284
  maxParabolaSagM,
1293
1285
  naturalFrequencyHz,
1294
- nominalSectionMM2,
1295
1286
  parabolaSagM,
1296
1287
  referenceTargetForceN,
1297
1288
  requiredStrokeMM,
@@ -1308,6 +1299,7 @@ function icingCheck(input) {
1308
1299
  tensionAt,
1309
1300
  tensionCurve,
1310
1301
  tensionMeta,
1302
+ unitWeightToKgPerM,
1311
1303
  versineM,
1312
1304
  voltageDropCheck,
1313
1305
  voltageDropMeta,