@theerapat-s28/ts-structural-eng-tools 2.0.1 → 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 (61) hide show
  1. package/README.md +26 -6
  2. package/dist/core/constants/frame.constant.d.ts +5 -0
  3. package/dist/core/constants/frame.constant.js +6 -1
  4. package/dist/core/constants/frame.constant.js.map +1 -1
  5. package/dist/core/errors/frame-analysis.error.d.ts +3 -0
  6. package/dist/core/errors/frame-analysis.error.js +14 -2
  7. package/dist/core/errors/frame-analysis.error.js.map +1 -1
  8. package/dist/core/index.d.ts +1 -1
  9. package/dist/core/index.js +2 -1
  10. package/dist/core/index.js.map +1 -1
  11. package/dist/esm/core/constants/frame.constant.js +5 -0
  12. package/dist/esm/core/constants/frame.constant.js.map +1 -1
  13. package/dist/esm/core/errors/frame-analysis.error.js +14 -2
  14. package/dist/esm/core/errors/frame-analysis.error.js.map +1 -1
  15. package/dist/esm/core/index.js +1 -1
  16. package/dist/esm/core/index.js.map +1 -1
  17. package/dist/esm/fea/frame/area/area-geometry.js +132 -0
  18. package/dist/esm/fea/frame/area/area-geometry.js.map +1 -0
  19. package/dist/esm/fea/frame/area/distribute-area-loads.js +267 -0
  20. package/dist/esm/fea/frame/area/distribute-area-loads.js.map +1 -0
  21. package/dist/esm/fea/frame/area/edge-members.js +62 -0
  22. package/dist/esm/fea/frame/area/edge-members.js.map +1 -0
  23. package/dist/esm/fea/frame/elements/fixed-end-forces.js +16 -3
  24. package/dist/esm/fea/frame/elements/fixed-end-forces.js.map +1 -1
  25. package/dist/esm/fea/frame/index.js +1 -0
  26. package/dist/esm/fea/frame/index.js.map +1 -1
  27. package/dist/esm/fea/frame/post/member-diagram.js +71 -28
  28. package/dist/esm/fea/frame/post/member-diagram.js.map +1 -1
  29. package/dist/esm/fea/frame/solver/analyze-frame.js +19 -11
  30. package/dist/esm/fea/frame/solver/analyze-frame.js.map +1 -1
  31. package/dist/esm/fea/frame/solver/load-case-solver.js +21 -7
  32. package/dist/esm/fea/frame/solver/load-case-solver.js.map +1 -1
  33. package/dist/esm/fea/frame/validation/validate-model.js +103 -6
  34. package/dist/esm/fea/frame/validation/validate-model.js.map +1 -1
  35. package/dist/fea/frame/area/area-geometry.d.ts +56 -0
  36. package/dist/fea/frame/area/area-geometry.js +142 -0
  37. package/dist/fea/frame/area/area-geometry.js.map +1 -0
  38. package/dist/fea/frame/area/distribute-area-loads.d.ts +30 -0
  39. package/dist/fea/frame/area/distribute-area-loads.js +272 -0
  40. package/dist/fea/frame/area/distribute-area-loads.js.map +1 -0
  41. package/dist/fea/frame/area/edge-members.d.ts +25 -0
  42. package/dist/fea/frame/area/edge-members.js +67 -0
  43. package/dist/fea/frame/area/edge-members.js.map +1 -0
  44. package/dist/fea/frame/elements/fixed-end-forces.d.ts +17 -3
  45. package/dist/fea/frame/elements/fixed-end-forces.js +18 -4
  46. package/dist/fea/frame/elements/fixed-end-forces.js.map +1 -1
  47. package/dist/fea/frame/index.d.ts +2 -1
  48. package/dist/fea/frame/index.js +3 -1
  49. package/dist/fea/frame/index.js.map +1 -1
  50. package/dist/fea/frame/post/member-diagram.js +71 -28
  51. package/dist/fea/frame/post/member-diagram.js.map +1 -1
  52. package/dist/fea/frame/solver/analyze-frame.d.ts +7 -4
  53. package/dist/fea/frame/solver/analyze-frame.js +19 -11
  54. package/dist/fea/frame/solver/analyze-frame.js.map +1 -1
  55. package/dist/fea/frame/solver/load-case-solver.js +21 -7
  56. package/dist/fea/frame/solver/load-case-solver.js.map +1 -1
  57. package/dist/fea/frame/types/model.type.d.ts +59 -1
  58. package/dist/fea/frame/validation/validate-model.d.ts +1 -1
  59. package/dist/fea/frame/validation/validate-model.js +103 -6
  60. package/dist/fea/frame/validation/validate-model.js.map +1 -1
  61. package/package.json +9 -3
