@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.
- package/README.md +57 -6
- package/dist/core/constants/frame.constant.d.ts +19 -0
- package/dist/core/constants/frame.constant.js +23 -0
- package/dist/core/constants/frame.constant.js.map +1 -0
- package/dist/core/errors/frame-analysis.error.d.ts +36 -0
- package/dist/core/errors/frame-analysis.error.js +86 -0
- package/dist/core/errors/frame-analysis.error.js.map +1 -0
- package/dist/core/index.d.ts +4 -0
- package/dist/core/index.js +13 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/types/section-properties.type.d.ts +13 -0
- package/dist/core/types/section-properties.type.js +3 -0
- package/dist/core/types/section-properties.type.js.map +1 -0
- package/dist/esm/core/constants/frame.constant.js +20 -0
- package/dist/esm/core/constants/frame.constant.js.map +1 -0
- package/dist/esm/core/constants/rc.constant.js +63 -0
- package/dist/esm/core/constants/rc.constant.js.map +1 -0
- package/dist/esm/core/errors/frame-analysis.error.js +82 -0
- package/dist/esm/core/errors/frame-analysis.error.js.map +1 -0
- package/dist/esm/core/errors/rc-design.error.js +64 -0
- package/dist/esm/core/errors/rc-design.error.js.map +1 -0
- package/dist/esm/core/index.js +9 -0
- package/dist/esm/core/index.js.map +1 -0
- package/dist/esm/core/types/output-message.type.js +2 -0
- package/dist/esm/core/types/output-message.type.js.map +1 -0
- package/dist/esm/core/types/plate-jacketing.type.js +18 -0
- package/dist/esm/core/types/plate-jacketing.type.js.map +1 -0
- package/dist/esm/core/types/rc-beam.type.js +11 -0
- package/dist/esm/core/types/rc-beam.type.js.map +1 -0
- package/dist/esm/core/types/section-properties.type.js +2 -0
- package/dist/esm/core/types/section-properties.type.js.map +1 -0
- package/dist/esm/core/types/unit.type.js +2 -0
- package/dist/esm/core/types/unit.type.js.map +1 -0
- package/dist/esm/fea/frame/area/area-geometry.js +132 -0
- package/dist/esm/fea/frame/area/area-geometry.js.map +1 -0
- package/dist/esm/fea/frame/area/distribute-area-loads.js +267 -0
- package/dist/esm/fea/frame/area/distribute-area-loads.js.map +1 -0
- package/dist/esm/fea/frame/area/edge-members.js +62 -0
- package/dist/esm/fea/frame/area/edge-members.js.map +1 -0
- package/dist/esm/fea/frame/elements/beam-3d-stiffness.js +84 -0
- package/dist/esm/fea/frame/elements/beam-3d-stiffness.js.map +1 -0
- package/dist/esm/fea/frame/elements/fixed-end-forces.js +88 -0
- package/dist/esm/fea/frame/elements/fixed-end-forces.js.map +1 -0
- package/dist/esm/fea/frame/elements/static-condensation.js +55 -0
- package/dist/esm/fea/frame/elements/static-condensation.js.map +1 -0
- package/dist/esm/fea/frame/index.js +7 -0
- package/dist/esm/fea/frame/index.js.map +1 -0
- package/dist/esm/fea/frame/post/demand-envelope.js +97 -0
- package/dist/esm/fea/frame/post/demand-envelope.js.map +1 -0
- package/dist/esm/fea/frame/post/envelope.js +59 -0
- package/dist/esm/fea/frame/post/envelope.js.map +1 -0
- package/dist/esm/fea/frame/post/member-diagram.js +375 -0
- package/dist/esm/fea/frame/post/member-diagram.js.map +1 -0
- package/dist/esm/fea/frame/post/present-state.js +106 -0
- package/dist/esm/fea/frame/post/present-state.js.map +1 -0
- package/dist/esm/fea/frame/solver/analyze-frame.js +131 -0
- package/dist/esm/fea/frame/solver/analyze-frame.js.map +1 -0
- package/dist/esm/fea/frame/solver/boundary-conditions.js +33 -0
- package/dist/esm/fea/frame/solver/boundary-conditions.js.map +1 -0
- package/dist/esm/fea/frame/solver/combinations.js +69 -0
- package/dist/esm/fea/frame/solver/combinations.js.map +1 -0
- package/dist/esm/fea/frame/solver/frame-system.js +122 -0
- package/dist/esm/fea/frame/solver/frame-system.js.map +1 -0
- package/dist/esm/fea/frame/solver/global-assembly.js +27 -0
- package/dist/esm/fea/frame/solver/global-assembly.js.map +1 -0
- package/dist/esm/fea/frame/solver/load-case-solver.js +133 -0
- package/dist/esm/fea/frame/solver/load-case-solver.js.map +1 -0
- package/dist/esm/fea/frame/transformation/coordinate-transform.js +71 -0
- package/dist/esm/fea/frame/transformation/coordinate-transform.js.map +1 -0
- package/dist/esm/fea/frame/types/model.type.js +2 -0
- package/dist/esm/fea/frame/types/model.type.js.map +1 -0
- package/dist/esm/fea/frame/types/results.type.js +2 -0
- package/dist/esm/fea/frame/types/results.type.js.map +1 -0
- package/dist/esm/fea/frame/validation/validate-model.js +389 -0
- package/dist/esm/fea/frame/validation/validate-model.js.map +1 -0
- package/dist/esm/fea/index.js +3 -0
- package/dist/esm/fea/index.js.map +1 -0
- package/dist/esm/index.js +10 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/package.json +1 -0
- package/dist/esm/rc/general.js +32 -0
- package/dist/esm/rc/general.js.map +1 -0
- package/dist/esm/rc/index.js +5 -0
- package/dist/esm/rc/index.js.map +1 -0
- package/dist/esm/rc/rc-bar-layout.js +89 -0
- package/dist/esm/rc/rc-bar-layout.js.map +1 -0
- package/dist/esm/rc/rc-beam-design.js +320 -0
- package/dist/esm/rc/rc-beam-design.js.map +1 -0
- package/dist/esm/rc/rc-section-properties.js +55 -0
- package/dist/esm/rc/rc-section-properties.js.map +1 -0
- package/dist/esm/strengthening/index.js +4 -0
- package/dist/esm/strengthening/index.js.map +1 -0
- package/dist/esm/strengthening/rc-beam-plate-interface-bolts.js +338 -0
- package/dist/esm/strengthening/rc-beam-plate-interface-bolts.js.map +1 -0
- package/dist/esm/strengthening/rc-beam-side-plate-shear.js +381 -0
- package/dist/esm/strengthening/rc-beam-side-plate-shear.js.map +1 -0
- package/dist/esm/strengthening/rc-beam-steel-plate-jacketing.js +90 -0
- package/dist/esm/strengthening/rc-beam-steel-plate-jacketing.js.map +1 -0
- package/dist/esm/utils/index.js +5 -0
- package/dist/esm/utils/index.js.map +1 -0
- package/dist/esm/utils/math.js +30 -0
- package/dist/esm/utils/math.js.map +1 -0
- package/dist/esm/utils/matrix.js +145 -0
- package/dist/esm/utils/matrix.js.map +1 -0
- package/dist/esm/utils/merge-warning.js +11 -0
- package/dist/esm/utils/merge-warning.js.map +1 -0
- package/dist/esm/utils/skyline.js +151 -0
- package/dist/esm/utils/skyline.js.map +1 -0
- package/dist/fea/frame/area/area-geometry.d.ts +56 -0
- package/dist/fea/frame/area/area-geometry.js +142 -0
- package/dist/fea/frame/area/area-geometry.js.map +1 -0
- package/dist/fea/frame/area/distribute-area-loads.d.ts +30 -0
- package/dist/fea/frame/area/distribute-area-loads.js +272 -0
- package/dist/fea/frame/area/distribute-area-loads.js.map +1 -0
- package/dist/fea/frame/area/edge-members.d.ts +25 -0
- package/dist/fea/frame/area/edge-members.js +67 -0
- package/dist/fea/frame/area/edge-members.js.map +1 -0
- package/dist/fea/frame/elements/beam-3d-stiffness.d.ts +29 -0
- package/dist/fea/frame/elements/beam-3d-stiffness.js +90 -0
- package/dist/fea/frame/elements/beam-3d-stiffness.js.map +1 -0
- package/dist/fea/frame/elements/fixed-end-forces.d.ts +36 -0
- package/dist/fea/frame/elements/fixed-end-forces.js +93 -0
- package/dist/fea/frame/elements/fixed-end-forces.js.map +1 -0
- package/dist/fea/frame/elements/static-condensation.d.ts +19 -0
- package/dist/fea/frame/elements/static-condensation.js +59 -0
- package/dist/fea/frame/elements/static-condensation.js.map +1 -0
- package/dist/fea/frame/index.d.ts +10 -0
- package/dist/fea/frame/index.js +18 -0
- package/dist/fea/frame/index.js.map +1 -0
- package/dist/fea/frame/post/demand-envelope.d.ts +36 -0
- package/dist/fea/frame/post/demand-envelope.js +101 -0
- package/dist/fea/frame/post/demand-envelope.js.map +1 -0
- package/dist/fea/frame/post/envelope.d.ts +8 -0
- package/dist/fea/frame/post/envelope.js +63 -0
- package/dist/fea/frame/post/envelope.js.map +1 -0
- package/dist/fea/frame/post/member-diagram.d.ts +26 -0
- package/dist/fea/frame/post/member-diagram.js +379 -0
- package/dist/fea/frame/post/member-diagram.js.map +1 -0
- package/dist/fea/frame/post/present-state.d.ts +19 -0
- package/dist/fea/frame/post/present-state.js +111 -0
- package/dist/fea/frame/post/present-state.js.map +1 -0
- package/dist/fea/frame/solver/analyze-frame.d.ts +70 -0
- package/dist/fea/frame/solver/analyze-frame.js +136 -0
- package/dist/fea/frame/solver/analyze-frame.js.map +1 -0
- package/dist/fea/frame/solver/boundary-conditions.d.ts +14 -0
- package/dist/fea/frame/solver/boundary-conditions.js +37 -0
- package/dist/fea/frame/solver/boundary-conditions.js.map +1 -0
- package/dist/fea/frame/solver/combinations.d.ts +11 -0
- package/dist/fea/frame/solver/combinations.js +73 -0
- package/dist/fea/frame/solver/combinations.js.map +1 -0
- package/dist/fea/frame/solver/frame-system.d.ts +42 -0
- package/dist/fea/frame/solver/frame-system.js +126 -0
- package/dist/fea/frame/solver/frame-system.js.map +1 -0
- package/dist/fea/frame/solver/global-assembly.d.ts +17 -0
- package/dist/fea/frame/solver/global-assembly.js +33 -0
- package/dist/fea/frame/solver/global-assembly.js.map +1 -0
- package/dist/fea/frame/solver/load-case-solver.d.ts +34 -0
- package/dist/fea/frame/solver/load-case-solver.js +138 -0
- package/dist/fea/frame/solver/load-case-solver.js.map +1 -0
- package/dist/fea/frame/transformation/coordinate-transform.d.ts +21 -0
- package/dist/fea/frame/transformation/coordinate-transform.js +76 -0
- package/dist/fea/frame/transformation/coordinate-transform.js.map +1 -0
- package/dist/fea/frame/types/model.type.d.ts +170 -0
- package/dist/fea/frame/types/model.type.js +3 -0
- package/dist/fea/frame/types/model.type.js.map +1 -0
- package/dist/fea/frame/types/results.type.d.ts +134 -0
- package/dist/fea/frame/types/results.type.js +3 -0
- package/dist/fea/frame/types/results.type.js.map +1 -0
- package/dist/fea/frame/validation/validate-model.d.ts +18 -0
- package/dist/fea/frame/validation/validate-model.js +395 -0
- package/dist/fea/frame/validation/validate-model.js.map +1 -0
- package/dist/fea/index.d.ts +1 -0
- package/dist/fea/index.js +19 -0
- package/dist/fea/index.js.map +1 -0
- package/dist/index.d.ts +8 -4
- package/dist/index.js +37 -1
- package/dist/index.js.map +1 -1
- package/dist/rc/index.d.ts +2 -0
- package/dist/rc/index.js +3 -1
- package/dist/rc/index.js.map +1 -1
- package/dist/rc/rc-section-properties.d.ts +35 -0
- package/dist/rc/rc-section-properties.js +59 -0
- package/dist/rc/rc-section-properties.js.map +1 -0
- package/dist/utils/index.d.ts +4 -0
- package/dist/utils/index.js +19 -1
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/matrix.d.ts +45 -0
- package/dist/utils/matrix.js +157 -0
- package/dist/utils/matrix.js.map +1 -0
- package/dist/utils/skyline.d.ts +49 -0
- package/dist/utils/skyline.js +161 -0
- package/dist/utils/skyline.js.map +1 -0
- package/package.json +28 -4
|
@@ -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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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { type Matrix } from "../../../utils/matrix";
|
|
2
|
+
/**
|
|
3
|
+
* Local stiffness matrix of a 3D prismatic beam element, exactly as in the reference
|
|
4
|
+
* "Complete Beam Stiffness Matrix".
|
|
5
|
+
*
|
|
6
|
+
* DOF order for node i then node j: [U1, U2, U3, R1, R2, R3]. Local 1 runs along the member.
|
|
7
|
+
* The reference matrix measures the bending rotations R2 and R3 opposite to the right-hand
|
|
8
|
+
* rule; use `beam3dLocalStiffnessRightHanded` for the right-handed form.
|
|
9
|
+
*
|
|
10
|
+
* The reference uses one `EI`; here the U2–R3 terms use `E·I33` and the U3–R2 terms use
|
|
11
|
+
* `E·I22`, which reduces to the reference when `I22 = I33`.
|
|
12
|
+
*
|
|
13
|
+
* @param E - Young's modulus in MPa
|
|
14
|
+
* @param G - Shear modulus in MPa
|
|
15
|
+
* @param A - Area in mm²
|
|
16
|
+
* @param I22 - Second moment about local 2 in mm⁴
|
|
17
|
+
* @param I33 - Second moment about local 3 in mm⁴
|
|
18
|
+
* @param J - Torsion constant in mm⁴
|
|
19
|
+
* @param L - Member length in mm
|
|
20
|
+
* @returns 12×12 symmetric matrix in N and mm
|
|
21
|
+
*/
|
|
22
|
+
export declare const beam3dLocalStiffness: (E: number, G: number, A: number, I22: number, I33: number, J: number, L: number) => Matrix;
|
|
23
|
+
/**
|
|
24
|
+
* Converts a local matrix between the reference rotation convention and the right-hand rule
|
|
25
|
+
* (`D·k·D`, with `D` flipping the sign of R2 and R3 at both ends). The conversion is its own inverse.
|
|
26
|
+
*/
|
|
27
|
+
export declare const flipBendingRotationSigns: (k: Matrix) => Matrix;
|
|
28
|
+
/** Same element as `beam3dLocalStiffness` with all rotations following the right-hand rule. */
|
|
29
|
+
export declare const beam3dLocalStiffnessRightHanded: (E: number, G: number, A: number, I22: number, I33: number, J: number, L: number) => Matrix;
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.beam3dLocalStiffnessRightHanded = exports.flipBendingRotationSigns = exports.beam3dLocalStiffness = void 0;
|
|
4
|
+
const matrix_1 = require("../../../utils/matrix");
|
|
5
|
+
/**
|
|
6
|
+
* Local DOF indices (0-based) whose reference-matrix rotation sign is opposite to the
|
|
7
|
+
* right-hand rule: R2 and R3 at the start and end nodes.
|
|
8
|
+
*/
|
|
9
|
+
const FLIPPED_DOFS = [4, 5, 10, 11];
|
|
10
|
+
/**
|
|
11
|
+
* Local stiffness matrix of a 3D prismatic beam element, exactly as in the reference
|
|
12
|
+
* "Complete Beam Stiffness Matrix".
|
|
13
|
+
*
|
|
14
|
+
* DOF order for node i then node j: [U1, U2, U3, R1, R2, R3]. Local 1 runs along the member.
|
|
15
|
+
* The reference matrix measures the bending rotations R2 and R3 opposite to the right-hand
|
|
16
|
+
* rule; use `beam3dLocalStiffnessRightHanded` for the right-handed form.
|
|
17
|
+
*
|
|
18
|
+
* The reference uses one `EI`; here the U2–R3 terms use `E·I33` and the U3–R2 terms use
|
|
19
|
+
* `E·I22`, which reduces to the reference when `I22 = I33`.
|
|
20
|
+
*
|
|
21
|
+
* @param E - Young's modulus in MPa
|
|
22
|
+
* @param G - Shear modulus in MPa
|
|
23
|
+
* @param A - Area in mm²
|
|
24
|
+
* @param I22 - Second moment about local 2 in mm⁴
|
|
25
|
+
* @param I33 - Second moment about local 3 in mm⁴
|
|
26
|
+
* @param J - Torsion constant in mm⁴
|
|
27
|
+
* @param L - Member length in mm
|
|
28
|
+
* @returns 12×12 symmetric matrix in N and mm
|
|
29
|
+
*/
|
|
30
|
+
const beam3dLocalStiffness = (E, G, A, I22, I33, J, L) => {
|
|
31
|
+
const k = (0, matrix_1.zeros)(12, 12);
|
|
32
|
+
// 1-based row/column, upper triangle as written in the reference; mirrored for symmetry.
|
|
33
|
+
const set = (row, col, value) => {
|
|
34
|
+
k[row - 1][col - 1] = value;
|
|
35
|
+
k[col - 1][row - 1] = value;
|
|
36
|
+
};
|
|
37
|
+
const ax = (E * A) / L;
|
|
38
|
+
const tor = (G * J) / L;
|
|
39
|
+
// U2–R3 bending (I33)
|
|
40
|
+
const a3 = (12 * E * I33) / L ** 3;
|
|
41
|
+
const b3 = (6 * E * I33) / L ** 2;
|
|
42
|
+
const c3 = (4 * E * I33) / L;
|
|
43
|
+
const d3 = (2 * E * I33) / L;
|
|
44
|
+
// U3–R2 bending (I22)
|
|
45
|
+
const a2 = (12 * E * I22) / L ** 3;
|
|
46
|
+
const b2 = (6 * E * I22) / L ** 2;
|
|
47
|
+
const c2 = (4 * E * I22) / L;
|
|
48
|
+
const d2 = (2 * E * I22) / L;
|
|
49
|
+
set(1, 1, ax);
|
|
50
|
+
set(1, 7, -ax);
|
|
51
|
+
set(7, 7, ax);
|
|
52
|
+
set(2, 2, a3);
|
|
53
|
+
set(2, 6, -b3);
|
|
54
|
+
set(2, 8, -a3);
|
|
55
|
+
set(2, 12, -b3);
|
|
56
|
+
set(6, 6, c3);
|
|
57
|
+
set(6, 8, b3);
|
|
58
|
+
set(6, 12, d3);
|
|
59
|
+
set(8, 8, a3);
|
|
60
|
+
set(8, 12, b3);
|
|
61
|
+
set(12, 12, c3);
|
|
62
|
+
set(3, 3, a2);
|
|
63
|
+
set(3, 5, b2);
|
|
64
|
+
set(3, 9, -a2);
|
|
65
|
+
set(3, 11, b2);
|
|
66
|
+
set(5, 5, c2);
|
|
67
|
+
set(5, 9, -b2);
|
|
68
|
+
set(5, 11, d2);
|
|
69
|
+
set(9, 9, a2);
|
|
70
|
+
set(9, 11, -b2);
|
|
71
|
+
set(11, 11, c2);
|
|
72
|
+
set(4, 4, tor);
|
|
73
|
+
set(4, 10, -tor);
|
|
74
|
+
set(10, 10, tor);
|
|
75
|
+
return k;
|
|
76
|
+
};
|
|
77
|
+
exports.beam3dLocalStiffness = beam3dLocalStiffness;
|
|
78
|
+
/**
|
|
79
|
+
* Converts a local matrix between the reference rotation convention and the right-hand rule
|
|
80
|
+
* (`D·k·D`, with `D` flipping the sign of R2 and R3 at both ends). The conversion is its own inverse.
|
|
81
|
+
*/
|
|
82
|
+
const flipBendingRotationSigns = (k) => {
|
|
83
|
+
const flipped = new Set(FLIPPED_DOFS);
|
|
84
|
+
return k.map((row, i) => row.map((value, j) => (flipped.has(i) !== flipped.has(j) ? -value : value)));
|
|
85
|
+
};
|
|
86
|
+
exports.flipBendingRotationSigns = flipBendingRotationSigns;
|
|
87
|
+
/** Same element as `beam3dLocalStiffness` with all rotations following the right-hand rule. */
|
|
88
|
+
const beam3dLocalStiffnessRightHanded = (E, G, A, I22, I33, J, L) => (0, exports.flipBendingRotationSigns)((0, exports.beam3dLocalStiffness)(E, G, A, I22, I33, J, L));
|
|
89
|
+
exports.beam3dLocalStiffnessRightHanded = beam3dLocalStiffnessRightHanded;
|
|
90
|
+
//# sourceMappingURL=beam-3d-stiffness.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"beam-3d-stiffness.js","sourceRoot":"","sources":["../../../../src/fea/frame/elements/beam-3d-stiffness.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
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
|
+
*/
|
|
6
|
+
export type LocalMemberLoad = {
|
|
7
|
+
type: "distributed";
|
|
8
|
+
axis: 1 | 2 | 3;
|
|
9
|
+
w1: number;
|
|
10
|
+
w2: number;
|
|
11
|
+
start: number;
|
|
12
|
+
end: number;
|
|
13
|
+
} | {
|
|
14
|
+
type: "point";
|
|
15
|
+
axis: 1 | 2 | 3;
|
|
16
|
+
P: number;
|
|
17
|
+
a: number;
|
|
18
|
+
} | {
|
|
19
|
+
type: "torque";
|
|
20
|
+
t: number;
|
|
21
|
+
start: number;
|
|
22
|
+
end: number;
|
|
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;
|
|
28
|
+
/**
|
|
29
|
+
* Fixed-end forces of a member under local loads: the end forces (right-hand local axes,
|
|
30
|
+
* N and N·mm) that hold both ends fully fixed. Equivalent nodal loads are the negative.
|
|
31
|
+
*
|
|
32
|
+
* @param loads - Loads in local axes, N and mm
|
|
33
|
+
* @param L - Member length in mm
|
|
34
|
+
* @throws {FrameAnalysisError} 308 if a load lies outside the member
|
|
35
|
+
*/
|
|
36
|
+
export declare const fixedEndForces: (loads: LocalMemberLoad[], L: number) => number[];
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.fixedEndForces = exports.loadIntensity = void 0;
|
|
4
|
+
const frame_analysis_error_1 = require("../../../core/errors/frame-analysis.error");
|
|
5
|
+
/** Intensity of a distributed load at `x` (inside its extent), in N/mm. */
|
|
6
|
+
const loadIntensity = (load, x) => load.w1 + ((load.w2 - load.w1) * (x - load.start)) / (load.end - load.start);
|
|
7
|
+
exports.loadIntensity = loadIntensity;
|
|
8
|
+
// 4-point Gauss–Legendre rule, exact up to degree 7: cubic shape functions × linear loads
|
|
9
|
+
const GAUSS_POINTS = [
|
|
10
|
+
-0.8611363115940526, -0.3399810435848563, 0.3399810435848563, 0.8611363115940526,
|
|
11
|
+
];
|
|
12
|
+
const GAUSS_WEIGHTS = [
|
|
13
|
+
0.3478548451374538, 0.6521451548625461, 0.6521451548625461, 0.3478548451374538,
|
|
14
|
+
];
|
|
15
|
+
/**
|
|
16
|
+
* Equivalent nodal loads of a unit transverse/axial load at distance `x`, from the
|
|
17
|
+
* Euler–Bernoulli shape functions: the exact fixed-end solution for a prismatic member.
|
|
18
|
+
* Returned per unit of load, right-hand local DOF order [i: U1..R3, j: U1..R3].
|
|
19
|
+
*/
|
|
20
|
+
const unitEquivalentLoad = (axis, x, L) => {
|
|
21
|
+
const xi = x / L;
|
|
22
|
+
const out = new Array(12).fill(0);
|
|
23
|
+
if (axis === 1) {
|
|
24
|
+
out[0] = 1 - xi;
|
|
25
|
+
out[6] = xi;
|
|
26
|
+
return out;
|
|
27
|
+
}
|
|
28
|
+
const n1 = 1 - 3 * xi ** 2 + 2 * xi ** 3;
|
|
29
|
+
const n2 = L * (xi - 2 * xi ** 2 + xi ** 3);
|
|
30
|
+
const n3 = 3 * xi ** 2 - 2 * xi ** 3;
|
|
31
|
+
const n4 = L * (-(xi ** 2) + xi ** 3);
|
|
32
|
+
if (axis === 2) {
|
|
33
|
+
// load along local 2: force U2, moment about 3 (R3 = +dv/dx)
|
|
34
|
+
out[1] = n1;
|
|
35
|
+
out[5] = n2;
|
|
36
|
+
out[7] = n3;
|
|
37
|
+
out[11] = n4;
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
// load along local 3: force U3, moment about 2 (R2 = −dw/dx)
|
|
41
|
+
out[2] = n1;
|
|
42
|
+
out[4] = -n2;
|
|
43
|
+
out[8] = n3;
|
|
44
|
+
out[10] = -n4;
|
|
45
|
+
}
|
|
46
|
+
return out;
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* Fixed-end forces of a member under local loads: the end forces (right-hand local axes,
|
|
50
|
+
* N and N·mm) that hold both ends fully fixed. Equivalent nodal loads are the negative.
|
|
51
|
+
*
|
|
52
|
+
* @param loads - Loads in local axes, N and mm
|
|
53
|
+
* @param L - Member length in mm
|
|
54
|
+
* @throws {FrameAnalysisError} 308 if a load lies outside the member
|
|
55
|
+
*/
|
|
56
|
+
const fixedEndForces = (loads, L) => {
|
|
57
|
+
const equivalent = new Array(12).fill(0);
|
|
58
|
+
const add = (unit, factor) => {
|
|
59
|
+
for (let i = 0; i < 12; i++)
|
|
60
|
+
equivalent[i] += unit[i] * factor;
|
|
61
|
+
};
|
|
62
|
+
for (const load of loads) {
|
|
63
|
+
if (load.type === "torque") {
|
|
64
|
+
if (!(load.start >= 0 && load.end <= L && load.start < load.end)) {
|
|
65
|
+
throw new frame_analysis_error_1.FrameAnalysisError(frame_analysis_error_1.FrameErrors.LOAD_OUTSIDE_MEMBER);
|
|
66
|
+
}
|
|
67
|
+
// linear torsion shape functions 1 − ξ and ξ, integrated over [start, end]
|
|
68
|
+
const resultant = load.t * (load.end - load.start);
|
|
69
|
+
const centroid = (load.start + load.end) / 2;
|
|
70
|
+
equivalent[3] += resultant * (1 - centroid / L);
|
|
71
|
+
equivalent[9] += (resultant * centroid) / L;
|
|
72
|
+
}
|
|
73
|
+
else if (load.type === "point") {
|
|
74
|
+
if (!(load.a >= 0 && load.a <= L))
|
|
75
|
+
throw new frame_analysis_error_1.FrameAnalysisError(frame_analysis_error_1.FrameErrors.LOAD_OUTSIDE_MEMBER);
|
|
76
|
+
add(unitEquivalentLoad(load.axis, load.a, L), load.P);
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
if (!(load.start >= 0 && load.end <= L && load.start < load.end)) {
|
|
80
|
+
throw new frame_analysis_error_1.FrameAnalysisError(frame_analysis_error_1.FrameErrors.LOAD_OUTSIDE_MEMBER);
|
|
81
|
+
}
|
|
82
|
+
const half = (load.end - load.start) / 2;
|
|
83
|
+
const mid = (load.end + load.start) / 2;
|
|
84
|
+
GAUSS_POINTS.forEach((p, index) => {
|
|
85
|
+
const x = mid + half * p;
|
|
86
|
+
add(unitEquivalentLoad(load.axis, x, L), (0, exports.loadIntensity)(load, x) * half * GAUSS_WEIGHTS[index]);
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return equivalent.map((v) => -v);
|
|
91
|
+
};
|
|
92
|
+
exports.fixedEndForces = fixedEndForces;
|
|
93
|
+
//# sourceMappingURL=fixed-end-forces.js.map
|