excel-codegen 0.9.0__py3-none-any.whl

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 (82) hide show
  1. excel_codegen/__init__.py +160 -0
  2. excel_codegen/__main__.py +8 -0
  3. excel_codegen/cli.py +1250 -0
  4. excel_codegen/derived.py +465 -0
  5. excel_codegen/example_pack.py +107 -0
  6. excel_codegen/examples/README.md +69 -0
  7. excel_codegen/examples/abs_fpi/ABS_FPI_load_cases.xlsx +0 -0
  8. excel_codegen/examples/abs_fpi/ABS_FPI_load_cases_render.bat +22 -0
  9. excel_codegen/examples/abs_fpi/ABS_FPI_load_cases_render.sh +23 -0
  10. excel_codegen/examples/abs_fpi/README.md +121 -0
  11. excel_codegen/examples/abs_fpi/abs_fpi.yaml +310 -0
  12. excel_codegen/examples/abs_fpi/abs_fpi_external.xlsx +0 -0
  13. excel_codegen/examples/abs_fpi/abs_fpi_external.yaml +162 -0
  14. excel_codegen/examples/abs_fpi/abs_fpi_external_render.bat +22 -0
  15. excel_codegen/examples/abs_fpi/abs_fpi_external_render.sh +23 -0
  16. excel_codegen/examples/abs_fpi/abs_fpi_internal.xlsx +0 -0
  17. excel_codegen/examples/abs_fpi/abs_fpi_internal.yaml +266 -0
  18. excel_codegen/examples/abs_fpi/abs_fpi_internal_render.bat +22 -0
  19. excel_codegen/examples/abs_fpi/abs_fpi_internal_render.sh +23 -0
  20. excel_codegen/examples/abs_fpi/compose.yaml +20 -0
  21. excel_codegen/examples/abs_fpi/generated/COT1-d20.559-mu60.js +124 -0
  22. excel_codegen/examples/abs_fpi/generated/COT1-d20.559-mu60_summary.md +30 -0
  23. excel_codegen/examples/abs_fpi/generated/EXT-T15-mu0-kf-1.js +91 -0
  24. excel_codegen/examples/abs_fpi/generated/EXT-T15-mu0-kf-1_summary.md +23 -0
  25. excel_codegen/examples/abs_fpi/generated/EXT-T15-mu90-kf+1.js +91 -0
  26. excel_codegen/examples/abs_fpi/generated/EXT-T15-mu90-kf+1_summary.md +23 -0
  27. excel_codegen/examples/abs_fpi/generated/EXT-T20.559-mu90-kf+1.js +91 -0
  28. excel_codegen/examples/abs_fpi/generated/EXT-T20.559-mu90-kf+1_summary.md +23 -0
  29. excel_codegen/examples/abs_fpi/generated/WBT6-d15.059-mu0.js +124 -0
  30. excel_codegen/examples/abs_fpi/generated/WBT6-d15.059-mu0_summary.md +30 -0
  31. excel_codegen/examples/abs_fpi/generated/WBT6-d8-mu90.js +124 -0
  32. excel_codegen/examples/abs_fpi/generated/WBT6-d8-mu90_summary.md +30 -0
  33. excel_codegen/examples/abs_fpi/generated/WBT7-d20.559-mu90.js +124 -0
  34. excel_codegen/examples/abs_fpi/generated/WBT7-d20.559-mu90_summary.md +30 -0
  35. excel_codegen/examples/abs_fpi/templates/ext_body.js.j2 +91 -0
  36. excel_codegen/examples/abs_fpi/templates/ext_summary.md.j2 +23 -0
  37. excel_codegen/examples/abs_fpi/templates/int_body.js.j2 +124 -0
  38. excel_codegen/examples/abs_fpi/templates/int_summary.md.j2 +30 -0
  39. excel_codegen/examples/basic/example.yaml +97 -0
  40. excel_codegen/examples/basic/example_formula.yaml +86 -0
  41. excel_codegen/examples/basic/generated/uart_init_Case1.c +6 -0
  42. excel_codegen/examples/basic/generated/uart_init_Case2.c +6 -0
  43. excel_codegen/examples/basic/generated/uart_summary_Case1.md +4 -0
  44. excel_codegen/examples/basic/generated/uart_summary_Case2.md +4 -0
  45. excel_codegen/examples/basic/generated_formula/uart_init_Case1.c +5 -0
  46. excel_codegen/examples/basic/generated_formula/uart_init_Case2.c +5 -0
  47. excel_codegen/examples/basic/generated_formula/uart_pins_Case1.csv +1 -0
  48. excel_codegen/examples/basic/generated_formula/uart_pins_Case2.csv +1 -0
  49. excel_codegen/examples/basic/template.xlsx +0 -0
  50. excel_codegen/examples/basic/template_formula.xlsx +0 -0
  51. excel_codegen/examples/basic/template_formula_render.bat +22 -0
  52. excel_codegen/examples/basic/template_formula_render.sh +23 -0
  53. excel_codegen/examples/basic/template_render.bat +22 -0
  54. excel_codegen/examples/basic/template_render.sh +23 -0
  55. excel_codegen/examples/nastran/generated/case_control.deck +18 -0
  56. excel_codegen/examples/nastran/generated/cc_01_LC1.inc +8 -0
  57. excel_codegen/examples/nastran/generated/cc_02_LC2.inc +8 -0
  58. excel_codegen/examples/nastran/generated/cc_03_LC3.inc +8 -0
  59. excel_codegen/examples/nastran/generated/cc_04_COMB4.inc +8 -0
  60. excel_codegen/examples/nastran/generated/cc_05_LC5.inc +8 -0
  61. excel_codegen/examples/nastran/generated/cc_summary_01_LC1.md +1 -0
  62. excel_codegen/examples/nastran/generated/cc_summary_02_LC2.md +1 -0
  63. excel_codegen/examples/nastran/generated/cc_summary_03_LC3.md +1 -0
  64. excel_codegen/examples/nastran/generated/cc_summary_04_COMB4.md +1 -0
  65. excel_codegen/examples/nastran/generated/cc_summary_05_LC5.md +1 -0
  66. excel_codegen/examples/nastran/nastran_case_control.xlsx +0 -0
  67. excel_codegen/examples/nastran/nastran_case_control.yaml +141 -0
  68. excel_codegen/examples/nastran/nastran_case_control_render.bat +22 -0
  69. excel_codegen/examples/nastran/nastran_case_control_render.sh +23 -0
  70. excel_codegen/excel_io.py +1885 -0
  71. excel_codegen/formula.py +674 -0
  72. excel_codegen/formula_eval.py +685 -0
  73. excel_codegen/jinja_env.py +92 -0
  74. excel_codegen/models.py +1008 -0
  75. excel_codegen/renderer.py +558 -0
  76. excel_codegen/utils.py +225 -0
  77. excel_codegen-0.9.0.dist-info/METADATA +179 -0
  78. excel_codegen-0.9.0.dist-info/RECORD +82 -0
  79. excel_codegen-0.9.0.dist-info/WHEEL +5 -0
  80. excel_codegen-0.9.0.dist-info/entry_points.txt +2 -0
  81. excel_codegen-0.9.0.dist-info/licenses/LICENSE +21 -0
  82. excel_codegen-0.9.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,266 @@
