@theerapat-s28/ts-structural-eng-tools 2.3.0 → 3.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/CHANGELOG.md +80 -1
- package/README.md +35 -11
- package/dist/core/constants/frame.constant.d.ts +15 -0
- package/dist/core/constants/frame.constant.js +16 -1
- package/dist/core/constants/frame.constant.js.map +1 -1
- package/dist/core/errors/frame-analysis.error.d.ts +1 -0
- package/dist/core/errors/frame-analysis.error.js +18 -2
- package/dist/core/errors/frame-analysis.error.js.map +1 -1
- package/dist/core/index.d.ts +1 -1
- package/dist/core/index.js +2 -1
- package/dist/core/index.js.map +1 -1
- package/dist/esm/core/constants/frame.constant.js +15 -0
- package/dist/esm/core/constants/frame.constant.js.map +1 -1
- package/dist/esm/core/errors/frame-analysis.error.js +18 -2
- package/dist/esm/core/errors/frame-analysis.error.js.map +1 -1
- package/dist/esm/core/index.js +1 -1
- package/dist/esm/core/index.js.map +1 -1
- package/dist/esm/fea/frame/elements/shell/dkq-plate.js +109 -0
- package/dist/esm/fea/frame/elements/shell/dkq-plate.js.map +1 -0
- package/dist/esm/fea/frame/elements/shell/flat-shell.js +111 -0
- package/dist/esm/fea/frame/elements/shell/flat-shell.js.map +1 -0
- package/dist/esm/fea/frame/elements/shell/membrane-quad.js +107 -0
- package/dist/esm/fea/frame/elements/shell/membrane-quad.js.map +1 -0
- package/dist/esm/fea/frame/elements/shell/quad-geometry.js +127 -0
- package/dist/esm/fea/frame/elements/shell/quad-geometry.js.map +1 -0
- package/dist/esm/fea/frame/elements/shell/rigidity.js +19 -0
- package/dist/esm/fea/frame/elements/shell/rigidity.js.map +1 -0
- package/dist/esm/fea/frame/elements/shell/shell-axes.js +97 -0
- package/dist/esm/fea/frame/elements/shell/shell-axes.js.map +1 -0
- package/dist/esm/fea/frame/mesh/expand-model.js +129 -0
- package/dist/esm/fea/frame/mesh/expand-model.js.map +1 -0
- package/dist/esm/fea/frame/mesh/mesh-shells.js +239 -0
- package/dist/esm/fea/frame/mesh/mesh-shells.js.map +1 -0
- package/dist/esm/fea/frame/post/envelope.js +38 -1
- package/dist/esm/fea/frame/post/envelope.js.map +1 -1
- package/dist/esm/fea/frame/post/member-diagram.js +51 -2
- package/dist/esm/fea/frame/post/member-diagram.js.map +1 -1
- package/dist/esm/fea/frame/post/present-state.js +34 -16
- package/dist/esm/fea/frame/post/present-state.js.map +1 -1
- package/dist/esm/fea/frame/post/shell-forces.js +111 -0
- package/dist/esm/fea/frame/post/shell-forces.js.map +1 -0
- package/dist/esm/fea/frame/solver/analyze-frame.js +27 -7
- package/dist/esm/fea/frame/solver/analyze-frame.js.map +1 -1
- package/dist/esm/fea/frame/solver/auto-restraint.js +58 -10
- package/dist/esm/fea/frame/solver/auto-restraint.js.map +1 -1
- package/dist/esm/fea/frame/solver/frame-system.js +148 -40
- package/dist/esm/fea/frame/solver/frame-system.js.map +1 -1
- package/dist/esm/fea/frame/solver/global-assembly.js +5 -3
- package/dist/esm/fea/frame/solver/global-assembly.js.map +1 -1
- package/dist/esm/fea/frame/solver/load-case-solver.js +102 -9
- package/dist/esm/fea/frame/solver/load-case-solver.js.map +1 -1
- package/dist/esm/fea/frame/validation/validate-model.js +120 -3
- package/dist/esm/fea/frame/validation/validate-model.js.map +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/fea/frame/elements/shell/dkq-plate.d.ts +50 -0
- package/dist/fea/frame/elements/shell/dkq-plate.js +115 -0
- package/dist/fea/frame/elements/shell/dkq-plate.js.map +1 -0
- package/dist/fea/frame/elements/shell/flat-shell.d.ts +63 -0
- package/dist/fea/frame/elements/shell/flat-shell.js +118 -0
- package/dist/fea/frame/elements/shell/flat-shell.js.map +1 -0
- package/dist/fea/frame/elements/shell/membrane-quad.d.ts +61 -0
- package/dist/fea/frame/elements/shell/membrane-quad.js +113 -0
- package/dist/fea/frame/elements/shell/membrane-quad.js.map +1 -0
- package/dist/fea/frame/elements/shell/quad-geometry.d.ts +71 -0
- package/dist/fea/frame/elements/shell/quad-geometry.js +136 -0
- package/dist/fea/frame/elements/shell/quad-geometry.js.map +1 -0
- package/dist/fea/frame/elements/shell/rigidity.d.ts +14 -0
- package/dist/fea/frame/elements/shell/rigidity.js +23 -0
- package/dist/fea/frame/elements/shell/rigidity.js.map +1 -0
- package/dist/fea/frame/elements/shell/shell-axes.d.ts +43 -0
- package/dist/fea/frame/elements/shell/shell-axes.js +102 -0
- package/dist/fea/frame/elements/shell/shell-axes.js.map +1 -0
- package/dist/fea/frame/index.d.ts +2 -2
- package/dist/fea/frame/mesh/expand-model.d.ts +29 -0
- package/dist/fea/frame/mesh/expand-model.js +133 -0
- package/dist/fea/frame/mesh/expand-model.js.map +1 -0
- package/dist/fea/frame/mesh/mesh-shells.d.ts +38 -0
- package/dist/fea/frame/mesh/mesh-shells.js +244 -0
- package/dist/fea/frame/mesh/mesh-shells.js.map +1 -0
- package/dist/fea/frame/post/envelope.js +38 -1
- package/dist/fea/frame/post/envelope.js.map +1 -1
- package/dist/fea/frame/post/member-diagram.d.ts +21 -1
- package/dist/fea/frame/post/member-diagram.js +53 -3
- package/dist/fea/frame/post/member-diagram.js.map +1 -1
- package/dist/fea/frame/post/present-state.d.ts +3 -2
- package/dist/fea/frame/post/present-state.js +33 -15
- package/dist/fea/frame/post/present-state.js.map +1 -1
- package/dist/fea/frame/post/shell-forces.d.ts +27 -0
- package/dist/fea/frame/post/shell-forces.js +116 -0
- package/dist/fea/frame/post/shell-forces.js.map +1 -0
- package/dist/fea/frame/solver/analyze-frame.d.ts +8 -4
- package/dist/fea/frame/solver/analyze-frame.js +27 -7
- package/dist/fea/frame/solver/analyze-frame.js.map +1 -1
- package/dist/fea/frame/solver/auto-restraint.d.ts +23 -10
- package/dist/fea/frame/solver/auto-restraint.js +60 -11
- package/dist/fea/frame/solver/auto-restraint.js.map +1 -1
- package/dist/fea/frame/solver/frame-system.d.ts +47 -8
- package/dist/fea/frame/solver/frame-system.js +146 -38
- package/dist/fea/frame/solver/frame-system.js.map +1 -1
- package/dist/fea/frame/solver/global-assembly.d.ts +11 -0
- package/dist/fea/frame/solver/global-assembly.js +7 -4
- package/dist/fea/frame/solver/global-assembly.js.map +1 -1
- package/dist/fea/frame/solver/load-case-solver.d.ts +11 -1
- package/dist/fea/frame/solver/load-case-solver.js +100 -7
- package/dist/fea/frame/solver/load-case-solver.js.map +1 -1
- package/dist/fea/frame/types/model.type.d.ts +82 -4
- package/dist/fea/frame/types/results.type.d.ts +61 -1
- package/dist/fea/frame/validation/validate-model.d.ts +3 -2
- package/dist/fea/frame/validation/validate-model.js +120 -3
- package/dist/fea/frame/validation/validate-model.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,83 @@ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [3.1.0] — 2026-10-31
|
|
10
|
+
|
|
11
|
+
**Engine reorganised, and a guide for upgrading from 2.x.** The analysis engine behind `/fea` is reorganised into separate parts for frame members, shell elements and the analysis that runs them together. Nothing you call changes: every export keeps its name, its import path and its behaviour, and every result is identical to 3.0.0. Coming from 2.x? Read **Upgrading from 2.x** below; it covers this release and 3.0.0 together.
|
|
12
|
+
|
|
13
|
+
### Changed
|
|
14
|
+
|
|
15
|
+
- **Files inside `dist/` moved.** The code behind `/fea` moved from `dist/fea/frame/…` into `dist/fea/shared/`, `dist/fea/frame/` (members and null areas), `dist/fea/shell/` (the shell element) and `dist/fea/analysis/` (`analyzeFrame`, `validateFrameModel`, and the model and result types), in both the CommonJS and the ES-module builds. Imports from the package root and the subpaths (`/fea`, `/core`, …) are unaffected. An import of a file inside `dist/` no longer resolves: the `exports` map has never allowed one, but TypeScript's legacy `"moduleResolution": "node"` and bundler aliases can reach those files. Import from the root or `/fea` instead. Your editor's "go to definition" now opens the new files.
|
|
16
|
+
|
|
17
|
+
### Fixed
|
|
18
|
+
|
|
19
|
+
- The type comment and the reference page for `FrameCaseResult.shellForces` said one entry per shell area. There is one entry per shell element, area by area in model order, as the results have always had.
|
|
20
|
+
|
|
21
|
+
### Upgrading from 2.x
|
|
22
|
+
|
|
23
|
+
Nothing has been removed or renamed since 2.3.0, and no input has become required. A model that runs on 2.3.0 runs unchanged and gives the same numbers, warnings and validation issues; results only gain the fields in step 3. Most frontends need step 1 and a look at steps 3 and 4. Step 5 matters once you start sending shells (see 3.0.0 for the shell features themselves).
|
|
24
|
+
|
|
25
|
+
1. **Update the dependency.** A `^2.x` range does not pick up a major version: run `pnpm add @theerapat-s28/ts-structural-eng-tools@^3.1.0` (or `npm install` / `yarn add` with the same spec).
|
|
26
|
+
|
|
27
|
+
2. **Imports.** Nothing to change. Every name exported in 2.3.0 is still exported from the same place: the package root and `/fea`, `/rc`, `/strengthening`, `/core`, `/utils`. Only imports of files inside `dist/` break (see **Changed**).
|
|
28
|
+
|
|
29
|
+
3. **New result fields, on every result.** Without shells they are empty or zero:
|
|
30
|
+
|
|
31
|
+
| Field | Without shells |
|
|
32
|
+
| --- | --- |
|
|
33
|
+
| `cases[id].shellForces`, `combinations[id].shellForces` | `[]` |
|
|
34
|
+
| `envelope.shells` (when the model has combinations) | `[]` |
|
|
35
|
+
| `calculationDetails.shellCount` | `0` |
|
|
36
|
+
| `units.forcePerLength`, `units.momentPerLength`, `units.stress` | `"kN/m"`, `"kN·m/m"`, `"MPa"` |
|
|
37
|
+
| `mesh` | absent; present only when the model has shells |
|
|
38
|
+
|
|
39
|
+
Code that only reads results needs no change. Update code that:
|
|
40
|
+
- **builds** a `FrameResult` or `FrameCaseResult` itself, such as an empty placeholder in app state, test fixtures or mocks. TypeScript names the missing fields.
|
|
41
|
+
- **validates** stored or received results against a strict schema (Zod `.strict()`, JSON Schema `additionalProperties: false`).
|
|
42
|
+
- **snapshots** whole results. Refresh the snapshots once; the values in them do not change.
|
|
43
|
+
- maps **every key of `units`** to a label, e.g. for a units display.
|
|
44
|
+
|
|
45
|
+
4. **Errors and warnings.** For frame-only models the codes, `details` and the order of `issues` are unchanged, but two messages are reworded to mention shells:
|
|
46
|
+
- 303 `DUPLICATE_ID`: "Node ids, member ids and restrained node ids must each be unique, area ids must be unique across null areas and shells, and load case and combination ids must be unique across both lists."
|
|
47
|
+
- 313 `MISSING_UNIT_WEIGHT`: "A load case requests self-weight but a member or shell section has no unitWeight; set unitWeight (0 for a weightless member or shell)."
|
|
48
|
+
|
|
49
|
+
If your code matches on `message`, match on `code` instead. Models with shells can also raise 326 `INVALID_SHELL_GEOMETRY`, 327 `INVALID_SHELL_SECTION`, 328 `SHELL_DOF_UNSUPPORTED` and 329 `INVALID_SHELL_MESH`, located by the new `details.shellId` (the shell area's id). Add them to any code-to-message table, and highlight the shell area that `shellId` names. The new warning **Shell area meshing** appears in `result.warnings`.
|
|
50
|
+
|
|
51
|
+
5. **When you add shells to a model.** These points apply only to models with `shells`:
|
|
52
|
+
- **Generated nodes in node results.** Meshing adds nodes. `nodalDisplacements` and `reactions` list them after your own nodes, with string ids — `"<areaId>:<i>,<j>"` inside an area, `"<a>~<b>:<k>"` along an edge between your nodes `a` and `b` — even when your ids are numbers. Their coordinates are in `result.mesh.nodes`. Do not assume every node id in a result is one of yours; `calculationDetails.nodeCount` counts the generated nodes too.
|
|
53
|
+
- **Drawing the mesh.** `result.mesh.shells` lists every element with its four node ids. `shellForces[].shellId` and `envelope.shells[].shellId` name these elements, and `areaId` groups them under your area; an area that is not meshed is one element with the area's own id. `calculationDetails.shellCount` counts elements, not areas.
|
|
54
|
+
- **Contours.** Shell results are corner values in each element's local axes (`ShellCornerForces`), and `ShellForceComponent` lists the components for a picker. As usual for shell results, elements meeting at a node give different values there; average them for a smooth contour.
|
|
55
|
+
- **Members along meshed edges** are split internally at the mesh nodes on them, but every member result (end forces, diagrams, release deformations, envelopes, `memberDemandEnvelope`) stays under the member's own id, along its full length. `calculationDetails.memberCount` counts your members.
|
|
56
|
+
- **One id namespace for areas.** A null area and a shell cannot share an id (303), and an `AreaLoad` can name either. `distributeAreaLoads` returns only the loads from null areas; loads on shells stay on the shell.
|
|
57
|
+
- **Supports along an edge.** Fix a wall base or a slab edge with `lineRestraints`: they reach the generated nodes, which a point `Restraint` cannot name.
|
|
58
|
+
- **Model size.** Shell models have many more nodes than frames. Run the analysis in a Web Worker, and consider `diagrams: "extremes"` with `createFrameAnalysis(...).memberDiagram` to compute member diagrams on demand.
|
|
59
|
+
|
|
60
|
+
## [3.0.0] — 2026-10-31
|
|
61
|
+
|
|
62
|
+
**Shell element analysis.** `analyzeFrame` now analyses walls, cores, slabs and mats as shell elements alongside the frame: four-node flat shells with membrane and plate stiffness, meshed by the engine, with internal forces and stresses in every load case, combination and envelope. The major version marks this milestone; nothing is removed or renamed, and frame-only models give the same results as in 2.3.0, which only gain the new fields below (empty `shellForces` and `envelope.shells`, and the new `units` keys).
|
|
63
|
+
|
|
64
|
+
### Added
|
|
65
|
+
|
|
66
|
+
- **Shell areas** (`model.shells`): `ShellArea` (`{ id, nodeIds, type?, section, angle?, modifiers?, mesh? }`), a four-node flat shell with its own stiffness, sharing nodes with members and other shells. Null areas are unchanged; use shells where a surface's stiffness matters.
|
|
67
|
+
- The element is a drilling-rotation membrane (after Ibrahimbegovic, Taylor & Wilson), so a beam framing into a wall in its plane transfers its moment, plus a thin DKQ plate (Batoz & Ben Tahar). `type` `"membrane"` or `"plate"` keeps only one part; `"shell"` (the default) keeps both.
|
|
68
|
+
- Slightly warped quads are built on their mean plane and linked to their corners, up to `SHELL_WARPING_LIMIT` (0.1 × √A off the plane).
|
|
69
|
+
- Local axes follow ETABS: local 3 by the right-hand rule around `nodeIds`, local 2 up on walls, local 1 = +X on horizontal shells, rotated by `angle`.
|
|
70
|
+
- `ShellSection` (`thickness`, `E`, `nu`, `unitWeight?`) and `ShellModifiers` (`f11`, `f22`, `f12`, `m11`, `m22`, `m12`, `weight`) for cracked-section stiffness, e.g. the ACI 318-19 6.6.3.1.1 values entered by the user.
|
|
71
|
+
- **Engine meshing**: `ShellArea.mesh` (`ShellMesh`: `{ maxSize }` in mm, or `{ divisions: [n1, n2] }` as a minimum) divides an area into elements. Neighbouring areas share their mesh nodes, also where an area edge meets another at a node (a slab edge on two wall panels); division counts grow as needed, and an unmeshed area next to a meshed one is divided too. Model nodes lying on an area edge become mesh nodes. Generated elements are named `"<areaId>:<i>,<j>"`, generated nodes `"<areaId>:<i>,<j>"` inside an area or `"<a>~<b>:<k>"` on an edge; an area that stays one element keeps its id.
|
|
72
|
+
- **Members along meshed edges** (an edge beam under a slab, a beam on a wall top) are split at the mesh nodes inside them so they share them with the shells; their end forces, release deformations, diagrams, envelopes and design demands stay under the member's own id, the diagram stitched along its full length.
|
|
73
|
+
- **Line restraints** (`model.lineRestraints`, `LineRestraint`): `{ nodeIds: [a, b], ux?…rz? }` fixes those DOFs at every node on the segment from a to b, generated mesh nodes included, e.g. a wall base fixed along its length. A DOF fixed by a point or a line restraint is fixed.
|
|
74
|
+
- **Loads on shells**: an `AreaLoad` names a shell area by its id (area ids are shared by null areas and shells) and loads all its elements; self-weight acts as `selfWeight · unitWeight · thickness · modifiers.weight` per unit area. Both act as forces at the element corners.
|
|
75
|
+
- **Shell results**: every load case and combination has `shellForces` (`ShellElementForces[]`), per element with its `areaId`, the forces per unit width at its corners in its local axes: membrane forces `F11`, `F22`, `F12` (kN/m), moments `M11`, `M22`, `M12` (kN·m/m, positive with the −3 face in tension, i.e. sagging when local 3 is up, like a member's `M3`), transverse shears `V13`, `V23` (kN/m, `V13 = −(∂M11/∂x₁ + ∂M12/∂x₂)`), and top and bottom face stresses `S11Top` … `S12Bot` (MPa). They are extrapolated from the element's Gauss points, combine by superposition and are enveloped per corner in `envelope.shells`. The shears are recovered from the moments and are the coarsest output. Types `ShellCornerForces` and `ShellForceComponent`.
|
|
76
|
+
- `result.mesh` (`FrameMesh`): the generated nodes and every shell element with its nodes, for drawing; displacements and reactions include the generated nodes. `calculationDetails.shellCount`; `units.forcePerLength` (`"kN/m"`), `units.momentPerLength` (`"kN·m/m"`) and `units.stress` (`"MPa"`).
|
|
77
|
+
- Errors 326 (`INVALID_SHELL_GEOMETRY`), 327 (`INVALID_SHELL_SECTION`), 328 (`SHELL_DOF_UNSUPPORTED`: a translation that nothing resists at a node connected only to membrane or plate shells, with `nodeId`, `shellId` and `dof`) and 329 (`INVALID_SHELL_MESH`: areas that cannot be meshed), and `FrameErrorDetails.shellId`. A warning (**Shell area meshing**) for a member node inside a shell area but not on its mesh, which leaves it unconnected.
|
|
78
|
+
- Types `ShellArea`, `ShellSection`, `ShellModifiers`, `ShellType`, `ShellMesh`, `LineRestraint`, `ShellElementForces`, `ShellCornerForces`, `ShellForceComponent` and `FrameMesh` from `/fea` and the package root; `SHELL_WARPING_LIMIT` from `/core` and the root.
|
|
79
|
+
- Shell element theory notes in the documentation (`shell-element.html`): how the element's stiffness is formed, the integration choices, and the benchmarks it is checked against (patch tests, MacNeal–Harder cantilevers and twisted beam, Timoshenko plates, Scordelis–Lo roof, pinched cylinder).
|
|
80
|
+
|
|
81
|
+
### Changed
|
|
82
|
+
|
|
83
|
+
- `calculationDetails.nodeCount` counts the generated mesh nodes too, and `memberCount` counts model members (not the pieces a meshed edge splits them into).
|
|
84
|
+
- Error 303 also covers an area id used by both a null area and a shell, and 313 also covers a shell section without `unitWeight`; their messages say so.
|
|
85
|
+
|
|
9
86
|
## [2.3.0] — 2026-10-24
|
|
10
87
|
|
|
11
88
|
### Added
|
|
@@ -137,7 +214,9 @@ Maintenance release with no changes to the library code.
|
|
|
137
214
|
|
|
138
215
|
First version, under the unscoped name `ts-structural-eng-tools`: `rectBeamMomentCapacity` (singly and doubly reinforced rectangular beams per ACI 318-19), steel plate jacketing, and concrete property helpers.
|
|
139
216
|
|
|
140
|
-
[Unreleased]: https://github.com/theerapat-s28/ts-structural-eng/compare/
|
|
217
|
+
[Unreleased]: https://github.com/theerapat-s28/ts-structural-eng/compare/v3.1.0...HEAD
|
|
218
|
+
[3.1.0]: https://github.com/theerapat-s28/ts-structural-eng/compare/v3.0.0...v3.1.0
|
|
219
|
+
[3.0.0]: https://github.com/theerapat-s28/ts-structural-eng/compare/v2.3.0...v3.0.0
|
|
141
220
|
[2.3.0]: https://github.com/theerapat-s28/ts-structural-eng/compare/v2.2.0...v2.3.0
|
|
142
221
|
[2.2.0]: https://github.com/theerapat-s28/ts-structural-eng/compare/v2.1.1...v2.2.0
|
|
143
222
|
[2.1.1]: https://github.com/theerapat-s28/ts-structural-eng/compare/v2.1.0...v2.1.1
|
package/README.md
CHANGED
|
@@ -30,6 +30,7 @@ Full API reference, with parameter tables, worked examples, warnings and error c
|
|
|
30
30
|
- [RC Beam Design](https://theerapat-s28.github.io/ts-structural-eng/rc/) — `@theerapat-s28/ts-structural-eng-tools/rc`
|
|
31
31
|
- [Strengthening](https://theerapat-s28.github.io/ts-structural-eng/strengthening/) — `@theerapat-s28/ts-structural-eng-tools/strengthening`
|
|
32
32
|
- [FEA — Frame Analysis](https://theerapat-s28.github.io/ts-structural-eng/fea/) — `@theerapat-s28/ts-structural-eng-tools/fea`
|
|
33
|
+
- [Shell element theory notes](https://theerapat-s28.github.io/ts-structural-eng/shell-element.html) — how the shell element's stiffness is formed, with its benchmarks
|
|
33
34
|
|
|
34
35
|
The pages are served from [`html-docs/`](https://github.com/theerapat-s28/ts-structural-eng/tree/main/html-docs) via GitHub Pages.
|
|
35
36
|
|
|
@@ -142,15 +143,35 @@ src/
|
|
|
142
143
|
│ └── rc-beam-side-plate-shear.ts # Shear capacity before/after bolted side plates (two models)
|
|
143
144
|
├── fea/ # Finite-element analysis
|
|
144
145
|
│ ├── index.ts
|
|
145
|
-
│
|
|
146
|
+
│ ├── shared/ # The base every part builds on
|
|
147
|
+
│ │ ├── index.ts
|
|
148
|
+
│ │ ├── types/ # Nodes, restraints, area loads
|
|
149
|
+
│ │ ├── solver/ # Generic element assembly, boundary conditions, automatic restraint
|
|
150
|
+
│ │ └── validation/ # Issue helpers shared by the model checks
|
|
151
|
+
│ ├── frame/ # Frame members (3D beam element) and null areas
|
|
152
|
+
│ │ ├── index.ts
|
|
153
|
+
│ │ ├── area/ # Null areas: geometry, edge-member chains, area-load distribution
|
|
154
|
+
│ │ ├── elements/ # Reference beam stiffness matrix, fixed-end forces, end releases and partial-fixity condensation
|
|
155
|
+
│ │ ├── transformation/ # ETABS-style local axes and the 12×12 transformation
|
|
156
|
+
│ │ ├── solver/ # Member pieces, member-load resolution, member assembly helpers
|
|
157
|
+
│ │ ├── validation/ # Checks on members, member loads and null areas
|
|
158
|
+
│ │ ├── post/ # Member force diagrams
|
|
159
|
+
│ │ └── types/ # Member, member-load and null-area types; member result types
|
|
160
|
+
│ ├── shell/ # Flat shell element (drilling membrane + DKQ plate)
|
|
161
|
+
│ │ ├── index.ts
|
|
162
|
+
│ │ ├── elements/ # Membrane, DKQ plate, flat shell, local axes, warping links, quad geometry
|
|
163
|
+
│ │ ├── mesh/ # Shell-area meshing
|
|
164
|
+
│ │ ├── solver/ # Shell elements of the system and their surface-load vectors
|
|
165
|
+
│ │ ├── post/ # Shell forces and stresses
|
|
166
|
+
│ │ ├── validation/ # Checks on shell areas
|
|
167
|
+
│ │ └── types/ # Shell-area model and result types
|
|
168
|
+
│ └── analysis/ # The whole model, members and shells together (direct stiffness method)
|
|
146
169
|
│ ├── index.ts
|
|
147
|
-
│ ├──
|
|
148
|
-
│ ├──
|
|
149
|
-
│ ├── transformation/ # ETABS-style local axes and the 12×12 transformation
|
|
150
|
-
│ ├── solver/ # System build (with automatic joint restraint) + skyline factorisation, per-case solve, combinations, analyzeFrame
|
|
170
|
+
│ ├── mesh/ # The analysed model: shell mesh, line restraints, member splitting at mesh nodes
|
|
171
|
+
│ ├── solver/ # System build + skyline factorisation, per-case solve, combinations, analyzeFrame, distributeAreaLoads
|
|
151
172
|
│ ├── validation/ # validateFrameModel: every input problem, with its location
|
|
152
|
-
│ ├── post/ # Result presentation,
|
|
153
|
-
│ └── types/ #
|
|
173
|
+
│ ├── post/ # Result presentation, envelopes, design demands
|
|
174
|
+
│ └── types/ # FrameModel (load cases, combinations, nodal loads, line restraints) and FrameResult
|
|
154
175
|
├── core/ # Shared infrastructure
|
|
155
176
|
│ ├── index.ts
|
|
156
177
|
│ ├── constants/ # RC design constants (ACI 318) and frame-analysis tolerances
|
|
@@ -167,7 +188,10 @@ examples/
|
|
|
167
188
|
tests/
|
|
168
189
|
├── rc/ # Tests for RC module
|
|
169
190
|
├── strengthening/ # Tests for strengthening module
|
|
170
|
-
├── fea/frame/ # Tests for
|
|
191
|
+
├── fea/frame/ # Tests for members and null areas
|
|
192
|
+
├── fea/shell/ # Tests for shell elements, meshing and shell results
|
|
193
|
+
├── fea/shared/ # Tests for element assembly and automatic restraint
|
|
194
|
+
├── fea/analysis/ # Tests for analyzeFrame, combinations, validation, errors and RC integration
|
|
171
195
|
└── utils/ # Tests for utilities
|
|
172
196
|
html-docs/ # HTML API reference, deployed to GitHub Pages
|
|
173
197
|
├── DESIGN.md # Style guide for the doc pages
|
|
@@ -230,10 +254,10 @@ ACI 440.2R-17 11.4.2 (spacing, which defers to the ACI 318 limits) and 11.4.3 (`
|
|
|
230
254
|
|
|
231
255
|
Linear-elastic 3D frame analysis by the direct stiffness method, imported from `@theerapat-s28/ts-structural-eng-tools/fea`. Global axes X, Y, Z (Z up) and ETABS-style local axes 1, 2, 3; inputs in mm, MPa, kN and kN·m, results in kN, kN·m, mm and rad.
|
|
232
256
|
|
|
233
|
-
- **`analyzeFrame(model, options?)`** — Analyses every load case in `model.loadCases` (dead, superimposed dead, live, wind…, each with an optional `selfWeight` multiplier) and forms every combination in `model.combinations` by superposition. The loads are flat top-level lists, `model.nodalLoads` and `model.memberLoads` (uniform, trapezoidal and point loads in local or global directions, and torques about the member axis; uniform and trapezoidal loads in a global direction can be given per unit projected length with `projected: true`, e.g. snow on a sloped rafter), each load tagged with its `loadCase`, so large models stay readable. Area loads (`model.areaLoads`, kN/m²) on null areas (`model.areas`) are first distributed to the members along each area's edges — see `distributeAreaLoads`. A combination is a list of factored terms `{ case, factor }` or `{ combination, factor }`; factors are entered by the user, and nested combinations are expanded. Supports end releases — full (`true`) or partial fixity (a spring stiffness in series with the member end) on any of the six end DOFs, with the deformation across each release reported in `releaseDeformations` — and fixed or spring supports. Joint rotations that no member resists, as at pin-jointed truss joints, are held automatically and listed in `calculationDetails.autoRestrainedDofs`. The stiffness matrix is factorised once for all cases. Returns `cases` and `combinations` keyed by id — each with displacements, reactions, member end forces, member diagrams along each member (forces `N`, `V2`, `V3`, `T`, `M2`, `M3` and deflections `u1`–`u3` local / `ux`–`uz` global, ready for plotting) and an equilibrium check — and an `envelope` of max/min over the combinations with the governing combination. Combination diagrams are rebuilt exactly, not summed from case extremes. The stiffness is stored in skyline (banded) form with nodes in reverse Cuthill–McKee order, so a building of ~850 nodes runs in about 1.5 s. Model and result are plain JSON, so it runs in a Web Worker. Invalid models, load cases or combinations and mechanisms throw `FrameAnalysisError` (codes 301–317) with `details` locating the problem.
|
|
257
|
+
- **`analyzeFrame(model, options?)`** — Analyses every load case in `model.loadCases` (dead, superimposed dead, live, wind…, each with an optional `selfWeight` multiplier) and forms every combination in `model.combinations` by superposition. The loads are flat top-level lists, `model.nodalLoads` and `model.memberLoads` (uniform, trapezoidal and point loads in local or global directions, and torques about the member axis; uniform and trapezoidal loads in a global direction can be given per unit projected length with `projected: true`, e.g. snow on a sloped rafter), each load tagged with its `loadCase`, so large models stay readable. Area loads (`model.areaLoads`, kN/m²) on null areas (`model.areas`) are first distributed to the members along each area's edges — see `distributeAreaLoads`. Shell areas (`model.shells`, `{ id, nodeIds, type?, section: { thickness, E, nu, unitWeight? }, angle?, modifiers? }`) are four-node flat shell elements with their own stiffness — a drilling-rotation membrane and a thin (DKQ) plate, as `"shell"`, `"membrane"` or `"plate"` — for walls, cores and slabs; they share nodes with members, take `areaLoads` naming their id and self-weight as corner forces, and accept cracked-section modifiers (`f11`…`m12`). Give an area `mesh: { maxSize }` (or `{ divisions }`) and the engine meshes it: neighbouring areas, including T-junctions, share their mesh nodes, model nodes on an area edge become mesh nodes, and members along meshed edges are split internally while their results stay under their own id; `model.lineRestraints` (`{ nodeIds: [a, b], ux?…rz? }`) fix every node on a line, generated nodes included, and `result.mesh` lists the generated nodes and elements. A translation that nothing resists at a node connected only to membranes or plates throws 328, an area that cannot be meshed 329. Each case and combination reports `shellForces` — per shell and corner, membrane forces `F11`, `F22`, `F12` (kN/m), moments `M11`, `M22`, `M12` (kN·m/m, sagging positive), shears `V13`, `V23` and top/bottom stresses — and the envelope has them per corner. A combination is a list of factored terms `{ case, factor }` or `{ combination, factor }`; factors are entered by the user, and nested combinations are expanded. Supports end releases — full (`true`) or partial fixity (a spring stiffness in series with the member end) on any of the six end DOFs, with the deformation across each release reported in `releaseDeformations` — and fixed or spring supports. Joint rotations that no member resists, as at pin-jointed truss joints, are held automatically and listed in `calculationDetails.autoRestrainedDofs`. The stiffness matrix is factorised once for all cases. Returns `cases` and `combinations` keyed by id — each with displacements, reactions, member end forces, member diagrams along each member (forces `N`, `V2`, `V3`, `T`, `M2`, `M3` and deflections `u1`–`u3` local / `ux`–`uz` global, ready for plotting) and an equilibrium check — and an `envelope` of max/min over the combinations with the governing combination. Combination diagrams are rebuilt exactly, not summed from case extremes. The stiffness is stored in skyline (banded) form with nodes in reverse Cuthill–McKee order, so a building of ~850 nodes runs in about 1.5 s. Model and result are plain JSON, so it runs in a Web Worker. Invalid models, load cases or combinations and mechanisms throw `FrameAnalysisError` (codes 301–317 and 326–329) with `details` locating the problem.
|
|
234
258
|
- **`createFrameAnalysis(model, options?)`** — Same analysis, keeping the solution: returns `{ result, memberDiagram(resultId, memberId) }` so full member diagrams can be computed on demand. Combine with `options.diagrams: "extremes"`, which keeps diagram extremes (and the envelope) but drops the station arrays, for results about 4× smaller on large models.
|
|
235
|
-
- **`validateFrameModel(model)`** — Checks a model without analysing it and returns every problem, each with `details` (`nodeId`, `memberId`, `areaId`, `edge`, `loadCaseId`, `combinationId`, `field`, `dof`) for highlighting in a UI. `analyzeFrame` runs it first and throws the first problem as a `FrameAnalysisError` whose `issues` lists all of them; non-finite numbers, negative springs, invalid end-release values and unknown option values are rejected (314).
|
|
236
|
-
- **`distributeAreaLoads(model)`** — Returns `{ memberLoads, warnings }`: the member loads that the model's null areas send to their edge members, exactly what `analyzeFrame` adds, for checking or previewing. A null area (`{ id, nodeIds, distribution, supportEdges? }`) has 3 or 4 nodes forming a planar convex polygon and adds no stiffness. `"twoWay"` sends each point to its nearest edge (the corner-bisector split, any convex shape); `"oneWay"` spans strips between the listed `supportEdges`, parallel to the unsupported edges, half to each end; `"cantilever"` (rectangles) puts `q·c` and a torque `q·c²/2` on its one support edge. Area loads (`{ loadCase, areaId, direction: "3" | "X" | "Y" | "Z", q, projected? }`) are per unit true area, `"3"` being the area's normal; with `projected: true` and a global direction, `q` is per unit projected area (e.g. per plan area on a ramp) and is converted to true area before distribution. Edges split by intermediate nodes are cut at them. Area problems throw 315 (geometry), 316 (an edge without members) or 317 (supports that do not fit the distribution).
|
|
259
|
+
- **`validateFrameModel(model)`** — Checks a model without analysing it and returns every problem, each with `details` (`nodeId`, `memberId`, `areaId`, `shellId`, `edge`, `loadCaseId`, `combinationId`, `field`, `dof`) for highlighting in a UI. `analyzeFrame` runs it first and throws the first problem as a `FrameAnalysisError` whose `issues` lists all of them; non-finite numbers, negative springs, invalid end-release values and unknown option values are rejected (314).
|
|
260
|
+
- **`distributeAreaLoads(model)`** — Returns `{ memberLoads, warnings }`: the member loads that the model's null areas send to their edge members, exactly what `analyzeFrame` adds, for checking or previewing (loads on shell areas act on the shells and are not included). A null area (`{ id, nodeIds, distribution, supportEdges? }`) has 3 or 4 nodes forming a planar convex polygon and adds no stiffness. `"twoWay"` sends each point to its nearest edge (the corner-bisector split, any convex shape); `"oneWay"` spans strips between the listed `supportEdges`, parallel to the unsupported edges, half to each end; `"cantilever"` (rectangles) puts `q·c` and a torque `q·c²/2` on its one support edge. Area loads (`{ loadCase, areaId, direction: "3" | "X" | "Y" | "Z", q, projected? }`) are per unit true area, `"3"` being the area's normal; with `projected: true` and a global direction, `q` is per unit projected area (e.g. per plan area on a ramp) and is converted to true area before distribution. Edges split by intermediate nodes are cut at them. Area problems throw 315 (geometry), 316 (an edge without members) or 317 (supports that do not fit the distribution).
|
|
237
261
|
- **`memberDemandEnvelope(result, memberId, options?)`** — Reduces a member's diagrams to `MuPositive`, `MuNegative`, `Vu` (optionally at distance `d` from the supports) and `Nu`, enveloped over all combinations (or the `combinations` / `cases` you select), with the `governing` combination of each, for the RC capacity functions.
|
|
238
262
|
- **`rectBeamToSectionProperties(section, options?)`** (from `rc`) — Converts a rectangular RC section into `SectionProperties` (`E`, `G`, `A`, `I22`, `I33`, `J`, `unitWeight`) with the ACI 318-19 6.6.3.1.1 inertia modifiers (0.35 beams, 0.70 columns) and a unit weight for self-weight (default 24 kN/m³, common practice rather than an ACI value).
|
|
239
263
|
- **`beam3dLocalStiffness(E, G, A, I22, I33, J, L)`** — The 12×12 local stiffness matrix exactly as in the reference "Complete Beam Stiffness Matrix". Its bending rotations R2 and R3 follow the opposite sign to the right-hand rule; **`beam3dLocalStiffnessRightHanded`** returns the right-handed form that `analyzeFrame` uses.
|
|
@@ -17,3 +17,18 @@ export declare const EQUILIBRIUM_TOLERANCE = 0.000001;
|
|
|
17
17
|
* edges, nodes lying on an edge): distances are compared with this times the longest edge.
|
|
18
18
|
*/
|
|
19
19
|
export declare const AREA_GEOMETRY_TOLERANCE = 0.000001;
|
|
20
|
+
/**
|
|
21
|
+
* Penalty factor γ of the shell membrane's drilling rotation, as a multiple of the shear modulus
|
|
22
|
+
* G: the term ½·γ·t·∫(θ − ω)² dA, integrated at the element centre, ties each element's rotation
|
|
23
|
+
* about the shell normal θ to the in-plane rotation of the material ω = ½(v,x − u,y). γ = G
|
|
24
|
+
* follows Ibrahimbegovic, Taylor & Wilson (1990); with the one-point rule the results change by
|
|
25
|
+
* well under 1 % for γ between 0.01 G and 100 G.
|
|
26
|
+
*/
|
|
27
|
+
export declare const DRILLING_PENALTY_RATIO = 1;
|
|
28
|
+
/**
|
|
29
|
+
* Largest warping of a shell element accepted, as the distance of its corners from their mean
|
|
30
|
+
* plane relative to √A (A = projected area). Warped elements are built flat on the mean plane
|
|
31
|
+
* and linked rigidly to their corners, which is accurate for mild warping (the MacNeal–Harder
|
|
32
|
+
* twisted beam, 0.024, is within 0.5 %); beyond this the element is rejected (326).
|
|
33
|
+
*/
|
|
34
|
+
export declare const SHELL_WARPING_LIMIT = 0.1;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.AREA_GEOMETRY_TOLERANCE = exports.EQUILIBRIUM_TOLERANCE = exports.SINGULARITY_TOLERANCE = exports.VERTICAL_MEMBER_TOLERANCE = exports.CONCRETE_UNIT_WEIGHT = exports.COLUMN_INERTIA_MODIFIER = exports.BEAM_INERTIA_MODIFIER = exports.CONCRETE_POISSON_RATIO = void 0;
|
|
3
|
+
exports.SHELL_WARPING_LIMIT = exports.DRILLING_PENALTY_RATIO = exports.AREA_GEOMETRY_TOLERANCE = exports.EQUILIBRIUM_TOLERANCE = exports.SINGULARITY_TOLERANCE = exports.VERTICAL_MEMBER_TOLERANCE = exports.CONCRETE_UNIT_WEIGHT = exports.COLUMN_INERTIA_MODIFIER = exports.BEAM_INERTIA_MODIFIER = exports.CONCRETE_POISSON_RATIO = void 0;
|
|
4
4
|
/** Poisson's ratio of concrete, for G = E / (2(1 + ν)). */
|
|
5
5
|
exports.CONCRETE_POISSON_RATIO = 0.2;
|
|
6
6
|
/** ACI 318-19 Table 6.6.3.1.1(a): effective I of beams for elastic analysis at factored load. */
|
|
@@ -20,4 +20,19 @@ exports.EQUILIBRIUM_TOLERANCE = 1e-6;
|
|
|
20
20
|
* edges, nodes lying on an edge): distances are compared with this times the longest edge.
|
|
21
21
|
*/
|
|
22
22
|
exports.AREA_GEOMETRY_TOLERANCE = 1e-6;
|
|
23
|
+
/**
|
|
24
|
+
* Penalty factor γ of the shell membrane's drilling rotation, as a multiple of the shear modulus
|
|
25
|
+
* G: the term ½·γ·t·∫(θ − ω)² dA, integrated at the element centre, ties each element's rotation
|
|
26
|
+
* about the shell normal θ to the in-plane rotation of the material ω = ½(v,x − u,y). γ = G
|
|
27
|
+
* follows Ibrahimbegovic, Taylor & Wilson (1990); with the one-point rule the results change by
|
|
28
|
+
* well under 1 % for γ between 0.01 G and 100 G.
|
|
29
|
+
*/
|
|
30
|
+
exports.DRILLING_PENALTY_RATIO = 1;
|
|
31
|
+
/**
|
|
32
|
+
* Largest warping of a shell element accepted, as the distance of its corners from their mean
|
|
33
|
+
* plane relative to √A (A = projected area). Warped elements are built flat on the mean plane
|
|
34
|
+
* and linked rigidly to their corners, which is accurate for mild warping (the MacNeal–Harder
|
|
35
|
+
* twisted beam, 0.024, is within 0.5 %); beyond this the element is rejected (326).
|
|
36
|
+
*/
|
|
37
|
+
exports.SHELL_WARPING_LIMIT = 0.1;
|
|
23
38
|
//# sourceMappingURL=frame.constant.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"frame.constant.js","sourceRoot":"","sources":["../../../src/core/constants/frame.constant.ts"],"names":[],"mappings":";;;AAAA,2DAA2D;AAC9C,QAAA,sBAAsB,GAAG,GAAG,CAAC;AAE1C,iGAAiG;AACpF,QAAA,qBAAqB,GAAG,IAAI,CAAC;AAE1C,mGAAmG;AACtF,QAAA,uBAAuB,GAAG,GAAG,CAAC;AAE3C,qGAAqG;AACxF,QAAA,oBAAoB,GAAG,EAAE,CAAC;AAEvC,gGAAgG;AACnF,QAAA,yBAAyB,GAAG,IAAI,CAAC;AAE9C,uGAAuG;AAC1F,QAAA,qBAAqB,GAAG,IAAI,CAAC;AAE1C,2EAA2E;AAC9D,QAAA,qBAAqB,GAAG,IAAI,CAAC;AAE1C;;;GAGG;AACU,QAAA,uBAAuB,GAAG,IAAI,CAAC"}
|
|
1
|
+
{"version":3,"file":"frame.constant.js","sourceRoot":"","sources":["../../../src/core/constants/frame.constant.ts"],"names":[],"mappings":";;;AAAA,2DAA2D;AAC9C,QAAA,sBAAsB,GAAG,GAAG,CAAC;AAE1C,iGAAiG;AACpF,QAAA,qBAAqB,GAAG,IAAI,CAAC;AAE1C,mGAAmG;AACtF,QAAA,uBAAuB,GAAG,GAAG,CAAC;AAE3C,qGAAqG;AACxF,QAAA,oBAAoB,GAAG,EAAE,CAAC;AAEvC,gGAAgG;AACnF,QAAA,yBAAyB,GAAG,IAAI,CAAC;AAE9C,uGAAuG;AAC1F,QAAA,qBAAqB,GAAG,IAAI,CAAC;AAE1C,2EAA2E;AAC9D,QAAA,qBAAqB,GAAG,IAAI,CAAC;AAE1C;;;GAGG;AACU,QAAA,uBAAuB,GAAG,IAAI,CAAC;AAE5C;;;;;;GAMG;AACU,QAAA,sBAAsB,GAAG,CAAC,CAAC;AAExC;;;;;GAKG;AACU,QAAA,mBAAmB,GAAG,GAAG,CAAC"}
|
|
@@ -5,6 +5,7 @@ export interface FrameErrorDetails {
|
|
|
5
5
|
nodeId?: string | number;
|
|
6
6
|
memberId?: string | number;
|
|
7
7
|
areaId?: string | number;
|
|
8
|
+
shellId?: string | number;
|
|
8
9
|
/** For an area: the edge index, edge i running from `nodeIds[i]` to `nodeIds[i + 1]`. */
|
|
9
10
|
edge?: number;
|
|
10
11
|
loadCaseId?: string;
|
|
@@ -24,7 +24,7 @@ exports.FrameErrors = {
|
|
|
24
24
|
},
|
|
25
25
|
DUPLICATE_ID: {
|
|
26
26
|
code: 303,
|
|
27
|
-
message: "Node ids, member ids
|
|
27
|
+
message: "Node ids, member ids and restrained node ids must each be unique, area ids must be unique across null areas and shells, and load case and combination ids must be unique across both lists.",
|
|
28
28
|
},
|
|
29
29
|
STRUCTURE_UNSTABLE: {
|
|
30
30
|
code: 304,
|
|
@@ -64,7 +64,7 @@ exports.FrameErrors = {
|
|
|
64
64
|
},
|
|
65
65
|
MISSING_UNIT_WEIGHT: {
|
|
66
66
|
code: 313,
|
|
67
|
-
message: "A load case requests self-weight but a member section has no unitWeight; set unitWeight (0 for a weightless member).",
|
|
67
|
+
message: "A load case requests self-weight but a member or shell section has no unitWeight; set unitWeight (0 for a weightless member or shell).",
|
|
68
68
|
},
|
|
69
69
|
INVALID_INPUT_VALUE: {
|
|
70
70
|
code: 314,
|
|
@@ -82,5 +82,21 @@ exports.FrameErrors = {
|
|
|
82
82
|
code: 317,
|
|
83
83
|
message: "An area's supportEdges do not fit its distribution: two-way takes none; one-way needs at least one edge left unsupported, with every unsupported edge parallel to the others (the span direction); cantilever needs exactly one, and its loads may not act along that edge.",
|
|
84
84
|
},
|
|
85
|
+
INVALID_SHELL_GEOMETRY: {
|
|
86
|
+
code: 326,
|
|
87
|
+
message: "A shell area must have 4 distinct nodes, listed in order around it, forming a convex quadrilateral that is close to flat (each corner within 0.1·√A of the mean plane).",
|
|
88
|
+
},
|
|
89
|
+
INVALID_SHELL_SECTION: {
|
|
90
|
+
code: 327,
|
|
91
|
+
message: "A shell section's thickness and E must be positive, nu must be at least 0 and below 0.5, and unitWeight, when given, must not be negative.",
|
|
92
|
+
},
|
|
93
|
+
SHELL_DOF_UNSUPPORTED: {
|
|
94
|
+
code: 328,
|
|
95
|
+
message: 'A node connected only to shells has a translation that nothing resists: a membrane carries no load out of its plane and a plate none in its plane. Restrain that DOF, connect a member, or use type "shell".',
|
|
96
|
+
},
|
|
97
|
+
INVALID_SHELL_MESH: {
|
|
98
|
+
code: 329,
|
|
99
|
+
message: "Shell areas cannot be meshed: no division counts make the meshes of areas sharing edges meet node to node, a generated element is not a valid quadrilateral, or a generated id is already in use. Divide the areas so they meet edge to edge, or change their mesh sizes.",
|
|
100
|
+
},
|
|
85
101
|
};
|
|
86
102
|
//# sourceMappingURL=frame-analysis.error.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"frame-analysis.error.js","sourceRoot":"","sources":["../../../src/core/errors/frame-analysis.error.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"frame-analysis.error.js","sourceRoot":"","sources":["../../../src/core/errors/frame-analysis.error.ts"],"names":[],"mappings":";;;AAkBA,MAAa,kBAAmB,SAAQ,KAAK;IAO3C,YACE,MAA8B,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,eAAe,EAAE,EACnE,UAA6B,EAAE,EAC/B,MAA0B;QAE1B,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACnB,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;QACrB,IAAI,CAAC,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC;QAC3B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,MAAM,GAAG,MAAM,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;QAC5E,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,kBAAkB,CAAC,SAAS,CAAC,CAAC;IAC5D,CAAC;CACF;AAnBD,gDAmBC;AAcY,QAAA,WAAW,GAA2C;IACjE,8BAA8B;IAC9B,kBAAkB,EAAE;QAClB,IAAI,EAAE,GAAG;QACT,OAAO,EAAE,sEAAsE;KAChF;IACD,sBAAsB,EAAE;QACtB,IAAI,EAAE,GAAG;QACT,OAAO,EACL,iGAAiG;KACpG;IACD,YAAY,EAAE;QACZ,IAAI,EAAE,GAAG;QACT,OAAO,EACL,6LAA6L;KAChM;IACD,kBAAkB,EAAE;QAClB,IAAI,EAAE,GAAG;QACT,OAAO,EACL,mHAAmH;KACtH;IACD,0BAA0B,EAAE;QAC1B,IAAI,EAAE,GAAG;QACT,OAAO,EACL,2HAA2H;KAC9H;IACD,aAAa,EAAE;QACb,IAAI,EAAE,GAAG;QACT,OAAO,EAAE,iDAAiD;KAC3D;IACD,eAAe,EAAE;QACf,IAAI,EAAE,GAAG;QACT,OAAO,EACL,yFAAyF;KAC5F;IACD,mBAAmB,EAAE;QACnB,IAAI,EAAE,GAAG;QACT,OAAO,EAAE,4EAA4E;KACtF;IACD,iBAAiB,EAAE;QACjB,IAAI,EAAE,GAAG;QACT,OAAO,EACL,2HAA2H;KAC9H;IACD,oBAAoB,EAAE;QACpB,IAAI,EAAE,GAAG;QACT,OAAO,EAAE,mDAAmD;KAC7D;IACD,mBAAmB,EAAE;QACnB,IAAI,EAAE,GAAG;QACT,OAAO,EACL,4GAA4G;KAC/G;IACD,aAAa,EAAE;QACb,IAAI,EAAE,GAAG;QACT,OAAO,EAAE,gEAAgE;KAC1E;IACD,mBAAmB,EAAE;QACnB,IAAI,EAAE,GAAG;QACT,OAAO,EACL,wIAAwI;KAC3I;IACD,mBAAmB,EAAE;QACnB,IAAI,EAAE,GAAG;QACT,OAAO,EACL,8JAA8J;KACjK;IACD,qBAAqB,EAAE;QACrB,IAAI,EAAE,GAAG;QACT,OAAO,EACL,gJAAgJ;KACnJ;IACD,qBAAqB,EAAE;QACrB,IAAI,EAAE,GAAG;QACT,OAAO,EACL,gIAAgI;KACnI;IACD,yBAAyB,EAAE;QACzB,IAAI,EAAE,GAAG;QACT,OAAO,EACL,6QAA6Q;KAChR;IACD,sBAAsB,EAAE;QACtB,IAAI,EAAE,GAAG;QACT,OAAO,EACL,yKAAyK;KAC5K;IACD,qBAAqB,EAAE;QACrB,IAAI,EAAE,GAAG;QACT,OAAO,EACL,4IAA4I;KAC/I;IACD,qBAAqB,EAAE;QACrB,IAAI,EAAE,GAAG;QACT,OAAO,EACL,8MAA8M;KACjN;IACD,kBAAkB,EAAE;QAClB,IAAI,EAAE,GAAG;QACT,OAAO,EACL,2QAA2Q;KAC9Q;CACF,CAAC"}
|
package/dist/core/index.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ export type { SectionProperties } from "./types/section-properties.type";
|
|
|
6
6
|
export type { Warnings, calculationResult } from "./types/output-message.type";
|
|
7
7
|
export type { unit } from "./types/unit.type";
|
|
8
8
|
export { FLEXURAL_STRENGTH_REDUCTION_FACTOR, CONCRETE_ULTIMATE_STRAIN, SHEAR_STRENGTH_REDUCTION_FACTOR, ANCHOR_SHEAR_STRENGTH_REDUCTION_FACTOR, MAX_PLATE_BOLT_SPACING, PLATE_SHEAR_YIELD_COEFFICIENT, SIDE_PLATE_EFFECTIVE_STRAIN_LIMIT, SIDE_PLATE_REDUCTION_FACTOR_PSI, } from "./constants/rc.constant";
|
|
9
|
-
export { CONCRETE_POISSON_RATIO, CONCRETE_UNIT_WEIGHT, BEAM_INERTIA_MODIFIER, COLUMN_INERTIA_MODIFIER, VERTICAL_MEMBER_TOLERANCE, SINGULARITY_TOLERANCE, EQUILIBRIUM_TOLERANCE, AREA_GEOMETRY_TOLERANCE, } from "./constants/frame.constant";
|
|
9
|
+
export { CONCRETE_POISSON_RATIO, CONCRETE_UNIT_WEIGHT, BEAM_INERTIA_MODIFIER, COLUMN_INERTIA_MODIFIER, VERTICAL_MEMBER_TOLERANCE, SINGULARITY_TOLERANCE, EQUILIBRIUM_TOLERANCE, AREA_GEOMETRY_TOLERANCE, SHELL_WARPING_LIMIT, } from "./constants/frame.constant";
|
|
10
10
|
export { RCDesignError, Errors } from "./errors/rc-design.error";
|
|
11
11
|
export { FrameAnalysisError, FrameErrors } from "./errors/frame-analysis.error";
|
|
12
12
|
export type { FrameErrorDetails, FrameModelIssue } from "./errors/frame-analysis.error";
|
package/dist/core/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.FrameErrors = exports.FrameAnalysisError = exports.Errors = exports.RCDesignError = exports.AREA_GEOMETRY_TOLERANCE = exports.EQUILIBRIUM_TOLERANCE = exports.SINGULARITY_TOLERANCE = exports.VERTICAL_MEMBER_TOLERANCE = exports.COLUMN_INERTIA_MODIFIER = exports.BEAM_INERTIA_MODIFIER = exports.CONCRETE_UNIT_WEIGHT = exports.CONCRETE_POISSON_RATIO = exports.SIDE_PLATE_REDUCTION_FACTOR_PSI = exports.SIDE_PLATE_EFFECTIVE_STRAIN_LIMIT = exports.PLATE_SHEAR_YIELD_COEFFICIENT = exports.MAX_PLATE_BOLT_SPACING = exports.ANCHOR_SHEAR_STRENGTH_REDUCTION_FACTOR = exports.SHEAR_STRENGTH_REDUCTION_FACTOR = exports.CONCRETE_ULTIMATE_STRAIN = exports.FLEXURAL_STRENGTH_REDUCTION_FACTOR = exports.hasSidePlate = exports.hasBottomPlate = exports.hasTopPlate = exports.isSinglyReinforced = void 0;
|
|
3
|
+
exports.FrameErrors = exports.FrameAnalysisError = exports.Errors = exports.RCDesignError = exports.SHELL_WARPING_LIMIT = exports.AREA_GEOMETRY_TOLERANCE = exports.EQUILIBRIUM_TOLERANCE = exports.SINGULARITY_TOLERANCE = exports.VERTICAL_MEMBER_TOLERANCE = exports.COLUMN_INERTIA_MODIFIER = exports.BEAM_INERTIA_MODIFIER = exports.CONCRETE_UNIT_WEIGHT = exports.CONCRETE_POISSON_RATIO = exports.SIDE_PLATE_REDUCTION_FACTOR_PSI = exports.SIDE_PLATE_EFFECTIVE_STRAIN_LIMIT = exports.PLATE_SHEAR_YIELD_COEFFICIENT = exports.MAX_PLATE_BOLT_SPACING = exports.ANCHOR_SHEAR_STRENGTH_REDUCTION_FACTOR = exports.SHEAR_STRENGTH_REDUCTION_FACTOR = exports.CONCRETE_ULTIMATE_STRAIN = exports.FLEXURAL_STRENGTH_REDUCTION_FACTOR = exports.hasSidePlate = exports.hasBottomPlate = exports.hasTopPlate = exports.isSinglyReinforced = void 0;
|
|
4
4
|
var rc_beam_type_1 = require("./types/rc-beam.type");
|
|
5
5
|
Object.defineProperty(exports, "isSinglyReinforced", { enumerable: true, get: function () { return rc_beam_type_1.isSinglyReinforced; } });
|
|
6
6
|
var plate_jacketing_type_1 = require("./types/plate-jacketing.type");
|
|
@@ -26,6 +26,7 @@ Object.defineProperty(exports, "VERTICAL_MEMBER_TOLERANCE", { enumerable: true,
|
|
|
26
26
|
Object.defineProperty(exports, "SINGULARITY_TOLERANCE", { enumerable: true, get: function () { return frame_constant_1.SINGULARITY_TOLERANCE; } });
|
|
27
27
|
Object.defineProperty(exports, "EQUILIBRIUM_TOLERANCE", { enumerable: true, get: function () { return frame_constant_1.EQUILIBRIUM_TOLERANCE; } });
|
|
28
28
|
Object.defineProperty(exports, "AREA_GEOMETRY_TOLERANCE", { enumerable: true, get: function () { return frame_constant_1.AREA_GEOMETRY_TOLERANCE; } });
|
|
29
|
+
Object.defineProperty(exports, "SHELL_WARPING_LIMIT", { enumerable: true, get: function () { return frame_constant_1.SHELL_WARPING_LIMIT; } });
|
|
29
30
|
// Errors
|
|
30
31
|
var rc_design_error_1 = require("./errors/rc-design.error");
|
|
31
32
|
Object.defineProperty(exports, "RCDesignError", { enumerable: true, get: function () { return rc_design_error_1.RCDesignError; } });
|
package/dist/core/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":";;;AAWA,qDAA0D;AAAjD,kHAAA,kBAAkB,OAAA;AAW3B,qEAAyF;AAAhF,mHAAA,WAAW,OAAA;AAAE,sHAAA,cAAc,OAAA;AAAE,oHAAA,YAAY,OAAA;AAKlD,YAAY;AACZ,uDASiC;AAR/B,iIAAA,kCAAkC,OAAA;AAClC,uHAAA,wBAAwB,OAAA;AACxB,8HAAA,+BAA+B,OAAA;AAC/B,qIAAA,sCAAsC,OAAA;AACtC,qHAAA,sBAAsB,OAAA;AACtB,4HAAA,6BAA6B,OAAA;AAC7B,gIAAA,iCAAiC,OAAA;AACjC,8HAAA,+BAA+B,OAAA;AAGjC,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":";;;AAWA,qDAA0D;AAAjD,kHAAA,kBAAkB,OAAA;AAW3B,qEAAyF;AAAhF,mHAAA,WAAW,OAAA;AAAE,sHAAA,cAAc,OAAA;AAAE,oHAAA,YAAY,OAAA;AAKlD,YAAY;AACZ,uDASiC;AAR/B,iIAAA,kCAAkC,OAAA;AAClC,uHAAA,wBAAwB,OAAA;AACxB,8HAAA,+BAA+B,OAAA;AAC/B,qIAAA,sCAAsC,OAAA;AACtC,qHAAA,sBAAsB,OAAA;AACtB,4HAAA,6BAA6B,OAAA;AAC7B,gIAAA,iCAAiC,OAAA;AACjC,8HAAA,+BAA+B,OAAA;AAGjC,6DAUoC;AATlC,wHAAA,sBAAsB,OAAA;AACtB,sHAAA,oBAAoB,OAAA;AACpB,uHAAA,qBAAqB,OAAA;AACrB,yHAAA,uBAAuB,OAAA;AACvB,2HAAA,yBAAyB,OAAA;AACzB,uHAAA,qBAAqB,OAAA;AACrB,uHAAA,qBAAqB,OAAA;AACrB,yHAAA,uBAAuB,OAAA;AACvB,qHAAA,mBAAmB,OAAA;AAGrB,SAAS;AACT,4DAAiE;AAAxD,gHAAA,aAAa,OAAA;AAAE,yGAAA,MAAM,OAAA;AAC9B,sEAAgF;AAAvE,0HAAA,kBAAkB,OAAA;AAAE,mHAAA,WAAW,OAAA"}
|
|
@@ -17,4 +17,19 @@ export const EQUILIBRIUM_TOLERANCE = 1e-6;
|
|
|
17
17
|
* edges, nodes lying on an edge): distances are compared with this times the longest edge.
|
|
18
18
|
*/
|
|
19
19
|
export const AREA_GEOMETRY_TOLERANCE = 1e-6;
|
|
20
|
+
/**
|
|
21
|
+
* Penalty factor γ of the shell membrane's drilling rotation, as a multiple of the shear modulus
|
|
22
|
+
* G: the term ½·γ·t·∫(θ − ω)² dA, integrated at the element centre, ties each element's rotation
|
|
23
|
+
* about the shell normal θ to the in-plane rotation of the material ω = ½(v,x − u,y). γ = G
|
|
24
|
+
* follows Ibrahimbegovic, Taylor & Wilson (1990); with the one-point rule the results change by
|
|
25
|
+
* well under 1 % for γ between 0.01 G and 100 G.
|
|
26
|
+
*/
|
|
27
|
+
export const DRILLING_PENALTY_RATIO = 1;
|
|
28
|
+
/**
|
|
29
|
+
* Largest warping of a shell element accepted, as the distance of its corners from their mean
|
|
30
|
+
* plane relative to √A (A = projected area). Warped elements are built flat on the mean plane
|
|
31
|
+
* and linked rigidly to their corners, which is accurate for mild warping (the MacNeal–Harder
|
|
32
|
+
* twisted beam, 0.024, is within 0.5 %); beyond this the element is rejected (326).
|
|
33
|
+
*/
|
|
34
|
+
export const SHELL_WARPING_LIMIT = 0.1;
|
|
20
35
|
//# sourceMappingURL=frame.constant.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"frame.constant.js","sourceRoot":"","sources":["../../../../src/core/constants/frame.constant.ts"],"names":[],"mappings":"AAAA,2DAA2D;AAC3D,MAAM,CAAC,MAAM,sBAAsB,GAAG,GAAG,CAAC;AAE1C,iGAAiG;AACjG,MAAM,CAAC,MAAM,qBAAqB,GAAG,IAAI,CAAC;AAE1C,mGAAmG;AACnG,MAAM,CAAC,MAAM,uBAAuB,GAAG,GAAG,CAAC;AAE3C,qGAAqG;AACrG,MAAM,CAAC,MAAM,oBAAoB,GAAG,EAAE,CAAC;AAEvC,gGAAgG;AAChG,MAAM,CAAC,MAAM,yBAAyB,GAAG,IAAI,CAAC;AAE9C,uGAAuG;AACvG,MAAM,CAAC,MAAM,qBAAqB,GAAG,IAAI,CAAC;AAE1C,2EAA2E;AAC3E,MAAM,CAAC,MAAM,qBAAqB,GAAG,IAAI,CAAC;AAE1C;;;GAGG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,IAAI,CAAC"}
|
|
1
|
+
{"version":3,"file":"frame.constant.js","sourceRoot":"","sources":["../../../../src/core/constants/frame.constant.ts"],"names":[],"mappings":"AAAA,2DAA2D;AAC3D,MAAM,CAAC,MAAM,sBAAsB,GAAG,GAAG,CAAC;AAE1C,iGAAiG;AACjG,MAAM,CAAC,MAAM,qBAAqB,GAAG,IAAI,CAAC;AAE1C,mGAAmG;AACnG,MAAM,CAAC,MAAM,uBAAuB,GAAG,GAAG,CAAC;AAE3C,qGAAqG;AACrG,MAAM,CAAC,MAAM,oBAAoB,GAAG,EAAE,CAAC;AAEvC,gGAAgG;AAChG,MAAM,CAAC,MAAM,yBAAyB,GAAG,IAAI,CAAC;AAE9C,uGAAuG;AACvG,MAAM,CAAC,MAAM,qBAAqB,GAAG,IAAI,CAAC;AAE1C,2EAA2E;AAC3E,MAAM,CAAC,MAAM,qBAAqB,GAAG,IAAI,CAAC;AAE1C;;;GAGG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,IAAI,CAAC;AAE5C;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC;AAExC;;;;;GAKG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,GAAG,CAAC"}
|
|
@@ -20,7 +20,7 @@ export const FrameErrors = {
|
|
|
20
20
|
},
|
|
21
21
|
DUPLICATE_ID: {
|
|
22
22
|
code: 303,
|
|
23
|
-
message: "Node ids, member ids
|
|
23
|
+
message: "Node ids, member ids and restrained node ids must each be unique, area ids must be unique across null areas and shells, and load case and combination ids must be unique across both lists.",
|
|
24
24
|
},
|
|
25
25
|
STRUCTURE_UNSTABLE: {
|
|
26
26
|
code: 304,
|
|
@@ -60,7 +60,7 @@ export const FrameErrors = {
|
|
|
60
60
|
},
|
|
61
61
|
MISSING_UNIT_WEIGHT: {
|
|
62
62
|
code: 313,
|
|
63
|
-
message: "A load case requests self-weight but a member section has no unitWeight; set unitWeight (0 for a weightless member).",
|
|
63
|
+
message: "A load case requests self-weight but a member or shell section has no unitWeight; set unitWeight (0 for a weightless member or shell).",
|
|
64
64
|
},
|
|
65
65
|
INVALID_INPUT_VALUE: {
|
|
66
66
|
code: 314,
|
|
@@ -78,5 +78,21 @@ export const FrameErrors = {
|
|
|
78
78
|
code: 317,
|
|
79
79
|
message: "An area's supportEdges do not fit its distribution: two-way takes none; one-way needs at least one edge left unsupported, with every unsupported edge parallel to the others (the span direction); cantilever needs exactly one, and its loads may not act along that edge.",
|
|
80
80
|
},
|
|
81
|
+
INVALID_SHELL_GEOMETRY: {
|
|
82
|
+
code: 326,
|
|
83
|
+
message: "A shell area must have 4 distinct nodes, listed in order around it, forming a convex quadrilateral that is close to flat (each corner within 0.1·√A of the mean plane).",
|
|
84
|
+
},
|
|
85
|
+
INVALID_SHELL_SECTION: {
|
|
86
|
+
code: 327,
|
|
87
|
+
message: "A shell section's thickness and E must be positive, nu must be at least 0 and below 0.5, and unitWeight, when given, must not be negative.",
|
|
88
|
+
},
|
|
89
|
+
SHELL_DOF_UNSUPPORTED: {
|
|
90
|
+
code: 328,
|
|
91
|
+
message: 'A node connected only to shells has a translation that nothing resists: a membrane carries no load out of its plane and a plate none in its plane. Restrain that DOF, connect a member, or use type "shell".',
|
|
92
|
+
},
|
|
93
|
+
INVALID_SHELL_MESH: {
|
|
94
|
+
code: 329,
|
|
95
|
+
message: "Shell areas cannot be meshed: no division counts make the meshes of areas sharing edges meet node to node, a generated element is not a valid quadrilateral, or a generated id is already in use. Divide the areas so they meet edge to edge, or change their mesh sizes.",
|
|
96
|
+
},
|
|
81
97
|
};
|
|
82
98
|
//# sourceMappingURL=frame-analysis.error.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"frame-analysis.error.js","sourceRoot":"","sources":["../../../../src/core/errors/frame-analysis.error.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"frame-analysis.error.js","sourceRoot":"","sources":["../../../../src/core/errors/frame-analysis.error.ts"],"names":[],"mappings":"AAkBA,MAAM,OAAO,kBAAmB,SAAQ,KAAK;IAO3C,YACE,MAA8B,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,eAAe,EAAE,EACnE,UAA6B,EAAE,EAC/B,MAA0B;QAE1B,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACnB,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;QACrB,IAAI,CAAC,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC;QAC3B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,MAAM,GAAG,MAAM,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;QAC5E,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,kBAAkB,CAAC,SAAS,CAAC,CAAC;IAC5D,CAAC;CACF;AAcD,MAAM,CAAC,MAAM,WAAW,GAA2C;IACjE,8BAA8B;IAC9B,kBAAkB,EAAE;QAClB,IAAI,EAAE,GAAG;QACT,OAAO,EAAE,sEAAsE;KAChF;IACD,sBAAsB,EAAE;QACtB,IAAI,EAAE,GAAG;QACT,OAAO,EACL,iGAAiG;KACpG;IACD,YAAY,EAAE;QACZ,IAAI,EAAE,GAAG;QACT,OAAO,EACL,6LAA6L;KAChM;IACD,kBAAkB,EAAE;QAClB,IAAI,EAAE,GAAG;QACT,OAAO,EACL,mHAAmH;KACtH;IACD,0BAA0B,EAAE;QAC1B,IAAI,EAAE,GAAG;QACT,OAAO,EACL,2HAA2H;KAC9H;IACD,aAAa,EAAE;QACb,IAAI,EAAE,GAAG;QACT,OAAO,EAAE,iDAAiD;KAC3D;IACD,eAAe,EAAE;QACf,IAAI,EAAE,GAAG;QACT,OAAO,EACL,yFAAyF;KAC5F;IACD,mBAAmB,EAAE;QACnB,IAAI,EAAE,GAAG;QACT,OAAO,EAAE,4EAA4E;KACtF;IACD,iBAAiB,EAAE;QACjB,IAAI,EAAE,GAAG;QACT,OAAO,EACL,2HAA2H;KAC9H;IACD,oBAAoB,EAAE;QACpB,IAAI,EAAE,GAAG;QACT,OAAO,EAAE,mDAAmD;KAC7D;IACD,mBAAmB,EAAE;QACnB,IAAI,EAAE,GAAG;QACT,OAAO,EACL,4GAA4G;KAC/G;IACD,aAAa,EAAE;QACb,IAAI,EAAE,GAAG;QACT,OAAO,EAAE,gEAAgE;KAC1E;IACD,mBAAmB,EAAE;QACnB,IAAI,EAAE,GAAG;QACT,OAAO,EACL,wIAAwI;KAC3I;IACD,mBAAmB,EAAE;QACnB,IAAI,EAAE,GAAG;QACT,OAAO,EACL,8JAA8J;KACjK;IACD,qBAAqB,EAAE;QACrB,IAAI,EAAE,GAAG;QACT,OAAO,EACL,gJAAgJ;KACnJ;IACD,qBAAqB,EAAE;QACrB,IAAI,EAAE,GAAG;QACT,OAAO,EACL,gIAAgI;KACnI;IACD,yBAAyB,EAAE;QACzB,IAAI,EAAE,GAAG;QACT,OAAO,EACL,6QAA6Q;KAChR;IACD,sBAAsB,EAAE;QACtB,IAAI,EAAE,GAAG;QACT,OAAO,EACL,yKAAyK;KAC5K;IACD,qBAAqB,EAAE;QACrB,IAAI,EAAE,GAAG;QACT,OAAO,EACL,4IAA4I;KAC/I;IACD,qBAAqB,EAAE;QACrB,IAAI,EAAE,GAAG;QACT,OAAO,EACL,8MAA8M;KACjN;IACD,kBAAkB,EAAE;QAClB,IAAI,EAAE,GAAG;QACT,OAAO,EACL,2QAA2Q;KAC9Q;CACF,CAAC"}
|
package/dist/esm/core/index.js
CHANGED
|
@@ -2,7 +2,7 @@ export { isSinglyReinforced } from "./types/rc-beam.type.js";
|
|
|
2
2
|
export { hasTopPlate, hasBottomPlate, hasSidePlate } from "./types/plate-jacketing.type.js";
|
|
3
3
|
// Constants
|
|
4
4
|
export { FLEXURAL_STRENGTH_REDUCTION_FACTOR, CONCRETE_ULTIMATE_STRAIN, SHEAR_STRENGTH_REDUCTION_FACTOR, ANCHOR_SHEAR_STRENGTH_REDUCTION_FACTOR, MAX_PLATE_BOLT_SPACING, PLATE_SHEAR_YIELD_COEFFICIENT, SIDE_PLATE_EFFECTIVE_STRAIN_LIMIT, SIDE_PLATE_REDUCTION_FACTOR_PSI, } from "./constants/rc.constant.js";
|
|
5
|
-
export { CONCRETE_POISSON_RATIO, CONCRETE_UNIT_WEIGHT, BEAM_INERTIA_MODIFIER, COLUMN_INERTIA_MODIFIER, VERTICAL_MEMBER_TOLERANCE, SINGULARITY_TOLERANCE, EQUILIBRIUM_TOLERANCE, AREA_GEOMETRY_TOLERANCE, } from "./constants/frame.constant.js";
|
|
5
|
+
export { CONCRETE_POISSON_RATIO, CONCRETE_UNIT_WEIGHT, BEAM_INERTIA_MODIFIER, COLUMN_INERTIA_MODIFIER, VERTICAL_MEMBER_TOLERANCE, SINGULARITY_TOLERANCE, EQUILIBRIUM_TOLERANCE, AREA_GEOMETRY_TOLERANCE, SHELL_WARPING_LIMIT, } from "./constants/frame.constant.js";
|
|
6
6
|
// Errors
|
|
7
7
|
export { RCDesignError, Errors } from "./errors/rc-design.error.js";
|
|
8
8
|
export { FrameAnalysisError, FrameErrors } from "./errors/frame-analysis.error.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/index.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAW1D,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAKzF,YAAY;AACZ,OAAO,EACL,kCAAkC,EAClC,wBAAwB,EACxB,+BAA+B,EAC/B,sCAAsC,EACtC,sBAAsB,EACtB,6BAA6B,EAC7B,iCAAiC,EACjC,+BAA+B,GAChC,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EACL,sBAAsB,EACtB,oBAAoB,EACpB,qBAAqB,EACrB,uBAAuB,EACvB,yBAAyB,EACzB,qBAAqB,EACrB,qBAAqB,EACrB,uBAAuB,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/index.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAW1D,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAKzF,YAAY;AACZ,OAAO,EACL,kCAAkC,EAClC,wBAAwB,EACxB,+BAA+B,EAC/B,sCAAsC,EACtC,sBAAsB,EACtB,6BAA6B,EAC7B,iCAAiC,EACjC,+BAA+B,GAChC,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EACL,sBAAsB,EACtB,oBAAoB,EACpB,qBAAqB,EACrB,uBAAuB,EACvB,yBAAyB,EACzB,qBAAqB,EACrB,qBAAqB,EACrB,uBAAuB,EACvB,mBAAmB,GACpB,MAAM,4BAA4B,CAAC;AAEpC,SAAS;AACT,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { zeros } from "../../../../utils/matrix.js";
|
|
2
|
+
import { GAUSS_2X2, quadJacobian, serendipityShape } from "./quad-geometry.js";
|
|
3
|
+
import { isotropicRigidity } from "./rigidity.js";
|
|
4
|
+
const edgeCoefficients = (corners) => [0, 1, 2, 3].map((k) => {
|
|
5
|
+
const [xi, yi] = corners[k];
|
|
6
|
+
const [xj, yj] = corners[(k + 1) % 4];
|
|
7
|
+
const x = xi - xj;
|
|
8
|
+
const y = yi - yj;
|
|
9
|
+
const l2 = x * x + y * y;
|
|
10
|
+
return {
|
|
11
|
+
a: -x / l2,
|
|
12
|
+
b: (0.75 * x * y) / l2,
|
|
13
|
+
c: (0.25 * x * x - 0.5 * y * y) / l2,
|
|
14
|
+
d: -y / l2,
|
|
15
|
+
e: (0.25 * y * y - 0.5 * x * x) / l2,
|
|
16
|
+
};
|
|
17
|
+
});
|
|
18
|
+
/**
|
|
19
|
+
* The rotations of the normal `βx = Hxᵀ·U`, `βy = Hyᵀ·U` (or a derivative of them), given the
|
|
20
|
+
* eight serendipity values `F` (or the same derivative of them): corners in `F[0…3]`, mid-sides
|
|
21
|
+
* of edges 1→2, 2→3, 3→4, 4→1 in `F[4…7]`.
|
|
22
|
+
*/
|
|
23
|
+
const rotationRows = (edges, F) => {
|
|
24
|
+
const Hx = new Array(12).fill(0);
|
|
25
|
+
const Hy = new Array(12).fill(0);
|
|
26
|
+
for (let i = 0; i < 4; i++) {
|
|
27
|
+
// m: the edge that starts at corner i; k: the edge that ends at it
|
|
28
|
+
const m = i;
|
|
29
|
+
const k = (i + 3) % 4;
|
|
30
|
+
const Fm = F[4 + m];
|
|
31
|
+
const Fk = F[4 + k];
|
|
32
|
+
const em = edges[m];
|
|
33
|
+
const ek = edges[k];
|
|
34
|
+
Hx[3 * i] = 1.5 * (em.a * Fm - ek.a * Fk);
|
|
35
|
+
Hx[3 * i + 1] = em.b * Fm + ek.b * Fk;
|
|
36
|
+
Hx[3 * i + 2] = F[i] - em.c * Fm - ek.c * Fk;
|
|
37
|
+
Hy[3 * i] = 1.5 * (em.d * Fm - ek.d * Fk);
|
|
38
|
+
Hy[3 * i + 1] = -F[i] + em.e * Fm + ek.e * Fk;
|
|
39
|
+
Hy[3 * i + 2] = -Hx[3 * i + 1];
|
|
40
|
+
}
|
|
41
|
+
return { Hx, Hy };
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Curvature–displacement rows of the discrete Kirchhoff quadrilateral (DKQ) at (ξ, η).
|
|
45
|
+
*
|
|
46
|
+
* The rotations of the normal βx, βy (with u = z·βx, v = z·βy) are interpolated over the 8
|
|
47
|
+
* serendipity nodes; the Kirchhoff condition at the corners (βx = −w,x, βy = −w,y), a cubic w
|
|
48
|
+
* along each edge with ∫(w,s + βs) ds = 0, and a normal rotation linear along each edge
|
|
49
|
+
* eliminate the mid-side values (Batoz & Ben Tahar 1982). The geometry map stays bilinear.
|
|
50
|
+
*
|
|
51
|
+
* @param corners - The four corners in the element plane (mm), counter-clockwise
|
|
52
|
+
* @param xi - Natural coordinate ξ
|
|
53
|
+
* @param eta - Natural coordinate η
|
|
54
|
+
*/
|
|
55
|
+
export const dkqCurvatureRows = (corners, xi, eta) => {
|
|
56
|
+
const jacobian = quadJacobian(corners, xi, eta);
|
|
57
|
+
const shape = serendipityShape(xi, eta);
|
|
58
|
+
const edges = edgeCoefficients(corners);
|
|
59
|
+
const dXi = rotationRows(edges, shape.dXi);
|
|
60
|
+
const dEta = rotationRows(edges, shape.dEta);
|
|
61
|
+
const [[j11, j12], [j21, j22]] = jacobian.inverse;
|
|
62
|
+
const B = [[], [], []];
|
|
63
|
+
for (let p = 0; p < 12; p++) {
|
|
64
|
+
const HxX = j11 * dXi.Hx[p] + j12 * dEta.Hx[p];
|
|
65
|
+
const HxY = j21 * dXi.Hx[p] + j22 * dEta.Hx[p];
|
|
66
|
+
const HyX = j11 * dXi.Hy[p] + j12 * dEta.Hy[p];
|
|
67
|
+
const HyY = j21 * dXi.Hy[p] + j22 * dEta.Hy[p];
|
|
68
|
+
B[0].push(HxX);
|
|
69
|
+
B[1].push(HyY);
|
|
70
|
+
B[2].push(HxY + HyX);
|
|
71
|
+
}
|
|
72
|
+
return { B, detJ: jacobian.detJ };
|
|
73
|
+
};
|
|
74
|
+
/**
|
|
75
|
+
* Plate bending rigidity `E·t³/(12(1 − ν²))·[[1, ν, 0], [ν, 1, 0], [0, 0, (1 − ν)/2]]`
|
|
76
|
+
* (N·mm), with the stiffness modifiers applied (see `isotropicRigidity`).
|
|
77
|
+
*/
|
|
78
|
+
export const plateRigidity = ({ E, nu, t, modifiers }) => isotropicRigidity((E * t ** 3) / (12 * (1 - nu * nu)), nu, modifiers);
|
|
79
|
+
/**
|
|
80
|
+
* Local stiffness of the discrete Kirchhoff quadrilateral (DKQ, Batoz & Ben Tahar 1982), a thin
|
|
81
|
+
* plate element without transverse shear deformation, integrated with 2×2 Gauss points.
|
|
82
|
+
*
|
|
83
|
+
* The DOFs are `[w₁ θx₁ θy₁ … w₄ θx₄ θy₄]`: the deflection along the element normal and the
|
|
84
|
+
* right-handed rotations about the element's x and y axes (θx = w,y, θy = −w,x), at corners listed
|
|
85
|
+
* counter-clockwise about the normal. The quad must be convex (det J > 0 throughout), which
|
|
86
|
+
* validation guarantees.
|
|
87
|
+
*
|
|
88
|
+
* @param corners - The four corners in the element plane (mm)
|
|
89
|
+
* @param properties - E (MPa), ν and thickness t (mm)
|
|
90
|
+
* @returns The symmetric 12×12 stiffness in N and mm (N/mm, N, N·mm/rad); exactly three
|
|
91
|
+
* zero-energy modes, the out-of-plane rigid-body motions
|
|
92
|
+
*/
|
|
93
|
+
export const dkqPlateStiffness = (corners, properties) => {
|
|
94
|
+
const D = plateRigidity(properties);
|
|
95
|
+
const k = zeros(12, 12);
|
|
96
|
+
for (const { xi, eta, weight } of GAUSS_2X2) {
|
|
97
|
+
const { B, detJ } = dkqCurvatureRows(corners, xi, eta);
|
|
98
|
+
const scale = detJ * weight;
|
|
99
|
+
// Bᵀ·D·B via D·B
|
|
100
|
+
const DB = D.map((row) => B[0].map((_, a) => row[0] * B[0][a] + row[1] * B[1][a] + row[2] * B[2][a]));
|
|
101
|
+
for (let a = 0; a < 12; a++) {
|
|
102
|
+
for (let b = 0; b < 12; b++) {
|
|
103
|
+
k[a][b] += (B[0][a] * DB[0][b] + B[1][a] * DB[1][b] + B[2][a] * DB[2][b]) * scale;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return k;
|
|
108
|
+
};
|
|
109
|
+
//# sourceMappingURL=dkq-plate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dkq-plate.js","sourceRoot":"","sources":["../../../../../../src/fea/frame/elements/shell/dkq-plate.ts"],"names":[],"mappings":"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"}
|