@theerapat-s28/ts-structural-eng-tools 3.1.0 → 3.2.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 +33 -1
- package/README.md +284 -127
- package/dist/core/errors/fea.error.d.ts +47 -0
- package/dist/{esm/core/errors/frame-analysis.error.js → core/errors/fea.error.js} +14 -5
- package/dist/core/errors/fea.error.js.map +1 -0
- package/dist/core/index.d.ts +4 -2
- package/dist/core/index.js +8 -4
- package/dist/core/index.js.map +1 -1
- package/dist/{core/errors/frame-analysis.error.js → esm/core/errors/fea.error.js} +10 -9
- package/dist/esm/core/errors/fea.error.js.map +1 -0
- package/dist/esm/core/index.js +3 -1
- package/dist/esm/core/index.js.map +1 -1
- package/dist/esm/fea/analysis/index.js +6 -0
- package/dist/esm/fea/analysis/index.js.map +1 -0
- package/dist/esm/fea/{frame → analysis}/mesh/expand-model.js +12 -6
- package/dist/esm/fea/analysis/mesh/expand-model.js.map +1 -0
- package/dist/esm/fea/{frame → analysis}/post/demand-envelope.js +4 -4
- package/dist/esm/fea/analysis/post/demand-envelope.js.map +1 -0
- package/dist/esm/fea/analysis/post/envelope.js.map +1 -0
- package/dist/esm/fea/{frame → analysis}/post/present-state.js +4 -4
- package/dist/esm/fea/analysis/post/present-state.js.map +1 -0
- package/dist/esm/fea/{frame/solver/frame-system.js → analysis/solver/analysis-system.js} +17 -90
- package/dist/esm/fea/analysis/solver/analysis-system.js.map +1 -0
- package/dist/esm/fea/{frame/solver/analyze-frame.js → analysis/solver/analyze.js} +20 -18
- package/dist/esm/fea/analysis/solver/analyze.js.map +1 -0
- package/dist/esm/fea/{frame → analysis}/solver/combinations.js +8 -8
- package/dist/esm/fea/analysis/solver/combinations.js.map +1 -0
- package/dist/esm/fea/analysis/solver/distribute-area-loads.js +25 -0
- package/dist/esm/fea/analysis/solver/distribute-area-loads.js.map +1 -0
- package/dist/esm/fea/analysis/solver/load-case-solver.js +103 -0
- package/dist/esm/fea/analysis/solver/load-case-solver.js.map +1 -0
- package/dist/esm/fea/analysis/types/model.type.js +2 -0
- package/dist/esm/fea/analysis/types/model.type.js.map +1 -0
- package/dist/esm/fea/analysis/types/results.type.js +2 -0
- package/dist/esm/fea/analysis/types/results.type.js.map +1 -0
- package/dist/esm/fea/analysis/validation/validate-model.js +263 -0
- package/dist/esm/fea/analysis/validation/validate-model.js.map +1 -0
- package/dist/esm/fea/deprecated.js +9 -0
- package/dist/esm/fea/deprecated.js.map +1 -0
- package/dist/esm/fea/frame/area/{distribute-area-loads.js → area-member-loads.js} +7 -28
- package/dist/esm/fea/frame/area/area-member-loads.js.map +1 -0
- package/dist/esm/fea/frame/area/edge-members.js.map +1 -1
- package/dist/esm/fea/frame/elements/end-releases.js +2 -6
- package/dist/esm/fea/frame/elements/end-releases.js.map +1 -1
- package/dist/esm/fea/frame/elements/fixed-end-forces.js +5 -5
- package/dist/esm/fea/frame/elements/fixed-end-forces.js.map +1 -1
- package/dist/esm/fea/frame/elements/static-condensation.js +3 -3
- package/dist/esm/fea/frame/elements/static-condensation.js.map +1 -1
- package/dist/esm/fea/frame/index.js +1 -4
- package/dist/esm/fea/frame/index.js.map +1 -1
- package/dist/esm/fea/frame/post/member-diagram.js.map +1 -1
- package/dist/esm/fea/frame/solver/{global-assembly.js → member-assembly.js} +2 -10
- package/dist/esm/fea/frame/solver/member-assembly.js.map +1 -0
- package/dist/esm/fea/frame/solver/member-loads.js +141 -0
- package/dist/esm/fea/frame/solver/member-loads.js.map +1 -0
- package/dist/esm/fea/frame/solver/system-member.js +66 -0
- package/dist/esm/fea/frame/solver/system-member.js.map +1 -0
- package/dist/esm/fea/frame/transformation/coordinate-transform.js +3 -3
- package/dist/esm/fea/frame/transformation/coordinate-transform.js.map +1 -1
- package/dist/esm/fea/frame/validation/validate-members.js +160 -0
- package/dist/esm/fea/frame/validation/validate-members.js.map +1 -0
- package/dist/esm/fea/frame/validation/validate-null-areas.js +88 -0
- package/dist/esm/fea/frame/validation/validate-null-areas.js.map +1 -0
- package/dist/esm/fea/index.js +4 -1
- package/dist/esm/fea/index.js.map +1 -1
- package/dist/esm/fea/shared/index.js +2 -0
- package/dist/esm/fea/shared/index.js.map +1 -0
- package/dist/esm/fea/shared/solver/auto-restraint.js.map +1 -0
- package/dist/esm/fea/{frame → shared}/solver/boundary-conditions.js +5 -1
- package/dist/esm/fea/shared/solver/boundary-conditions.js.map +1 -0
- package/dist/esm/fea/shared/solver/global-assembly.js +10 -0
- package/dist/esm/fea/shared/solver/global-assembly.js.map +1 -0
- package/dist/esm/fea/shared/types/model.type.js +2 -0
- package/dist/esm/fea/shared/types/model.type.js.map +1 -0
- package/dist/esm/fea/shared/validation/issues.js +32 -0
- package/dist/esm/fea/shared/validation/issues.js.map +1 -0
- package/dist/esm/fea/{frame/elements/shell → shell/elements}/dkq-plate.js +1 -1
- package/dist/esm/fea/shell/elements/dkq-plate.js.map +1 -0
- package/dist/esm/fea/{frame/elements/shell → shell/elements}/flat-shell.js +1 -1
- package/dist/esm/fea/shell/elements/flat-shell.js.map +1 -0
- package/dist/esm/fea/{frame/elements/shell → shell/elements}/membrane-quad.js +2 -2
- package/dist/esm/fea/shell/elements/membrane-quad.js.map +1 -0
- package/dist/esm/fea/shell/elements/quad-geometry.js.map +1 -0
- package/dist/esm/fea/shell/elements/rigidity.js.map +1 -0
- package/dist/esm/fea/{frame/elements/shell → shell/elements}/shell-axes.js +1 -1
- package/dist/esm/fea/shell/elements/shell-axes.js.map +1 -0
- package/dist/esm/fea/shell/index.js +2 -0
- package/dist/esm/fea/shell/index.js.map +1 -0
- package/dist/esm/fea/{frame → shell}/mesh/mesh-shells.js +1 -1
- package/dist/esm/fea/shell/mesh/mesh-shells.js.map +1 -0
- package/dist/esm/fea/{frame → shell}/post/shell-forces.js +4 -4
- package/dist/esm/fea/{frame → shell}/post/shell-forces.js.map +1 -1
- package/dist/esm/fea/shell/solver/shell-loads.js +53 -0
- package/dist/esm/fea/shell/solver/shell-loads.js.map +1 -0
- package/dist/esm/fea/shell/solver/system-shell.js +37 -0
- package/dist/esm/fea/shell/solver/system-shell.js.map +1 -0
- package/dist/esm/fea/shell/types/model.type.js +2 -0
- package/dist/esm/fea/shell/types/model.type.js.map +1 -0
- package/dist/esm/fea/shell/types/results.type.js +2 -0
- package/dist/esm/fea/shell/types/results.type.js.map +1 -0
- package/dist/esm/fea/shell/validation/validate-shells.js +98 -0
- package/dist/esm/fea/shell/validation/validate-shells.js.map +1 -0
- package/dist/esm/index.js +5 -3
- package/dist/esm/index.js.map +1 -1
- package/dist/fea/analysis/index.d.ts +8 -0
- package/dist/fea/analysis/index.js +14 -0
- package/dist/fea/analysis/index.js.map +1 -0
- package/dist/fea/{frame → analysis}/mesh/expand-model.d.ts +9 -7
- package/dist/fea/{frame → analysis}/mesh/expand-model.js +12 -6
- package/dist/fea/analysis/mesh/expand-model.js.map +1 -0
- package/dist/fea/{frame → analysis}/post/demand-envelope.d.ts +5 -5
- package/dist/fea/{frame → analysis}/post/demand-envelope.js +4 -4
- package/dist/fea/analysis/post/demand-envelope.js.map +1 -0
- package/dist/fea/{frame → analysis}/post/envelope.d.ts +2 -2
- package/dist/fea/analysis/post/envelope.js.map +1 -0
- package/dist/fea/{frame → analysis}/post/present-state.d.ts +6 -5
- package/dist/fea/{frame → analysis}/post/present-state.js +5 -5
- package/dist/fea/analysis/post/present-state.js.map +1 -0
- package/dist/fea/analysis/solver/analysis-system.d.ts +46 -0
- package/dist/fea/{frame/solver/frame-system.js → analysis/solver/analysis-system.js} +22 -95
- package/dist/fea/analysis/solver/analysis-system.js.map +1 -0
- package/dist/fea/{frame/solver/analyze-frame.d.ts → analysis/solver/analyze.d.ts} +23 -20
- package/dist/fea/{frame/solver/analyze-frame.js → analysis/solver/analyze.js} +25 -23
- package/dist/fea/analysis/solver/analyze.js.map +1 -0
- package/dist/fea/{frame → analysis}/solver/combinations.d.ts +1 -1
- package/dist/fea/{frame → analysis}/solver/combinations.js +8 -8
- package/dist/fea/analysis/solver/combinations.js.map +1 -0
- package/dist/fea/{frame/area → analysis/solver}/distribute-area-loads.d.ts +6 -15
- package/dist/fea/analysis/solver/distribute-area-loads.js +29 -0
- package/dist/fea/analysis/solver/distribute-area-loads.js.map +1 -0
- package/dist/fea/{frame → analysis}/solver/load-case-solver.d.ts +9 -13
- package/dist/fea/analysis/solver/load-case-solver.js +108 -0
- package/dist/fea/analysis/solver/load-case-solver.js.map +1 -0
- package/dist/fea/analysis/types/model.type.d.ts +80 -0
- package/dist/fea/analysis/types/model.type.js +3 -0
- package/dist/fea/analysis/types/model.type.js.map +1 -0
- package/dist/fea/analysis/types/results.type.d.ts +113 -0
- package/dist/fea/analysis/types/results.type.js +3 -0
- package/dist/fea/analysis/types/results.type.js.map +1 -0
- package/dist/fea/analysis/validation/validate-model.d.ts +12 -0
- package/dist/fea/analysis/validation/validate-model.js +267 -0
- package/dist/fea/analysis/validation/validate-model.js.map +1 -0
- package/dist/fea/deprecated.d.ts +27 -0
- package/dist/fea/deprecated.js +12 -0
- package/dist/fea/deprecated.js.map +1 -0
- package/dist/fea/frame/area/area-member-loads.d.ts +19 -0
- package/dist/fea/frame/area/{distribute-area-loads.js → area-member-loads.js} +8 -30
- package/dist/fea/frame/area/area-member-loads.js.map +1 -0
- package/dist/fea/frame/area/edge-members.d.ts +5 -4
- package/dist/fea/frame/area/edge-members.js.map +1 -1
- package/dist/fea/frame/elements/end-releases.d.ts +1 -6
- package/dist/fea/frame/elements/end-releases.js +4 -8
- package/dist/fea/frame/elements/end-releases.js.map +1 -1
- package/dist/fea/frame/elements/fixed-end-forces.d.ts +1 -1
- package/dist/fea/frame/elements/fixed-end-forces.js +5 -5
- package/dist/fea/frame/elements/fixed-end-forces.js.map +1 -1
- package/dist/fea/frame/elements/static-condensation.d.ts +1 -1
- package/dist/fea/frame/elements/static-condensation.js +3 -3
- package/dist/fea/frame/elements/static-condensation.js.map +1 -1
- package/dist/fea/frame/index.d.ts +2 -8
- package/dist/fea/frame/index.js +2 -10
- package/dist/fea/frame/index.js.map +1 -1
- package/dist/fea/frame/post/member-diagram.d.ts +3 -3
- package/dist/fea/frame/post/member-diagram.js.map +1 -1
- package/dist/fea/frame/solver/{global-assembly.d.ts → member-assembly.d.ts} +0 -11
- package/dist/fea/frame/solver/{global-assembly.js → member-assembly.js} +4 -13
- package/dist/fea/frame/solver/member-assembly.js.map +1 -0
- package/dist/fea/frame/solver/member-loads.d.ts +21 -0
- package/dist/fea/frame/solver/member-loads.js +146 -0
- package/dist/fea/frame/solver/member-loads.js.map +1 -0
- package/dist/fea/frame/solver/system-member.d.ts +50 -0
- package/dist/fea/frame/solver/system-member.js +70 -0
- package/dist/fea/frame/solver/system-member.js.map +1 -0
- package/dist/fea/frame/transformation/coordinate-transform.d.ts +1 -1
- package/dist/fea/frame/transformation/coordinate-transform.js +3 -3
- package/dist/fea/frame/transformation/coordinate-transform.js.map +1 -1
- package/dist/fea/frame/types/model.type.d.ts +10 -175
- package/dist/fea/frame/types/results.type.d.ts +4 -159
- package/dist/fea/frame/validation/validate-members.d.ts +30 -0
- package/dist/fea/frame/validation/validate-members.js +165 -0
- package/dist/fea/frame/validation/validate-members.js.map +1 -0
- package/dist/fea/frame/validation/validate-null-areas.d.ts +38 -0
- package/dist/fea/frame/validation/validate-null-areas.js +93 -0
- package/dist/fea/frame/validation/validate-null-areas.js.map +1 -0
- package/dist/fea/index.d.ts +4 -0
- package/dist/fea/index.js +4 -1
- package/dist/fea/index.js.map +1 -1
- package/dist/fea/shared/index.d.ts +1 -0
- package/dist/fea/shared/index.js +3 -0
- package/dist/fea/shared/index.js.map +1 -0
- package/dist/fea/shared/solver/auto-restraint.js.map +1 -0
- package/dist/fea/{frame → shared}/solver/boundary-conditions.d.ts +5 -0
- package/dist/fea/{frame → shared}/solver/boundary-conditions.js +7 -3
- package/dist/fea/shared/solver/boundary-conditions.js.map +1 -0
- package/dist/fea/shared/solver/global-assembly.d.ts +12 -0
- package/dist/fea/shared/solver/global-assembly.js +14 -0
- package/dist/fea/shared/solver/global-assembly.js.map +1 -0
- package/dist/fea/shared/types/model.type.d.ts +34 -0
- package/dist/fea/shared/types/model.type.js +3 -0
- package/dist/fea/shared/types/model.type.js.map +1 -0
- package/dist/fea/shared/validation/issues.d.ts +9 -0
- package/dist/fea/shared/validation/issues.js +38 -0
- package/dist/fea/shared/validation/issues.js.map +1 -0
- package/dist/fea/{frame/elements/shell → shell/elements}/dkq-plate.d.ts +1 -1
- package/dist/fea/{frame/elements/shell → shell/elements}/dkq-plate.js +1 -1
- package/dist/fea/shell/elements/dkq-plate.js.map +1 -0
- package/dist/fea/{frame/elements/shell → shell/elements}/flat-shell.d.ts +1 -1
- package/dist/fea/{frame/elements/shell → shell/elements}/flat-shell.js +1 -1
- package/dist/fea/shell/elements/flat-shell.js.map +1 -0
- package/dist/fea/{frame/elements/shell → shell/elements}/membrane-quad.d.ts +1 -1
- package/dist/fea/{frame/elements/shell → shell/elements}/membrane-quad.js +2 -2
- package/dist/fea/shell/elements/membrane-quad.js.map +1 -0
- package/dist/fea/shell/elements/quad-geometry.js.map +1 -0
- package/dist/fea/{frame/elements/shell → shell/elements}/rigidity.d.ts +1 -1
- package/dist/fea/shell/elements/rigidity.js.map +1 -0
- package/dist/fea/{frame/elements/shell → shell/elements}/shell-axes.d.ts +1 -1
- package/dist/fea/{frame/elements/shell → shell/elements}/shell-axes.js +1 -1
- package/dist/fea/shell/elements/shell-axes.js.map +1 -0
- package/dist/fea/shell/index.d.ts +2 -0
- package/dist/fea/shell/index.js +3 -0
- package/dist/fea/shell/index.js.map +1 -0
- package/dist/fea/{frame → shell}/mesh/mesh-shells.d.ts +7 -6
- package/dist/fea/{frame → shell}/mesh/mesh-shells.js +1 -1
- package/dist/fea/shell/mesh/mesh-shells.js.map +1 -0
- package/dist/fea/{frame → shell}/post/shell-forces.d.ts +1 -1
- package/dist/fea/{frame → shell}/post/shell-forces.js +4 -4
- package/dist/fea/{frame → shell}/post/shell-forces.js.map +1 -1
- package/dist/fea/shell/solver/shell-loads.d.ts +17 -0
- package/dist/fea/shell/solver/shell-loads.js +57 -0
- package/dist/fea/shell/solver/shell-loads.js.map +1 -0
- package/dist/fea/shell/solver/system-shell.d.ts +29 -0
- package/dist/fea/shell/solver/system-shell.js +41 -0
- package/dist/fea/shell/solver/system-shell.js.map +1 -0
- package/dist/fea/shell/types/model.type.d.ts +57 -0
- package/dist/fea/shell/types/model.type.js +3 -0
- package/dist/fea/shell/types/model.type.js.map +1 -0
- package/dist/fea/shell/types/results.type.d.ts +47 -0
- package/dist/fea/shell/types/results.type.js +3 -0
- package/dist/fea/shell/types/results.type.js.map +1 -0
- package/dist/fea/shell/validation/validate-shells.d.ts +21 -0
- package/dist/fea/shell/validation/validate-shells.js +103 -0
- package/dist/fea/shell/validation/validate-shells.js.map +1 -0
- package/dist/index.d.ts +6 -4
- package/dist/index.js +13 -6
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/core/errors/frame-analysis.error.d.ts +0 -37
- package/dist/core/errors/frame-analysis.error.js.map +0 -1
- package/dist/esm/core/errors/frame-analysis.error.js.map +0 -1
- package/dist/esm/fea/frame/area/distribute-area-loads.js.map +0 -1
- package/dist/esm/fea/frame/elements/shell/dkq-plate.js.map +0 -1
- package/dist/esm/fea/frame/elements/shell/flat-shell.js.map +0 -1
- package/dist/esm/fea/frame/elements/shell/membrane-quad.js.map +0 -1
- package/dist/esm/fea/frame/elements/shell/quad-geometry.js.map +0 -1
- package/dist/esm/fea/frame/elements/shell/rigidity.js.map +0 -1
- package/dist/esm/fea/frame/elements/shell/shell-axes.js.map +0 -1
- package/dist/esm/fea/frame/mesh/expand-model.js.map +0 -1
- package/dist/esm/fea/frame/mesh/mesh-shells.js.map +0 -1
- package/dist/esm/fea/frame/post/demand-envelope.js.map +0 -1
- package/dist/esm/fea/frame/post/envelope.js.map +0 -1
- package/dist/esm/fea/frame/post/present-state.js.map +0 -1
- package/dist/esm/fea/frame/solver/analyze-frame.js.map +0 -1
- package/dist/esm/fea/frame/solver/auto-restraint.js.map +0 -1
- package/dist/esm/fea/frame/solver/boundary-conditions.js.map +0 -1
- package/dist/esm/fea/frame/solver/combinations.js.map +0 -1
- package/dist/esm/fea/frame/solver/frame-system.js.map +0 -1
- package/dist/esm/fea/frame/solver/global-assembly.js.map +0 -1
- package/dist/esm/fea/frame/solver/load-case-solver.js +0 -255
- package/dist/esm/fea/frame/solver/load-case-solver.js.map +0 -1
- package/dist/esm/fea/frame/validation/validate-model.js +0 -529
- package/dist/esm/fea/frame/validation/validate-model.js.map +0 -1
- package/dist/fea/frame/area/distribute-area-loads.js.map +0 -1
- package/dist/fea/frame/elements/shell/dkq-plate.js.map +0 -1
- package/dist/fea/frame/elements/shell/flat-shell.js.map +0 -1
- package/dist/fea/frame/elements/shell/membrane-quad.js.map +0 -1
- package/dist/fea/frame/elements/shell/quad-geometry.js.map +0 -1
- package/dist/fea/frame/elements/shell/rigidity.js.map +0 -1
- package/dist/fea/frame/elements/shell/shell-axes.js.map +0 -1
- package/dist/fea/frame/mesh/expand-model.js.map +0 -1
- package/dist/fea/frame/mesh/mesh-shells.js.map +0 -1
- package/dist/fea/frame/post/demand-envelope.js.map +0 -1
- package/dist/fea/frame/post/envelope.js.map +0 -1
- package/dist/fea/frame/post/present-state.js.map +0 -1
- package/dist/fea/frame/solver/analyze-frame.js.map +0 -1
- package/dist/fea/frame/solver/auto-restraint.js.map +0 -1
- package/dist/fea/frame/solver/boundary-conditions.js.map +0 -1
- package/dist/fea/frame/solver/combinations.js.map +0 -1
- package/dist/fea/frame/solver/frame-system.d.ts +0 -89
- package/dist/fea/frame/solver/frame-system.js.map +0 -1
- package/dist/fea/frame/solver/global-assembly.js.map +0 -1
- package/dist/fea/frame/solver/load-case-solver.js +0 -260
- package/dist/fea/frame/solver/load-case-solver.js.map +0 -1
- package/dist/fea/frame/validation/validate-model.d.ts +0 -19
- package/dist/fea/frame/validation/validate-model.js +0 -535
- package/dist/fea/frame/validation/validate-model.js.map +0 -1
- /package/dist/esm/fea/{frame → analysis}/post/envelope.js +0 -0
- /package/dist/esm/fea/{frame → shared}/solver/auto-restraint.js +0 -0
- /package/dist/esm/fea/{frame/elements/shell → shell/elements}/quad-geometry.js +0 -0
- /package/dist/esm/fea/{frame/elements/shell → shell/elements}/rigidity.js +0 -0
- /package/dist/fea/{frame → analysis}/post/envelope.js +0 -0
- /package/dist/fea/{frame → shared}/solver/auto-restraint.d.ts +0 -0
- /package/dist/fea/{frame → shared}/solver/auto-restraint.js +0 -0
- /package/dist/fea/{frame/elements/shell → shell/elements}/quad-geometry.d.ts +0 -0
- /package/dist/fea/{frame/elements/shell → shell/elements}/quad-geometry.js +0 -0
- /package/dist/fea/{frame/elements/shell → shell/elements}/rigidity.js +0 -0
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import { type LocalMemberLoad } from "
|
|
2
|
-
import type {
|
|
3
|
-
import type {
|
|
1
|
+
import { type LocalMemberLoad } from "../../frame/elements/fixed-end-forces";
|
|
2
|
+
import type { MemberLoad } from "../../frame/types/model.type";
|
|
3
|
+
import type { AreaLoad } from "../../shared/types/model.type";
|
|
4
|
+
import type { LoadCase, NodalLoad } from "../types/model.type";
|
|
5
|
+
import type { AnalysisSystem } from "./analysis-system";
|
|
4
6
|
/**
|
|
5
7
|
* Unrounded result of one load case or combination, in N and mm. Every field is linear in the
|
|
6
8
|
* loads, so combinations are formed by factoring and adding states.
|
|
@@ -16,24 +18,18 @@ export interface RawState {
|
|
|
16
18
|
/**
|
|
17
19
|
* Solves one load case against the prepared, factorised system.
|
|
18
20
|
*
|
|
19
|
-
*
|
|
21
|
+
* Members take their loads and self-weight as fixed-end forces (see `memberPieceLoads`); shells
|
|
22
|
+
* take their area loads and self-weight as forces at their corners (see `addShellLoads`).
|
|
20
23
|
*
|
|
21
24
|
* @param loadCase - The load case (id and self-weight multiplier)
|
|
22
|
-
* @param loads - The nodal and member loads tagged with this load case
|
|
23
|
-
*
|
|
24
|
-
* Shell areas take `selfWeight · unitWeight · thickness · modifiers.weight` per unit area along
|
|
25
|
-
* −Z and their `AreaLoad`s as forces at their corners, each corner the share `∫ Nᵢ dA` of the
|
|
26
|
-
* element's area on its mean plane (no corner moments, so a warped element's offsets do not load
|
|
27
|
-
* the rotations auto-restraint holds).
|
|
28
|
-
*
|
|
29
25
|
* @param loads - The nodal and member loads tagged with this load case, and its area loads on
|
|
30
26
|
* shell areas
|
|
31
27
|
*
|
|
32
|
-
* @throws {
|
|
28
|
+
* @throws {FeaError} 304 if a load has a moment about a joint rotation that nothing
|
|
33
29
|
* resists (an auto-restrained axis), 308 for a load outside its member, 313 if self-weight is
|
|
34
30
|
* requested for a member without `unitWeight`
|
|
35
31
|
*/
|
|
36
|
-
export declare const solveLoadCase: (system:
|
|
32
|
+
export declare const solveLoadCase: (system: AnalysisSystem, loadCase: LoadCase, loads: {
|
|
37
33
|
nodalLoads: NodalLoad[];
|
|
38
34
|
memberLoads: MemberLoad[];
|
|
39
35
|
shellLoads?: AreaLoad[];
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.combineStates = exports.solveLoadCase = void 0;
|
|
4
|
+
const frame_constant_1 = require("../../../core/constants/frame.constant");
|
|
5
|
+
const fea_error_1 = require("../../../core/errors/fea.error");
|
|
6
|
+
const fixed_end_forces_1 = require("../../frame/elements/fixed-end-forces");
|
|
7
|
+
const member_assembly_1 = require("../../frame/solver/member-assembly");
|
|
8
|
+
const member_loads_1 = require("../../frame/solver/member-loads");
|
|
9
|
+
const global_assembly_1 = require("../../shared/solver/global-assembly");
|
|
10
|
+
const issues_1 = require("../../shared/validation/issues");
|
|
11
|
+
const shell_forces_1 = require("../../shell/post/shell-forces");
|
|
12
|
+
const shell_loads_1 = require("../../shell/solver/shell-loads");
|
|
13
|
+
const matrix_1 = require("../../../utils/matrix");
|
|
14
|
+
const skyline_1 = require("../../../utils/skyline");
|
|
15
|
+
/**
|
|
16
|
+
* Solves one load case against the prepared, factorised system.
|
|
17
|
+
*
|
|
18
|
+
* Members take their loads and self-weight as fixed-end forces (see `memberPieceLoads`); shells
|
|
19
|
+
* take their area loads and self-weight as forces at their corners (see `addShellLoads`).
|
|
20
|
+
*
|
|
21
|
+
* @param loadCase - The load case (id and self-weight multiplier)
|
|
22
|
+
* @param loads - The nodal and member loads tagged with this load case, and its area loads on
|
|
23
|
+
* shell areas
|
|
24
|
+
*
|
|
25
|
+
* @throws {FeaError} 304 if a load has a moment about a joint rotation that nothing
|
|
26
|
+
* resists (an auto-restrained axis), 308 for a load outside its member, 313 if self-weight is
|
|
27
|
+
* requested for a member without `unitWeight`
|
|
28
|
+
*/
|
|
29
|
+
const solveLoadCase = (system, loadCase, loads) => {
|
|
30
|
+
const { members, dofCount, boundary, equation, free, factor, nodeIndex, memberIndex } = system;
|
|
31
|
+
const F = new Array(dofCount).fill(0);
|
|
32
|
+
const selfWeight = loadCase.selfWeight ?? 0;
|
|
33
|
+
const memberLoads = (0, member_loads_1.memberPieceLoads)(system.memberGroups, members, memberIndex, loads.memberLoads, loadCase.id, selfWeight);
|
|
34
|
+
const fixed = members.map((member, m) => {
|
|
35
|
+
const condensed = member.condenseFixedEndForces((0, fixed_end_forces_1.fixedEndForces)(memberLoads[m], member.length));
|
|
36
|
+
(0, member_assembly_1.scatterMemberForces)(F, member, condensed, -1);
|
|
37
|
+
return condensed;
|
|
38
|
+
});
|
|
39
|
+
// Shell surface loads as forces at the element corners
|
|
40
|
+
(0, shell_loads_1.addShellLoads)(F, system.shells, system.shellsByArea, loads.shellLoads ?? [], selfWeight);
|
|
41
|
+
for (const load of loads.nodalLoads) {
|
|
42
|
+
const base = 6 * nodeIndex.get(load.nodeId);
|
|
43
|
+
[load.fx, load.fy, load.fz].forEach((v, k) => (F[base + k] += (v ?? 0) * 1e3));
|
|
44
|
+
[load.mx, load.my, load.mz].forEach((v, k) => (F[base + 3 + k] += (v ?? 0) * 1e6));
|
|
45
|
+
}
|
|
46
|
+
// A held rotation axis is decoupled from the structure: a moment about it has no load path.
|
|
47
|
+
let momentScale = 0;
|
|
48
|
+
for (let n = 0; n < system.nodes.length; n++) {
|
|
49
|
+
for (let k = 3; k < 6; k++)
|
|
50
|
+
momentScale = Math.max(momentScale, Math.abs(F[6 * n + k]));
|
|
51
|
+
}
|
|
52
|
+
for (const { node, axis } of system.autoRestraints) {
|
|
53
|
+
const moment = axis.reduce((sum, a, i) => sum + a * F[6 * node + 3 + i], 0);
|
|
54
|
+
if (Math.abs(moment) > frame_constant_1.SINGULARITY_TOLERANCE * momentScale) {
|
|
55
|
+
const lead = axis.reduce((best, a, i) => (Math.abs(a) > Math.abs(axis[best]) ? i : best), 0);
|
|
56
|
+
(0, issues_1.throwIssues)([
|
|
57
|
+
(0, issues_1.modelIssue)(fea_error_1.FeaErrors.STRUCTURE_UNSTABLE, {
|
|
58
|
+
nodeId: system.nodes[node].id,
|
|
59
|
+
dof: ["rx", "ry", "rz"][lead],
|
|
60
|
+
loadCaseId: loadCase.id,
|
|
61
|
+
}),
|
|
62
|
+
]);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
const U = new Array(dofCount).fill(0);
|
|
66
|
+
if (factor) {
|
|
67
|
+
const solution = (0, skyline_1.skylineSolve)(factor, free.map((dof) => F[dof]));
|
|
68
|
+
free.forEach((dof) => (U[dof] = solution[equation[dof]]));
|
|
69
|
+
}
|
|
70
|
+
// Elastic end forces k·u per member; their global sum is K·U, from which R = K·U − F
|
|
71
|
+
const KU = new Array(dofCount).fill(0);
|
|
72
|
+
const memberForces = members.map((member, m) => {
|
|
73
|
+
const uLocal = (0, matrix_1.matVec)(member.T, (0, member_assembly_1.memberDofs)(member).map((d) => U[d]));
|
|
74
|
+
const elastic = (0, matrix_1.matVec)(member.k, uLocal);
|
|
75
|
+
(0, member_assembly_1.scatterMemberForces)(KU, member, elastic, 1);
|
|
76
|
+
return elastic.map((v, i) => v + fixed[m][i]);
|
|
77
|
+
});
|
|
78
|
+
for (const shell of system.shells) {
|
|
79
|
+
const dofs = (0, global_assembly_1.elementDofs)(shell.nodeIndices);
|
|
80
|
+
const forces = (0, matrix_1.matVec)(shell.element.kGlobal, dofs.map((d) => U[d]));
|
|
81
|
+
dofs.forEach((d, a) => (KU[d] += forces[a]));
|
|
82
|
+
}
|
|
83
|
+
const R = KU.map((v, i) => (boundary.restrained[i] ? v - F[i] : 0));
|
|
84
|
+
const shellForces = system.shells.map((shell) => (0, shell_forces_1.shellRawForces)(shell, U));
|
|
85
|
+
return { U, R, F, memberForces, shellForces, memberLoads };
|
|
86
|
+
};
|
|
87
|
+
exports.solveLoadCase = solveLoadCase;
|
|
88
|
+
/** Superposes factored states: `Σ factor × state`. Member loads are concatenated, scaled. */
|
|
89
|
+
const combineStates = (terms) => {
|
|
90
|
+
const first = terms[0].state;
|
|
91
|
+
const add = (pick, length) => {
|
|
92
|
+
const out = new Array(length).fill(0);
|
|
93
|
+
for (const { state, factor } of terms) {
|
|
94
|
+
pick(state).forEach((v, i) => (out[i] += factor * v));
|
|
95
|
+
}
|
|
96
|
+
return out;
|
|
97
|
+
};
|
|
98
|
+
return {
|
|
99
|
+
U: add((s) => s.U, first.U.length),
|
|
100
|
+
R: add((s) => s.R, first.R.length),
|
|
101
|
+
F: add((s) => s.F, first.F.length),
|
|
102
|
+
memberForces: first.memberForces.map((_, m) => add((s) => s.memberForces[m], 12)),
|
|
103
|
+
shellForces: first.shellForces.map((f, sh) => add((s) => s.shellForces[sh], f.length)),
|
|
104
|
+
memberLoads: first.memberLoads.map((_, m) => terms.flatMap(({ state, factor }) => factor === 0 ? [] : state.memberLoads[m].map((l) => (0, member_loads_1.scaleMemberLoad)(l, factor)))),
|
|
105
|
+
};
|
|
106
|
+
};
|
|
107
|
+
exports.combineStates = combineStates;
|
|
108
|
+
//# sourceMappingURL=load-case-solver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"load-case-solver.js","sourceRoot":"","sources":["../../../../src/fea/analysis/solver/load-case-solver.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import type { Member, MemberLoad, NullArea } from "../../frame/types/model.type";
|
|
2
|
+
import type { AreaLoad, FeaId, FeaNode, Restraint } from "../../shared/types/model.type";
|
|
3
|
+
import type { ShellArea } from "../../shell/types/model.type";
|
|
4
|
+
/**
|
|
5
|
+
* Fixed DOFs along a straight line: every node on the segment between two nodes, including the
|
|
6
|
+
* nodes the engine generates when it meshes shell areas, e.g. a wall base fixed along its
|
|
7
|
+
* length. `true` fixes the DOF; there are no line springs. Combined with point restraints at
|
|
8
|
+
* the same node, a fixed DOF stays fixed.
|
|
9
|
+
*/
|
|
10
|
+
export interface LineRestraint {
|
|
11
|
+
nodeIds: [FeaId, FeaId];
|
|
12
|
+
ux?: boolean;
|
|
13
|
+
uy?: boolean;
|
|
14
|
+
uz?: boolean;
|
|
15
|
+
rx?: boolean;
|
|
16
|
+
ry?: boolean;
|
|
17
|
+
rz?: boolean;
|
|
18
|
+
}
|
|
19
|
+
export interface NodalLoad {
|
|
20
|
+
loadCase: string;
|
|
21
|
+
nodeId: FeaId;
|
|
22
|
+
fx?: number;
|
|
23
|
+
fy?: number;
|
|
24
|
+
fz?: number;
|
|
25
|
+
mx?: number;
|
|
26
|
+
my?: number;
|
|
27
|
+
mz?: number;
|
|
28
|
+
}
|
|
29
|
+
/** Descriptive category of a load case; it labels the case and does not change the analysis. */
|
|
30
|
+
export type LoadCaseType = "dead" | "superDead" | "live" | "roofLive" | "snow" | "wind" | "seismic" | "other";
|
|
31
|
+
/**
|
|
32
|
+
* One independently analysed set of loads, e.g. dead, superimposed dead or live. The loads
|
|
33
|
+
* themselves are listed in `FeaModel.nodalLoads` and `FeaModel.memberLoads`, each tagged
|
|
34
|
+
* with its `loadCase`.
|
|
35
|
+
*/
|
|
36
|
+
export interface LoadCase {
|
|
37
|
+
id: string;
|
|
38
|
+
name?: string;
|
|
39
|
+
type?: LoadCaseType;
|
|
40
|
+
/**
|
|
41
|
+
* Self-weight multiplier (1 = full self-weight). Applies `selfWeight · unitWeight · A` per unit
|
|
42
|
+
* length of every member and `selfWeight · unitWeight · thickness` (times `modifiers.weight`)
|
|
43
|
+
* per unit area of every shell, along global −Z. Default 0.
|
|
44
|
+
*/
|
|
45
|
+
selfWeight?: number;
|
|
46
|
+
}
|
|
47
|
+
/** One term of a load combination: a factor times a load case or another combination. */
|
|
48
|
+
export type CombinationTerm = {
|
|
49
|
+
case: string;
|
|
50
|
+
factor: number;
|
|
51
|
+
} | {
|
|
52
|
+
combination: string;
|
|
53
|
+
factor: number;
|
|
54
|
+
};
|
|
55
|
+
/** A linear combination (sum of factored terms) of load cases and other combinations. */
|
|
56
|
+
export interface LoadCombination {
|
|
57
|
+
id: string;
|
|
58
|
+
name?: string;
|
|
59
|
+
terms: CombinationTerm[];
|
|
60
|
+
}
|
|
61
|
+
export interface FeaModel {
|
|
62
|
+
nodes: FeaNode[];
|
|
63
|
+
/** Frame members; omit for a model of shells only, e.g. a mat foundation. */
|
|
64
|
+
members?: Member[];
|
|
65
|
+
restraints: Restraint[];
|
|
66
|
+
/** Fixed DOFs of every node along straight lines, generated mesh nodes included. */
|
|
67
|
+
lineRestraints?: LineRestraint[];
|
|
68
|
+
loadCases: LoadCase[];
|
|
69
|
+
/** Nodal loads of every load case, each tagged with its `loadCase`. */
|
|
70
|
+
nodalLoads?: NodalLoad[];
|
|
71
|
+
/** Member loads of every load case, each tagged with its `loadCase`. */
|
|
72
|
+
memberLoads?: MemberLoad[];
|
|
73
|
+
/** Null areas that distribute `areaLoads` to the members along their edges. */
|
|
74
|
+
areas?: NullArea[];
|
|
75
|
+
/** Shell areas: four-node flat shell elements with membrane and/or plate stiffness. */
|
|
76
|
+
shells?: ShellArea[];
|
|
77
|
+
/** Area loads of every load case, each tagged with its `loadCase`. */
|
|
78
|
+
areaLoads?: AreaLoad[];
|
|
79
|
+
combinations?: LoadCombination[];
|
|
80
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model.type.js","sourceRoot":"","sources":["../../../../src/fea/analysis/types/model.type.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import type { Warnings } from "../../../core/types/output-message.type";
|
|
2
|
+
import type { MemberDiagram, MemberEndForces, MemberReleaseDeformations, StationComponent } from "../../frame/types/results.type";
|
|
3
|
+
import type { FeaId } from "../../shared/types/model.type";
|
|
4
|
+
import type { FeaMesh, ShellElementForces, ShellForceComponent } from "../../shell/types/results.type";
|
|
5
|
+
import type { LoadCaseType } from "./model.type";
|
|
6
|
+
export interface NodalDisplacement {
|
|
7
|
+
nodeId: FeaId;
|
|
8
|
+
ux: number;
|
|
9
|
+
uy: number;
|
|
10
|
+
uz: number;
|
|
11
|
+
rx: number;
|
|
12
|
+
ry: number;
|
|
13
|
+
rz: number;
|
|
14
|
+
}
|
|
15
|
+
export interface NodalReaction {
|
|
16
|
+
nodeId: FeaId;
|
|
17
|
+
fx: number;
|
|
18
|
+
fy: number;
|
|
19
|
+
fz: number;
|
|
20
|
+
mx: number;
|
|
21
|
+
my: number;
|
|
22
|
+
mz: number;
|
|
23
|
+
}
|
|
24
|
+
/** A rotation direction at a node held by `analyze` because no member resists it. */
|
|
25
|
+
export interface AutoRestrainedDof {
|
|
26
|
+
nodeId: FeaId;
|
|
27
|
+
/** Unit vector of the held rotation axis, global X, Y, Z. */
|
|
28
|
+
axis: [number, number, number];
|
|
29
|
+
/** The global rotation DOF when `axis` is a global axis. */
|
|
30
|
+
dof?: "rx" | "ry" | "rz";
|
|
31
|
+
}
|
|
32
|
+
/** Max or min of a result across combinations, with the combination that produces it. */
|
|
33
|
+
export interface GoverningValue {
|
|
34
|
+
value: number;
|
|
35
|
+
combinationId: string;
|
|
36
|
+
}
|
|
37
|
+
export interface GoverningExtremeValue extends GoverningValue {
|
|
38
|
+
x: number;
|
|
39
|
+
}
|
|
40
|
+
export type Bound<T> = {
|
|
41
|
+
max: T;
|
|
42
|
+
min: T;
|
|
43
|
+
};
|
|
44
|
+
/** Results of one load case or one load combination. */
|
|
45
|
+
export interface FeaCaseResult {
|
|
46
|
+
id: string;
|
|
47
|
+
kind: "case" | "combination";
|
|
48
|
+
name?: string;
|
|
49
|
+
type?: LoadCaseType;
|
|
50
|
+
nodalDisplacements: NodalDisplacement[];
|
|
51
|
+
reactions: NodalReaction[];
|
|
52
|
+
memberEndForces: MemberEndForces[];
|
|
53
|
+
/** One entry per member with any released or spring end DOF, in model order. */
|
|
54
|
+
releaseDeformations: MemberReleaseDeformations[];
|
|
55
|
+
memberDiagrams: MemberDiagram[];
|
|
56
|
+
/** One entry per shell element, area by area in model order (see `FeaResult.mesh`). */
|
|
57
|
+
shellForces: ShellElementForces[];
|
|
58
|
+
equilibriumResidual: {
|
|
59
|
+
force: number;
|
|
60
|
+
moment: number;
|
|
61
|
+
};
|
|
62
|
+
warnings: Warnings;
|
|
63
|
+
}
|
|
64
|
+
/** Max/min of every result across a set of combinations, with the governing combination. */
|
|
65
|
+
export interface FeaEnvelope {
|
|
66
|
+
combinationIds: string[];
|
|
67
|
+
nodalDisplacements: ({
|
|
68
|
+
nodeId: FeaId;
|
|
69
|
+
} & Record<"ux" | "uy" | "uz" | "rx" | "ry" | "rz", Bound<GoverningValue>>)[];
|
|
70
|
+
reactions: ({
|
|
71
|
+
nodeId: FeaId;
|
|
72
|
+
} & Record<"fx" | "fy" | "fz" | "mx" | "my" | "mz", Bound<GoverningValue>>)[];
|
|
73
|
+
members: {
|
|
74
|
+
memberId: FeaId;
|
|
75
|
+
extremes: Record<StationComponent, Bound<GoverningExtremeValue>>;
|
|
76
|
+
}[];
|
|
77
|
+
shells: {
|
|
78
|
+
shellId: FeaId;
|
|
79
|
+
corners: ({
|
|
80
|
+
nodeId: FeaId;
|
|
81
|
+
} & Record<ShellForceComponent, Bound<GoverningValue>>)[];
|
|
82
|
+
}[];
|
|
83
|
+
}
|
|
84
|
+
export interface FeaResult {
|
|
85
|
+
cases: Record<string, FeaCaseResult>;
|
|
86
|
+
combinations: Record<string, FeaCaseResult>;
|
|
87
|
+
/** Envelope over all combinations; absent when the model has none. */
|
|
88
|
+
envelope?: FeaEnvelope;
|
|
89
|
+
/** The shell mesh; absent when the model has no shells. */
|
|
90
|
+
mesh?: FeaMesh;
|
|
91
|
+
calculationDetails: {
|
|
92
|
+
nodeCount: number;
|
|
93
|
+
memberCount: number;
|
|
94
|
+
shellCount: number;
|
|
95
|
+
dofCount: number;
|
|
96
|
+
freeDofCount: number;
|
|
97
|
+
profileSize: number;
|
|
98
|
+
loadCaseCount: number;
|
|
99
|
+
combinationCount: number;
|
|
100
|
+
/** Joint rotations held because every member there releases them (e.g. truss joints). */
|
|
101
|
+
autoRestrainedDofs: AutoRestrainedDof[];
|
|
102
|
+
};
|
|
103
|
+
units: {
|
|
104
|
+
force: "kN";
|
|
105
|
+
moment: "kN·m";
|
|
106
|
+
length: "mm";
|
|
107
|
+
rotation: "rad";
|
|
108
|
+
forcePerLength: "kN/m";
|
|
109
|
+
momentPerLength: "kN·m/m";
|
|
110
|
+
stress: "MPa";
|
|
111
|
+
};
|
|
112
|
+
warnings: Warnings;
|
|
113
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"results.type.js","sourceRoot":"","sources":["../../../../src/fea/analysis/types/results.type.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type FeaModelIssue } from "../../../core/errors/fea.error";
|
|
2
|
+
import type { FeaModel } from "../types/model.type";
|
|
3
|
+
/**
|
|
4
|
+
* Checks a model without analysing it and returns every problem found, each with the
|
|
5
|
+
* node, member, load case, combination and field it concerns. An empty array means the
|
|
6
|
+
* model can be analysed, apart from an unstable structure (304) and a translation that nothing
|
|
7
|
+
* resists at a node connected only to shells (328), which only assembling the stiffness detects.
|
|
8
|
+
*
|
|
9
|
+
* @param model - The model to check
|
|
10
|
+
* @returns Every problem found (codes 301–303, 305–317 and 326–327, 329), in model order
|
|
11
|
+
*/
|
|
12
|
+
export declare const validateModel: (model: FeaModel) => FeaModelIssue[];
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.validateModel = void 0;
|
|
4
|
+
const fea_error_1 = require("../../../core/errors/fea.error");
|
|
5
|
+
const validate_members_1 = require("../../frame/validation/validate-members");
|
|
6
|
+
const validate_null_areas_1 = require("../../frame/validation/validate-null-areas");
|
|
7
|
+
const issues_1 = require("../../shared/validation/issues");
|
|
8
|
+
const validate_shells_1 = require("../../shell/validation/validate-shells");
|
|
9
|
+
const combinations_1 = require("../solver/combinations");
|
|
10
|
+
const DOF_KEYS = ["ux", "uy", "uz", "rx", "ry", "rz"];
|
|
11
|
+
const NODAL_LOAD_KEYS = ["fx", "fy", "fz", "mx", "my", "mz"];
|
|
12
|
+
const GLOBAL_DIRECTIONS = new Set(["X", "Y", "Z"]);
|
|
13
|
+
const AREA_DIRECTIONS = {
|
|
14
|
+
"3": "normal",
|
|
15
|
+
X: [1, 0, 0],
|
|
16
|
+
Y: [0, 1, 0],
|
|
17
|
+
Z: [0, 0, 1],
|
|
18
|
+
};
|
|
19
|
+
const LOAD_CASE_TYPES = new Set([
|
|
20
|
+
"dead",
|
|
21
|
+
"superDead",
|
|
22
|
+
"live",
|
|
23
|
+
"roofLive",
|
|
24
|
+
"snow",
|
|
25
|
+
"wind",
|
|
26
|
+
"seismic",
|
|
27
|
+
"other",
|
|
28
|
+
]);
|
|
29
|
+
/**
|
|
30
|
+
* Checks a model without analysing it and returns every problem found, each with the
|
|
31
|
+
* node, member, load case, combination and field it concerns. An empty array means the
|
|
32
|
+
* model can be analysed, apart from an unstable structure (304) and a translation that nothing
|
|
33
|
+
* resists at a node connected only to shells (328), which only assembling the stiffness detects.
|
|
34
|
+
*
|
|
35
|
+
* @param model - The model to check
|
|
36
|
+
* @returns Every problem found (codes 301–303, 305–317 and 326–327, 329), in model order
|
|
37
|
+
*/
|
|
38
|
+
const validateModel = (model) => {
|
|
39
|
+
const issues = [];
|
|
40
|
+
const add = (std, details = {}) => issues.push((0, issues_1.modelIssue)(std, details));
|
|
41
|
+
const nodes = Array.isArray(model.nodes) ? model.nodes : [];
|
|
42
|
+
const members = Array.isArray(model.members) ? model.members : [];
|
|
43
|
+
const restraints = Array.isArray(model.restraints) ? model.restraints : [];
|
|
44
|
+
const loadCases = Array.isArray(model.loadCases) ? model.loadCases : [];
|
|
45
|
+
const combinations = Array.isArray(model.combinations) ? model.combinations : [];
|
|
46
|
+
const nodalLoads = Array.isArray(model.nodalLoads) ? model.nodalLoads : [];
|
|
47
|
+
const memberLoads = Array.isArray(model.memberLoads) ? model.memberLoads : [];
|
|
48
|
+
const areas = Array.isArray(model.areas) ? model.areas : [];
|
|
49
|
+
const shells = Array.isArray(model.shells) ? model.shells : [];
|
|
50
|
+
const lineRestraints = Array.isArray(model.lineRestraints) ? model.lineRestraints : [];
|
|
51
|
+
const areaLoads = Array.isArray(model.areaLoads) ? model.areaLoads : [];
|
|
52
|
+
// ---- Ids -------------------------------------------------------------------------
|
|
53
|
+
const duplicates = (ids) => ids.filter((id, i) => ids.indexOf(id) !== i);
|
|
54
|
+
for (const nodeId of new Set(duplicates(nodes.map((n) => n.id)))) {
|
|
55
|
+
add(fea_error_1.FeaErrors.DUPLICATE_ID, { nodeId, field: "id" });
|
|
56
|
+
}
|
|
57
|
+
for (const memberId of new Set(duplicates(members.map((m) => m.id)))) {
|
|
58
|
+
add(fea_error_1.FeaErrors.DUPLICATE_ID, { memberId, field: "id" });
|
|
59
|
+
}
|
|
60
|
+
for (const areaId of new Set(duplicates(areas.map((a) => a.id)))) {
|
|
61
|
+
add(fea_error_1.FeaErrors.DUPLICATE_ID, { areaId, field: "id" });
|
|
62
|
+
}
|
|
63
|
+
// shells share the area id namespace: a duplicate within shells or with a null area
|
|
64
|
+
const nullAreaIds = new Set(areas.map((a) => a.id));
|
|
65
|
+
for (const shellId of new Set([
|
|
66
|
+
...duplicates(shells.map((sh) => sh.id)),
|
|
67
|
+
...shells.map((sh) => sh.id).filter((id) => nullAreaIds.has(id)),
|
|
68
|
+
])) {
|
|
69
|
+
add(fea_error_1.FeaErrors.DUPLICATE_ID, { shellId, field: "id" });
|
|
70
|
+
}
|
|
71
|
+
for (const nodeId of new Set(duplicates(restraints.map((r) => r.nodeId)))) {
|
|
72
|
+
add(fea_error_1.FeaErrors.DUPLICATE_ID, { nodeId, field: "restraints" });
|
|
73
|
+
}
|
|
74
|
+
const caseIds = new Set(loadCases.map((c) => c.id));
|
|
75
|
+
const combinationIds = new Set(combinations.map((c) => c.id));
|
|
76
|
+
for (const id of new Set(duplicates([...loadCases.map((c) => c.id), ...combinations.map((c) => c.id)]))) {
|
|
77
|
+
add(fea_error_1.FeaErrors.DUPLICATE_ID, combinationIds.has(id) && !caseIds.has(id) ? { combinationId: id } : { loadCaseId: id });
|
|
78
|
+
}
|
|
79
|
+
// ---- Nodes -----------------------------------------------------------------------
|
|
80
|
+
const nodeById = new Map();
|
|
81
|
+
const validNode = new Set();
|
|
82
|
+
for (const node of nodes) {
|
|
83
|
+
nodeById.set(node.id, node);
|
|
84
|
+
let ok = true;
|
|
85
|
+
for (const field of ["x", "y", "z"]) {
|
|
86
|
+
if (!(0, issues_1.isFiniteNumber)(node[field])) {
|
|
87
|
+
add(fea_error_1.FeaErrors.INVALID_INPUT_VALUE, { nodeId: node.id, field });
|
|
88
|
+
ok = false;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
if (ok)
|
|
92
|
+
validNode.add(node.id);
|
|
93
|
+
}
|
|
94
|
+
// ---- Members ---------------------------------------------------------------------
|
|
95
|
+
const checkedMembers = (0, validate_members_1.validateMembers)(members, nodeById, validNode);
|
|
96
|
+
issues.push(...checkedMembers.issues);
|
|
97
|
+
const { memberLength } = checkedMembers;
|
|
98
|
+
// ---- Restraints ------------------------------------------------------------------
|
|
99
|
+
let anyRestrained = false;
|
|
100
|
+
for (const restraint of restraints) {
|
|
101
|
+
if (!nodeById.has(restraint.nodeId)) {
|
|
102
|
+
add(fea_error_1.FeaErrors.UNKNOWN_NODE_REFERENCE, { nodeId: restraint.nodeId, field: "restraints" });
|
|
103
|
+
}
|
|
104
|
+
for (const field of DOF_KEYS) {
|
|
105
|
+
const v = restraint[field];
|
|
106
|
+
if (v === undefined || v === false)
|
|
107
|
+
continue;
|
|
108
|
+
if (v === true) {
|
|
109
|
+
anyRestrained = true;
|
|
110
|
+
}
|
|
111
|
+
else if ((0, issues_1.isFiniteNumber)(v) && v >= 0) {
|
|
112
|
+
if (v > 0)
|
|
113
|
+
anyRestrained = true;
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
add(fea_error_1.FeaErrors.INVALID_INPUT_VALUE, { nodeId: restraint.nodeId, field });
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
for (const line of lineRestraints) {
|
|
121
|
+
const ids = Array.isArray(line.nodeIds) ? line.nodeIds : [];
|
|
122
|
+
const at = { nodeId: ids[0], field: "lineRestraints.nodeIds" };
|
|
123
|
+
if (ids.length !== 2 || ids[0] === ids[1])
|
|
124
|
+
add(fea_error_1.FeaErrors.INVALID_INPUT_VALUE, at);
|
|
125
|
+
else if (ids.some((id) => !nodeById.has(id)))
|
|
126
|
+
add(fea_error_1.FeaErrors.UNKNOWN_NODE_REFERENCE, at);
|
|
127
|
+
for (const field of DOF_KEYS) {
|
|
128
|
+
const v = line[field];
|
|
129
|
+
if (v === undefined || v === false)
|
|
130
|
+
continue;
|
|
131
|
+
if (v === true)
|
|
132
|
+
anyRestrained = true;
|
|
133
|
+
else
|
|
134
|
+
add(fea_error_1.FeaErrors.INVALID_INPUT_VALUE, { nodeId: ids[0], field: `lineRestraints.${field}` });
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
if (!anyRestrained)
|
|
138
|
+
add(fea_error_1.FeaErrors.NO_RESTRAINTS);
|
|
139
|
+
// ---- Load cases ------------------------------------------------------------------
|
|
140
|
+
if (loadCases.length === 0)
|
|
141
|
+
add(fea_error_1.FeaErrors.NO_LOAD_CASES);
|
|
142
|
+
for (const loadCase of loadCases) {
|
|
143
|
+
const at = { loadCaseId: loadCase.id };
|
|
144
|
+
if (loadCase.type !== undefined && !LOAD_CASE_TYPES.has(loadCase.type)) {
|
|
145
|
+
add(fea_error_1.FeaErrors.INVALID_INPUT_VALUE, { ...at, field: "type" });
|
|
146
|
+
}
|
|
147
|
+
if (loadCase.selfWeight === undefined)
|
|
148
|
+
continue;
|
|
149
|
+
if (!(0, issues_1.isFiniteNumber)(loadCase.selfWeight)) {
|
|
150
|
+
add(fea_error_1.FeaErrors.INVALID_LOAD_FACTOR, { ...at, field: "selfWeight" });
|
|
151
|
+
continue;
|
|
152
|
+
}
|
|
153
|
+
if (loadCase.selfWeight !== 0) {
|
|
154
|
+
for (const member of members) {
|
|
155
|
+
if (member.section?.unitWeight === undefined) {
|
|
156
|
+
add(fea_error_1.FeaErrors.MISSING_UNIT_WEIGHT, { ...at, memberId: member.id, field: "unitWeight" });
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
for (const shell of shells) {
|
|
160
|
+
if (shell.section?.unitWeight === undefined) {
|
|
161
|
+
add(fea_error_1.FeaErrors.MISSING_UNIT_WEIGHT, {
|
|
162
|
+
...at,
|
|
163
|
+
shellId: shell.id,
|
|
164
|
+
field: "section.unitWeight",
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
// ---- Loads -----------------------------------------------------------------------
|
|
171
|
+
for (const load of nodalLoads) {
|
|
172
|
+
const at = { loadCaseId: load.loadCase, nodeId: load.nodeId };
|
|
173
|
+
if (!caseIds.has(load.loadCase))
|
|
174
|
+
add(fea_error_1.FeaErrors.UNKNOWN_LOAD_CASE, { ...at, field: "loadCase" });
|
|
175
|
+
if (!nodeById.has(load.nodeId))
|
|
176
|
+
add(fea_error_1.FeaErrors.UNKNOWN_NODE_REFERENCE, { ...at, field: "nodeId" });
|
|
177
|
+
for (const field of NODAL_LOAD_KEYS) {
|
|
178
|
+
if (load[field] !== undefined && !(0, issues_1.isFiniteNumber)(load[field])) {
|
|
179
|
+
add(fea_error_1.FeaErrors.INVALID_INPUT_VALUE, { ...at, field });
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
issues.push(...(0, validate_members_1.validateMemberLoads)(memberLoads, members, memberLength, caseIds));
|
|
184
|
+
// ---- Areas -----------------------------------------------------------------------
|
|
185
|
+
const checkedAreas = (0, validate_null_areas_1.validateNullAreas)(areas, members, memberLength, nodeById, validNode);
|
|
186
|
+
issues.push(...checkedAreas.issues);
|
|
187
|
+
const { areaInfo } = checkedAreas;
|
|
188
|
+
// ---- Shells ----------------------------------------------------------------------
|
|
189
|
+
issues.push(...(0, validate_shells_1.validateShells)(shells, nodeById, validNode));
|
|
190
|
+
// the mesh, once every shell and its mesh settings are valid
|
|
191
|
+
const shellProblem = issues.some((i) => i.details.shellId !== undefined);
|
|
192
|
+
const nodeProblem = nodes.length !== validNode.size;
|
|
193
|
+
if (shells.length > 0 && !shellProblem && !nodeProblem) {
|
|
194
|
+
issues.push(...(0, validate_shells_1.validateShellMesh)(nodes, shells));
|
|
195
|
+
}
|
|
196
|
+
const areaIds = new Set([...areas.map((a) => a.id), ...shells.map((sh) => sh.id)]);
|
|
197
|
+
for (const load of areaLoads) {
|
|
198
|
+
const at = { loadCaseId: load.loadCase, areaId: load.areaId };
|
|
199
|
+
if (!caseIds.has(load.loadCase))
|
|
200
|
+
add(fea_error_1.FeaErrors.UNKNOWN_LOAD_CASE, { ...at, field: "loadCase" });
|
|
201
|
+
if (!areaIds.has(load.areaId)) {
|
|
202
|
+
add(fea_error_1.FeaErrors.UNKNOWN_NODE_REFERENCE, { ...at, field: "areaId" });
|
|
203
|
+
}
|
|
204
|
+
const direction = Object.prototype.hasOwnProperty.call(AREA_DIRECTIONS, load.direction)
|
|
205
|
+
? AREA_DIRECTIONS[load.direction]
|
|
206
|
+
: undefined;
|
|
207
|
+
if (!direction)
|
|
208
|
+
add(fea_error_1.FeaErrors.INVALID_INPUT_VALUE, { ...at, field: "direction" });
|
|
209
|
+
if (!(0, issues_1.isFiniteNumber)(load.q))
|
|
210
|
+
add(fea_error_1.FeaErrors.INVALID_INPUT_VALUE, { ...at, field: "q" });
|
|
211
|
+
if ((load.projected !== undefined && typeof load.projected !== "boolean") ||
|
|
212
|
+
(load.projected === true && !GLOBAL_DIRECTIONS.has(load.direction))) {
|
|
213
|
+
add(fea_error_1.FeaErrors.INVALID_INPUT_VALUE, { ...at, field: "projected" });
|
|
214
|
+
}
|
|
215
|
+
const info = areaInfo.get(load.areaId);
|
|
216
|
+
if (direction &&
|
|
217
|
+
direction !== "normal" &&
|
|
218
|
+
info &&
|
|
219
|
+
(0, validate_null_areas_1.loadsAlongCantileverSupport)(info, direction)) {
|
|
220
|
+
add(fea_error_1.FeaErrors.INVALID_AREA_DISTRIBUTION, { ...at, field: "direction" });
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
// ---- Combinations ----------------------------------------------------------------
|
|
224
|
+
let referencesOk = true;
|
|
225
|
+
for (const combination of combinations) {
|
|
226
|
+
const at = { combinationId: combination.id };
|
|
227
|
+
if (!Array.isArray(combination.terms) || combination.terms.length === 0) {
|
|
228
|
+
add(fea_error_1.FeaErrors.INVALID_LOAD_FACTOR, { ...at, field: "terms" });
|
|
229
|
+
referencesOk = false;
|
|
230
|
+
continue;
|
|
231
|
+
}
|
|
232
|
+
for (const term of combination.terms) {
|
|
233
|
+
if (!(0, issues_1.isFiniteNumber)(term.factor)) {
|
|
234
|
+
add(fea_error_1.FeaErrors.INVALID_LOAD_FACTOR, { ...at, field: "factor" });
|
|
235
|
+
referencesOk = false;
|
|
236
|
+
}
|
|
237
|
+
const caseRef = "case" in term ? term.case : undefined;
|
|
238
|
+
const comboRef = "combination" in term ? term.combination : undefined;
|
|
239
|
+
if ((caseRef === undefined) === (comboRef === undefined)) {
|
|
240
|
+
add(fea_error_1.FeaErrors.UNKNOWN_LOAD_CASE, { ...at, field: "terms" });
|
|
241
|
+
referencesOk = false;
|
|
242
|
+
}
|
|
243
|
+
else if (caseRef !== undefined && !caseIds.has(caseRef)) {
|
|
244
|
+
add(fea_error_1.FeaErrors.UNKNOWN_LOAD_CASE, { ...at, loadCaseId: caseRef, field: "case" });
|
|
245
|
+
referencesOk = false;
|
|
246
|
+
}
|
|
247
|
+
else if (comboRef !== undefined && !combinationIds.has(comboRef)) {
|
|
248
|
+
add(fea_error_1.FeaErrors.UNKNOWN_LOAD_CASE, { ...at, field: "combination" });
|
|
249
|
+
referencesOk = false;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
if (referencesOk && combinations.length > 0) {
|
|
254
|
+
try {
|
|
255
|
+
(0, combinations_1.resolveCombinations)(combinations, caseIds);
|
|
256
|
+
}
|
|
257
|
+
catch (e) {
|
|
258
|
+
if (e instanceof fea_error_1.FeaError)
|
|
259
|
+
issues.push({ ...(0, issues_1.modelIssue)(e, e.details) });
|
|
260
|
+
else
|
|
261
|
+
throw e;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
return issues;
|
|
265
|
+
};
|
|
266
|
+
exports.validateModel = validateModel;
|
|
267
|
+
//# sourceMappingURL=validate-model.js.map
|