@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.
- package/README.md +34 -3
- package/dist/core/constants/frame.constant.d.ts +14 -0
- package/dist/core/constants/frame.constant.js +18 -0
- package/dist/core/constants/frame.constant.js.map +1 -0
- package/dist/core/errors/frame-analysis.error.d.ts +33 -0
- package/dist/core/errors/frame-analysis.error.js +74 -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 +12 -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 +15 -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 +70 -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/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 +75 -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 +6 -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 +332 -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 +123 -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 +119 -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 +292 -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/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 +22 -0
- package/dist/fea/frame/elements/fixed-end-forces.js +79 -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 +9 -0
- package/dist/fea/frame/index.js +16 -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 +336 -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 +67 -0
- package/dist/fea/frame/solver/analyze-frame.js +128 -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 +124 -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 +112 -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 +298 -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 +20 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"static-condensation.js","sourceRoot":"","sources":["../../../../src/fea/frame/elements/static-condensation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { analyzeFrame, createFrameAnalysis } from "./solver/analyze-frame";
|
|
2
|
+
export type { AnalyzeFrameOptions, FrameAnalysis } from "./solver/analyze-frame";
|
|
3
|
+
export { validateFrameModel } from "./validation/validate-model";
|
|
4
|
+
export { beam3dLocalStiffness, beam3dLocalStiffnessRightHanded, } from "./elements/beam-3d-stiffness";
|
|
5
|
+
export { memberAxes } from "./transformation/coordinate-transform";
|
|
6
|
+
export { memberDemandEnvelope } from "./post/demand-envelope";
|
|
7
|
+
export type { MemberDemandEnvelope, DemandEnvelopeOptions } from "./post/demand-envelope";
|
|
8
|
+
export type { FrameId, FrameNode, DofRestraint, Restraint, MemberEndRelease, Member, NodalLoad, LoadDirection, UniformMemberLoad, PointMemberLoad, MemberLoad, LoadCaseType, LoadCase, CombinationTerm, LoadCombination, FrameModel, } from "./types/model.type";
|
|
9
|
+
export type { NodalDisplacement, NodalReaction, MemberEndForce, MemberEndForces, MemberStation, StationComponent, ExtremeValue, MemberDiagram, GoverningValue, GoverningExtremeValue, Bound, FrameCaseResult, FrameEnvelope, FrameResult, } from "./types/results.type";
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.memberDemandEnvelope = exports.memberAxes = exports.beam3dLocalStiffnessRightHanded = exports.beam3dLocalStiffness = exports.validateFrameModel = exports.createFrameAnalysis = exports.analyzeFrame = void 0;
|
|
4
|
+
var analyze_frame_1 = require("./solver/analyze-frame");
|
|
5
|
+
Object.defineProperty(exports, "analyzeFrame", { enumerable: true, get: function () { return analyze_frame_1.analyzeFrame; } });
|
|
6
|
+
Object.defineProperty(exports, "createFrameAnalysis", { enumerable: true, get: function () { return analyze_frame_1.createFrameAnalysis; } });
|
|
7
|
+
var validate_model_1 = require("./validation/validate-model");
|
|
8
|
+
Object.defineProperty(exports, "validateFrameModel", { enumerable: true, get: function () { return validate_model_1.validateFrameModel; } });
|
|
9
|
+
var beam_3d_stiffness_1 = require("./elements/beam-3d-stiffness");
|
|
10
|
+
Object.defineProperty(exports, "beam3dLocalStiffness", { enumerable: true, get: function () { return beam_3d_stiffness_1.beam3dLocalStiffness; } });
|
|
11
|
+
Object.defineProperty(exports, "beam3dLocalStiffnessRightHanded", { enumerable: true, get: function () { return beam_3d_stiffness_1.beam3dLocalStiffnessRightHanded; } });
|
|
12
|
+
var coordinate_transform_1 = require("./transformation/coordinate-transform");
|
|
13
|
+
Object.defineProperty(exports, "memberAxes", { enumerable: true, get: function () { return coordinate_transform_1.memberAxes; } });
|
|
14
|
+
var demand_envelope_1 = require("./post/demand-envelope");
|
|
15
|
+
Object.defineProperty(exports, "memberDemandEnvelope", { enumerable: true, get: function () { return demand_envelope_1.memberDemandEnvelope; } });
|
|
16
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/fea/frame/index.ts"],"names":[],"mappings":";;;AAAA,wDAA2E;AAAlE,6GAAA,YAAY,OAAA;AAAE,oHAAA,mBAAmB,OAAA;AAE1C,8DAAiE;AAAxD,oHAAA,kBAAkB,OAAA;AAC3B,kEAGsC;AAFpC,yHAAA,oBAAoB,OAAA;AACpB,oIAAA,+BAA+B,OAAA;AAEjC,8EAAmE;AAA1D,kHAAA,UAAU,OAAA;AACnB,0DAA8D;AAArD,uHAAA,oBAAoB,OAAA"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { FrameId } from "../types/model.type";
|
|
2
|
+
import type { FrameResult } from "../types/results.type";
|
|
3
|
+
export interface MemberDemandEnvelope {
|
|
4
|
+
memberId: FrameId;
|
|
5
|
+
MuPositive: number;
|
|
6
|
+
MuNegative: number;
|
|
7
|
+
Vu: number;
|
|
8
|
+
Nu: number;
|
|
9
|
+
VuRange: {
|
|
10
|
+
from: number;
|
|
11
|
+
to: number;
|
|
12
|
+
};
|
|
13
|
+
/** Load case or combination id producing each demand; null when that demand is zero. */
|
|
14
|
+
governing: Record<"MuPositive" | "MuNegative" | "Vu" | "Nu", string | null>;
|
|
15
|
+
}
|
|
16
|
+
export interface DemandEnvelopeOptions {
|
|
17
|
+
/** Combination ids to envelope. Default: every combination, unless `cases` is given. */
|
|
18
|
+
combinations?: string[];
|
|
19
|
+
/** Load case ids to envelope as well (or instead). Default: none. */
|
|
20
|
+
cases?: string[];
|
|
21
|
+
/** mm. Take Vu only between this distance from each end, e.g. the effective depth d. Default 0. */
|
|
22
|
+
shearCriticalDistance?: number;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Reduces a member's force diagrams to the demands used in beam design — Mu⁺, Mu⁻, Vu, Nu —
|
|
26
|
+
* enveloped over load combinations (and optionally load cases), with the governing id of each.
|
|
27
|
+
* Works on plain numbers and does not depend on the `rc` module.
|
|
28
|
+
*
|
|
29
|
+
* @param result - Result of `analyzeFrame`
|
|
30
|
+
* @param memberId - Member to reduce
|
|
31
|
+
* @param options - Combinations and/or cases to envelope, `shearCriticalDistance` in mm
|
|
32
|
+
* @returns Demands in kN and kN·m with their governing load case or combination
|
|
33
|
+
* @throws {Error} if the member or a requested id is not in the result, if nothing is selected,
|
|
34
|
+
* or if `shearCriticalDistance` is used on a result analysed with `diagrams: "extremes"`
|
|
35
|
+
*/
|
|
36
|
+
export declare const memberDemandEnvelope: (result: FrameResult, memberId: FrameId, options?: DemandEnvelopeOptions) => MemberDemandEnvelope;
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.memberDemandEnvelope = void 0;
|
|
4
|
+
const math_1 = require("../../../utils/math");
|
|
5
|
+
/** Demands of one diagram; Vu between `from` and `to`. */
|
|
6
|
+
const diagramDemands = (diagram, from, to) => {
|
|
7
|
+
const { N, M3, V2 } = diagram.extremes;
|
|
8
|
+
const moments = {
|
|
9
|
+
MuPositive: Math.max(M3.max.value, 0),
|
|
10
|
+
MuNegative: Math.max(-M3.min.value, 0),
|
|
11
|
+
Nu: Math.abs(N.max.value) >= Math.abs(N.min.value) ? N.max.value : N.min.value,
|
|
12
|
+
};
|
|
13
|
+
if (diagram.stations.length === 0) {
|
|
14
|
+
// analysed with diagrams: "extremes" — Vu over the whole length comes from the extremes
|
|
15
|
+
if (from > 0) {
|
|
16
|
+
throw new Error('shearCriticalDistance needs member stations: analyse with diagrams: "full", or pass a diagram from createFrameAnalysis(...).memberDiagram.');
|
|
17
|
+
}
|
|
18
|
+
return { ...moments, Vu: Math.max(Math.abs(V2.max.value), Math.abs(V2.min.value)) };
|
|
19
|
+
}
|
|
20
|
+
// V2 is piecewise linear with stations at every breakpoint, so interpolation is exact.
|
|
21
|
+
// Stations at a point load come as a (left, right) pair sharing the same x.
|
|
22
|
+
const v2At = (x, side) => {
|
|
23
|
+
const stations = diagram.stations;
|
|
24
|
+
const hits = stations.filter((s) => s.x === x);
|
|
25
|
+
if (hits.length > 0)
|
|
26
|
+
return side === "left" ? hits[0].V2 : hits[hits.length - 1].V2;
|
|
27
|
+
for (let i = 0; i < stations.length - 1; i++) {
|
|
28
|
+
const a = stations[i];
|
|
29
|
+
const b = stations[i + 1];
|
|
30
|
+
if (a.x < x && x < b.x)
|
|
31
|
+
return a.V2 + ((b.V2 - a.V2) * (x - a.x)) / (b.x - a.x);
|
|
32
|
+
}
|
|
33
|
+
return stations[stations.length - 1].V2;
|
|
34
|
+
};
|
|
35
|
+
const candidates = [v2At(from, "right"), v2At(to, "left")];
|
|
36
|
+
for (const s of diagram.stations) {
|
|
37
|
+
if (s.x >= from && s.x <= to)
|
|
38
|
+
candidates.push(s.V2);
|
|
39
|
+
}
|
|
40
|
+
return { ...moments, Vu: (0, math_1.roundToDecimalPlaces)(Math.max(...candidates.map(Math.abs)), 4) + 0 };
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* Reduces a member's force diagrams to the demands used in beam design — Mu⁺, Mu⁻, Vu, Nu —
|
|
44
|
+
* enveloped over load combinations (and optionally load cases), with the governing id of each.
|
|
45
|
+
* Works on plain numbers and does not depend on the `rc` module.
|
|
46
|
+
*
|
|
47
|
+
* @param result - Result of `analyzeFrame`
|
|
48
|
+
* @param memberId - Member to reduce
|
|
49
|
+
* @param options - Combinations and/or cases to envelope, `shearCriticalDistance` in mm
|
|
50
|
+
* @returns Demands in kN and kN·m with their governing load case or combination
|
|
51
|
+
* @throws {Error} if the member or a requested id is not in the result, if nothing is selected,
|
|
52
|
+
* or if `shearCriticalDistance` is used on a result analysed with `diagrams: "extremes"`
|
|
53
|
+
*/
|
|
54
|
+
const memberDemandEnvelope = (result, memberId, options = {}) => {
|
|
55
|
+
const pick = (source, ids, label) => ids.map((id) => {
|
|
56
|
+
const r = source[id];
|
|
57
|
+
if (!r)
|
|
58
|
+
throw new Error(`${label} "${id}" is not in the frame result.`);
|
|
59
|
+
return r;
|
|
60
|
+
});
|
|
61
|
+
const combinationIds = options.combinations ?? (options.cases ? [] : Object.keys(result.combinations));
|
|
62
|
+
const selected = [
|
|
63
|
+
...pick(result.combinations, combinationIds, "Load combination"),
|
|
64
|
+
...pick(result.cases, options.cases ?? [], "Load case"),
|
|
65
|
+
];
|
|
66
|
+
if (selected.length === 0) {
|
|
67
|
+
throw new Error("No load combinations or cases selected; the result has no combinations, so pass `cases`.");
|
|
68
|
+
}
|
|
69
|
+
const diagrams = selected.map((r) => {
|
|
70
|
+
const diagram = r.memberDiagrams.find((d) => d.memberId === memberId);
|
|
71
|
+
if (!diagram)
|
|
72
|
+
throw new Error(`Member ${String(memberId)} is not in the frame result.`);
|
|
73
|
+
return { id: r.id, diagram };
|
|
74
|
+
});
|
|
75
|
+
const L = diagrams[0].diagram.length;
|
|
76
|
+
const from = Math.min(Math.max(options.shearCriticalDistance ?? 0, 0), L / 2);
|
|
77
|
+
const to = L - from;
|
|
78
|
+
const envelope = {
|
|
79
|
+
MuPositive: 0,
|
|
80
|
+
MuNegative: 0,
|
|
81
|
+
Vu: 0,
|
|
82
|
+
Nu: 0,
|
|
83
|
+
governing: { MuPositive: null, MuNegative: null, Vu: null, Nu: null },
|
|
84
|
+
};
|
|
85
|
+
for (const { id, diagram } of diagrams) {
|
|
86
|
+
const d = diagramDemands(diagram, from, to);
|
|
87
|
+
for (const key of ["MuPositive", "MuNegative", "Vu"]) {
|
|
88
|
+
if (d[key] > envelope[key]) {
|
|
89
|
+
envelope[key] = d[key];
|
|
90
|
+
envelope.governing[key] = id;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
if (Math.abs(d.Nu) > Math.abs(envelope.Nu)) {
|
|
94
|
+
envelope.Nu = d.Nu;
|
|
95
|
+
envelope.governing.Nu = id;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return { memberId, ...envelope, VuRange: { from, to } };
|
|
99
|
+
};
|
|
100
|
+
exports.memberDemandEnvelope = memberDemandEnvelope;
|
|
101
|
+
//# sourceMappingURL=demand-envelope.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"demand-envelope.js","sourceRoot":"","sources":["../../../../src/fea/frame/post/demand-envelope.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { FrameCaseResult, FrameEnvelope } from "../types/results.type";
|
|
2
|
+
/**
|
|
3
|
+
* Max/min of every presented result across combinations, each with the combination that
|
|
4
|
+
* governs it. Combinations must come from the same model (same nodes and members, same order).
|
|
5
|
+
*
|
|
6
|
+
* @param results - Combination results, in model order
|
|
7
|
+
*/
|
|
8
|
+
export declare const buildEnvelope: (results: FrameCaseResult[]) => FrameEnvelope;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildEnvelope = void 0;
|
|
4
|
+
const DISPLACEMENT_KEYS = ["ux", "uy", "uz", "rx", "ry", "rz"];
|
|
5
|
+
const REACTION_KEYS = ["fx", "fy", "fz", "mx", "my", "mz"];
|
|
6
|
+
const COMPONENTS = ["N", "V2", "V3", "T", "M2", "M3", "u1", "u2", "u3"];
|
|
7
|
+
/** Keeps the larger max and smaller min; the first combination wins a tie. */
|
|
8
|
+
const update = (bound, max, min) => {
|
|
9
|
+
if (!bound)
|
|
10
|
+
return { max, min };
|
|
11
|
+
return {
|
|
12
|
+
max: max.value > bound.max.value ? max : bound.max,
|
|
13
|
+
min: min.value < bound.min.value ? min : bound.min,
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Max/min of every presented result across combinations, each with the combination that
|
|
18
|
+
* governs it. Combinations must come from the same model (same nodes and members, same order).
|
|
19
|
+
*
|
|
20
|
+
* @param results - Combination results, in model order
|
|
21
|
+
*/
|
|
22
|
+
const buildEnvelope = (results) => {
|
|
23
|
+
const first = results[0];
|
|
24
|
+
const nodalDisplacements = first.nodalDisplacements.map((d, n) => {
|
|
25
|
+
const entry = { nodeId: d.nodeId };
|
|
26
|
+
for (const key of DISPLACEMENT_KEYS) {
|
|
27
|
+
let bound;
|
|
28
|
+
for (const r of results) {
|
|
29
|
+
const g = { value: r.nodalDisplacements[n][key], combinationId: r.id };
|
|
30
|
+
bound = update(bound, g, g);
|
|
31
|
+
}
|
|
32
|
+
entry[key] = bound;
|
|
33
|
+
}
|
|
34
|
+
return entry;
|
|
35
|
+
});
|
|
36
|
+
const reactions = first.reactions.map((d, n) => {
|
|
37
|
+
const entry = { nodeId: d.nodeId };
|
|
38
|
+
for (const key of REACTION_KEYS) {
|
|
39
|
+
let bound;
|
|
40
|
+
for (const r of results) {
|
|
41
|
+
const g = { value: r.reactions[n][key], combinationId: r.id };
|
|
42
|
+
bound = update(bound, g, g);
|
|
43
|
+
}
|
|
44
|
+
entry[key] = bound;
|
|
45
|
+
}
|
|
46
|
+
return entry;
|
|
47
|
+
});
|
|
48
|
+
const members = first.memberDiagrams.map((d, m) => {
|
|
49
|
+
const extremes = {};
|
|
50
|
+
for (const c of COMPONENTS) {
|
|
51
|
+
let bound;
|
|
52
|
+
for (const r of results) {
|
|
53
|
+
const e = r.memberDiagrams[m].extremes[c];
|
|
54
|
+
bound = update(bound, { ...e.max, combinationId: r.id }, { ...e.min, combinationId: r.id });
|
|
55
|
+
}
|
|
56
|
+
extremes[c] = bound;
|
|
57
|
+
}
|
|
58
|
+
return { memberId: d.memberId, extremes };
|
|
59
|
+
});
|
|
60
|
+
return { combinationIds: results.map((r) => r.id), nodalDisplacements, reactions, members };
|
|
61
|
+
};
|
|
62
|
+
exports.buildEnvelope = buildEnvelope;
|
|
63
|
+
//# sourceMappingURL=envelope.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"envelope.js","sourceRoot":"","sources":["../../../../src/fea/frame/post/envelope.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { SectionProperties } from "../../../core/types/section-properties.type";
|
|
2
|
+
import type { Matrix } from "../../../utils/matrix";
|
|
3
|
+
import type { LocalMemberLoad } from "../elements/fixed-end-forces";
|
|
4
|
+
import type { FrameId } from "../types/model.type";
|
|
5
|
+
import type { MemberDiagram } from "../types/results.type";
|
|
6
|
+
/** The member data a diagram needs. */
|
|
7
|
+
export interface DiagramMember {
|
|
8
|
+
id: FrameId;
|
|
9
|
+
length: number;
|
|
10
|
+
section: Pick<SectionProperties, "E" | "A" | "I22" | "I33">;
|
|
11
|
+
lambda: Matrix;
|
|
12
|
+
released: boolean[];
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Builds the force and displacement diagrams of one member from its end forces, its end
|
|
16
|
+
* displacements and its loads.
|
|
17
|
+
*
|
|
18
|
+
* @param member - Member geometry, section, axes and end releases
|
|
19
|
+
* @param startForce - Force the start node exerts on the member, right-hand local, N and N·mm
|
|
20
|
+
* @param endDisplacements - The 12 local right-hand displacements of the member's end nodes, mm and rad
|
|
21
|
+
* @param loads - Member loads in local axes, N and mm
|
|
22
|
+
* @param stationCount - Number of evenly spaced stations (at least 2); load breakpoints and
|
|
23
|
+
* zero-shear points are added, with both sides reported at a point load
|
|
24
|
+
* @param withStations - false returns the extremes only, with an empty `stations` array
|
|
25
|
+
*/
|
|
26
|
+
export declare const memberDiagram: (member: DiagramMember, startForce: number[], endDisplacements: number[], loads: LocalMemberLoad[], stationCount?: number, withStations?: boolean) => MemberDiagram;
|
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.memberDiagram = void 0;
|
|
4
|
+
const math_1 = require("../../../utils/math");
|
|
5
|
+
const FORCE_COMPONENTS = ["N", "V2", "V3", "T", "M2", "M3"];
|
|
6
|
+
const DISPLACEMENT_COMPONENTS = ["u1", "u2", "u3"];
|
|
7
|
+
const COMPONENTS = [...FORCE_COMPONENTS, ...DISPLACEMENT_COMPONENTS];
|
|
8
|
+
/** Evenly spaced grid for the deflection extremes (force extremes need no grid: see below). */
|
|
9
|
+
const DEFLECTION_GRID_INTERVALS = 40;
|
|
10
|
+
/** Golden-section steps refining each deflection extreme between its neighbouring grid points. */
|
|
11
|
+
const REFINE_STEPS = 30;
|
|
12
|
+
const GOLDEN = (Math.sqrt(5) - 1) / 2;
|
|
13
|
+
const FORCE_DECIMALS = 4;
|
|
14
|
+
const DISPLACEMENT_DECIMALS = 5;
|
|
15
|
+
/**
|
|
16
|
+
* Internal forces at distance `x` from the member start, in N and N·mm. Taken from the
|
|
17
|
+
* free body of the segment [0, x]; N is positive in tension, `M3` is positive for sagging
|
|
18
|
+
* when local 2 points up. At a point load, `side` picks the value just before or after it.
|
|
19
|
+
*
|
|
20
|
+
* @param startForce - Right-hand local force the start node exerts on the member: [F1, F2, F3, M1, M2, M3]
|
|
21
|
+
*/
|
|
22
|
+
const internalForces = (startForce, loads, x, side) => {
|
|
23
|
+
const [f1, f2, f3, m1, m2, m3] = startForce;
|
|
24
|
+
// Q[axis]: resultant of loads in [0, x]; I[axis]: ∫(s − x)·q ds over [0, x]
|
|
25
|
+
const Q = [0, 0, 0, 0];
|
|
26
|
+
const I = [0, 0, 0, 0];
|
|
27
|
+
for (const load of loads) {
|
|
28
|
+
if (load.type === "point") {
|
|
29
|
+
const included = side === "left" ? load.a < x : load.a <= x;
|
|
30
|
+
if (included) {
|
|
31
|
+
Q[load.axis] += load.P;
|
|
32
|
+
I[load.axis] += load.P * (load.a - x);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
const m = Math.min(x, load.end);
|
|
37
|
+
if (m > load.start) {
|
|
38
|
+
Q[load.axis] += load.w * (m - load.start);
|
|
39
|
+
I[load.axis] += (load.w * ((m - x) ** 2 - (load.start - x) ** 2)) / 2;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return {
|
|
44
|
+
N: -f1 - Q[1],
|
|
45
|
+
V2: -f2 - Q[2],
|
|
46
|
+
V3: -f3 - Q[3],
|
|
47
|
+
T: -m1,
|
|
48
|
+
M2: -m2 - x * f3 + I[3],
|
|
49
|
+
M3: -m3 + x * f2 - I[2],
|
|
50
|
+
};
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* Local displacements u1, u2, u3 (mm) at every grid point, from Euler–Bernoulli kinematics:
|
|
54
|
+
* `u1' = N/EA`, `u2'' = M3/EI33` (R3 = u2'), `u3'' = −M2/EI22` (R2 = −u3').
|
|
55
|
+
*
|
|
56
|
+
* Each field is `a + b·x + x·∫₀ˣκ − ∫₀ˣ s·κ`, with the running integrals accumulated once along
|
|
57
|
+
* the sorted grid. The grid contains every load breakpoint, so each interval lies inside one
|
|
58
|
+
* smooth piece where N is at most linear and M at most quadratic, and one Simpson panel per
|
|
59
|
+
* interval integrates the (at most cubic) integrands exactly.
|
|
60
|
+
*
|
|
61
|
+
* The constants come from the member's own end displacements: end translations first, an end
|
|
62
|
+
* rotation only where a translation is released. A released rotation (hinge) never enters, so
|
|
63
|
+
* the curve is correct at hinged ends whose rotation differs from the node's.
|
|
64
|
+
*/
|
|
65
|
+
const displacementsOnGrid = (member, startForce, endDisplacements, loads, grid) => {
|
|
66
|
+
const { E, A, I22, I33 } = member.section;
|
|
67
|
+
const L = member.length;
|
|
68
|
+
const n = grid.length;
|
|
69
|
+
// integrands: [N/EA, M3/EI33, s·M3/EI33, −M2/EI22, −s·M2/EI22]
|
|
70
|
+
const integrands = (s, side) => {
|
|
71
|
+
const f = internalForces(startForce, loads, s, side);
|
|
72
|
+
const k3 = f.M3 / (E * I33);
|
|
73
|
+
const k2 = -f.M2 / (E * I22);
|
|
74
|
+
return [f.N / (E * A), k3, s * k3, k2, s * k2];
|
|
75
|
+
};
|
|
76
|
+
const cumulative = Array.from({ length: 5 }, () => new Float64Array(n));
|
|
77
|
+
for (let i = 1; i < n; i++) {
|
|
78
|
+
const a = grid[i - 1];
|
|
79
|
+
const b = grid[i];
|
|
80
|
+
const ga = integrands(a, "right");
|
|
81
|
+
const gm = integrands((a + b) / 2, "right");
|
|
82
|
+
const gb = integrands(b, "left");
|
|
83
|
+
for (let c = 0; c < 5; c++) {
|
|
84
|
+
cumulative[c][i] = cumulative[c][i - 1] + ((b - a) / 6) * (ga[c] + 4 * gm[c] + gb[c]);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
const [strain, k3, sk3, k2, sk2] = cumulative;
|
|
88
|
+
const last = n - 1;
|
|
89
|
+
/** a, b of `u = a + b·x + P(x)` from the first independent pair of end conditions. */
|
|
90
|
+
const planeConstants = (translation, rotation, rotationSign, PL, // P(L)
|
|
91
|
+
dPL) => {
|
|
92
|
+
const { released } = member;
|
|
93
|
+
// rows [ca, cb | rhs] of ca·a + cb·b = rhs
|
|
94
|
+
const conditions = [];
|
|
95
|
+
if (!released[translation])
|
|
96
|
+
conditions.push([1, 0, endDisplacements[translation]]);
|
|
97
|
+
if (!released[6 + translation]) {
|
|
98
|
+
conditions.push([1, L, endDisplacements[6 + translation] - PL]);
|
|
99
|
+
}
|
|
100
|
+
if (!released[rotation])
|
|
101
|
+
conditions.push([0, 1, rotationSign * endDisplacements[rotation]]);
|
|
102
|
+
if (!released[6 + rotation]) {
|
|
103
|
+
conditions.push([0, 1, rotationSign * endDisplacements[6 + rotation] - dPL]);
|
|
104
|
+
}
|
|
105
|
+
for (let i = 0; i < conditions.length; i++) {
|
|
106
|
+
for (let j = i + 1; j < conditions.length; j++) {
|
|
107
|
+
const [a1, b1, r1] = conditions[i];
|
|
108
|
+
const [a2, b2, r2] = conditions[j];
|
|
109
|
+
const det = a1 * b2 - a2 * b1;
|
|
110
|
+
if (Math.abs(det) > 1e-12 * Math.max(1, L)) {
|
|
111
|
+
return { a: (r1 * b2 - r2 * b1) / det, b: (a1 * r2 - a2 * r1) / det };
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return { a: 0, b: 0 }; // unreachable: such releases are rejected as a mechanism (307)
|
|
116
|
+
};
|
|
117
|
+
const P3 = (i) => grid[i] * k3[i] - sk3[i];
|
|
118
|
+
const P2 = (i) => grid[i] * k2[i] - sk2[i];
|
|
119
|
+
const plane2 = planeConstants(1, 5, 1, P3(last), k3[last]); // u2, with u2' = R3
|
|
120
|
+
const plane3 = planeConstants(2, 4, -1, P2(last), k2[last]); // u3, with u3' = −R2
|
|
121
|
+
const axialStart = member.released[0] ? endDisplacements[6] - strain[last] : endDisplacements[0];
|
|
122
|
+
const onGrid = grid.map((x, i) => ({
|
|
123
|
+
u1: axialStart + strain[i],
|
|
124
|
+
u2: plane2.a + plane2.b * x + P3(i),
|
|
125
|
+
u3: plane3.a + plane3.b * x + P2(i),
|
|
126
|
+
}));
|
|
127
|
+
/** Displacement anywhere: the grid value plus one exact Simpson panel to x. */
|
|
128
|
+
const at = (x) => {
|
|
129
|
+
let lo = 0;
|
|
130
|
+
let hi = last;
|
|
131
|
+
while (lo < hi) {
|
|
132
|
+
const mid = (lo + hi + 1) >> 1;
|
|
133
|
+
if (grid[mid] <= x)
|
|
134
|
+
lo = mid;
|
|
135
|
+
else
|
|
136
|
+
hi = mid - 1;
|
|
137
|
+
}
|
|
138
|
+
const a = grid[lo];
|
|
139
|
+
if (x - a <= 0)
|
|
140
|
+
return onGrid[lo];
|
|
141
|
+
const ga = integrands(a, "right");
|
|
142
|
+
const gm = integrands((a + x) / 2, "right");
|
|
143
|
+
const gx = integrands(x, "left");
|
|
144
|
+
const c = cumulative.map((col, k) => col[lo] + ((x - a) / 6) * (ga[k] + 4 * gm[k] + gx[k]));
|
|
145
|
+
return {
|
|
146
|
+
u1: axialStart + c[0],
|
|
147
|
+
u2: plane2.a + plane2.b * x + (x * c[1] - c[2]),
|
|
148
|
+
u3: plane3.a + plane3.b * x + (x * c[3] - c[4]),
|
|
149
|
+
};
|
|
150
|
+
};
|
|
151
|
+
return { onGrid, at };
|
|
152
|
+
};
|
|
153
|
+
const SCALE = {
|
|
154
|
+
N: 1e-3,
|
|
155
|
+
V2: 1e-3,
|
|
156
|
+
V3: 1e-3,
|
|
157
|
+
T: 1e-6,
|
|
158
|
+
M2: 1e-6,
|
|
159
|
+
M3: 1e-6,
|
|
160
|
+
u1: 1,
|
|
161
|
+
u2: 1,
|
|
162
|
+
u3: 1,
|
|
163
|
+
};
|
|
164
|
+
const present = (c, value) => (0, math_1.roundToDecimalPlaces)(value * SCALE[c], c === "u1" || c === "u2" || c === "u3" ? DISPLACEMENT_DECIMALS : FORCE_DECIMALS) + 0;
|
|
165
|
+
/**
|
|
166
|
+
* Builds the force and displacement diagrams of one member from its end forces, its end
|
|
167
|
+
* displacements and its loads.
|
|
168
|
+
*
|
|
169
|
+
* @param member - Member geometry, section, axes and end releases
|
|
170
|
+
* @param startForce - Force the start node exerts on the member, right-hand local, N and N·mm
|
|
171
|
+
* @param endDisplacements - The 12 local right-hand displacements of the member's end nodes, mm and rad
|
|
172
|
+
* @param loads - Member loads in local axes, N and mm
|
|
173
|
+
* @param stationCount - Number of evenly spaced stations (at least 2); load breakpoints and
|
|
174
|
+
* zero-shear points are added, with both sides reported at a point load
|
|
175
|
+
* @param withStations - false returns the extremes only, with an empty `stations` array
|
|
176
|
+
*/
|
|
177
|
+
const memberDiagram = (member, startForce, endDisplacements, loads, stationCount = 21, withStations = true) => {
|
|
178
|
+
const L = member.length;
|
|
179
|
+
const tolerance = 1e-9 * L;
|
|
180
|
+
const breakpoints = new Set([0, L]);
|
|
181
|
+
for (const load of loads) {
|
|
182
|
+
if (load.type === "point")
|
|
183
|
+
breakpoints.add(load.a);
|
|
184
|
+
else {
|
|
185
|
+
breakpoints.add(load.start);
|
|
186
|
+
breakpoints.add(load.end);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
const sortedBreaks = [...breakpoints].sort((a, b) => a - b);
|
|
190
|
+
const isBreak = (x) => sortedBreaks.some((b) => Math.abs(b - x) < tolerance);
|
|
191
|
+
/** Sorted, with points closer than the tolerance merged (the first one kept). */
|
|
192
|
+
const mergeSorted = (values) => {
|
|
193
|
+
const sorted = [...values].sort((a, b) => a - b);
|
|
194
|
+
const out = [];
|
|
195
|
+
for (const v of sorted)
|
|
196
|
+
if (out.length === 0 || v - out[out.length - 1] >= tolerance)
|
|
197
|
+
out.push(v);
|
|
198
|
+
return out;
|
|
199
|
+
};
|
|
200
|
+
// Zero-shear points: V is linear inside each piece between breakpoints, so the root is exact
|
|
201
|
+
const roots = [];
|
|
202
|
+
for (let i = 0; i < sortedBreaks.length - 1; i++) {
|
|
203
|
+
const xa = sortedBreaks[i];
|
|
204
|
+
const xb = sortedBreaks[i + 1];
|
|
205
|
+
const fa = internalForces(startForce, loads, xa, "right");
|
|
206
|
+
const fb = internalForces(startForce, loads, xb, "left");
|
|
207
|
+
for (const key of ["V2", "V3"]) {
|
|
208
|
+
if (fa[key] * fb[key] < 0)
|
|
209
|
+
roots.push(xa + ((xb - xa) * fa[key]) / (fa[key] - fb[key]));
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
const coarse = Array.from({ length: DEFLECTION_GRID_INTERVALS + 1 }, (_, i) => (L * i) / DEFLECTION_GRID_INTERVALS);
|
|
213
|
+
const count = Math.max(2, Math.floor(stationCount));
|
|
214
|
+
const uniform = withStations
|
|
215
|
+
? Array.from({ length: count }, (_, i) => (L * i) / (count - 1))
|
|
216
|
+
: [];
|
|
217
|
+
// One grid for everything: breakpoints, zero-shear points, stations and the deflection grid
|
|
218
|
+
const grid = mergeSorted([...sortedBreaks, ...roots, ...uniform, ...coarse]);
|
|
219
|
+
const field = displacementsOnGrid(member, startForce, endDisplacements, loads, grid);
|
|
220
|
+
const displacements = field.onGrid;
|
|
221
|
+
const gridIndex = (x) => {
|
|
222
|
+
let lo = 0;
|
|
223
|
+
let hi = grid.length - 1;
|
|
224
|
+
while (lo < hi) {
|
|
225
|
+
const mid = (lo + hi) >> 1;
|
|
226
|
+
if (grid[mid] < x - tolerance)
|
|
227
|
+
lo = mid + 1;
|
|
228
|
+
else
|
|
229
|
+
hi = mid;
|
|
230
|
+
}
|
|
231
|
+
return lo;
|
|
232
|
+
};
|
|
233
|
+
// ---- Stations -------------------------------------------------------------------
|
|
234
|
+
const stations = [];
|
|
235
|
+
if (withStations) {
|
|
236
|
+
const [l1, l2, l3] = member.lambda;
|
|
237
|
+
const toStation = (x, f, u) => {
|
|
238
|
+
const station = { x: (0, math_1.roundToDecimalPlaces)(x, 3) };
|
|
239
|
+
for (const c of FORCE_COMPONENTS)
|
|
240
|
+
station[c] = present(c, f[c]);
|
|
241
|
+
for (const c of DISPLACEMENT_COMPONENTS)
|
|
242
|
+
station[c] = present(c, u[c]);
|
|
243
|
+
// global = Σ local component × its axis direction
|
|
244
|
+
const g = [0, 1, 2].map((k) => u.u1 * l1[k] + u.u2 * l2[k] + u.u3 * l3[k]);
|
|
245
|
+
station.ux = (0, math_1.roundToDecimalPlaces)(g[0], DISPLACEMENT_DECIMALS) + 0;
|
|
246
|
+
station.uy = (0, math_1.roundToDecimalPlaces)(g[1], DISPLACEMENT_DECIMALS) + 0;
|
|
247
|
+
station.uz = (0, math_1.roundToDecimalPlaces)(g[2], DISPLACEMENT_DECIMALS) + 0;
|
|
248
|
+
return station;
|
|
249
|
+
};
|
|
250
|
+
const stationXs = mergeSorted([...uniform, ...sortedBreaks, ...roots]);
|
|
251
|
+
for (const x of stationXs) {
|
|
252
|
+
const u = displacements[gridIndex(x)];
|
|
253
|
+
const right = internalForces(startForce, loads, x, "right");
|
|
254
|
+
if (isBreak(x) && x > 0 && x < L) {
|
|
255
|
+
const left = internalForces(startForce, loads, x, "left");
|
|
256
|
+
if (FORCE_COMPONENTS.some((c) => Math.abs(left[c] - right[c]) > 1e-9)) {
|
|
257
|
+
stations.push(toStation(x, left, u));
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
stations.push(toStation(x, right, u));
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
// ---- Extremes -------------------------------------------------------------------
|
|
264
|
+
// N, V and T are linear and M quadratic inside each piece, so their extremes lie at a
|
|
265
|
+
// breakpoint (either side) or a zero-shear point — all on the grid, so these are exact.
|
|
266
|
+
// Deflections are taken on the grid, then refined by golden-section search.
|
|
267
|
+
const extremes = {};
|
|
268
|
+
const best = {};
|
|
269
|
+
const consider = (c, value, x, i) => {
|
|
270
|
+
const b = best[c];
|
|
271
|
+
if (!b)
|
|
272
|
+
best[c] = { max: [value, x, i], min: [value, x, i] };
|
|
273
|
+
else {
|
|
274
|
+
if (value > b.max[0])
|
|
275
|
+
b.max = [value, x, i];
|
|
276
|
+
if (value < b.min[0])
|
|
277
|
+
b.min = [value, x, i];
|
|
278
|
+
}
|
|
279
|
+
};
|
|
280
|
+
grid.forEach((x, i) => {
|
|
281
|
+
const sides = isBreak(x) && x > 0 && x < L ? ["right", "left"] : ["right"];
|
|
282
|
+
for (const side of sides) {
|
|
283
|
+
const f = internalForces(startForce, loads, x, side);
|
|
284
|
+
for (const c of FORCE_COMPONENTS)
|
|
285
|
+
consider(c, f[c], x, i);
|
|
286
|
+
}
|
|
287
|
+
for (const c of DISPLACEMENT_COMPONENTS)
|
|
288
|
+
consider(c, displacements[i][c], x, i);
|
|
289
|
+
});
|
|
290
|
+
const refine = (c, i, sign) => {
|
|
291
|
+
// maximise sign·u between the neighbouring grid points
|
|
292
|
+
let a = grid[Math.max(0, i - 1)];
|
|
293
|
+
let b = grid[Math.min(grid.length - 1, i + 1)];
|
|
294
|
+
const value = (x) => sign * field.at(x)[c];
|
|
295
|
+
let x1 = b - GOLDEN * (b - a);
|
|
296
|
+
let x2 = a + GOLDEN * (b - a);
|
|
297
|
+
let f1 = value(x1);
|
|
298
|
+
let f2 = value(x2);
|
|
299
|
+
for (let step = 0; step < REFINE_STEPS; step++) {
|
|
300
|
+
if (f1 < f2) {
|
|
301
|
+
a = x1;
|
|
302
|
+
x1 = x2;
|
|
303
|
+
f1 = f2;
|
|
304
|
+
x2 = a + GOLDEN * (b - a);
|
|
305
|
+
f2 = value(x2);
|
|
306
|
+
}
|
|
307
|
+
else {
|
|
308
|
+
b = x2;
|
|
309
|
+
x2 = x1;
|
|
310
|
+
f2 = f1;
|
|
311
|
+
x1 = b - GOLDEN * (b - a);
|
|
312
|
+
f1 = value(x1);
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
return f1 >= f2 ? [sign * f1, x1] : [sign * f2, x2];
|
|
316
|
+
};
|
|
317
|
+
for (const c of DISPLACEMENT_COMPONENTS) {
|
|
318
|
+
const b = best[c];
|
|
319
|
+
const [maxValue, maxX] = refine(c, b.max[2], 1);
|
|
320
|
+
if (maxValue > b.max[0])
|
|
321
|
+
b.max = [maxValue, maxX, b.max[2]];
|
|
322
|
+
const [minValue, minX] = refine(c, b.min[2], -1);
|
|
323
|
+
if (minValue < b.min[0])
|
|
324
|
+
b.min = [minValue, minX, b.min[2]];
|
|
325
|
+
}
|
|
326
|
+
for (const c of COMPONENTS) {
|
|
327
|
+
const make = ([value, x]) => ({
|
|
328
|
+
value: present(c, value),
|
|
329
|
+
x: (0, math_1.roundToDecimalPlaces)(x, 3),
|
|
330
|
+
});
|
|
331
|
+
extremes[c] = { max: make(best[c].max), min: make(best[c].min) };
|
|
332
|
+
}
|
|
333
|
+
return { memberId: member.id, length: L, stations, extremes };
|
|
334
|
+
};
|
|
335
|
+
exports.memberDiagram = memberDiagram;
|
|
336
|
+
//# sourceMappingURL=member-diagram.js.map
|