@@ -0,0 +1,142 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.clipPolygon = exports.resolveAreaSupports = exports.edgeDirection = exports.isRectangle = exports.edgesParallel = exports.areaPlane = exports.edgeVector = void 0;
4
+ const frame_constant_1 = require("../../../core/constants/frame.constant");
5
+ const sub = (a, b) => [a[0] - b[0], a[1] - b[1], a[2] - b[2]];
6
+ const dot = (a, b) => a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
7
+ const cross = (a, b) => [
8
+ a[1] * b[2] - a[2] * b[1],
9
+ a[2] * b[0] - a[0] * b[2],
10
+ a[0] * b[1] - a[1] * b[0],
11
+ ];
12
+ const norm = (a) => Math.hypot(a[0], a[1], a[2]);
13
+ const scale = (a, s) => [a[0] * s, a[1] * s, a[2] * s];
14
+ const cross2 = (a, b) => a[0] * b[1] - a[1] * b[0];
15
+ const dot2 = (a, b) => a[0] * b[0] + a[1] * b[1];
16
+ /** The 2D edge vector i → i + 1 of a polygon. */
17
+ const edgeVector = (corners, i) => {
18
+ const a = corners[i];
19
+ const b = corners[(i + 1) % corners.length];
20
+ return [b[0] - a[0], b[1] - a[1]];
21
+ };
22
+ exports.edgeVector = edgeVector;
23
+ /**
24
+ * Builds the plane of an area from its corners, or names the problem: not 3 or 4 corners,
25
+ * two consecutive corners coinciding, no area, corners off one plane, or a polygon that is
26
+ * not strictly convex (a reflex corner, three corners in line or a crossed quad).
27
+ *
28
+ * @param points - Corner coordinates in mm, in order around the area
29
+ */
30
+ const areaPlane = (points) => {
31
+ const n = points.length;
32
+ if (n !== 3 && n !== 4)
33
+ return { problem: "nodeCount" };
34
+ const edges = points.map((p, i) => sub(points[(i + 1) % n], p));
35
+ const size = Math.max(...edges.map(norm));
36
+ const tolerance = frame_constant_1.AREA_GEOMETRY_TOLERANCE * size;
37
+ if (!(size > 0) || edges.some((e) => norm(e) <= tolerance))
38
+ return { problem: "repeatedNode" };
39
+ // Newell's method: the vector area, exact for a planar polygon
40
+ const vectorArea = points.reduce((sum, p, i) => {
41
+ const c = cross(p, points[(i + 1) % n]);
42
+ return [sum[0] + c[0] / 2, sum[1] + c[1] / 2, sum[2] + c[2] / 2];
43
+ }, [0, 0, 0]);
44
+ const area = norm(vectorArea);
45
+ if (!(area > tolerance * size))
46
+ return { problem: "degenerate" };
47
+ const normal = scale(vectorArea, 1 / area);
48
+ const centroid = scale(points.reduce((s, p) => [s[0] + p[0], s[1] + p[1], s[2] + p[2]], [0, 0, 0]), 1 / n);
49
+ if (points.some((p) => Math.abs(dot(sub(p, centroid), normal)) > tolerance)) {
50
+ return { problem: "nonPlanar" };
51
+ }
52
+ const along = sub(edges[0], scale(normal, dot(edges[0], normal)));
53
+ const u = scale(along, 1 / norm(along));
54
+ const v = cross(normal, u);
55
+ const corners = points.map((p) => [dot(sub(p, points[0]), u), dot(sub(p, points[0]), v)]);
56
+ // Strictly convex: every turn is to the left by more than the tolerance (sine of the turn)
57
+ for (let i = 0; i < n; i++) {
58
+ const a = (0, exports.edgeVector)(corners, i);
59
+ const b = (0, exports.edgeVector)(corners, (i + 1) % n);
60
+ if (!(cross2(a, b) > frame_constant_1.AREA_GEOMETRY_TOLERANCE * Math.hypot(...a) * Math.hypot(...b))) {
61
+ return { problem: "nonConvex" };
62
+ }
63
+ }
64
+ return { points, normal, u, v, corners, area, size };
65
+ };
66
+ exports.areaPlane = areaPlane;
67
+ /** Whether edges i and j are parallel (either way round) within the tolerance. */
68
+ const edgesParallel = (plane, i, j) => {
69
+ const a = (0, exports.edgeVector)(plane.corners, i);
70
+ const b = (0, exports.edgeVector)(plane.corners, j);
71
+ return Math.abs(cross2(a, b)) <= frame_constant_1.AREA_GEOMETRY_TOLERANCE * Math.hypot(...a) * Math.hypot(...b);
72
+ };
73
+ exports.edgesParallel = edgesParallel;
74
+ /** Whether a 4-corner area is a rectangle (every corner square within the tolerance). */
75
+ const isRectangle = (plane) => plane.corners.length === 4 &&
76
+ plane.corners.every((_, i) => {
77
+ const a = (0, exports.edgeVector)(plane.corners, i);
78
+ const b = (0, exports.edgeVector)(plane.corners, (i + 1) % 4);
79
+ return Math.abs(dot2(a, b)) <= frame_constant_1.AREA_GEOMETRY_TOLERANCE * Math.hypot(...a) * Math.hypot(...b);
80
+ });
81
+ exports.isRectangle = isRectangle;
82
+ /** Unit vector of edge i in global coordinates. */
83
+ const edgeDirection = (plane, i) => {
84
+ const n = plane.points.length;
85
+ const d = sub(plane.points[(i + 1) % n], plane.points[i]);
86
+ return scale(d, 1 / norm(d));
87
+ };
88
+ exports.edgeDirection = edgeDirection;
89
+ /**
90
+ * Resolves which edges of an area receive load from its distribution and `supportEdges`.
91
+ * Two-way loads every edge and takes no `supportEdges`. One-way spans parallel to the edges
92
+ * not listed, which must exist and all be parallel; cantilever takes exactly one edge.
93
+ *
94
+ * @returns The loaded edges, or `null` if `supportEdges` does not fit the distribution
95
+ */
96
+ const resolveAreaSupports = (plane, distribution, supportEdges) => {
97
+ const n = plane.corners.length;
98
+ if (distribution === "twoWay") {
99
+ return supportEdges === undefined ? { loadedEdges: [...Array(n).keys()] } : null;
100
+ }
101
+ if (!Array.isArray(supportEdges) ||
102
+ supportEdges.length === 0 ||
103
+ supportEdges.some((e) => !Number.isInteger(e) || e < 0 || e >= n) ||
104
+ new Set(supportEdges).size !== supportEdges.length) {
105
+ return null;
106
+ }
107
+ const loadedEdges = [...supportEdges].sort((a, b) => a - b);
108
+ if (distribution === "cantilever")
109
+ return loadedEdges.length === 1 ? { loadedEdges } : null;
110
+ const free = [...Array(n).keys()].filter((e) => !loadedEdges.includes(e));
111
+ if (free.length === 0 || free.some((e) => !(0, exports.edgesParallel)(plane, free[0], e)))
112
+ return null;
113
+ const d = (0, exports.edgeVector)(plane.corners, free[0]);
114
+ const length = Math.hypot(...d);
115
+ return { loadedEdges, span: [d[0] / length, d[1] / length] };
116
+ };
117
+ exports.resolveAreaSupports = resolveAreaSupports;
118
+ /**
119
+ * Clips a convex polygon to the half-plane `a · p ≤ c` (Sutherland–Hodgman, one plane).
120
+ *
121
+ * @param polygon - Corners in order, mm
122
+ * @returns The clipped polygon, in the same order; empty if nothing remains
123
+ */
124
+ const clipPolygon = (polygon, a, c) => {
125
+ const out = [];
126
+ const side = (p) => dot2(a, p) - c;
127
+ for (let i = 0; i < polygon.length; i++) {
128
+ const p = polygon[i];
129
+ const q = polygon[(i + 1) % polygon.length];
130
+ const sp = side(p);
131
+ const sq = side(q);
132
+ if (sp <= 0)
133
+ out.push(p);
134
+ if ((sp < 0 && sq > 0) || (sp > 0 && sq < 0)) {
135
+ const t = sp / (sp - sq);
136
+ out.push([p[0] + t * (q[0] - p[0]), p[1] + t * (q[1] - p[1])]);
137
+ }
138
+ }
139
+ return out;
140
+ };
141
+ exports.clipPolygon = clipPolygon;
142
+ //# sourceMappingURL=area-geometry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"area-geometry.js","sourceRoot":"","sources":["../../../../src/fea/frame/area/area-geometry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ import type { Warnings } from "../../../core/types/output-message.type";
2
+ import type { FrameModel, MemberLoad } from "../types/model.type";
3
+ /**
4
+ * Turns the area loads of a model into member loads, assuming the model is valid (as
5
+ * `validateFrameModel` checks): each area's edge profiles are built once, then scaled for each
6
+ * of its loads and split into global X, Y and Z trapezoidal loads (plus torques for a cantilever).
7
+ * Everything is linear in `q`, so load-case superposition still holds.
8
+ */
9
+ export declare const areaMemberLoads: (model: FrameModel) => {
10
+ memberLoads: MemberLoad[];
11
+ warnings: Warnings;
12
+ };
13
+ /**
14
+ * The member loads that a model's null areas send to the members along their edges — what
15
+ * `analyzeFrame` adds to `memberLoads` — so they can be checked or previewed.
16
+ *
17
+ * Two-way areas send each point to the nearest edge (corner-bisector split); one-way areas
18
+ * split strips parallel to their unsupported edges half to each end; cantilever areas send
19
+ * `q · c` and a torque `q · c² / 2` per unit length to their support edge (c = depth). Edges
20
+ * split by intermediate nodes are cut at those nodes. Loads are per unit true area and come
21
+ * out as trapezoidal loads in global X, Y and Z (and torques), each tagged with its load case.
22
+ *
23
+ * @param model - The frame model, validated first
24
+ * @returns `memberLoads` and `warnings` (a one-way support edge parallel to the span)
25
+ * @throws {FrameAnalysisError} 301–317 for an invalid model, with every problem in `issues`
26
+ */
27
+ export declare const distributeAreaLoads: (model: FrameModel) => {
28
+ memberLoads: MemberLoad[];
29
+ warnings: Warnings;
30
+ };
@@ -0,0 +1,272 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.distributeAreaLoads = exports.areaMemberLoads = void 0;
4
+ const frame_constant_1 = require("../../../core/constants/frame.constant");
5
+ const validate_model_1 = require("../validation/validate-model");
6
+ const area_geometry_1 = require("./area-geometry");
7
+ const edge_members_1 = require("./edge-members");
8
+ const GLOBAL_AXES = [
9
+ ["X", 0],
10
+ ["Y", 1],
11
+ ["Z", 2],
12
+ ];
13
+ const dot2 = (a, b) => a[0] * b[0] + a[1] * b[1];
14
+ /** Linear interpolation of a profile at `s` (0 outside it). */
15
+ const valueAt = (profile, s) => {
16
+ for (let k = 1; k < profile.length; k++) {
17
+ const a = profile[k - 1];
18
+ const b = profile[k];
19
+ if (s >= a.s && s <= b.s)
20
+ return b.s > a.s ? a.w + ((b.w - a.w) * (s - a.s)) / (b.s - a.s) : b.w;
21
+ }
22
+ return 0;
23
+ };
24
+ /**
25
+ * Width of a convex polygon, given in (s, d) coordinates, across the s axis: the extent in d
26
+ * at each vertex position s. Between vertices the width is linear, so this is exact.
27
+ */
28
+ const widthProfile = (polygon, tolerance) => {
29
+ const positions = [];
30
+ for (const s of polygon.map((p) => p[0]).sort((a, b) => a - b)) {
31
+ if (positions.length === 0 || s - positions[positions.length - 1] > tolerance)
32
+ positions.push(s);
33
+ }
34
+ return positions.map((s) => {
35
+ let min = Infinity;
36
+ let max = -Infinity;
37
+ polygon.forEach((p, i) => {
38
+ const q = polygon[(i + 1) % polygon.length];
39
+ const lo = Math.min(p[0], q[0]) - tolerance;
40
+ const hi = Math.max(p[0], q[0]) + tolerance;
41
+ if (s < lo || s > hi)
42
+ return;
43
+ const ds = q[0] - p[0];
44
+ const values = Math.abs(ds) <= tolerance ? [p[1], q[1]] : [p[1] + ((s - p[0]) / ds) * (q[1] - p[1])];
45
+ for (const d of values) {
46
+ min = Math.min(min, d);
47
+ max = Math.max(max, d);
48
+ }
49
+ });
50
+ return { s, w: max - min };
51
+ });
52
+ };
53
+ /** Unit inward normal of edge i of a counter-clockwise polygon (the area is on its left). */
54
+ const inwardNormal = (corners, i) => {
55
+ const e = (0, area_geometry_1.edgeVector)(corners, i);
56
+ const L = Math.hypot(...e);
57
+ return [-e[1] / L, e[0] / L];
58
+ };
59
+ /** A profile pinned to the edge ends: clamped to [0, L], with breakpoints at 0 and L. */
60
+ const pinToEdge = (profile, L) => {
61
+ const inside = profile.filter((p) => p.s > 0 && p.s < L);
62
+ return [{ s: 0, w: valueAt(profile, 0) }, ...inside, { s: L, w: valueAt(profile, L) }];
63
+ };
64
+ /**
65
+ * Two-way: every point of the area goes to the nearest edge line, so edge i takes the area
66
+ * clipped by `dᵢ(p) ≤ dⱼ(p)` for every other edge j (the corner-bisector, or straight-skeleton,
67
+ * split of a convex polygon), carried straight across onto the edge.
68
+ */
69
+ const twoWayProfile = (plane, i, tolerance) => {
70
+ const { corners } = plane;
71
+ const ni = inwardNormal(corners, i);
72
+ let region = corners;
73
+ corners.forEach((cj, j) => {
74
+ if (j === i)
75
+ return;
76
+ const nj = inwardNormal(corners, j);
77
+ // dᵢ(p) ≤ dⱼ(p) ⇔ (nᵢ − nⱼ)·p ≤ nᵢ·cᵢ − nⱼ·cⱼ
78
+ region = (0, area_geometry_1.clipPolygon)(region, [ni[0] - nj[0], ni[1] - nj[1]], dot2(ni, corners[i]) - dot2(nj, cj));
79
+ });
80
+ const e = (0, area_geometry_1.edgeVector)(corners, i);
81
+ const L = Math.hypot(...e);
82
+ const t = [e[0] / L, e[1] / L];
83
+ const local = region.map((p) => {
84
+ const r = [p[0] - corners[i][0], p[1] - corners[i][1]];
85
+ return [dot2(r, t), dot2(r, ni)];
86
+ });
87
+ return pinToEdge(widthProfile(local, tolerance), L);
88
+ };
89
+ /**
90
+ * One-way: strips parallel to `span` run across the area and half of each strip goes to each
91
+ * edge it ends on. A strip of width db meets edge i (at angle θ to the span) over ds = db/sin θ,
92
+ * so the edge takes `chord(b) / 2 · sin θ` per unit length; edges parallel to the span take none.
93
+ */
94
+ const oneWayProfile = (plane, i, span, tolerance) => {
95
+ const { corners } = plane;
96
+ const across = [-span[1], span[0]];
97
+ const chord = widthProfile(corners.map((p) => [dot2(p, across), dot2(p, span)]), tolerance);
98
+ const e = (0, area_geometry_1.edgeVector)(corners, i);
99
+ const L = Math.hypot(...e);
100
+ const sin = Math.abs(e[0] * span[1] - e[1] * span[0]) / L;
101
+ if (sin <= frame_constant_1.AREA_GEOMETRY_TOLERANCE)
102
+ return null;
103
+ const b0 = dot2(corners[i], across);
104
+ const b1 = b0 + dot2(e, across);
105
+ const at = (b) => (valueAt(chord, b) / 2) * sin;
106
+ const inside = chord
107
+ .filter((p) => (p.s - b0) * (p.s - b1) < 0)
108
+ .map((p) => ({ s: ((p.s - b0) / (b1 - b0)) * L, w: at(p.s) }));
109
+ const profile = [{ s: 0, w: at(b0) }, ...inside, { s: L, w: at(b1) }];
110
+ return profile.sort((a, b) => a.s - b.s);
111
+ };
112
+ /**
113
+ * Cuts an edge profile at the members along the edge and maps each piece onto its member, as
114
+ * positions from the member start. Pieces that carry nothing are dropped.
115
+ */
116
+ const segmentPieces = (profile, segment, memberLength, tolerance) => {
117
+ const { from, to, reversed } = segment;
118
+ const cuts = [
119
+ from,
120
+ ...profile.map((p) => p.s).filter((s) => s > from + tolerance && s < to - tolerance),
121
+ to,
122
+ ];
123
+ const x = (s) => {
124
+ const along = ((s - from) / (to - from)) * memberLength;
125
+ return Math.min(memberLength, Math.max(0, reversed ? memberLength - along : along));
126
+ };
127
+ const peak = Math.max(...profile.map((p) => Math.abs(p.w)));
128
+ const pieces = [];
129
+ for (let k = 1; k < cuts.length; k++) {
130
+ const wa = valueAt(profile, cuts[k - 1]);
131
+ const wb = valueAt(profile, cuts[k]);
132
+ if (Math.max(Math.abs(wa), Math.abs(wb)) <= frame_constant_1.AREA_GEOMETRY_TOLERANCE * peak)
133
+ continue;
134
+ const [xa, xb] = [x(cuts[k - 1]), x(cuts[k])];
135
+ pieces.push(xa < xb ? { start: xa, end: xb, w1: wa, w2: wb } : { start: xb, end: xa, w1: wb, w2: wa });
136
+ }
137
+ return pieces;
138
+ };
139
+ /**
140
+ * Turns the area loads of a model into member loads, assuming the model is valid (as
141
+ * `validateFrameModel` checks): each area's edge profiles are built once, then scaled for each
142
+ * of its loads and split into global X, Y and Z trapezoidal loads (plus torques for a cantilever).
143
+ * Everything is linear in `q`, so load-case superposition still holds.
144
+ */
145
+ const areaMemberLoads = (model) => {
146
+ const areas = model.areas ?? [];
147
+ const areaLoads = model.areaLoads ?? [];
148
+ const memberLoads = [];
149
+ const warnings = [];
150
+ if (areas.length === 0 || areaLoads.length === 0)
151
+ return { memberLoads, warnings };
152
+ const nodeById = new Map(model.nodes.map((n) => [n.id, n]));
153
+ const position = (id) => {
154
+ const node = nodeById.get(id);
155
+ return [node.x, node.y, node.z];
156
+ };
157
+ const lengthOf = (member) => {
158
+ const [a, b] = [position(member.startNodeId), position(member.endNodeId)];
159
+ return Math.hypot(b[0] - a[0], b[1] - a[1], b[2] - a[2]);
160
+ };
161
+ const loadedAreas = new Set(areaLoads.map((l) => l.areaId));
162
+ const adjacency = (0, edge_members_1.memberAdjacency)(model.members);
163
+ const prepared = new Map();
164
+ for (const area of areas) {
165
+ if (!loadedAreas.has(area.id))
166
+ continue;
167
+ const ids = area.nodeIds;
168
+ const plane = (0, area_geometry_1.areaPlane)(ids.map(position));
169
+ const supports = (0, area_geometry_1.resolveAreaSupports)(plane, area.distribution, area.supportEdges);
170
+ const tolerance = frame_constant_1.AREA_GEOMETRY_TOLERANCE * plane.size;
171
+ const n = ids.length;
172
+ const edges = [];
173
+ for (const i of supports.loadedEdges) {
174
+ const chain = (0, edge_members_1.edgeMemberChain)(ids[i], ids[(i + 1) % n], position, adjacency);
175
+ const L = Math.hypot(...(0, area_geometry_1.edgeVector)(plane.corners, i));
176
+ if (area.distribution === "cantilever") {
177
+ const depth = Math.hypot(...(0, area_geometry_1.edgeVector)(plane.corners, (i + 1) % n));
178
+ edges.push({
179
+ chain,
180
+ profile: [
181
+ { s: 0, w: depth },
182
+ { s: L, w: depth },
183
+ ],
184
+ torque: depth ** 2 / 2,
185
+ });
186
+ }
187
+ else if (area.distribution === "twoWay") {
188
+ edges.push({ chain, profile: twoWayProfile(plane, i, tolerance) });
189
+ }
190
+ else {
191
+ const profile = oneWayProfile(plane, i, supports.span, tolerance);
192
+ if (profile)
193
+ edges.push({ chain, profile });
194
+ else {
195
+ warnings.push({
196
+ reference: "Null area, one-way distribution",
197
+ message: `Area "${String(area.id)}": support edge ${i} runs parallel to the span and receives no load.`,
198
+ });
199
+ }
200
+ }
201
+ }
202
+ prepared.set(area.id, { plane, edges });
203
+ }
204
+ for (const load of areaLoads) {
205
+ const area = prepared.get(load.areaId);
206
+ if (!area || load.q === 0)
207
+ continue;
208
+ const { plane, edges } = area;
209
+ const e = load.direction === "3"
210
+ ? plane.normal
211
+ : GLOBAL_AXES.map(([axis]) => (axis === load.direction ? 1 : 0));
212
+ const components = GLOBAL_AXES.filter(([, k]) => Math.abs(e[k]) > frame_constant_1.AREA_GEOMETRY_TOLERANCE);
213
+ // Lever arm (inward, in plane) × load: only the normal part of the load twists the edge,
214
+ // about +edge direction; validation rejects a load along a cantilever's support edge.
215
+ const normalPart = e[0] * plane.normal[0] + e[1] * plane.normal[1] + e[2] * plane.normal[2];
216
+ const tolerance = frame_constant_1.AREA_GEOMETRY_TOLERANCE * plane.size;
217
+ for (const { chain, profile, torque } of edges) {
218
+ for (const segment of chain) {
219
+ const { member } = segment;
220
+ const L = lengthOf(member);
221
+ for (const piece of segmentPieces(profile, segment, L, tolerance)) {
222
+ for (const [axis, k] of components) {
223
+ memberLoads.push({
224
+ loadCase: load.loadCase,
225
+ type: "trapezoidal",
226
+ memberId: member.id,
227
+ direction: axis,
228
+ w1: load.q * e[k] * piece.w1 * 1e-3, // kN/m² · mm → kN/m
229
+ w2: load.q * e[k] * piece.w2 * 1e-3,
230
+ start: piece.start,
231
+ end: piece.end,
232
+ });
233
+ }
234
+ }
235
+ if (torque !== undefined && Math.abs(normalPart) > frame_constant_1.AREA_GEOMETRY_TOLERANCE) {
236
+ // member local 1 is ±edge direction
237
+ const sign = segment.reversed ? -1 : 1;
238
+ memberLoads.push({
239
+ loadCase: load.loadCase,
240
+ type: "torque",
241
+ memberId: member.id,
242
+ t: load.q * normalPart * torque * sign * 1e-6, // kN/m² · mm² → kN·m/m
243
+ });
244
+ }
245
+ }
246
+ }
247
+ }
248
+ return { memberLoads, warnings };
249
+ };
250
+ exports.areaMemberLoads = areaMemberLoads;
251
+ /**
252
+ * The member loads that a model's null areas send to the members along their edges — what
253
+ * `analyzeFrame` adds to `memberLoads` — so they can be checked or previewed.
254
+ *
255
+ * Two-way areas send each point to the nearest edge (corner-bisector split); one-way areas
256
+ * split strips parallel to their unsupported edges half to each end; cantilever areas send
257
+ * `q · c` and a torque `q · c² / 2` per unit length to their support edge (c = depth). Edges
258
+ * split by intermediate nodes are cut at those nodes. Loads are per unit true area and come
259
+ * out as trapezoidal loads in global X, Y and Z (and torques), each tagged with its load case.
260
+ *
261
+ * @param model - The frame model, validated first
262
+ * @returns `memberLoads` and `warnings` (a one-way support edge parallel to the span)
263
+ * @throws {FrameAnalysisError} 301–317 for an invalid model, with every problem in `issues`
264
+ */
265
+ const distributeAreaLoads = (model) => {
266
+ const issues = (0, validate_model_1.validateFrameModel)(model);
267
+ if (issues.length > 0)
268
+ (0, validate_model_1.throwIssues)(issues);
269
+ return (0, exports.areaMemberLoads)(model);
270
+ };
271
+ exports.distributeAreaLoads = distributeAreaLoads;
272
+ //# sourceMappingURL=distribute-area-loads.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"distribute-area-loads.js","sourceRoot":"","sources":["../../../../src/fea/frame/area/distribute-area-loads.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import type { FrameId, Member } from "../types/model.type";
2
+ import type { Vec3 } from "./area-geometry";
3
+ /** The members meeting at each node, with the node at their other end. */
4
+ export type MemberAdjacency = Map<FrameId, {
5
+ member: Member;
6
+ other: FrameId;
7
+ }[]>;
8
+ /** One member covering part of an area edge, with positions along the edge from its start. */
9
+ export interface EdgeSegment {
10
+ member: Member;
11
+ from: number;
12
+ to: number;
13
+ reversed: boolean;
14
+ }
15
+ /** Indexes members by the nodes they connect. */
16
+ export declare const memberAdjacency: (members: Member[]) => MemberAdjacency;
17
+ /**
18
+ * The chain of collinear members covering an area edge from `start` to `end`, found by walking
19
+ * the members at each node towards `end`: each step takes the member whose far node lies on the
20
+ * edge nearest ahead, so intermediate nodes (beams framing in) split the edge into segments.
21
+ *
22
+ * @param position - Node coordinates in mm
23
+ * @returns The segments in order along the edge, or `null` if a gap leaves part of it uncovered
24
+ */
25
+ export declare const edgeMemberChain: (start: FrameId, end: FrameId, position: (id: FrameId) => Vec3, adjacency: MemberAdjacency) => EdgeSegment[] | null;
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.edgeMemberChain = exports.memberAdjacency = void 0;
4
+ const frame_constant_1 = require("../../../core/constants/frame.constant");
5
+ /** Indexes members by the nodes they connect. */
6
+ const memberAdjacency = (members) => {
7
+ const adjacency = new Map();
8
+ const link = (node, entry) => {
9
+ const list = adjacency.get(node);
10
+ if (list)
11
+ list.push(entry);
12
+ else
13
+ adjacency.set(node, [entry]);
14
+ };
15
+ for (const member of members) {
16
+ link(member.startNodeId, { member, other: member.endNodeId });
17
+ link(member.endNodeId, { member, other: member.startNodeId });
18
+ }
19
+ return adjacency;
20
+ };
21
+ exports.memberAdjacency = memberAdjacency;
22
+ /**
23
+ * The chain of collinear members covering an area edge from `start` to `end`, found by walking
24
+ * the members at each node towards `end`: each step takes the member whose far node lies on the
25
+ * edge nearest ahead, so intermediate nodes (beams framing in) split the edge into segments.
26
+ *
27
+ * @param position - Node coordinates in mm
28
+ * @returns The segments in order along the edge, or `null` if a gap leaves part of it uncovered
29
+ */
30
+ const edgeMemberChain = (start, end, position, adjacency) => {
31
+ const A = position(start);
32
+ const B = position(end);
33
+ const d = [B[0] - A[0], B[1] - A[1], B[2] - A[2]];
34
+ const L = Math.hypot(...d);
35
+ const t = [d[0] / L, d[1] / L, d[2] / L];
36
+ const tolerance = frame_constant_1.AREA_GEOMETRY_TOLERANCE * L;
37
+ const segments = [];
38
+ let current = start;
39
+ let s = 0;
40
+ while (current !== end) {
41
+ let next;
42
+ for (const { member, other } of adjacency.get(current) ?? []) {
43
+ const P = position(other);
44
+ const r = [P[0] - A[0], P[1] - A[1], P[2] - A[2]];
45
+ const along = r[0] * t[0] + r[1] * t[1] + r[2] * t[2];
46
+ const off = Math.hypot(r[0] - along * t[0], r[1] - along * t[1], r[2] - along * t[2]);
47
+ if (off > tolerance || along <= s + tolerance || along > L + tolerance)
48
+ continue;
49
+ if (!next || along < next.s)
50
+ next = { member, other, s: along };
51
+ }
52
+ if (!next)
53
+ return null;
54
+ const to = next.other === end ? L : next.s;
55
+ segments.push({
56
+ member: next.member,
57
+ from: s,
58
+ to,
59
+ reversed: next.member.startNodeId !== current,
60
+ });
61
+ current = next.other;
62
+ s = to;
63
+ }
64
+ return segments;
65
+ };
66
+ exports.edgeMemberChain = edgeMemberChain;
67
+ //# sourceMappingURL=edge-members.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"edge-members.js","sourceRoot":"","sources":["../../../../src/fea/frame/area/edge-members.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,13 @@
1
- /** A member load resolved into local axes, in N and mm. */
1
+ /**
2
+ * A member load resolved into local axes, in N and mm. A distributed load varies linearly
3
+ * from `w1` at `start` to `w2` at `end` (uniform when they are equal); a torque is uniform
4
+ * about local 1.
5
+ */
2
6
  export type LocalMemberLoad = {
3
- type: "udl";
7
+ type: "distributed";
4
8
  axis: 1 | 2 | 3;
5
- w: number;
9
+ w1: number;
10
+ w2: number;
6
11
  start: number;
7
12
  end: number;
8
13
  } | {
@@ -10,7 +15,16 @@ export type LocalMemberLoad = {
10
15
  axis: 1 | 2 | 3;
11
16
  P: number;
12
17
  a: number;
18
+ } | {
19
+ type: "torque";
20
+ t: number;
21
+ start: number;
22
+ end: number;
13
23
  };
24
+ /** Intensity of a distributed load at `x` (inside its extent), in N/mm. */
25
+ export declare const loadIntensity: (load: Extract<LocalMemberLoad, {
26
+ type: "distributed";
27
+ }>, x: number) => number;
14
28
  /**
15
29
  * Fixed-end forces of a member under local loads: the end forces (right-hand local axes,
16
30
  * N and N·mm) that hold both ends fully fixed. Equivalent nodal loads are the negative.