@theerapat-s28/ts-structural-eng-tools 1.5.0 → 2.1.0

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 (193) hide show
  1. package/README.md +57 -6
  2. package/dist/core/constants/frame.constant.d.ts +19 -0
  3. package/dist/core/constants/frame.constant.js +23 -0
  4. package/dist/core/constants/frame.constant.js.map +1 -0
  5. package/dist/core/errors/frame-analysis.error.d.ts +36 -0
  6. package/dist/core/errors/frame-analysis.error.js +86 -0
  7. package/dist/core/errors/frame-analysis.error.js.map +1 -0
  8. package/dist/core/index.d.ts +4 -0
  9. package/dist/core/index.js +13 -1
  10. package/dist/core/index.js.map +1 -1
  11. package/dist/core/types/section-properties.type.d.ts +13 -0
  12. package/dist/core/types/section-properties.type.js +3 -0
  13. package/dist/core/types/section-properties.type.js.map +1 -0
  14. package/dist/esm/core/constants/frame.constant.js +20 -0
  15. package/dist/esm/core/constants/frame.constant.js.map +1 -0
  16. package/dist/esm/core/constants/rc.constant.js +63 -0
  17. package/dist/esm/core/constants/rc.constant.js.map +1 -0
  18. package/dist/esm/core/errors/frame-analysis.error.js +82 -0
  19. package/dist/esm/core/errors/frame-analysis.error.js.map +1 -0
  20. package/dist/esm/core/errors/rc-design.error.js +64 -0
  21. package/dist/esm/core/errors/rc-design.error.js.map +1 -0
  22. package/dist/esm/core/index.js +9 -0
  23. package/dist/esm/core/index.js.map +1 -0
  24. package/dist/esm/core/types/output-message.type.js +2 -0
  25. package/dist/esm/core/types/output-message.type.js.map +1 -0
  26. package/dist/esm/core/types/plate-jacketing.type.js +18 -0
  27. package/dist/esm/core/types/plate-jacketing.type.js.map +1 -0
  28. package/dist/esm/core/types/rc-beam.type.js +11 -0
  29. package/dist/esm/core/types/rc-beam.type.js.map +1 -0
  30. package/dist/esm/core/types/section-properties.type.js +2 -0
  31. package/dist/esm/core/types/section-properties.type.js.map +1 -0
  32. package/dist/esm/core/types/unit.type.js +2 -0
  33. package/dist/esm/core/types/unit.type.js.map +1 -0
  34. package/dist/esm/fea/frame/area/area-geometry.js +132 -0
  35. package/dist/esm/fea/frame/area/area-geometry.js.map +1 -0
  36. package/dist/esm/fea/frame/area/distribute-area-loads.js +267 -0
  37. package/dist/esm/fea/frame/area/distribute-area-loads.js.map +1 -0
  38. package/dist/esm/fea/frame/area/edge-members.js +62 -0
  39. package/dist/esm/fea/frame/area/edge-members.js.map +1 -0
  40. package/dist/esm/fea/frame/elements/beam-3d-stiffness.js +84 -0
  41. package/dist/esm/fea/frame/elements/beam-3d-stiffness.js.map +1 -0
  42. package/dist/esm/fea/frame/elements/fixed-end-forces.js +88 -0
  43. package/dist/esm/fea/frame/elements/fixed-end-forces.js.map +1 -0
  44. package/dist/esm/fea/frame/elements/static-condensation.js +55 -0
  45. package/dist/esm/fea/frame/elements/static-condensation.js.map +1 -0
  46. package/dist/esm/fea/frame/index.js +7 -0
  47. package/dist/esm/fea/frame/index.js.map +1 -0
  48. package/dist/esm/fea/frame/post/demand-envelope.js +97 -0
  49. package/dist/esm/fea/frame/post/demand-envelope.js.map +1 -0
  50. package/dist/esm/fea/frame/post/envelope.js +59 -0
  51. package/dist/esm/fea/frame/post/envelope.js.map +1 -0
  52. package/dist/esm/fea/frame/post/member-diagram.js +375 -0
  53. package/dist/esm/fea/frame/post/member-diagram.js.map +1 -0
  54. package/dist/esm/fea/frame/post/present-state.js +106 -0
  55. package/dist/esm/fea/frame/post/present-state.js.map +1 -0
  56. package/dist/esm/fea/frame/solver/analyze-frame.js +131 -0
  57. package/dist/esm/fea/frame/solver/analyze-frame.js.map +1 -0
  58. package/dist/esm/fea/frame/solver/boundary-conditions.js +33 -0
  59. package/dist/esm/fea/frame/solver/boundary-conditions.js.map +1 -0
  60. package/dist/esm/fea/frame/solver/combinations.js +69 -0
  61. package/dist/esm/fea/frame/solver/combinations.js.map +1 -0
  62. package/dist/esm/fea/frame/solver/frame-system.js +122 -0
  63. package/dist/esm/fea/frame/solver/frame-system.js.map +1 -0
  64. package/dist/esm/fea/frame/solver/global-assembly.js +27 -0
  65. package/dist/esm/fea/frame/solver/global-assembly.js.map +1 -0
  66. package/dist/esm/fea/frame/solver/load-case-solver.js +133 -0
  67. package/dist/esm/fea/frame/solver/load-case-solver.js.map +1 -0
  68. package/dist/esm/fea/frame/transformation/coordinate-transform.js +71 -0
  69. package/dist/esm/fea/frame/transformation/coordinate-transform.js.map +1 -0
  70. package/dist/esm/fea/frame/types/model.type.js +2 -0
  71. package/dist/esm/fea/frame/types/model.type.js.map +1 -0
  72. package/dist/esm/fea/frame/types/results.type.js +2 -0
  73. package/dist/esm/fea/frame/types/results.type.js.map +1 -0
  74. package/dist/esm/fea/frame/validation/validate-model.js +389 -0
  75. package/dist/esm/fea/frame/validation/validate-model.js.map +1 -0
  76. package/dist/esm/fea/index.js +3 -0
  77. package/dist/esm/fea/index.js.map +1 -0
  78. package/dist/esm/index.js +10 -0
  79. package/dist/esm/index.js.map +1 -0
  80. package/dist/esm/package.json +1 -0
  81. package/dist/esm/rc/general.js +32 -0
  82. package/dist/esm/rc/general.js.map +1 -0
  83. package/dist/esm/rc/index.js +5 -0
  84. package/dist/esm/rc/index.js.map +1 -0
  85. package/dist/esm/rc/rc-bar-layout.js +89 -0
  86. package/dist/esm/rc/rc-bar-layout.js.map +1 -0
  87. package/dist/esm/rc/rc-beam-design.js +320 -0
  88. package/dist/esm/rc/rc-beam-design.js.map +1 -0
  89. package/dist/esm/rc/rc-section-properties.js +55 -0
  90. package/dist/esm/rc/rc-section-properties.js.map +1 -0
  91. package/dist/esm/strengthening/index.js +4 -0
  92. package/dist/esm/strengthening/index.js.map +1 -0
  93. package/dist/esm/strengthening/rc-beam-plate-interface-bolts.js +338 -0
  94. package/dist/esm/strengthening/rc-beam-plate-interface-bolts.js.map +1 -0
  95. package/dist/esm/strengthening/rc-beam-side-plate-shear.js +381 -0
  96. package/dist/esm/strengthening/rc-beam-side-plate-shear.js.map +1 -0
  97. package/dist/esm/strengthening/rc-beam-steel-plate-jacketing.js +90 -0
  98. package/dist/esm/strengthening/rc-beam-steel-plate-jacketing.js.map +1 -0
  99. package/dist/esm/utils/index.js +5 -0
  100. package/dist/esm/utils/index.js.map +1 -0
  101. package/dist/esm/utils/math.js +30 -0
  102. package/dist/esm/utils/math.js.map +1 -0
  103. package/dist/esm/utils/matrix.js +145 -0
  104. package/dist/esm/utils/matrix.js.map +1 -0
  105. package/dist/esm/utils/merge-warning.js +11 -0
  106. package/dist/esm/utils/merge-warning.js.map +1 -0
  107. package/dist/esm/utils/skyline.js +151 -0
  108. package/dist/esm/utils/skyline.js.map +1 -0
  109. package/dist/fea/frame/area/area-geometry.d.ts +56 -0
  110. package/dist/fea/frame/area/area-geometry.js +142 -0
  111. package/dist/fea/frame/area/area-geometry.js.map +1 -0
  112. package/dist/fea/frame/area/distribute-area-loads.d.ts +30 -0
  113. package/dist/fea/frame/area/distribute-area-loads.js +272 -0
  114. package/dist/fea/frame/area/distribute-area-loads.js.map +1 -0
  115. package/dist/fea/frame/area/edge-members.d.ts +25 -0
  116. package/dist/fea/frame/area/edge-members.js +67 -0
  117. package/dist/fea/frame/area/edge-members.js.map +1 -0
  118. package/dist/fea/frame/elements/beam-3d-stiffness.d.ts +29 -0
  119. package/dist/fea/frame/elements/beam-3d-stiffness.js +90 -0
  120. package/dist/fea/frame/elements/beam-3d-stiffness.js.map +1 -0
  121. package/dist/fea/frame/elements/fixed-end-forces.d.ts +36 -0
  122. package/dist/fea/frame/elements/fixed-end-forces.js +93 -0
  123. package/dist/fea/frame/elements/fixed-end-forces.js.map +1 -0
  124. package/dist/fea/frame/elements/static-condensation.d.ts +19 -0
  125. package/dist/fea/frame/elements/static-condensation.js +59 -0
  126. package/dist/fea/frame/elements/static-condensation.js.map +1 -0
  127. package/dist/fea/frame/index.d.ts +10 -0
  128. package/dist/fea/frame/index.js +18 -0
  129. package/dist/fea/frame/index.js.map +1 -0
  130. package/dist/fea/frame/post/demand-envelope.d.ts +36 -0
  131. package/dist/fea/frame/post/demand-envelope.js +101 -0
  132. package/dist/fea/frame/post/demand-envelope.js.map +1 -0
  133. package/dist/fea/frame/post/envelope.d.ts +8 -0
  134. package/dist/fea/frame/post/envelope.js +63 -0
  135. package/dist/fea/frame/post/envelope.js.map +1 -0
  136. package/dist/fea/frame/post/member-diagram.d.ts +26 -0
  137. package/dist/fea/frame/post/member-diagram.js +379 -0
  138. package/dist/fea/frame/post/member-diagram.js.map +1 -0
  139. package/dist/fea/frame/post/present-state.d.ts +19 -0
  140. package/dist/fea/frame/post/present-state.js +111 -0
  141. package/dist/fea/frame/post/present-state.js.map +1 -0
  142. package/dist/fea/frame/solver/analyze-frame.d.ts +70 -0
  143. package/dist/fea/frame/solver/analyze-frame.js +136 -0
  144. package/dist/fea/frame/solver/analyze-frame.js.map +1 -0
  145. package/dist/fea/frame/solver/boundary-conditions.d.ts +14 -0
  146. package/dist/fea/frame/solver/boundary-conditions.js +37 -0
  147. package/dist/fea/frame/solver/boundary-conditions.js.map +1 -0
  148. package/dist/fea/frame/solver/combinations.d.ts +11 -0
  149. package/dist/fea/frame/solver/combinations.js +73 -0
  150. package/dist/fea/frame/solver/combinations.js.map +1 -0
  151. package/dist/fea/frame/solver/frame-system.d.ts +42 -0
  152. package/dist/fea/frame/solver/frame-system.js +126 -0
  153. package/dist/fea/frame/solver/frame-system.js.map +1 -0
  154. package/dist/fea/frame/solver/global-assembly.d.ts +17 -0
  155. package/dist/fea/frame/solver/global-assembly.js +33 -0
  156. package/dist/fea/frame/solver/global-assembly.js.map +1 -0
  157. package/dist/fea/frame/solver/load-case-solver.d.ts +34 -0
  158. package/dist/fea/frame/solver/load-case-solver.js +138 -0
  159. package/dist/fea/frame/solver/load-case-solver.js.map +1 -0
  160. package/dist/fea/frame/transformation/coordinate-transform.d.ts +21 -0
  161. package/dist/fea/frame/transformation/coordinate-transform.js +76 -0
  162. package/dist/fea/frame/transformation/coordinate-transform.js.map +1 -0
  163. package/dist/fea/frame/types/model.type.d.ts +170 -0
  164. package/dist/fea/frame/types/model.type.js +3 -0
  165. package/dist/fea/frame/types/model.type.js.map +1 -0
  166. package/dist/fea/frame/types/results.type.d.ts +134 -0
  167. package/dist/fea/frame/types/results.type.js +3 -0
  168. package/dist/fea/frame/types/results.type.js.map +1 -0
  169. package/dist/fea/frame/validation/validate-model.d.ts +18 -0
  170. package/dist/fea/frame/validation/validate-model.js +395 -0
  171. package/dist/fea/frame/validation/validate-model.js.map +1 -0
  172. package/dist/fea/index.d.ts +1 -0
  173. package/dist/fea/index.js +19 -0
  174. package/dist/fea/index.js.map +1 -0
  175. package/dist/index.d.ts +8 -4
  176. package/dist/index.js +37 -1
  177. package/dist/index.js.map +1 -1
  178. package/dist/rc/index.d.ts +2 -0
  179. package/dist/rc/index.js +3 -1
  180. package/dist/rc/index.js.map +1 -1
  181. package/dist/rc/rc-section-properties.d.ts +35 -0
  182. package/dist/rc/rc-section-properties.js +59 -0
  183. package/dist/rc/rc-section-properties.js.map +1 -0
  184. package/dist/utils/index.d.ts +4 -0
  185. package/dist/utils/index.js +19 -1
  186. package/dist/utils/index.js.map +1 -1
  187. package/dist/utils/matrix.d.ts +45 -0
  188. package/dist/utils/matrix.js +157 -0
  189. package/dist/utils/matrix.js.map +1 -0
  190. package/dist/utils/skyline.d.ts +49 -0
  191. package/dist/utils/skyline.js +161 -0
  192. package/dist/utils/skyline.js.map +1 -0
  193. package/package.json +28 -4
