forked from 1b-agent/fieldcraft-upstream
Implicit solver: reference points, couplings, moments, wedge6 (M4) (#26)
* fem: wedge6 element (triangle × interval, 3 × 2 points), patch and cantilever tests Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01NmAttHhUZTokgPeEJia8sm * solver: reference points, kinematic and distributing couplings, moments by constraint elimination Coupled reference points get six degrees of freedom; kinematic couplings are rigid links, distributing couplings least-squares interpolation constraints. Every constraint row and prescribed value is eliminated master-slave (Abel-Shephard pivot choice), so the reduced matrix stays SPD; no coupling gives the old elimination bit for bit. Verified: rigid motion of a coupled block, clamping through a point, distributing tension vs pressure, bending and tube torsion. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01NmAttHhUZTokgPeEJia8sm * engine: reference point results in solve.static and solve.probe Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01NmAttHhUZTokgPeEJia8sm * docs: couplings, moments and wedge6 in the solver docs, literature and roadmap Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01NmAttHhUZTokgPeEJia8sm * solver: simplify constraint elimination and reference point plumbing Rows combine by one sort; T_f transposed once; K and M reduced in one pass on a shared pattern; prescribed motion computed once; reference point loads and BCs go through Resolved like node ones (Mesh::label_dofs); one dof-direction rule; StepResult::locate for probes; dead Csr::restrict removed. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01NmAttHhUZTokgPeEJia8sm * solver: refuse oversized reductions before allocating them A held distributing coupling point makes a dense (3N)^2 block; estimate it from the constraint rows and refuse it against the factorization's memory budget with a clear message, before anything is built. Other reductions with dependents count their entries first (stopping at the budget) and reserve fallibly. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01NmAttHhUZTokgPeEJia8sm --------- Co-authored-by: jyviko <[email protected]> Co-authored-by: Claude Opus 5.5 <[email protected]>
This commit is contained in:
18 files changed
+1502
-199
No files matched your search
+25
-10
@@ -21,7 +21,7 @@ crates in strictly lower layers.
|
||||
| L0 | `modelcraft-model` | Solver-neutral FE model: nodes and elements by label, their geometry tags, sets, materials, sections, couplings, BCs, loads and steps, the model check and the resolved view the writers read. Knows no file format and no geometry type. | started |
|
||||
| L1 | `modelcraft-geometry` | The only door to SolidCraft: opens `.solidcraft` designs (rebuilt from their timeline, bodies with persistent face names), B-rep bodies, measures, tessellation into a face-tagged `SurfaceMesh`; face-tagged 3MF files read into the same type without the kernel (docs/formats/tagged-mesh.md). No SolidCraft type in its API. | started |
|
||||
| L1 | `modelcraft-mesh` | Surface preparation (weld, watertightness, feature edges), robust predicates, Delaunay tetrahedralization and refinement, Voronoi-based optimization, hex meshing, quality metrics. | started |
|
||||
| L1 | `modelcraft-fem` | Element kernels shared by every structural solver: the element table (tet4, tet10, hex8 full and incompatible modes, hex20 full and reduced), shape functions, quadrature, element stiffness, consistent and lumped mass, body and pressure loads, stresses and their extrapolation, isotropic and orthotropic elasticity. Pure functions, no solver loop. | started |
|
||||
| L1 | `modelcraft-fem` | Element kernels shared by every structural solver: the element table (tet4, tet10, wedge6, hex8 full and incompatible modes, hex20 full and reduced), shape functions, quadrature, element stiffness, consistent and lumped mass, body and pressure loads, stresses and their extrapolation, isotropic and orthotropic elasticity. Pure functions, no solver loop. | started |
|
||||
| L1 | `modelcraft-decks` | Abaqus input, Nastran bulk data and LS-DYNA keyword readers and writers, to and from `model`. Text out, no file system; `deck.write` saves it. | started |
|
||||
| L1 | `modelcraft-render` | Display data without a GPU dependency: the visible faces, element edges and nodes of a model, the orbit camera, a CPU rasterizer for headless snapshots; contour maps later. | started |
|
||||
| L2 | `modelcraft-solver` | Implicit solver: assembly from the resolved model, boundary conditions, sparse direct solution, linear static and modal analysis, stresses and reactions. The explicit (`modelcraft-explicit`) and lattice Boltzmann (`modelcraft-lbm`) solvers join this layer. | started |
|
||||
@@ -130,19 +130,29 @@ module docs; ADR 0001 records why the linear algebra is our own.
|
||||
|
||||
1. **System.** `Model::resolve()`; each solid section's elements take their material's
|
||||
elasticity matrix and the section's formulation (`modelcraft_fem::element::ELEMENT_TYPES`, one
|
||||
row per element kind). Couplings, reference points, moments, shells and beams return "not
|
||||
supported yet". The step's boundary conditions prescribe translations (rotations do not exist
|
||||
on solid nodes); its loads become a load vector: forces and tractions from
|
||||
`Resolved::nodal_loads`, pressure as consistent face loads, gravity and body forces through the
|
||||
row per element kind: tet4, tet10, wedge6, hex8, hex20). Every reference point a coupling
|
||||
ties to the mesh gets six degrees of freedom (translations, rotations) after the mesh's. Shells
|
||||
and beams return "not supported yet". The step's boundary conditions prescribe translations
|
||||
(rotations do not exist on solid nodes) and a coupled point's six directions; its loads become
|
||||
a load vector: forces and tractions from `Resolved::nodal_loads`, forces and moments on coupled
|
||||
reference points, pressure as consistent face loads, gravity and body forces through the
|
||||
element shape functions.
|
||||
2. **Assembly** on the node graph (3 × 3 blocks, elements in label order, so sums are
|
||||
reproducible bit for bit).
|
||||
3. **Ordering and elimination.** Nested dissection of the nodes by coordinate bisection; free
|
||||
degrees of freedom numbered in that order; prescribed values moved to the right-hand side (no
|
||||
penalty).
|
||||
3. **Ordering and elimination** (`constraints`). Nested dissection of the nodes by coordinate
|
||||
bisection. Couplings become linear constraint rows: kinematic = rigid link of each coupled
|
||||
translation to the point's translation and rotation; distributing = the point follows the
|
||||
least-squares rigid fit of the set's translations (equal weights, the deck writers' choice).
|
||||
Prescribed values and rows are eliminated master–slave in a fixed order, one dependent degree
|
||||
of freedom per row (the coupled node or the distributing point while it is free, else the
|
||||
largest coefficient), giving u = T_f q + T_p u_p; the reduced matrix T_fᵀ K T_f stays
|
||||
symmetric positive definite (no penalty, no multipliers). Free mesh equations follow the
|
||||
node order, reference point equations come last. Without couplings T is a selection and the
|
||||
numbers are those of plain elimination, bit for bit.
|
||||
4. **Static solution.** Up-looking sparse Cholesky (the factor size is computed and capped before
|
||||
any value), reactions K u − f, integration-point stresses extrapolated to the nodes and
|
||||
averaged, von Mises. A zero pivot names the node and direction that can move freely.
|
||||
any value), reactions T_pᵀ (K u − f) (at nodes and at prescribed reference points, forces and
|
||||
moments), integration-point stresses extrapolated to the nodes and averaged, von Mises. A zero
|
||||
pivot names the node or reference point and direction that can move freely.
|
||||
5. **Frequency.** Shift-invert block Lanczos (block 6, full reorthogonalization) on
|
||||
K − σM, σ = 0 for a supported structure and slightly negative for a free one, so rigid-body
|
||||
modes come out at zero; mass-normalized shapes, participation factors and effective masses.
|
||||
@@ -154,6 +164,11 @@ Verification (`crates/solver/tests/verification.rs`, analytic only): displacemen
|
||||
patch tests for every element and formulation (exact to round-off), cantilever tip deflection
|
||||
against Timoshenko with convergence rates of the linear elements, Lamé's cylinder, Kirsch's
|
||||
plate with a hole (Kt → 3), cantilever and free–free beam frequencies with six rigid-body modes.
|
||||
`crates/solver/tests/couplings.rs`: a block given a rigid motion through a coupled point
|
||||
(kinematic and distributing), clamping through a coupled point equals clamping (static and
|
||||
modes), tension through a distributing coupling against the equivalent pressure away from the
|
||||
end, pure bending by a moment through a distributing coupling, torsion of a tube by a moment on
|
||||
a kinematically coupled point (twist and shear stress).
|
||||
|
||||
## Commands
|
||||
|
||||
|
||||
+1
-1
@@ -60,7 +60,7 @@ products are run, no documentation text is copied). Status: **done**, **started*
|
||||
| Decks | Nastran bulk data writer (`deck.write`, SOL 101 or 103 per deck; reports what Nastran cannot express) | M3 | | done |
|
||||
| Decks | LS-DYNA keyword writer (implicit; explicit in M8) | M3 | | done (implicit static and eigenvalue; beam sections planned) |
|
||||
| Decks | Readers keeping unknown keywords | M9 | | planned |
|
||||
| Solve | Own linear static and modal solver, verified against analytic solutions | M4 | yes | started (solid elements: tet4, tet10, hex8, hex20) |
|
||||
| Solve | Own linear static and modal solver, verified against analytic solutions | M4 | yes | started (solid elements: tet4, tet10, wedge6, hex8, hex20; reference points, kinematic and distributing couplings, moments) |
|
||||
| Results | Deformed shape, contours, mode shapes, probes, reaction sums | M4 | | started (results in the session, `solve.probe`, reaction sums; display planned) |
|
||||
| Results | XY and path plots, cuts, display groups, free-body forces, animation | M9 | | planned |
|
||||
| Results | Readers for public result formats (Nastran OP2, LS-DYNA d3plot, Abaqus `.fil`) | M9 | | planned |
|
||||
|
||||
@@ -977,6 +977,17 @@ the module docs):
|
||||
Lewis, H. D. Simon, SIAM J. Matrix Anal. Appl. 15(1):228–272, 1994; B. N. Parlett, *The
|
||||
Symmetric Eigenvalue Problem*, SIAM 1998; G. H. Golub, C. F. Van Loan, *Matrix Computations*,
|
||||
4th ed., 2013.
|
||||
- Wedge6: the linear triangle times the linear interval; the symmetric three-point triangle rule
|
||||
(Zienkiewicz, Taylor & Zhu 2013, table 6.3) times two-point Gauss–Legendre.
|
||||
- Couplings and constraint elimination: rigid links and master–slave elimination by
|
||||
transformation, R. D. Cook, D. S. Malkus, M. E. Plesha, R. J. Witt, *Concepts and Applications
|
||||
of Finite Element Analysis*, 4th ed., Wiley 2002, §9.2, and C. A. Felippa, *Introduction to
|
||||
Finite Element Methods*, ch. 8 (University of Colorado lecture notes); automatic choice of the
|
||||
dependent degree of freedom, J. F. Abel, M. S. Shephard, IJNME 14(3):464–467, 1979; the
|
||||
distributing (interpolation) constraint as a least-squares rigid fit with loads spread by
|
||||
virtual work, G. H. K. Heirman, W. Desmet, Multibody Syst. Dyn. 24(2):219–234, 2010; the
|
||||
reduced matrix product T_fᵀ K T_f row by row, F. G. Gustavson, ACM TOMS 4(3):250–269, 1978.
|
||||
- Verification: R. H. MacNeal, R. L. Harder, *A proposed standard set of problems to test finite
|
||||
element accuracy*, Finite Elem. Anal. Des. 1(1):3–20, 1985 (patch tests); Lamé, Kirsch,
|
||||
Timoshenko and Euler–Bernoulli closed forms.
|
||||
Timoshenko and Euler–Bernoulli closed forms; Saint-Venant's principle (tension through a
|
||||
coupling), pure bending σ = M z / I, torsion of a circular tube φ = T L / (G J), τ = T r / J.
|
||||
Reference in new issue
Block a user