2D elements: plane stress, plane strain and axisymmetric sections on the DOF framework; mesh.planar (M4) (#39)

Model: planar section kinds with Extent, element edges in sets, edge-weighted 2D loads,
centrifugal load, 2D model checks. fem: Plane kernels on Basis::{Tri3,Tri6,Quad4,Quad8}
declaring ElementDofs::new(DofSet::PLANE); QM6 incompatible modes with the
Wilson-Ibrahimbegovic correction. Solver: Kernel enum on the DofLayout; 3D results
bit-identical (hash-checked). Decks: Abaqus CPS/CPE/CAX, Nastran membranes and RFORCE,
LS-DYNA ELFORM 12/13. Mesh: free triangle mesher, planar region meshing, face boundaries.
Engine: mesh.planar with tagged edges. Analytic verification suite in solver/tests/plane.rs.


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:
authored and GitHub committed 2026-10-13 20:24:56 -04:00
1 parent 4e4d19b88c
commit 4c0fcc80ad
42 files changed
+3270 -128

No files matched your search

+12 -2
View File
@@ -133,14 +133,19 @@ 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: tet4, tet10, wedge6, hex8, hex20). Every reference point a coupling
row per element kind: tet4, tet10, wedge6, hex8, hex20); 2D sections (plane stress, plane
strain, axisymmetric) take the 2D table (`modelcraft_fem::plane::PLANE_TYPES`: tri3, tri6,
quad4, quad8), chosen by the section kind, and the model then has two degrees of freedom per
node: the 2D elements declare `ElementDofs::new(DofSet::PLANE)` (Ux, Uy) to the `DofLayout`. A 2D model
lies in the XY plane (axisymmetric: x the radius, Y the axis; nodes on the axis are held
radially), is loaded on element edges, and cannot mix with solids or couplings yet. 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
2. **Assembly** on the node graph (3 × 3 blocks for solids, 2 × 2 in 2D models, elements in label order, so sums are
reproducible bit for bit).
3. **Ordering and elimination** (`constraints`). Nested dissection of the nodes by coordinate
bisection. Couplings become linear constraint rows: kinematic = rigid link of each coupled
@@ -167,6 +172,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/plane.rs`: the 2D elements' displacement patch tests in plane stress, plane
strain and axisymmetry, uniform traction, a plane stress cantilever against Timoshenko with
convergence rates, Kirsch's plate, Lamé's cylinder in plane strain and axisymmetric, a rotating
disc (plane stress) and a rotating cylinder (axisymmetric) against Timoshenko & Goodier, masses
and 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
+3 -2
View File
@@ -5,7 +5,7 @@ Generated from the capability catalogue (`crates/engine/src/catalogue.rs`) by
Every entry is a toolbar button. **Ready** entries run their command; **coming soon** entries are
shown greyed with the roadmap milestone that brings them (ROADMAP.md).
45 ready, 55 coming soon.
46 ready, 55 coming soon.
## Geometry
@@ -30,6 +30,7 @@ shown greyed with the roadmap milestone that brings them (ROADMAP.md).
| Tet | Tet Mesh — Constrained Delaunay tet mesh of a body: every boundary triangle kept, faces tagged (refinement comes next) | ready | `mesh.tet.generate` |
| Tet | Quadratic — Second-order elements with mid-side nodes on the geometry | coming soon (M2) | |
| Tet | Delaunay Points — Delaunay tetrahedralization of a point list (debugging aid) | ready | `mesh.delaunay.points` |
| 2D | 2D Mesh — Quad or triangle mesh of a planar face or polygon in the XY plane for plane stress, plane strain and axisymmetric models; edges tagged | ready | `mesh.planar` |
| Structured Hex | Quad Faces — All-quad meshes of faces on shared edge nodes | coming soon (M5) | |
| Structured Hex | Mapped Hex — Mapped hex mesh of six-sided regions | coming soon (M5) | |
| Structured Hex | Sweep Hex — Hex mesh swept along extrusions and revolutions | coming soon (M5) | |
@@ -60,7 +61,7 @@ shown greyed with the roadmap milestone that brings them (ROADMAP.md).
| Materials | Damage — Damage initiation and evolution | coming soon (M8) | |
| Materials | Thermal — Conductivity, specific heat and expansion | coming soon (M8) | |
| Materials | Equation of State — Polynomial, ideal gas, Mie–Grüneisen, JWL and tabulated equations of state | coming soon (M11) | |
| Sections | Section — Solid, shell, beam or rod section assigned to a set, with its element formulation | ready | `model.section.create`, `model.section.edit`, `model.section.delete` |
| Sections | Section — Solid, shell, beam, rod or 2D (plane stress, plane strain, axisymmetric) section assigned to a set, with its element formulation | ready | `model.section.create`, `model.section.edit`, `model.section.delete` |
| Sections | Composite — Composite layups and continuum shells | coming soon (M8) | |
| Sections | Orientation — Material orientations | coming soon (M8) | |
| Sets | Set — A set of nodes, elements and faces, or of named geometry that survives remeshing | ready | `model.set.create`, `model.set.edit`, `model.set.delete`, `model.set.resolve` |
+7
View File
@@ -849,6 +849,13 @@ boundary nodes, so faces sharing an edge share its nodes. DOIs below were checke
[10.1016/S0925-7721(01)00047-5](https://doi.org/10.1016/S0925-7721(01)00047-5). Used without segment splitting
(boundary nodes are prescribed).
**B7.3a Free triangle meshes on prescribed boundary nodes** (`free_tri_mesh`, used by
`mesh.planar` for tri3/tri6 2D models): the same constrained Delaunay triangulation of the full
resolution loops, refined to the size by circumcentre insertion that never splits a boundary
segment (J. Ruppert, *A Delaunay refinement algorithm for quality 2-dimensional mesh generation*,
J. Algorithms 18(3):548–585, 1995, without segment splitting, so the boundary nodes stay the
input points), Steiner points kept half the local spacing from the boundary.
**B7.4 Smoothing and untangling of the quads.** **Verdict: BUILD ON.**
- L. A. Freitag. *On combining Laplacian and optimization-based mesh smoothing techniques.* AMD-Vol. 220, ASME 1997;
S. A. Canann, J. R. Tristano, M. L. Staten, *An approach to combined Laplacian and optimization-based smoothing for
+12 -2
View File
@@ -33,7 +33,7 @@ products are run, no documentation text is copied). Status: **done**, **started*
| Mesh | Size field: global, per face and edge seeds, bias, curvature and proximity refinement | M2 | yes | planned |
| Mesh | Free tet meshing (tet4, tet10 with mid-side nodes on the geometry) | M2 | | started |
| Mesh | Quality metrics, certified validity, verify per set | M1–M2 | yes | done (metrics, gate) |
| Mesh | 2D quad meshing of faces | M5 | yes | planned |
| Mesh | 2D quad meshing of faces | M5 | yes | started (`modelcraft_mesh::quad`; `mesh.planar`: 2D models of a polygon or a planar face, quad4/quad8/tri3/tri6, edges tagged by their neighbouring face) |
| Mesh | Mapped hex of six-sided regions | M5 | yes | planned |
| Mesh | Sweep hex (extrusions, revolutions) | M5 | yes | planned |
| Mesh | Automatic decomposition into sweepable and mappable regions | M5 | yes | planned |
@@ -46,6 +46,7 @@ products are run, no documentation text is copied). Status: **done**, **started*
| Model | Materials: elastic (isotropic, orthotropic), density, unit-system check | M3 | | done |
| Model | Materials: plasticity, hyperelasticity, damage, thermal | M8 | | planned |
| Model | Sections: solid, shell, beam profiles; assignment by set | M3 | | done |
| Model | 2D sections: plane stress, plane strain, axisymmetric (XY plane, Y the axis); element edges in sets; centrifugal load | M4 | | done |
| Model | Composite layups, material orientations, continuum shells | M8 | yes | planned |
| Model | Element formulation per region (integration, incompatible modes, hybrid) mapped per solver | M3 | yes | done (model; per-solver mapping with the deck writers) |
| Model | Boundary conditions: fixed, displacement, symmetry | M3 | | done |
@@ -60,7 +61,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, wedge6, hex8, hex20; reference points, kinematic and distributing couplings, moments) |
| Solve | Own linear static and modal solver, verified against analytic solutions | M4 | yes | started (solid elements: tet4, tet10, wedge6, hex8, hex20; 2D plane stress, plane strain and axisymmetric tri3, tri6, quad4 (full, incompatible modes), quad8 (full, reduced); reference points, kinematic and distributing couplings, moments; centrifugal loads) |
| Solve | Own explicit dynamics solver (central differences, one-point hex8 with hourglass control, nodal-pressure tet4, bulk viscosity, energy balance), verified against analytic wave and impact solutions | M10 | yes | started (X1 core: small-strain elastic, rigid walls; large deformation, plasticity and contact planned) |
| 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 |
@@ -98,6 +99,15 @@ products are run, no documentation text is copied). Status: **done**, **started*
body forces per volume, partial-DOF kinematic couplings, constraints on a coupled reference
point, gravity on different sets or on parts of sections, hybrid other than tet4, reduced
quadratic elements, materials without density, more than 10 shell integration points.
- 2D models: Abaqus writes CPS*/CPE*/CAX* (3, 6, 4, 4R, 4I, 8, 8R) with the thickness on the
`*SOLID SECTION` line, edge surfaces `S1`… and `BR`/`BZ` body forces for axisymmetric elements;
Nastran writes plane stress as membranes (`PSHELL` with MID1 only, grids holding 3456 through
`GRID` PS) and edge pressures as consistent `FORCE`s, and refuses plane strain and
axisymmetric elements (their cards differ between Nastran dialects); LS-DYNA writes plane stress
and plane strain (unit thickness) as `*SECTION_SHELL` ELFORM 12/13, one-point quad4 (reduced
integration, with hourglass control) and tri3, and refuses quadratic 2D elements, full or
incompatible-mode quad4 and axisymmetric sections. Centrifugal loads: Abaqus `CENTRIF`
(ω², point, axis), Nastran `RFORCE` about an axis through the origin, LS-DYNA not yet.
- Open item (LS-DYNA tet10 node order): the writer follows the manual's figure (mid-side nodes 8,
9, 10 on edges 2-4, 3-4, 1-4), which disagrees with an earlier reading as the Abaqus order. It
needs one confirmation run by a licensed user; agents never run commercial solvers.
+8
View File
@@ -979,6 +979,14 @@ 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.
- 2D elements (plane stress, plane strain, axisymmetric): Zienkiewicz, Taylor & Zhu 2013, ch. 6
and §6.6; Hughes 2000, §2.7 and §3.5. Quad4 incompatible modes (QM6): Wilson et al. 1973 and
Taylor, Beresford & Wilson 1976 as for hex8; in axisymmetric elements the modes' strain
operator is shifted by its volume mean, the patch-test correction of E. L. Wilson and A.
Ibrahimbegovic, *Use of incompatible displacement modes for the calculation of element
stiffnesses or stresses*, Finite Elements in Analysis and Design 7(3):229–241, 1990. Rotating
discs and cylinders for verification: S. Timoshenko, J. N. Goodier, *Theory of Elasticity*,
3rd ed., McGraw-Hill 1970, §32.
- 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