@@ -0,0 +1,375 @@
1
+ import { roundToDecimalPlaces } from "../../../utils/math.js";
2
+ const FORCE_COMPONENTS = ["N", "V2", "V3", "T", "M2", "M3"];
3
+ const DISPLACEMENT_COMPONENTS = ["u1", "u2", "u3"];
4
+ const COMPONENTS = [...FORCE_COMPONENTS, ...DISPLACEMENT_COMPONENTS];
5
+ /** Evenly spaced grid for the deflection extremes (force extremes need no grid: see below). */
6
+ const DEFLECTION_GRID_INTERVALS = 40;
7
+ /** Golden-section steps refining each deflection extreme between its neighbouring grid points. */
8
+ const REFINE_STEPS = 30;
9
+ const GOLDEN = (Math.sqrt(5) - 1) / 2;
10
+ // 3-point Gauss–Legendre rule on [−1, 1], exact up to degree 5
11
+ const GAUSS3_POINTS = [-Math.sqrt(3 / 5), 0, Math.sqrt(3 / 5)];
12
+ const GAUSS3_WEIGHTS = [5 / 9, 8 / 9, 5 / 9];
13
+ const FORCE_DECIMALS = 4;
14
+ const DISPLACEMENT_DECIMALS = 5;
15
+ /**
16
+ * Internal forces at distance `x` from the member start, in N and N·mm. Taken from the
17
+ * free body of the segment [0, x]; N is positive in tension, `M3` is positive for sagging
18
+ * when local 2 points up. At a point load, `side` picks the value just before or after it.
19
+ *
20
+ * @param startForce - Right-hand local force the start node exerts on the member: [F1, F2, F3, M1, M2, M3]
21
+ */
22
+ const internalForces = (startForce, loads, x, side) => {
23
+ const [f1, f2, f3, m1, m2, m3] = startForce;
24
+ // Q[axis]: resultant of loads in [0, x]; I[axis]: ∫(s − x)·q ds over [0, x]; Qt: torque in [0, x]
25
+ const Q = [0, 0, 0, 0];
26
+ const I = [0, 0, 0, 0];
27
+ let Qt = 0;
28
+ for (const load of loads) {
29
+ if (load.type === "torque") {
30
+ const m = Math.min(x, load.end);
31
+ if (m > load.start)
32
+ Qt += load.t * (m - load.start);
33
+ }
34
+ else if (load.type === "point") {
35
+ const included = side === "left" ? load.a < x : load.a <= x;
36
+ if (included) {
37
+ Q[load.axis] += load.P;
38
+ I[load.axis] += load.P * (load.a - x);
39
+ }
40
+ }
41
+ else {
42
+ const m = Math.min(x, load.end);
43
+ if (m > load.start) {
44
+ // q(s) = w1 + k·(s − start); in u = s − x over [a, b]: q = w1 + k·(u − a)
45
+ const k = (load.w2 - load.w1) / (load.end - load.start);
46
+ const a = load.start - x;
47
+ const b = m - x;
48
+ Q[load.axis] += load.w1 * (b - a) + (k * (b - a) ** 2) / 2;
49
+ I[load.axis] += ((load.w1 - k * a) * (b ** 2 - a ** 2)) / 2 + (k * (b ** 3 - a ** 3)) / 3;
50
+ }
51
+ }
52
+ }
53
+ return {
54
+ N: -f1 - Q[1],
55
+ V2: -f2 - Q[2],
56
+ V3: -f3 - Q[3],
57
+ T: -m1 - Qt,
58
+ M2: -m2 - x * f3 + I[3],
59
+ M3: -m3 + x * f2 - I[2],
60
+ };
61
+ };
62
+ /**
63
+ * Local displacements u1, u2, u3 (mm) at every grid point, from Euler–Bernoulli kinematics:
64
+ * `u1' = N/EA`, `u2'' = M3/EI33` (R3 = u2'), `u3'' = −M2/EI22` (R2 = −u3').
65
+ *
66
+ * Each field is `a + b·x + x·∫₀ˣκ − ∫₀ˣ s·κ`, with the running integrals accumulated once along
67
+ * the sorted grid. The grid contains every load breakpoint, so each interval lies inside one
68
+ * smooth piece where N is at most quadratic and M at most cubic, and one 3-point Gauss panel per
69
+ * interval integrates the (at most quartic) integrands exactly.
70
+ *
71
+ * The constants come from the member's own end displacements: end translations first, an end
72
+ * rotation only where a translation is released. A released rotation (hinge) never enters, so
73
+ * the curve is correct at hinged ends whose rotation differs from the node's.
74
+ */
75
+ const displacementsOnGrid = (member, startForce, endDisplacements, loads, grid) => {
76
+ const { E, A, I22, I33 } = member.section;
77
+ const L = member.length;
78
+ const n = grid.length;
79
+ // integrands: [N/EA, M3/EI33, s·M3/EI33, −M2/EI22, −s·M2/EI22]
80
+ const integrands = (s) => {
81
+ const f = internalForces(startForce, loads, s, "right");
82
+ const k3 = f.M3 / (E * I33);
83
+ const k2 = -f.M2 / (E * I22);
84
+ return [f.N / (E * A), k3, s * k3, k2, s * k2];
85
+ };
86
+ /** ∫ₐᵇ of every integrand: one 3-point Gauss panel, interior points only (no load side). */
87
+ const panel = (a, b) => {
88
+ const half = (b - a) / 2;
89
+ const mid = (a + b) / 2;
90
+ const out = [0, 0, 0, 0, 0];
91
+ GAUSS3_POINTS.forEach((p, k) => {
92
+ const g = integrands(mid + half * p);
93
+ for (let c = 0; c < 5; c++)
94
+ out[c] += half * GAUSS3_WEIGHTS[k] * g[c];
95
+ });
96
+ return out;
97
+ };
98
+ const cumulative = Array.from({ length: 5 }, () => new Float64Array(n));
99
+ for (let i = 1; i < n; i++) {
100
+ const g = panel(grid[i - 1], grid[i]);
101
+ for (let c = 0; c < 5; c++)
102
+ cumulative[c][i] = cumulative[c][i - 1] + g[c];
103
+ }
104
+ const [strain, k3, sk3, k2, sk2] = cumulative;
105
+ const last = n - 1;
106
+ /** a, b of `u = a + b·x + P(x)` from the first independent pair of end conditions. */
107
+ const planeConstants = (translation, rotation, rotationSign, PL, // P(L)
108
+ dPL) => {
109
+ const { released } = member;
110
+ // rows [ca, cb | rhs] of ca·a + cb·b = rhs
111
+ const conditions = [];
112
+ if (!released[translation])
113
+ conditions.push([1, 0, endDisplacements[translation]]);
114
+ if (!released[6 + translation]) {
115
+ conditions.push([1, L, endDisplacements[6 + translation] - PL]);
116
+ }
117
+ if (!released[rotation])
118
+ conditions.push([0, 1, rotationSign * endDisplacements[rotation]]);
119
+ if (!released[6 + rotation]) {
120
+ conditions.push([0, 1, rotationSign * endDisplacements[6 + rotation] - dPL]);
121
+ }
122
+ for (let i = 0; i < conditions.length; i++) {
123
+ for (let j = i + 1; j < conditions.length; j++) {
124
+ const [a1, b1, r1] = conditions[i];
125
+ const [a2, b2, r2] = conditions[j];
126
+ const det = a1 * b2 - a2 * b1;
127
+ if (Math.abs(det) > 1e-12 * Math.max(1, L)) {
128
+ return { a: (r1 * b2 - r2 * b1) / det, b: (a1 * r2 - a2 * r1) / det };
129
+ }
130
+ }
131
+ }
132
+ return { a: 0, b: 0 }; // unreachable: such releases are rejected as a mechanism (307)
133
+ };
134
+ const P3 = (i) => grid[i] * k3[i] - sk3[i];
135
+ const P2 = (i) => grid[i] * k2[i] - sk2[i];
136
+ const plane2 = planeConstants(1, 5, 1, P3(last), k3[last]); // u2, with u2' = R3
137
+ const plane3 = planeConstants(2, 4, -1, P2(last), k2[last]); // u3, with u3' = −R2
138
+ const axialStart = member.released[0] ? endDisplacements[6] - strain[last] : endDisplacements[0];
139
+ const onGrid = grid.map((x, i) => ({
140
+ u1: axialStart + strain[i],
141
+ u2: plane2.a + plane2.b * x + P3(i),
142
+ u3: plane3.a + plane3.b * x + P2(i),
143
+ }));
144
+ /** Displacement anywhere: the grid value plus one exact Gauss panel to x. */
145
+ const at = (x) => {
146
+ let lo = 0;
147
+ let hi = last;
148
+ while (lo < hi) {
149
+ const mid = (lo + hi + 1) >> 1;
150
+ if (grid[mid] <= x)
151
+ lo = mid;
152
+ else
153
+ hi = mid - 1;
154
+ }
155
+ const a = grid[lo];
156
+ if (x - a <= 0)
157
+ return onGrid[lo];
158
+ const g = panel(a, x);
159
+ const c = cumulative.map((col, k) => col[lo] + g[k]);
160
+ return {
161
+ u1: axialStart + c[0],
162
+ u2: plane2.a + plane2.b * x + (x * c[1] - c[2]),
163
+ u3: plane3.a + plane3.b * x + (x * c[3] - c[4]),
164
+ };
165
+ };
166
+ return { onGrid, at };
167
+ };
168
+ const SCALE = {
169
+ N: 1e-3,
170
+ V2: 1e-3,
171
+ V3: 1e-3,
172
+ T: 1e-6,
173
+ M2: 1e-6,
174
+ M3: 1e-6,
175
+ u1: 1,
176
+ u2: 1,
177
+ u3: 1,
178
+ };
179
+ const present = (c, value) => roundToDecimalPlaces(value * SCALE[c], c === "u1" || c === "u2" || c === "u3" ? DISPLACEMENT_DECIMALS : FORCE_DECIMALS) + 0;
180
+ /**
181
+ * Builds the force and displacement diagrams of one member from its end forces, its end
182
+ * displacements and its loads.
183
+ *
184
+ * @param member - Member geometry, section, axes and end releases
185
+ * @param startForce - Force the start node exerts on the member, right-hand local, N and N·mm
186
+ * @param endDisplacements - The 12 local right-hand displacements of the member's end nodes, mm and rad
187
+ * @param loads - Member loads in local axes, N and mm
188
+ * @param stationCount - Number of evenly spaced stations (at least 2); load breakpoints and
189
+ * zero-shear points are added, with both sides reported at a point load
190
+ * @param withStations - false returns the extremes only, with an empty `stations` array
191
+ */
192
+ export const memberDiagram = (member, startForce, endDisplacements, loads, stationCount = 21, withStations = true) => {
193
+ const L = member.length;
194
+ const tolerance = 1e-9 * L;
195
+ const breakpoints = new Set([0, L]);
196
+ for (const load of loads) {
197
+ if (load.type === "point")
198
+ breakpoints.add(load.a);
199
+ else {
200
+ breakpoints.add(load.start);
201
+ breakpoints.add(load.end);
202
+ }
203
+ }
204
+ const sortedBreaks = [...breakpoints].sort((a, b) => a - b);
205
+ const isBreak = (x) => sortedBreaks.some((b) => Math.abs(b - x) < tolerance);
206
+ /** Sorted, with points closer than the tolerance merged (the first one kept). */
207
+ const mergeSorted = (values) => {
208
+ const sorted = [...values].sort((a, b) => a - b);
209
+ const out = [];
210
+ for (const v of sorted)
211
+ if (out.length === 0 || v - out[out.length - 1] >= tolerance)
212
+ out.push(v);
213
+ return out;
214
+ };
215
+ // Inside each piece between breakpoints N and V are at most quadratic (linear loads), so the
216
+ // quadratic through both ends and the midpoint is exact. Its roots (zero shear: the moment
217
+ // extremes) and its vertex (zero load: the N and V extremes) are added to the grid.
218
+ const roots = [];
219
+ for (let i = 0; i < sortedBreaks.length - 1; i++) {
220
+ const xa = sortedBreaks[i];
221
+ const xb = sortedBreaks[i + 1];
222
+ const fa = internalForces(startForce, loads, xa, "right");
223
+ const fm = internalForces(startForce, loads, (xa + xb) / 2, "right");
224
+ const fb = internalForces(startForce, loads, xb, "left");
225
+ const inside = (t) => t > 0 && t < 1 && roots.push(xa + (xb - xa) * t);
226
+ for (const key of ["N", "V2", "V3"]) {
227
+ // f(t) = A·t² + B·t + C on t ∈ [0, 1]
228
+ const C = fa[key];
229
+ const A = 2 * fa[key] - 4 * fm[key] + 2 * fb[key];
230
+ const B = 4 * fm[key] - 3 * fa[key] - fb[key];
231
+ const scale = Math.max(Math.abs(fa[key]), Math.abs(fm[key]), Math.abs(fb[key]));
232
+ const curved = Math.abs(A) > 1e-12 * scale;
233
+ if (curved)
234
+ inside(-B / (2 * A));
235
+ if (key === "N")
236
+ continue;
237
+ if (!curved) {
238
+ if (Math.abs(B) > 1e-12 * scale)
239
+ inside(-C / B);
240
+ }
241
+ else {
242
+ const disc = B * B - 4 * A * C;
243
+ if (disc >= 0) {
244
+ const sq = Math.sqrt(disc);
245
+ inside((-B - sq) / (2 * A));
246
+ inside((-B + sq) / (2 * A));
247
+ }
248
+ }
249
+ }
250
+ }
251
+ const coarse = Array.from({ length: DEFLECTION_GRID_INTERVALS + 1 }, (_, i) => (L * i) / DEFLECTION_GRID_INTERVALS);
252
+ const count = Math.max(2, Math.floor(stationCount));
253
+ const uniform = withStations
254
+ ? Array.from({ length: count }, (_, i) => (L * i) / (count - 1))
255
+ : [];
256
+ // One grid for everything: breakpoints, zero-shear points, stations and the deflection grid
257
+ const grid = mergeSorted([...sortedBreaks, ...roots, ...uniform, ...coarse]);
258
+ const field = displacementsOnGrid(member, startForce, endDisplacements, loads, grid);
259
+ const displacements = field.onGrid;
260
+ const gridIndex = (x) => {
261
+ let lo = 0;
262
+ let hi = grid.length - 1;
263
+ while (lo < hi) {
264
+ const mid = (lo + hi) >> 1;
265
+ if (grid[mid] < x - tolerance)
266
+ lo = mid + 1;
267
+ else
268
+ hi = mid;
269
+ }
270
+ return lo;
271
+ };
272
+ // ---- Stations -------------------------------------------------------------------
273
+ const stations = [];
274
+ if (withStations) {
275
+ const [l1, l2, l3] = member.lambda;
276
+ const toStation = (x, f, u) => {
277
+ const station = { x: roundToDecimalPlaces(x, 3) };
278
+ for (const c of FORCE_COMPONENTS)
279
+ station[c] = present(c, f[c]);
280
+ for (const c of DISPLACEMENT_COMPONENTS)
281
+ station[c] = present(c, u[c]);
282
+ // global = Σ local component × its axis direction
283
+ const g = [0, 1, 2].map((k) => u.u1 * l1[k] + u.u2 * l2[k] + u.u3 * l3[k]);
284
+ station.ux = roundToDecimalPlaces(g[0], DISPLACEMENT_DECIMALS) + 0;
285
+ station.uy = roundToDecimalPlaces(g[1], DISPLACEMENT_DECIMALS) + 0;
286
+ station.uz = roundToDecimalPlaces(g[2], DISPLACEMENT_DECIMALS) + 0;
287
+ return station;
288
+ };
289
+ const stationXs = mergeSorted([...uniform, ...sortedBreaks, ...roots]);
290
+ for (const x of stationXs) {
291
+ const u = displacements[gridIndex(x)];
292
+ const right = internalForces(startForce, loads, x, "right");
293
+ if (isBreak(x) && x > 0 && x < L) {
294
+ const left = internalForces(startForce, loads, x, "left");
295
+ if (FORCE_COMPONENTS.some((c) => Math.abs(left[c] - right[c]) > 1e-9)) {
296
+ stations.push(toStation(x, left, u));
297
+ }
298
+ }
299
+ stations.push(toStation(x, right, u));
300
+ }
301
+ }
302
+ // ---- Extremes -------------------------------------------------------------------
303
+ // N and V are at most quadratic, T linear and M at most cubic inside each piece, so their
304
+ // extremes lie at a breakpoint (either side), a zero-load or a zero-shear point — all on the
305
+ // grid, so these are exact.
306
+ // Deflections are taken on the grid, then refined by golden-section search.
307
+ const extremes = {};
308
+ const best = {};
309
+ const consider = (c, value, x, i) => {
310
+ const b = best[c];
311
+ if (!b)
312
+ best[c] = { max: [value, x, i], min: [value, x, i] };
313
+ else {
314
+ if (value > b.max[0])
315
+ b.max = [value, x, i];
316
+ if (value < b.min[0])
317
+ b.min = [value, x, i];
318
+ }
319
+ };
320
+ grid.forEach((x, i) => {
321
+ const sides = isBreak(x) && x > 0 && x < L ? ["right", "left"] : ["right"];
322
+ for (const side of sides) {
323
+ const f = internalForces(startForce, loads, x, side);
324
+ for (const c of FORCE_COMPONENTS)
325
+ consider(c, f[c], x, i);
326
+ }
327
+ for (const c of DISPLACEMENT_COMPONENTS)
328
+ consider(c, displacements[i][c], x, i);
329
+ });
330
+ const refine = (c, i, sign) => {
331
+ // maximise sign·u between the neighbouring grid points
332
+ let a = grid[Math.max(0, i - 1)];
333
+ let b = grid[Math.min(grid.length - 1, i + 1)];
334
+ const value = (x) => sign * field.at(x)[c];
335
+ let x1 = b - GOLDEN * (b - a);
336
+ let x2 = a + GOLDEN * (b - a);
337
+ let f1 = value(x1);
338
+ let f2 = value(x2);
339
+ for (let step = 0; step < REFINE_STEPS; step++) {
340
+ if (f1 < f2) {
341
+ a = x1;
342
+ x1 = x2;
343
+ f1 = f2;
344
+ x2 = a + GOLDEN * (b - a);
345
+ f2 = value(x2);
346
+ }
347
+ else {
348
+ b = x2;
349
+ x2 = x1;
350
+ f2 = f1;
351
+ x1 = b - GOLDEN * (b - a);
352
+ f1 = value(x1);
353
+ }
354
+ }
355
+ return f1 >= f2 ? [sign * f1, x1] : [sign * f2, x2];
356
+ };
357
+ for (const c of DISPLACEMENT_COMPONENTS) {
358
+ const b = best[c];
359
+ const [maxValue, maxX] = refine(c, b.max[2], 1);
360
+ if (maxValue > b.max[0])
361
+ b.max = [maxValue, maxX, b.max[2]];
362
+ const [minValue, minX] = refine(c, b.min[2], -1);
363
+ if (minValue < b.min[0])
364
+ b.min = [minValue, minX, b.min[2]];
365
+ }
366
+ for (const c of COMPONENTS) {
367
+ const make = ([value, x]) => ({
368
+ value: present(c, value),
369
+ x: roundToDecimalPlaces(x, 3),
370
+ });
371
+ extremes[c] = { max: make(best[c].max), min: make(best[c].min) };
372
+ }
373
+ return { memberId: member.id, length: L, stations, extremes };
374
+ };
375
+ //# sourceMappingURL=member-diagram.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"member-diagram.js","sourceRoot":"","sources":["../../../../../src/fea/frame/post/member-diagram.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,106 @@
1
+ import { EQUILIBRIUM_TOLERANCE } from "../../../core/constants/frame.constant.js";
2
+ import { roundToDecimalPlaces } from "../../../utils/math.js";
3
+ import { matVec } from "../../../utils/matrix.js";
4
+ import { memberDofs } from "../solver/global-assembly.js";
5
+ import { memberDiagram } from "./member-diagram.js";
6
+ const FORCE_DECIMALS = 4;
7
+ const DISPLACEMENT_DECIMALS = 5;
8
+ const ROTATION_DECIMALS = 8;
9
+ const roundForce = (value, factor) => roundToDecimalPlaces(value * factor, FORCE_DECIMALS) + 0; // + 0 turns -0 into 0
10
+ const endForce = (f) => ({
11
+ f1: roundForce(f[0], 1e-3),
12
+ f2: roundForce(f[1], 1e-3),
13
+ f3: roundForce(f[2], 1e-3),
14
+ m1: roundForce(f[3], 1e-6),
15
+ m2: roundForce(f[4], 1e-6),
16
+ m3: roundForce(f[5], 1e-6),
17
+ });
18
+ /** Global force and moment residual of applied loads plus reactions, in kN and kN·m. */
19
+ const equilibrium = (system, state) => {
20
+ const { F, R } = state;
21
+ const total = { fx: 0, fy: 0, fz: 0, mx: 0, my: 0, mz: 0 };
22
+ let loadScale = 0;
23
+ system.nodes.forEach((node, n) => {
24
+ const q = (k) => F[6 * n + k] + R[6 * n + k]; // applied + reaction
25
+ const fx = q(0);
26
+ const fy = q(1);
27
+ const fz = q(2);
28
+ total.fx += fx;
29
+ total.fy += fy;
30
+ total.fz += fz;
31
+ total.mx += q(3) + node.y * fz - node.z * fy;
32
+ total.my += q(4) + node.z * fx - node.x * fz;
33
+ total.mz += q(5) + node.x * fy - node.y * fx;
34
+ loadScale += Math.abs(F[6 * n]) + Math.abs(F[6 * n + 1]) + Math.abs(F[6 * n + 2]);
35
+ });
36
+ const span = Math.max(1, ...system.nodes.map((n) => Math.hypot(n.x, n.y, n.z)));
37
+ const force = Math.hypot(total.fx, total.fy, total.fz); // N
38
+ const moment = Math.hypot(total.mx, total.my, total.mz); // N·mm
39
+ const scale = Math.max(loadScale, 1);
40
+ return {
41
+ force: force * 1e-3,
42
+ moment: moment * 1e-6,
43
+ exceeded: force > EQUILIBRIUM_TOLERANCE * scale || moment > EQUILIBRIUM_TOLERANCE * scale * span,
44
+ };
45
+ };
46
+ /**
47
+ * The presented diagram of member `m` in a raw state.
48
+ *
49
+ * @param stations - Evenly spaced stations
50
+ * @param withStations - false keeps only the extremes (empty `stations`)
51
+ */
52
+ export const presentMemberDiagram = (system, state, m, stations, withStations = true) => {
53
+ const member = system.members[m];
54
+ return memberDiagram(member, state.memberForces[m].slice(0, 6), matVec(member.T, memberDofs(member).map((d) => state.U[d])), state.memberLoads[m], stations, withStations);
55
+ };
56
+ /**
57
+ * Rounds a raw state into the presented result of one load case or combination.
58
+ *
59
+ * @param diagram - Evenly spaced station count, and whether to return stations or only extremes
60
+ */
61
+ export const presentState = (system, state, meta, diagram = {}) => {
62
+ const { U, R } = state;
63
+ const warnings = [];
64
+ const residual = equilibrium(system, state);
65
+ if (residual.exceeded) {
66
+ warnings.push({
67
+ reference: "Frame analysis, global equilibrium check",
68
+ message: `Global equilibrium residual is ${residual.force.toExponential(2)} kN and ${residual.moment.toExponential(2)} kN·m; the stiffness matrix may be ill-conditioned.`,
69
+ });
70
+ }
71
+ const mm = (v) => roundToDecimalPlaces(v, DISPLACEMENT_DECIMALS) + 0;
72
+ const rad = (v) => roundToDecimalPlaces(v, ROTATION_DECIMALS) + 0;
73
+ return {
74
+ ...meta,
75
+ nodalDisplacements: system.nodes.map((node, n) => ({
76
+ nodeId: node.id,
77
+ ux: mm(U[6 * n]),
78
+ uy: mm(U[6 * n + 1]),
79
+ uz: mm(U[6 * n + 2]),
80
+ rx: rad(U[6 * n + 3]),
81
+ ry: rad(U[6 * n + 4]),
82
+ rz: rad(U[6 * n + 5]),
83
+ })),
84
+ reactions: system.nodes.map((node, n) => ({
85
+ nodeId: node.id,
86
+ fx: roundForce(R[6 * n], 1e-3),
87
+ fy: roundForce(R[6 * n + 1], 1e-3),
88
+ fz: roundForce(R[6 * n + 2], 1e-3),
89
+ mx: roundForce(R[6 * n + 3], 1e-6),
90
+ my: roundForce(R[6 * n + 4], 1e-6),
91
+ mz: roundForce(R[6 * n + 5], 1e-6),
92
+ })),
93
+ memberEndForces: system.members.map((member, m) => ({
94
+ memberId: member.id,
95
+ start: endForce(state.memberForces[m].slice(0, 6)),
96
+ end: endForce(state.memberForces[m].slice(6, 12)),
97
+ })),
98
+ memberDiagrams: system.members.map((_, m) => presentMemberDiagram(system, state, m, diagram.stations, diagram.withStations ?? true)),
99
+ equilibriumResidual: {
100
+ force: roundToDecimalPlaces(residual.force, 8),
101
+ moment: roundToDecimalPlaces(residual.moment, 8),
102
+ },
103
+ warnings,
104
+ };
105
+ };
106
+ //# sourceMappingURL=present-state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"present-state.js","sourceRoot":"","sources":["../../../../../src/fea/frame/post/present-state.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,131 @@
1
+ import { areaMemberLoads } from "../area/distribute-area-loads.js";
2
+ import { buildEnvelope } from "../post/envelope.js";
3
+ import { presentMemberDiagram, presentState } from "../post/present-state.js";
4
+ import { throwIssues, validateFrameModel } from "../validation/validate-model.js";
5
+ import { resolveCombinations } from "./combinations.js";
6
+ import { prepareFrameSystem } from "./frame-system.js";
7
+ import { combineStates, solveLoadCase } from "./load-case-solver.js";
8
+ /** Groups loads by their load case id, keeping the input order within each case. */
9
+ const groupByCase = (loads = []) => {
10
+ const groups = new Map();
11
+ for (const load of loads) {
12
+ const group = groups.get(load.loadCase);
13
+ if (group)
14
+ group.push(load);
15
+ else
16
+ groups.set(load.loadCase, [load]);
17
+ }
18
+ return groups;
19
+ };
20
+ /**
21
+ * Analyses a 3D frame like `analyzeFrame` and keeps the solution, so that full member diagrams
22
+ * can be requested later one member at a time — e.g. analyse with `diagrams: "extremes"` and
23
+ * draw a member's diagram when the user selects it. Run it in a Web Worker for large models.
24
+ *
25
+ * @param model - Nodes, members, restraints, load cases, loads tagged with their load case,
26
+ * null areas, and combinations
27
+ * @param options - Diagram station count and detail
28
+ * @returns `{ result, memberDiagram }`
29
+ * @throws {FrameAnalysisError} 301–317 for an invalid model (with `details` and every problem in
30
+ * `issues`), 304 for an unstable structure
31
+ */
32
+ export const createFrameAnalysis = (model, options = {}) => {
33
+ const issues = validateFrameModel(model);
34
+ if (issues.length > 0)
35
+ throwIssues(issues);
36
+ const system = prepareFrameSystem(model);
37
+ const combinations = model.combinations ?? [];
38
+ const resolved = resolveCombinations(combinations, new Set(model.loadCases.map((c) => c.id)));
39
+ const withStations = (options.diagrams ?? "full") === "full";
40
+ const fromAreas = areaMemberLoads(model);
41
+ const states = new Map();
42
+ const cases = {};
43
+ const nodalByCase = groupByCase(model.nodalLoads);
44
+ const memberByCase = groupByCase([
45
+ ...(model.memberLoads ?? []),
46
+ ...fromAreas.memberLoads,
47
+ ]);
48
+ for (const loadCase of model.loadCases) {
49
+ const state = solveLoadCase(system, loadCase, {
50
+ nodalLoads: nodalByCase.get(loadCase.id) ?? [],
51
+ memberLoads: memberByCase.get(loadCase.id) ?? [],
52
+ });
53
+ states.set(loadCase.id, state);
54
+ cases[loadCase.id] = presentState(system, state, { id: loadCase.id, kind: "case", name: loadCase.name, type: loadCase.type }, { stations: options.stations, withStations });
55
+ }
56
+ const combinationStates = new Map();
57
+ const combinationResults = {};
58
+ for (const combination of combinations) {
59
+ // Non-empty: validation rejects combinations without terms
60
+ const terms = [...resolved.get(combination.id)].map(([caseId, factor]) => ({ state: states.get(caseId), factor }));
61
+ const state = combineStates(terms);
62
+ combinationStates.set(combination.id, state);
63
+ combinationResults[combination.id] = presentState(system, state, { id: combination.id, kind: "combination", name: combination.name }, { stations: options.stations, withStations });
64
+ }
65
+ const warnings = [
66
+ ...fromAreas.warnings,
67
+ ...[...Object.values(cases), ...Object.values(combinationResults)].flatMap((r) => r.warnings.map((w) => ({
68
+ ...w,
69
+ message: `${r.kind === "case" ? "Load case" : "Load combination"} "${r.id}": ${w.message}`,
70
+ }))),
71
+ ];
72
+ const combinationList = combinations.map((c) => combinationResults[c.id]);
73
+ const result = {
74
+ cases,
75
+ combinations: combinationResults,
76
+ envelope: combinationList.length > 0 ? buildEnvelope(combinationList) : undefined,
77
+ calculationDetails: {
78
+ nodeCount: system.nodes.length,
79
+ memberCount: system.members.length,
80
+ dofCount: system.dofCount,
81
+ freeDofCount: system.free.length,
82
+ profileSize: system.profileSize,
83
+ loadCaseCount: model.loadCases.length,
84
+ combinationCount: combinations.length,
85
+ },
86
+ units: { force: "kN", moment: "kN·m", length: "mm", rotation: "rad" },
87
+ warnings,
88
+ };
89
+ return {
90
+ result,
91
+ memberDiagram: (resultId, memberId, stations) => {
92
+ const state = combinationStates.get(resultId) ?? states.get(resultId);
93
+ if (!state)
94
+ throw new Error(`Load case or combination "${resultId}" is not in the model.`);
95
+ const m = system.memberIndex.get(memberId);
96
+ if (m === undefined)
97
+ throw new Error(`Member ${String(memberId)} is not in the model.`);
98
+ return presentMemberDiagram(system, state, m, stations ?? options.stations);
99
+ },
100
+ };
101
+ };
102
+ /**
103
+ * Analyses a 3D frame by the direct stiffness method (linear elastic, small displacements)
104
+ * for every load case, then forms every load combination by superposition.
105
+ *
106
+ * The model is validated first (`validateFrameModel`). The stiffness matrix is assembled once
107
+ * in skyline storage with the nodes in reverse Cuthill–McKee order and factorised once; each
108
+ * load case is a separate solve. A combination is the factored sum of its load cases (nested
109
+ * combinations are expanded), and its member diagrams are rebuilt from the combined end forces
110
+ * and factored member loads, so their extremes are exact rather than sums of case extremes.
111
+ *
112
+ * Units: node coordinates, section properties and positions in mm and MPa; loads in kN, kN·m
113
+ * and kN/m; springs in kN/mm and kN·m/rad; unit weight in kN/m³. Results are in kN, kN·m, mm
114
+ * and rad. Global axes X, Y, Z are right-handed with Z up; members use ETABS-style local axes
115
+ * 1, 2, 3 (see `memberAxes`). Member end forces and diagrams use right-hand rotations.
116
+ *
117
+ * Area loads on null areas (`areas`, `areaLoads`) are first turned into member loads on the
118
+ * members along each area's edges (see `distributeAreaLoads`); the areas add no stiffness.
119
+ *
120
+ * Model and result are plain data (JSON-serialisable), so the analysis can run in a Web Worker.
121
+ *
122
+ * @param model - Nodes, members, restraints, load cases, loads tagged with their load case,
123
+ * null areas, and combinations
124
+ * @param options - Diagram station count and detail
125
+ * @returns `cases` and `combinations` keyed by id, `envelope` over the combinations,
126
+ * `calculationDetails`, `units` and `warnings`
127
+ * @throws {FrameAnalysisError} 301–317 for an invalid model (with `details` and every problem in
128
+ * `issues`), 304 for an unstable structure
129
+ */
130
+ export const analyzeFrame = (model, options = {}) => createFrameAnalysis(model, options).result;
131
+ //# sourceMappingURL=analyze-frame.js.map