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

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