1
+ version: 1
2
+
3
+ # =========================================================================== #
4
+ # 规则集:ABS FPI 5A-3-2/5.7 内压(internal tank pressures)
5
+ #
6
+ # 与 abs_fpi_external.yaml 同构,可以单独生成一本工作簿,也可以被 compose.py
7
+ # 合进一本项目工作簿(与内压共用一张 Global 表)。
8
+ #
9
+ # 舱数据用**第三层作用域**(variables.group 成员表,指南 §18):
10
+ # 一个舱的参数只写一遍,工况用 local 变量 tank_ref 指向自己用哪个舱。
11
+ # 成员表在独立工作表 "Tank Data" 里:一行一个舱、B 列起一个变量一列。
12
+ # =========================================================================== #
13
+ excel:
14
+ output: "abs_fpi_internal.xlsx"
15
+ sheets:
16
+ global: "Global Parameter"
17
+ local: "Local Parameter"
18
+ outputs: ["Code", "Summary"]
19
+
20
+ variables:
21
+ # ------------------------------------------------------------------ 船 / 海 --
22
+ global:
23
+ - name: L
24
+ description: "规范船长 [m](3-1-1/3)"
25
+ default: 340
26
+ type: float
27
+ suffix: " m"
28
+ - name: B
29
+ description: "规范型宽 [m]"
30
+ default: 64
31
+ type: float
32
+ suffix: " m"
33
+ - name: D
34
+ description: "规范型深 [m]"
35
+ default: 32
36
+ type: float
37
+ suffix: " m"
38
+ - name: d_f
39
+ description: "结构吃水 [m];规范表按它给出,GM 四点表也按它插值"
40
+ default: 20.559
41
+ type: float
42
+ suffix: " m"
43
+ - name: rho_sea
44
+ description: "海水密度 [kg/m^3]"
45
+ default: 1025
46
+ type: float
47
+ suffix: " kg/m^3"
48
+ - name: g
49
+ description: "重力加速度 [m/s^2]"
50
+ default: 9.81
51
+ type: float
52
+ suffix: " m/s^2"
53
+ - name: Cb
54
+ description: "方形系数 [-]"
55
+ default: 1
56
+ type: float
57
+ - name: rho_g_lo
58
+ description: "k_s = 0.878 对应的 rho g [N/m^3](1.005 N/cm^2-m = 10050)"
59
+ default: 10050
60
+ type: float
61
+ suffix: " N/m^3"
62
+ - name: rho_g_hi
63
+ description: "k_s 达到 1.0 的 rho g [N/m^3](1.118 N/cm^2-m = 11180)"
64
+ default: 11180
65
+ type: float
66
+ suffix: " N/m^3"
67
+
68
+ # ------------------------------------------------------- 坐标映射(纯替换)--
69
+ - name: ax_x
70
+ description: "规范 x(自 AP)取自模型哪个轴:1=x, 2=y, 3=z"
71
+ default: "1"
72
+ type: string
73
+ - name: ax_y
74
+ description: "规范 y(自中线,向右舷为正)取自模型哪个轴"
75
+ default: "2"
76
+ type: string
77
+ - name: ax_z
78
+ description: "规范 z(基线以上,向上为正)取自模型哪个轴"
79
+ default: "3"
80
+ type: string
81
+ - name: neg_x
82
+ description: "规范 x 是否取反:填 - 表示取反,留空表示不取反"
83
+ default: ""
84
+ type: string
85
+ - name: neg_y
86
+ description: "规范 y 是否取反:填 - 表示取反,留空表示不取反"
87
+ default: ""
88
+ type: string
89
+ - name: neg_z
90
+ description: "规范 z 是否取反:填 - 表示取反,留空表示不取反"
91
+ default: ""
92
+ type: string
93
+
94
+ # ---------------------------------------------------------------- 每个工况 --
95
+ local:
96
+ - name: kind
97
+ description: "这个 Case 属于哪一套规则:EXT / INT(多规则集合用时用 case_filter 分流)"
98
+ default: "INT"
99
+ type: string
100
+ - name: draft
101
+ description: "工况吃水 [m]"
102
+ default: 8
103
+ type: float
104
+ suffix: " m"
105
+ - name: mu_deg
106
+ description: "浪向角 [deg](Table 1A D)"
107
+ default: 90
108
+ type: float
109
+ suffix: " deg"
110
+ - name: k_c
111
+ description: "组合工况相关系数 [-](Table 1A C)"
112
+ default: 1
113
+ type: float
114
+ - name: k_u
115
+ description: "载荷系数 [-]"
116
+ default: 1.1
117
+ type: float
118
+ - name: beta_VAC
119
+ description: "垂向加速度 ESF [-](5A-3-A1/3)"
120
+ default: 0.660
121
+ type: float
122
+ - name: beta_LAC
123
+ description: "纵向加速度 ESF [-]"
124
+ default: 0.758
125
+ type: float
126
+ - name: beta_TAC
127
+ description: "横向加速度 ESF [-]"
128
+ default: 0.557
129
+ type: float
130
+ - name: beta_PMO
131
+ description: "纵摇 ESF [-]"
132
+ default: 0.686
133
+ type: float
134
+ - name: beta_RMO
135
+ description: "横摇 ESF [-]"
136
+ default: 0.492
137
+ type: float
138
+ - name: k_esf
139
+ description: "项目对 ESF 的分项系数 [-]"
140
+ default: 1.1
141
+ type: float
142
+ - name: w_v
143
+ description: "垂向加速度权重 [-](Table 1A B)"
144
+ default: 0.75
145
+ type: float
146
+ - name: w_l
147
+ description: "纵向加速度权重 [-]"
148
+ default: 0.25
149
+ type: float
150
+ - name: w_t
151
+ description: "横向加速度权重 [-]"
152
+ default: 0.75
153
+ type: float
154
+ - name: xi
155
+ description: "舱长方向参考位置 [m](5.7.2(b))"
156
+ default: 21
157
+ type: float
158
+ suffix: " m"
159
+ - name: delta_b
160
+ description: "舱宽方向修正 [m](5.7.2(b));无则填 0"
161
+ default: 0
162
+ type: float
163
+ suffix: " m"
164
+ - name: delta_h
165
+ description: "舱高方向修正 [m](5.7.2(b));无则填 0"
166
+ default: 0
167
+ type: float
168
+ suffix: " m"
169
+
170
+ # ---- 指向成员表的"指针":这个 Case 用哪个舱 ----
171
+ # 舱本身的 13 个参数不在这里,在下面的 variables.group(工作表 "Tank Data")
172
+ - name: tank_ref
173
+ description: "本 Case 用哪个舱(成员表的行名)"
174
+ default: "WBT6"
175
+ type: string
176
+ choices: ["WBT6", "WBT7", "COT1"]
177
+
178
+ # ------------------------------------------------------------------ 每个舱 --
179
+ # 一行一个舱,只写一遍:多个工况用同一个舱时不再重复
180
+ group:
181
+ sheet: "Tank Data"
182
+ key: tank_ref
183
+ members: ["WBT6", "WBT7", "COT1"]
184
+ variables:
185
+ - name: rho_tank
186
+ description: "舱内液体密度 [kg/m^3]"
187
+ default: 1025
188
+ type: float
189
+ suffix: " kg/m^3"
190
+ - name: l_tank
191
+ description: "舱长 [m](Fig. 11)"
192
+ default: 42
193
+ type: float
194
+ suffix: " m"
195
+ - name: b_tank
196
+ description: "舱宽 [m](Fig. 11)"
197
+ default: 32
198
+ type: float
199
+ suffix: " m"
200
+ - name: h_tank
201
+ description: "舱高 [m](Fig. 11)"
202
+ default: 32
203
+ type: float
204
+ suffix: " m"
205
+ - name: eta_deck
206
+ description: "甲板以上高度 [m]"
207
+ default: 0
208
+ type: float
209
+ suffix: " m"
210
+ - name: eta_overflow
211
+ description: "溢流管高度 [m];Fig. 12 要求取 2/3 且不低于 760 mm"
212
+ default: 0
213
+ type: float
214
+ suffix: " m"
215
+ - name: C_dp
216
+ description: "舱形系数 [-](5.7.2(d)):矩形 1.0,J 形 0.7"
217
+ default: 1
218
+ type: float
219
+ - name: C_ru
220
+ description: "舱形系数 [-](5.7.2(d)):矩形 1.0,U 形 0.7"
221
+ default: 1
222
+ type: float
223
+ - name: p_vp
224
+ description: "真空/压力阀整定压力 [N/cm^2]"
225
+ default: 0
226
+ type: float
227
+ suffix: " N/cm^2"
228
+ - name: GM_full_in
229
+ description: "完整稳性 GM [m];填 0 时用规范估算 0.12 B"
230
+ default: 0
231
+ type: float
232
+ suffix: " m"
233
+ - name: k_r_in
234
+ description: "横摇惯性半径 [m];填 0 时用规范估算(0.35 B / 0.45 B)"
235
+ default: 0
236
+ type: float
237
+ suffix: " m"
238
+ - name: tank_is_ballast
239
+ description: "压载舱 1 / 货舱 0;决定 k_s 是否取 1"
240
+ default: 1
241
+ type: int
242
+ - name: member_11_17
243
+ description: "构件是否属于 5.7 表 3 的 11..17 项(1 = 是)"
244
+ default: 0
245
+ type: int
246
+
247
+ templates:
248
+ - name: genie_int
249
+ description: "ABS FPI 5A-3-2/5.7 内压 -- GeniE 强度函数体"
250
+ output_sheet: "Code"
251
+ start_cell: "B2"
252
+ direction: "horizontal"
253
+ write_case_headers: true
254
+ engine: "excel"
255
+ filename: "{{ case_name }}.js"
256
+ template_file: "templates/int_body.js.j2"
257
+
258
+ - name: int_summary
259
+ description: "内压工况输入汇总(Markdown)"
260
+ output_sheet: "Summary"
261
+ start_cell: "B2"
262
+ direction: "vertical"
263
+ write_case_headers: true
264
+ engine: "excel"
265
+ filename: "{{ case_name }}_summary.md"
266
+ template_file: "templates/int_summary.md.j2"
@@ -0,0 +1,22 @@
1
+ @echo off
2
+ REM ===========================================================================
3
+ REM 由 excel_codegen 生成 —— 改完参数双击本文件即可把结果写回 Output 表。
4
+ REM 重新生成工作簿(init)时会一并覆盖本文件。
5
+ REM ===========================================================================
6
+ cd /d "%~dp0"
7
+
8
+ where uv >nul 2>nul
9
+ if %errorlevel%==0 (
10
+ uv run excel-codegen render -c "abs_fpi_internal.yaml" -x "abs_fpi_internal.xlsx" --write-excel
11
+ ) else (
12
+ excel-codegen render -c "abs_fpi_internal.yaml" -x "abs_fpi_internal.xlsx" --write-excel
13
+ )
14
+
15
+ echo.
16
+ if errorlevel 1 (
17
+ echo [失败] 上面有报错信息。常见原因:依赖没装(跑一次 setup.sh / uv sync)、
18
+ echo 或者 Excel 正开着这个文件(先关掉再试)。
19
+ ) else (
20
+ echo [完成] 回到 Excel 打开「Output」表看结果。
21
+ )
22
+ pause
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env bash
2
+ # ===========================================================================
3
+ # 由 excel_codegen 生成 —— 改完参数跑一次本文件即可把结果写回 Output 表。
4
+ # 重新生成工作簿(init)时会一并覆盖本文件。
5
+ # ===========================================================================
6
+ set -uo pipefail
7
+ cd "$(dirname "$0")"
8
+
9
+ if command -v uv >/dev/null 2>&1; then
10
+ uv run excel-codegen render -c "abs_fpi_internal.yaml" -x "abs_fpi_internal.xlsx" --write-excel
11
+ else
12
+ excel-codegen render -c "abs_fpi_internal.yaml" -x "abs_fpi_internal.xlsx" --write-excel
13
+ fi
14
+ status=$?
15
+
16
+ echo
17
+ if [ "$status" -ne 0 ]; then
18
+ echo "[失败] 上面有报错信息。常见原因:依赖没装(跑一次 ./setup.sh 或 uv sync)、"
19
+ echo " 或者 Excel / WPS 正开着这个文件(先关掉再试)。"
20
+ else
21
+ echo "[完成] 回到 Excel 打开「Output」表看结果。"
22
+ fi
23
+ exit "$status"
@@ -0,0 +1,20 @@
1
+ # =========================================================================== #
2
+ # 项目工作簿的配方:把哪些规则集合进一本工作簿、各自用什么 case_filter 分流。
3
+ #
4
+ # python compose.py → abs_fpi.yaml → init / render
5
+ #
6
+ # 变量与模板的真源仍在各规则集 YAML 里;compose 会把它们合并、检查冲突,
7
+ # 再给每套模板加上 case_filter(只在多于一个规则集时才加)。
8
+ # =========================================================================== #
9
+ project: "abs_fpi.yaml"
10
+ output: "ABS_FPI_load_cases.xlsx"
11
+
12
+ rulesets:
13
+ # 外压放前面:case_filter 模式下"横向相对列"要在每个规则集内部保持连续,
14
+ # 同一规则集的工况必须相邻(见 README「工况顺序」)。
15
+ - file: "abs_fpi_external.yaml"
16
+ set: "EXT"
17
+ filter: "kind == 'EXT'"
18
+ - file: "abs_fpi_internal.yaml"
19
+ set: "INT"
20
+ filter: "kind == 'INT'"
@@ -0,0 +1,124 @@
1
+ // COT1-d20.559-mu60
2
+ // See ext_body.js.j2 for why the coordinates go through temporaries.
3
+ var t1 = x;
4
+ var t2 = y;
5
+ var t3 = z;
6
+ x = t1;
7
+ y = t2;
8
+ z = t3;
9
+ // --- global parameters (same for every case)
10
+ var L = 340 m;
11
+ var B = 64 m;
12
+ var D = 32 m;
13
+ var rho_sea = 1025 kg/m^3;
14
+ var g = 9.81 m/s^2;
15
+ var Cb = 1;
16
+ var d_f = 20.559 m;
17
+ var rho_g_lo = 10050 N/m^3;
18
+ var rho_g_hi = 11180 N/m^3;
19
+ // --- this case
20
+ var draft = 20.559 m;
21
+ var mu_deg = 60 deg;
22
+ var k_c = 0.5;
23
+ var k_u = 1.1;
24
+ var beta_VAC = 0.66;
25
+ var beta_LAC = 0.758;
26
+ var beta_TAC = 0.557;
27
+ var beta_PMO = 0.686;
28
+ var beta_RMO = 0.492;
29
+ var k_esf = 1.1;
30
+ var w_v = 0.75;
31
+ var w_l = 0.25;
32
+ var w_t = 0.75;
33
+ var xi = 21 m;
34
+ var delta_b = 0 m;
35
+ var delta_h = 0 m;
36
+ // --- the tank this case names: COT1
37
+ var rho_tank = 900 kg/m^3;
38
+ var l_tank = 42 m;
39
+ var b_tank = 32 m;
40
+ var h_tank = 32 m;
41
+ var eta_deck = 0 m;
42
+ var eta_overflow = 0 m;
43
+ var C_dp = 1;
44
+ var C_ru = 1;
45
+ var p_vp = 0.21 N/cm^2;
46
+ var GM_full_in = 0 m;
47
+ var k_r_in = 0 m;
48
+ var tank_is_ballast = 0;
49
+ var member_11_17 = 1;
50
+ // --- the calculation
51
+ var C_theta = 1; // C_theta, the roll angle factor of 5.7.2(b)
52
+ var C_phi = -0.45; // C_phi, the pitch angle factor of 5.7.2(b)
53
+ var k_theta = 0.005; // k_theta of the theta expression (5.7.1(b))
54
+ var C_R = 1.05; // C_R of the theta expression (5.7.1(b))
55
+ var k_o = 1.34 - 0.47 * Cb; // k_o (5.7.1(c))
56
+ var a_o = (k_o * (2.4 / Math.pow(L / 1 m, 0.5) + 34 / (L / 1 m) - 600 / Math.pow(L / 1 m, 2))) * 1 m; // a_o, the vertical acceleration parameter
57
+ var D_1 = (10 / Cb); // the (10 / C_b) term of phi
58
+ var phi = beta_PMO * k_esf * 1030 * Math.pow(D_1, 0.25) / (L / 1 m) * 1 deg; // phi, the pitch amplitude
59
+ if (phi > 10 deg) phi = 10 deg;
60
+ else phi = phi;
61
+ var GM_full = GM_full_in > 0 m ? GM_full_in : 0.12 * B; // 5.7.1(b): 0.12 B when GM(full) is not available
62
+ var k_r = k_r_in > 0 m ? k_r_in : (draft <= d_f ? 0.35 * B : 0.45 * B); // roll radius of gyration
63
+ var Delta = 10.05 kN/m^3 * L * B * d_f * Cb; // displacement, k_d = 10.05 kN/m^3
64
+ var C_di = 1.06 * (draft / d_f) - 0.06; // C_di = 1.06 (d_i/d_f) - 0.06
65
+ var GM = GM_full; // GM at the draft evaluated, filled in below
66
+ if (draft / d_f >= 1) GM = GM_full;
67
+ else if (draft / d_f >= 0.9) GM = 1.1 * GM_full;
68
+ else if (draft / d_f >= 2/3) GM = 1.5 * GM_full;
69
+ else if (draft / d_f >= 0.5) GM = 2.0 * GM_full;
70
+ else GM = GM_full;
71
+ var T_r = 2 * k_r * Math.pow(GM / 1 m, -0.5) / 1 m * 1 s; // T_r, the roll natural period, in seconds
72
+ var theta = C_R * beta_RMO * k_esf * (35 - k_theta * C_di * Delta / 1000 kN) * 1 deg; // theta, the roll amplitude
73
+ if (T_r > 20 s) theta = theta;
74
+ else if (T_r >= 12.5 s) theta = theta * (1.5375 - 0.027 * T_r / 1 s);
75
+ else theta = theta * (0.8625 + 0.027 * T_r / 1 s);
76
+ if (theta > 30 deg) theta = 30 deg;
77
+ else theta = theta;
78
+ var k_v = Math.pow(1 + 0.65 * Math.pow(5.3 - 45 / (L / 1 m), 2) * Math.pow(x / L - 0.45, 2), 0.5); // k_v (5.7.1(c))
79
+ var C_v = Math.cos(mu_deg) + (1 + 2.4 * z / B) * Math.sin(mu_deg) / k_v; // C_v (5.7.1(c))
80
+ var C_l = 0.35 - 0.0005 * (L / 1 m - 200); // C_l (5.7.1(c))
81
+ var k_l = 0.5 + 8 * y / L; // k_l (5.7.1(c)), the VERTICAL distribution
82
+ var C_t = 1.27 * Math.pow(1 + 1.52 * Math.pow(x / L - 0.45, 2), 0.5); // C_t (5.7.1(c))
83
+ var k_t = 0.35 + y / B; // k_t (5.7.1(c)), the VERTICAL distribution
84
+ var a_v = C_v * beta_VAC * k_esf * k_v * a_o / 1 m * g; // a_v, positive downward
85
+ var a_l = C_l * beta_LAC * k_esf * k_l * a_o / 1 m * g; // a_l, positive forward
86
+ var a_t = C_t * beta_TAC * k_esf * k_t * a_o / 1 m * g; // a_t, positive starboard
87
+ var rho_g = rho_tank * g; // the liquid specific weight (5.7.2(a))
88
+ var eta_overflow_add = Math.max(0.6666667 * eta_overflow, 760 mm); // Fig. 12: 2/3 of the overflow distance, at least 760 mm
89
+ var eta = h_tank + eta_deck + (eta_overflow > 0 m ? eta_overflow_add : 0 m) - z; // eta, measured down from the tank top
90
+ var k_s = 1; // k_s, filled in below
91
+ if (tank_is_ballast != 0 || member_11_17 == 0) {
92
+ k_s = 1;
93
+ } else {
94
+ k_s = 0.878 + (rho_g - rho_g_lo) / (rho_g_hi - rho_g_lo) * 0.122;
95
+ if (k_s < 0.878) k_s = 0.878;
96
+ else k_s = k_s;
97
+ if (k_s > 1) k_s = 1;
98
+ else k_s = k_s;
99
+ }
100
+ var p_o = p_vp > 0 N/cm^2 ? Math.max(p_vp - 2.06 N/cm^2, 0 N/cm^2) : 0 N/cm^2; // p_o = (p_vp - p_n), p_n = 2.06 N/cm^2
101
+ var a_i = 0.71 * C_dp * (w_v * a_v + w_l * (l_tank / h_tank) * a_l + w_t * (b_tank / h_tank) * a_t); // a_i (5.7.2(a))
102
+ var theta_e = 0.71 * C_theta * theta; // theta_e (5.7.2(b))
103
+ var phi_e = 0.71 * C_phi * phi; // phi_e (5.7.2(b))
104
+ var zeta = Math.abs(b_tank / 2 - z); // zeta, from the tank centre line
105
+ var zeta_e = zeta; // zeta_e, filled in below
106
+ var eta_e = eta; // eta_e, filled in below
107
+ var dh_i = 0 m; // delta h_i, filled in below
108
+ if (phi_e < 0 deg && theta_e > 0 deg) {
109
+ // branch i of 5.7.2(b)
110
+ zeta_e = b_tank - zeta;
111
+ eta_e = eta;
112
+ dh_i = xi * Math.sin(-phi_e) + C_ru * (zeta_e * Math.sin(theta_e) * Math.cos(phi_e)
113
+ + eta_e * Math.cos(theta_e) * Math.cos(phi_e) - eta);
114
+ } else {
115
+ // branch ii of 5.7.2(b)
116
+ zeta_e = zeta - delta_b;
117
+ eta_e = eta - delta_h;
118
+ dh_i = (l_tank - xi) * Math.sin(-phi_e) + C_ru * (zeta_e * Math.sin(theta_e) * Math.cos(phi_e)
119
+ + eta_e * Math.cos(theta_e) * Math.cos(phi_e) - eta);
120
+ }
121
+ var h_d = k_c * (eta * a_i / g + dh_i); // h_d = k_c (eta a_i / g + delta h_i) (5.7.2(a))
122
+ var p_s = k_s * rho_g * eta; // static pressure (5.7.2(a))
123
+ var p_d = k_s * rho_g * k_u * h_d; // dynamic pressure (5.7.2(a))
124
+ return p_s + p_d + p_o; // the pressure the function returns
@@ -0,0 +1,30 @@
1
+ | 项目 | 值 | 出处 |
2
+ | --- | --- | --- |
3
+ | case_name | COT1-d20.559-mu60 | 工况名(Excel 表头) |
4
+ | kind | INT | 规则集(多规则集共用一本工作簿时用 case_filter 分流) |
5
+ | tank_ref | COT1 | 指向成员表 `Tank Data` 的哪一行(指南 §18) |
6
+ | draft | 20.559 m | 装载工况 |
7
+ | mu_deg | 60 deg | Table 1A D |
8
+ | k_c | 0.5 | Table 1A C |
9
+ | k_u | 1.1 | 5A-3-2/7, /9 |
10
+ | beta_VAC | 0.66 | 5A-3-A1/3 |
11
+ | beta_LAC | 0.758 | 5A-3-A1/3 |
12
+ | beta_TAC | 0.557 | 5A-3-A1/3 |
13
+ | beta_PMO | 0.686 | 5A-3-A1/3 |
14
+ | beta_RMO | 0.492 | 5A-3-A1/3 |
15
+ | k_esf | 1.1 | 项目 |
16
+ | w_v / w_l / w_t | 0.75 / 0.25 / 0.75 | Table 1A B |
17
+ | xi | 21 m | 5.7.2(b) |
18
+ | delta_b / delta_h | 0 m / 0 m | 5.7.2(b) |
19
+ | rho_tank | 900 kg/m^3 | 成员表 Tank Data |
20
+ | l_tank / b_tank / h_tank | 42 m / 32 m / 32 m | Fig. 11 |
21
+ | eta_deck / eta_overflow | 0 m / 0 m | Fig. 12 |
22
+ | C_dp / C_ru | 1 / 1 | 5.7.2(d) |
23
+ | p_vp | 0.21 N/cm^2 | 成员表 Tank Data |
24
+ | GM_full_in / k_r_in | 0 m / 0 m | 稳性计算书 |
25
+ | tank_is_ballast / member_11_17 | 0 / 1 | Table 3 |
26
+ | L / B / D / d_f | 340 m / 64 m / 32 m / 20.559 m | 3-1-1/3 |
27
+ | rho_sea / g / Cb | 1025 kg/m^3 / 9.81 m/s^2 / 1 | 5.7.1 |
28
+ | rho_g_lo / rho_g_hi | 10050 N/m^3 / 11180 N/m^3 | 5.7.2(a) |
29
+ | axis ax | (1, 2, 3) | 模型 |
30
+ | axis neg | ( / / ) | 模型 |
@@ -0,0 +1,91 @@
1
+ // EXT-T15-mu0-kf-1
2
+ // The rules live in the RULE frame: x from the A.P., y from the centre line
3
+ // positive starboard, z above the baseline. The model usually is not, so the
4
+ // three mapping cells (ax_* / neg_*) convert it. All three coordinates go
5
+ // through temporaries first: assigning them in place would read a coordinate
6
+ // that has already been overwritten.
7
+ var t1 = x;
8
+ var t2 = y;
9
+ var t3 = z;
10
+ x = t1;
11
+ y = t2;
12
+ z = t3;
13
+ // --- global parameters (same for every case)
14
+ var L = 340 m;
15
+ var B = 64 m;
16
+ var D = 32 m;
17
+ var r_b = 0.703 m;
18
+ var freeboard = 0.5 m;
19
+ var rho_sea = 1025 kg/m^3;
20
+ var g = 9.81 m/s^2;
21
+ var Cb = 1;
22
+ // --- this case
23
+ var draft = 15 m;
24
+ var mu_deg = 0 deg;
25
+ var k_c = 0.5;
26
+ var k_f0 = -1;
27
+ var k_u = 1.1;
28
+ var beta_EPS = 0.733;
29
+ var beta_EPP = 0.733;
30
+ var k_esf = 1.1;
31
+ var x_o = 51 m;
32
+ // --- the calculation
33
+ var u = mu_deg; // the heading, as an Angle -- cos/sin take it directly
34
+ var C_1 = 0; // wave coefficient, 0 until a length bracket matches
35
+ // C_1 brackets of 3-2-1/3.5, closed at both ends; outside them C_1 is zero
36
+ if (L >= 61 m && L <= 90 m ) C_1 = 0.044 * (L / 1 m) + 3.75;
37
+ else if (L > 90 m && L < 300 m) C_1 = 10.75 - Math.pow((300 m - L) / 100 m, 1.5);
38
+ else if (L >= 300 m && L < 350 m) C_1 = 10.75;
39
+ else if (L >= 350 m && L <= 500 m) C_1 = 10.75 - Math.pow((L - 350 m) / 150 m, 1.5);
40
+ else C_1 = 0;
41
+ var h_do = 1.36 * C_1 * 1 m; // reference hydrodynamic head, k = 1 (5.5.1)
42
+ var z_bilge = r_b; // rule z of the bilge (the bilge radius)
43
+ var z_freeboard = D - freeboard; // rule z of the highest deck at side
44
+ var xL = x / L; // x / L, dimensionless
45
+ var k_lo = 1; // k_lo = 1.0 amidships
46
+ // Fig. 9: k_lo = 1 amidships, rising towards both ends
47
+ if (xL < 0.2) k_lo = 1.5 - xL * 2.5;
48
+ else if (xL > 0.7) k_lo = 1 + (xL - 0.7) * 5;
49
+ else k_lo = 1;
50
+ var k_l = 1 + (k_lo - 1) * Math.cos(u); // k_l = 1 + (k_lo - 1) cos mu; GeniE converts the angle inside cos
51
+ var k_f = k_f0 * (1 - (1 - Math.cos((x - x_o) / L * 360 deg)) * Math.cos(u)); // k_f, the reference station against the wave
52
+ var alpha_1 = (1 - 0.25 * Math.cos(u)) * k_f; // i = 1, at the waterline, starboard
53
+ var alpha_2 = (0.40 - 0.10 * Math.cos(u)) * k_f; // i = 2, at the bilge, starboard
54
+ var alpha_3 = (0.30 - 0.20 * Math.sin(u)) * k_f; // i = 3, at the bottom centre line
55
+ var alpha_5 = (0.75 - 1.25 * Math.sin(u)) * k_f; // i = 5, at the waterline, port
56
+ var alpha_4 = 2 * alpha_3 - alpha_2; // i = 4 = 2 alpha_3 - alpha_2, at the bilge, port
57
+ var h_d1 = k_l * alpha_1 * h_do; // hydrodynamic head at i = 1
58
+ var h_d5 = k_l * alpha_5 * h_do; // hydrodynamic head at i = 5
59
+ var h_star_s = Math.min(z_freeboard - draft, k_u * h_d1); // Fig. 10: the head above the waterline, capped at the freeboard, starboard
60
+ var h_star_p = Math.min(z_freeboard - draft, k_u * h_d5); // Fig. 10: the head above the waterline, capped at the freeboard, port
61
+ var alpha_i = 0; // alpha at the point evaluated, assigned by the girth branches
62
+ // Fig. 8: alpha at the point evaluated
63
+ if (z >= z_bilge) {
64
+ if (z <= draft) {
65
+ // bilge to waterline, on the side of the girth the point is on
66
+ if (y >= 0 m) alpha_i = alpha_2 + (alpha_1 - alpha_2) * (z - z_bilge) / (draft - z_bilge);
67
+ else alpha_i = alpha_4 + (alpha_5 - alpha_4) * (z - z_bilge) / (draft - z_bilge);
68
+ } else {
69
+ // above the waterline, faded out over that side's h_star
70
+ if (y >= 0 m) {
71
+ if (h_star_s <= 0 m) alpha_i = 0;
72
+ else alpha_i = alpha_1 - (z - draft) / h_star_s * alpha_1;
73
+ } else {
74
+ if (h_star_p <= 0 m) alpha_i = 0;
75
+ else alpha_i = alpha_5 - (z - draft) / h_star_p * alpha_5;
76
+ }
77
+ }
78
+ } else {
79
+ // below the bilge: linear across the flat of bottom
80
+ alpha_i = alpha_4 + (alpha_2 - alpha_4) * (z + z_bilge) / (2 * z_bilge);
81
+ }
82
+ // 5.5.1: which side of the girth, and so which ESF
83
+ // the ESF is a property of the SIDE the point is on: EPS to starboard, EPP to port
84
+ var ESF_side = 0;
85
+ if (y >= 0 m) ESF_side = beta_EPS * k_esf;
86
+ else ESF_side = beta_EPP * k_esf;
87
+ var h_di = k_l * alpha_i * h_do; // hydrodynamic head at the point evaluated (5.5.1)
88
+ var h_de = k_c * h_di; // h_de = k_c h_di (5.5.1 nominal form)
89
+ var p_s = Math.max(rho_sea * g * (draft - z), 0 Pa); // still-water pressure, zero above the waterline
90
+ var p_d = rho_sea * g * ESF_side * k_u * h_de; // hydrodynamic pressure, with the ESF of the side the point is on
91
+ return Math.max(p_s + p_d, 0 Pa); // the pressure the function returns
@@ -0,0 +1,23 @@
1
+ | 项目 | 值 | 出处 |
2
+ | --- | --- | --- |
3
+ | case_name | EXT-T15-mu0-kf-1 | 工况名(Excel 表头) |
4
+ | kind | EXT | 规则集(多规则集共用一本工作簿时用 case_filter 分流) |
5
+ | draft | 15 m | 装载工况 |
6
+ | mu_deg | 0 deg | Table 1A D |
7
+ | k_c | 0.5 | Table 1A B |
8
+ | k_f0 | -1 | Table 1A B |
9
+ | k_u | 1.1 | 5A-3-2/7, /9 |
10
+ | beta_EPS | 0.733 | 5A-3-A1/3 |
11
+ | beta_EPP | 0.733 | 5A-3-A1/3 |
12
+ | k_esf | 1.1 | 项目 |
13
+ | x_o | 51 m | Fig. 9 脚注 |
14
+ | L | 340 m | 3-1-1/3 |
15
+ | B | 64 m | 3-1-1/3 |
16
+ | D | 32 m | 3-1-1/3 |
17
+ | r_b | 0.703 m | Fig. 11 |
18
+ | freeboard | 0.5 m | Fig. 10 |
19
+ | rho_sea | 1025 kg/m^3 | 5.5.1 |
20
+ | g | 9.81 m/s^2 | 5.5.1 |
21
+ | Cb | 1 | 3-1-1/13.3 |
22
+ | axis ax | (1, 2, 3) | 模型 |
23
+ | axis neg | ( / / ) | 模型 |