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,30 @@
1
+ | 项目 | 值 | 出处 |
2
+ | --- | --- | --- |
3
+ | case_name | WBT7-d20.559-mu90 | 工况名(Excel 表头) |
4
+ | kind | INT | 规则集(多规则集共用一本工作簿时用 case_filter 分流) |
5
+ | tank_ref | WBT7 | 指向成员表 `Tank Data` 的哪一行(指南 §18) |
6
+ | draft | 20.559 m | 装载工况 |
7
+ | mu_deg | 90 deg | Table 1A D |
8
+ | k_c | 1 | 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 | 7.25 m | 5.7.2(b) |
18
+ | delta_b / delta_h | 0 m / 0 m | 5.7.2(b) |
19
+ | rho_tank | 1025 kg/m^3 | 成员表 Tank Data |
20
+ | l_tank / b_tank / h_tank | 14.5 m / 10.15 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 N/cm^2 | 成员表 Tank Data |
24
+ | GM_full_in / k_r_in | 0 m / 0 m | 稳性计算书 |
25
+ | tank_is_ballast / member_11_17 | 1 / 0 | 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
+ // {{ case_name }}
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 = {{ neg_x }}t{{ ax_x }};
11
+ y = {{ neg_y }}t{{ ax_y }};
12
+ z = {{ neg_z }}t{{ ax_z }};
13
+ // --- global parameters (same for every case)
14
+ var L = {{ L }};
15
+ var B = {{ B }};
16
+ var D = {{ D }};
17
+ var r_b = {{ r_b }};
18
+ var freeboard = {{ freeboard }};
19
+ var rho_sea = {{ rho_sea }};
20
+ var g = {{ g }};
21
+ var Cb = {{ Cb }};
22
+ // --- this case
23
+ var draft = {{ draft }};
24
+ var mu_deg = {{ mu_deg }};
25
+ var k_c = {{ k_c }};
26
+ var k_f0 = {{ k_f0 }};
27
+ var k_u = {{ k_u }};
28
+ var beta_EPS = {{ beta_EPS }};
29
+ var beta_EPP = {{ beta_EPP }};
30
+ var k_esf = {{ k_esf }};
31
+ var x_o = {{ x_o }};
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 | {{ case_name }} | 工况名(Excel 表头) |
4
+ | kind | {{ kind }} | 规则集(多规则集共用一本工作簿时用 case_filter 分流) |
5
+ | draft | {{ draft }} | 装载工况 |
6
+ | mu_deg | {{ mu_deg }} | Table 1A D |
7
+ | k_c | {{ k_c }} | Table 1A B |
8
+ | k_f0 | {{ k_f0 }} | Table 1A B |
9
+ | k_u | {{ k_u }} | 5A-3-2/7, /9 |
10
+ | beta_EPS | {{ beta_EPS }} | 5A-3-A1/3 |
11
+ | beta_EPP | {{ beta_EPP }} | 5A-3-A1/3 |
12
+ | k_esf | {{ k_esf }} | 项目 |
13
+ | x_o | {{ x_o }} | Fig. 9 脚注 |
14
+ | L | {{ L }} | 3-1-1/3 |
15
+ | B | {{ B }} | 3-1-1/3 |
16
+ | D | {{ D }} | 3-1-1/3 |
17
+ | r_b | {{ r_b }} | Fig. 11 |
18
+ | freeboard | {{ freeboard }} | Fig. 10 |
19
+ | rho_sea | {{ rho_sea }} | 5.5.1 |
20
+ | g | {{ g }} | 5.5.1 |
21
+ | Cb | {{ Cb }} | 3-1-1/13.3 |
22
+ | axis ax | ({{ ax_x }}, {{ ax_y }}, {{ ax_z }}) | 模型 |
23
+ | axis neg | ({{ neg_x }} / {{ neg_y }} / {{ neg_z }}) | 模型 |
@@ -0,0 +1,124 @@
1
+ // {{ case_name }}
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 = {{ neg_x }}t{{ ax_x }};
7
+ y = {{ neg_y }}t{{ ax_y }};
8
+ z = {{ neg_z }}t{{ ax_z }};
9
+ // --- global parameters (same for every case)
10
+ var L = {{ L }};
11
+ var B = {{ B }};
12
+ var D = {{ D }};
13
+ var rho_sea = {{ rho_sea }};
14
+ var g = {{ g }};
15
+ var Cb = {{ Cb }};
16
+ var d_f = {{ d_f }};
17
+ var rho_g_lo = {{ rho_g_lo }};
18
+ var rho_g_hi = {{ rho_g_hi }};
19
+ // --- this case
20
+ var draft = {{ draft }};
21
+ var mu_deg = {{ mu_deg }};
22
+ var k_c = {{ k_c }};
23
+ var k_u = {{ k_u }};
24
+ var beta_VAC = {{ beta_VAC }};
25
+ var beta_LAC = {{ beta_LAC }};
26
+ var beta_TAC = {{ beta_TAC }};
27
+ var beta_PMO = {{ beta_PMO }};
28
+ var beta_RMO = {{ beta_RMO }};
29
+ var k_esf = {{ k_esf }};
30
+ var w_v = {{ w_v }};
31
+ var w_l = {{ w_l }};
32
+ var w_t = {{ w_t }};
33
+ var xi = {{ xi }};
34
+ var delta_b = {{ delta_b }};
35
+ var delta_h = {{ delta_h }};
36
+ // --- the tank this case names: {{ tank_ref }}
37
+ var rho_tank = {{ rho_tank }};
38
+ var l_tank = {{ l_tank }};
39
+ var b_tank = {{ b_tank }};
40
+ var h_tank = {{ h_tank }};
41
+ var eta_deck = {{ eta_deck }};
42
+ var eta_overflow = {{ eta_overflow }};
43
+ var C_dp = {{ C_dp }};
44
+ var C_ru = {{ C_ru }};
45
+ var p_vp = {{ p_vp }};
46
+ var GM_full_in = {{ GM_full_in }};
47
+ var k_r_in = {{ k_r_in }};
48
+ var tank_is_ballast = {{ tank_is_ballast }};
49
+ var member_11_17 = {{ member_11_17 }};
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 | {{ case_name }} | 工况名(Excel 表头) |
4
+ | kind | {{ kind }} | 规则集(多规则集共用一本工作簿时用 case_filter 分流) |
5
+ | tank_ref | {{ tank_ref }} | 指向成员表 `Tank Data` 的哪一行(指南 §18) |
6
+ | draft | {{ draft }} | 装载工况 |
7
+ | mu_deg | {{ mu_deg }} | Table 1A D |
8
+ | k_c | {{ k_c }} | Table 1A C |
9
+ | k_u | {{ k_u }} | 5A-3-2/7, /9 |
10
+ | beta_VAC | {{ beta_VAC }} | 5A-3-A1/3 |
11
+ | beta_LAC | {{ beta_LAC }} | 5A-3-A1/3 |
12
+ | beta_TAC | {{ beta_TAC }} | 5A-3-A1/3 |
13
+ | beta_PMO | {{ beta_PMO }} | 5A-3-A1/3 |
14
+ | beta_RMO | {{ beta_RMO }} | 5A-3-A1/3 |
15
+ | k_esf | {{ k_esf }} | 项目 |
16
+ | w_v / w_l / w_t | {{ w_v }} / {{ w_l }} / {{ w_t }} | Table 1A B |
17
+ | xi | {{ xi }} | 5.7.2(b) |
18
+ | delta_b / delta_h | {{ delta_b }} / {{ delta_h }} | 5.7.2(b) |
19
+ | rho_tank | {{ rho_tank }} | 成员表 Tank Data |
20
+ | l_tank / b_tank / h_tank | {{ l_tank }} / {{ b_tank }} / {{ h_tank }} | Fig. 11 |
21
+ | eta_deck / eta_overflow | {{ eta_deck }} / {{ eta_overflow }} | Fig. 12 |
22
+ | C_dp / C_ru | {{ C_dp }} / {{ C_ru }} | 5.7.2(d) |
23
+ | p_vp | {{ p_vp }} | 成员表 Tank Data |
24
+ | GM_full_in / k_r_in | {{ GM_full_in }} / {{ k_r_in }} | 稳性计算书 |
25
+ | tank_is_ballast / member_11_17 | {{ tank_is_ballast }} / {{ member_11_17 }} | Table 3 |
26
+ | L / B / D / d_f | {{ L }} / {{ B }} / {{ D }} / {{ d_f }} | 3-1-1/3 |
27
+ | rho_sea / g / Cb | {{ rho_sea }} / {{ g }} / {{ Cb }} | 5.7.1 |
28
+ | rho_g_lo / rho_g_hi | {{ rho_g_lo }} / {{ rho_g_hi }} | 5.7.2(a) |
29
+ | axis ax | ({{ ax_x }}, {{ ax_y }}, {{ ax_z }}) | 模型 |
30
+ | axis neg | ({{ neg_x }} / {{ neg_y }} / {{ neg_z }}) | 模型 |
@@ -0,0 +1,97 @@
1
+ version: 1
2
+
3
+ # --------------------------------------------------------------------------- #
4
+ # Excel 模板文件的生成配置
5
+ # --------------------------------------------------------------------------- #
6
+ excel:
7
+ output: "template.xlsx"
8
+ template_sheet: "Template" # 隐藏工作表,保存模板原文;设为 null 可关闭
9
+ sheets:
10
+ global: "Global Parameter"
11
+ local: "Local Parameter"
12
+ outputs: ["Output", "Output Vertical"]
13
+
14
+ # --------------------------------------------------------------------------- #
15
+ # 变量定义
16
+ # global : 对所有 Case 生效(Excel 中只有一列取值)
17
+ # local : 每个 Case 一份取值。默认一个工况一列(Excel 中从 E 列开始);
18
+ # 把 excel.local_direction 改成 vertical 就变成一行一个工况(A 列写 Case 名)——
19
+ # 适合把按行给出的工况数据整块粘进表里(指南 §19)
20
+ # --------------------------------------------------------------------------- #
21
+ variables:
22
+ global:
23
+ - name: baud
24
+ description: "波特率"
25
+ unit: "bps"
26
+ default: 115200
27
+ prefix: ""
28
+ suffix: ""
29
+ type: int
30
+ # 取值约束:越界在 validate / render 时就报错,并写成 Excel 的数值范围校验
31
+ min: 300
32
+ max: 4000000
33
+ - name: baud_div
34
+ description: "分频值 = baud / 16(派生参数:引用另一个参数,不用手填)"
35
+ derived: "baud / 16"
36
+ type: float
37
+ - name: mcu
38
+ description: "MCU 型号(字符串变量示例)"
39
+ default: "STM32F103"
40
+ prefix: ""
41
+ suffix: ""
42
+ pattern: "^STM32[A-Z][0-9]{3}[A-Z]{0,2}$"
43
+
44
+ local:
45
+ - name: port
46
+ description: "端口"
47
+ default: "A"
48
+ prefix: "GPIO"
49
+ suffix: "_PORT"
50
+ pattern: "^[A-H]$"
51
+ - name: mode
52
+ description: "模式(取值约束:Excel 里会变成下拉列表)"
53
+ default: "TX_RX"
54
+ prefix: "MODE_"
55
+ suffix: ""
56
+ choices: ["TX", "RX", "TX_RX"]
57
+
58
+ # --------------------------------------------------------------------------- #
59
+ # 输出模板
60
+ # --------------------------------------------------------------------------- #
61
+ templates:
62
+ # 横向布局:每个 Case 占 Output 表的一列,结果行向下展开
63
+ #
64
+ # ⚠ 这里**显式**写 engine: snapshot(默认是 excel / 公式模式)。
65
+ # 因为下面用了过滤器({{ port.value | pvs(...) }}),而公式模式表达不了过滤器。
66
+ # 想体验"改 Excel 就改输出"请看 examples/example_formula.yaml 与
67
+ # examples/nastran_case_control.yaml —— 那两个都是默认的公式模式。
68
+ - name: uart_init
69
+ description: "UART 初始化代码(快照模式)"
70
+ output_sheet: "Output"
71
+ start_cell: "B2"
72
+ direction: "horizontal"
73
+ write_case_headers: true
74
+ engine: "snapshot"
75
+ filename: "uart_init_{{ case_name }}.c"
76
+ code: |
77
+ // Case: {{ case_name }}
78
+ UART_Init({{ baud }}, {{ port }}, {{ mode }});
79
+ // 纯值: {{ port.value }}, 前缀: {{ port.prefix }}, 后缀: {{ port.suffix }}
80
+ // 分频: {{ baud_div }}
81
+ // 过滤器: {{ port.value | pvs("GPIO", "_PORT") }}
82
+ // MCU: {{ mcu }}
83
+
84
+ # 纵向布局:每个 Case 占一行,结果行向右展开
85
+ - name: uart_summary
86
+ description: "UART 配置汇总表(Markdown,快照模式)"
87
+ output_sheet: "Output Vertical"
88
+ start_cell: "B2"
89
+ direction: "vertical"
90
+ write_case_headers: true
91
+ engine: "snapshot"
92
+ filename: "uart_summary_{{ case_name }}.md"
93
+ code: |
94
+ | case_name | baud | port | mode |
95
+ | --- | --- | --- | --- |
96
+ | {{ case_name }} | {{ baud }} | {{ port }} | {{ mode }} |
97
+ | 纯值/组合值 | {{ baud.value }} | {{ port.value | wrap("GPIO", "_PORT") }} | 前缀={{ mode.prefix }} 纯值={{ mode.value }} |
@@ -0,0 +1,86 @@
1
+ version: 1
2
+
3
+ # --------------------------------------------------------------------------- #
4
+ # 公式模式示例 —— 也是**默认**引擎
5
+ #
6
+ # 这就是本工具推荐的用法:写一个 YAML → 生成一本 Excel → 之后就在 Excel 里干活。
7
+ # Output 表里写进去的是**公式**而不是文本快照 —— 改了 Global / Local 的参数之后,
8
+ # Excel 打开即自动重算,**不需要再跑任何命令**,工作簿脱离命令行也独立可用。
9
+ #
10
+ # (下面每个模板仍然写了 `engine: "excel"`,只是为了让你一眼看到这个字段;
11
+ # 不写也是公式模式。对照示例见 example.yaml,它显式声明了 engine: snapshot。)
12
+ #
13
+ # 代价(务必知悉):
14
+ # 1. 只支持"占位符替换 + 单行 {% if %}":{{ x }} / {{ x.value }} / {{ x.prefix }} /
15
+ # {{ x.suffix }} / {{ case_name }} / {{ template_name }};{% if %} 会编译成 Excel 的
16
+ # IF()(指南 §14.1.1)。{% for %} / 过滤器 / 多行 {% if %} 会直接报错(带行号);
17
+ # 2. 值只存在于 Excel / WPS 里:导出代码文件(--outdir)与 CI 检查(check)仍走命令行;
18
+ # 3. 改模板(这个 YAML)需要重跑一次 --write-excel 刷新公式,改参数不用。
19
+ # --------------------------------------------------------------------------- #
20
+ excel:
21
+ output: "template_formula.xlsx"
22
+ template_sheet: "Template"
23
+ howto_sheet: "HOWTO"
24
+ sheets:
25
+ global: "Global Parameter"
26
+ local: "Local Parameter"
27
+ outputs: ["Output", "Output Vertical"]
28
+
29
+ variables:
30
+ global:
31
+ - name: baud
32
+ description: "波特率"
33
+ default: 115200
34
+ prefix: ""
35
+ suffix: ""
36
+ type: int
37
+ - name: baud_khz
38
+ description: "波特率(kHz)= baud / 1000 —— 派生参数示例"
39
+ derived: "baud / 1000" # ← 引用另一个参数,不用自己在表里算
40
+ type: float
41
+ - name: mcu
42
+ description: "MCU 型号(字符串变量示例)"
43
+ default: "STM32F103"
44
+ prefix: ""
45
+ suffix: ""
46
+
47
+ local:
48
+ - name: port
49
+ description: "端口"
50
+ default: "A"
51
+ prefix: "GPIO"
52
+ suffix: "_PORT"
53
+ - name: mode
54
+ description: "模式"
55
+ default: "TX_RX"
56
+ prefix: "MODE_"
57
+ suffix: ""
58
+
59
+ templates:
60
+ # 横向:一个 Case 一列;每行一个公式,右拉即多一个 Case
61
+ - name: uart_init
62
+ description: "UART 初始化代码(公式模式)"
63
+ output_sheet: "Output"
64
+ start_cell: "B2"
65
+ direction: "horizontal"
66
+ write_case_headers: true
67
+ engine: "excel"
68
+ filename: "uart_init_{{ case_name }}.c"
69
+ code: |
70
+ // Case: {{ case_name }}
71
+ UART_Init({{ baud }}, {{ port }}, {{ mode }});
72
+ // 纯值: {{ port.value }}, 前缀: {{ port.prefix }}, 后缀: {{ port.suffix }}
73
+ // 派生参数: {{ baud_khz }} kHz
74
+ // MCU: {{ mcu }}
75
+
76
+ # 纵向:一个 Case 一行(公式一样有效,只是右拉会换列)
77
+ - name: uart_pins
78
+ description: "端口占用表(公式模式,纵向)"
79
+ output_sheet: "Output Vertical"
80
+ start_cell: "B2"
81
+ direction: "vertical"
82
+ write_case_headers: true
83
+ engine: "excel"
84
+ filename: "uart_pins_{{ case_name }}.csv"
85
+ code: |
86
+ {{ case_name }},{{ port }},{{ mode }},{{ baud }}
@@ -0,0 +1,6 @@
1
+ // Case: Case1
2
+ UART_Init(115200, GPIOA_PORT, MODE_TX_RX);
3
+ // 纯值: A, 前缀: GPIO, 后缀: _PORT
4
+ // 分频: 7200
5
+ // 过滤器: GPIOA_PORT
6
+ // MCU: STM32F103
@@ -0,0 +1,6 @@
1
+ // Case: Case2
2
+ UART_Init(115200, GPIOA_PORT, MODE_TX_RX);
3
+ // 纯值: A, 前缀: GPIO, 后缀: _PORT
4
+ // 分频: 7200
5
+ // 过滤器: GPIOA_PORT
6
+ // MCU: STM32F103
@@ -0,0 +1,4 @@
1
+ | case_name | baud | port | mode |
2
+ | --- | --- | --- | --- |
3
+ | Case1 | 115200 | GPIOA_PORT | MODE_TX_RX |
4
+ | 纯值/组合值 | 115200 | GPIOA_PORT | 前缀=MODE_ 纯值=TX_RX |
@@ -0,0 +1,4 @@
1
+ | case_name | baud | port | mode |
2
+ | --- | --- | --- | --- |
3
+ | Case2 | 115200 | GPIOA_PORT | MODE_TX_RX |
4
+ | 纯值/组合值 | 115200 | GPIOA_PORT | 前缀=MODE_ 纯值=TX_RX |
@@ -0,0 +1,5 @@
1
+ // Case: Case1
2
+ UART_Init(115200, GPIOA_PORT, MODE_TX_RX);
3
+ // 纯值: A, 前缀: GPIO, 后缀: _PORT
4
+ // 派生参数: 115.2 kHz
5
+ // MCU: STM32F103
@@ -0,0 +1,5 @@
1
+ // Case: Case2
2
+ UART_Init(115200, GPIOA_PORT, MODE_TX_RX);
3
+ // 纯值: A, 前缀: GPIO, 后缀: _PORT
4
+ // 派生参数: 115.2 kHz
5
+ // MCU: STM32F103
@@ -0,0 +1 @@
1
+ Case1,GPIOA_PORT,MODE_TX_RX,115200
@@ -0,0 +1 @@
1
+ Case2,GPIOA_PORT,MODE_TX_RX,115200
@@ -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 "example_formula.yaml" -x "template_formula.xlsx" --write-excel
11
+ ) else (
12
+ excel-codegen render -c "example_formula.yaml" -x "template_formula.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 "example_formula.yaml" -x "template_formula.xlsx" --write-excel
11
+ else
12
+ excel-codegen render -c "example_formula.yaml" -x "template_formula.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,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 "example.yaml" -x "template.xlsx" --write-excel
11
+ ) else (
12
+ excel-codegen render -c "example.yaml" -x "template.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 "example.yaml" -x "template.xlsx" --write-excel
11
+ else
12
+ excel-codegen render -c "example.yaml" -x "template.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,18 @@
1
+ SUBCASE 1
2
+ SUBTITLE = HEAD SEA
3
+ LOAD = 1001
4
+ SPC = 1
5
+ SUBCASE 2
6
+ SUBTITLE = BEAM SEA
7
+ LOAD = 1002
8
+ SPC = 1
9
+ SUBCASE 3
10
+ LABEL = QTR
11
+ SUBTITLE = QUARTERING SEA
12
+ METHOD = 1
13
+ LOAD = 1003
14
+ SPC = 2
15
+ SUBCOM 4
16
+ SUBTITLE = COMBINED 1.0 / 1.2 / 1.3
17
+ SUBSEQ = 1, 1.2, 1.3
18
+ SUBCASE 5
@@ -0,0 +1,8 @@
1
+ SUBCASE 1
2
+
3
+ SUBTITLE = HEAD SEA
4
+
5
+
6
+ LOAD = 1001
7
+ SPC = 1
8
+