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 <2501648+jyviko@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
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

+15 -1
View File
@@ -97,7 +97,9 @@ pub(crate) struct Elform {
/// hexahedra), reduced 15 (two-point pentahedron); tet4 10 (one point, exact for a linear
/// tetrahedron), hybrid 13 (nodal pressure); tet10 16; hex20 23. Shells: quad4 16 (fully
/// integrated), reduced 2 (one-point) with hourglass control; tri3 4 (C0 triangle); quad8 23;
/// tri6 24. Rods: 3 (truss).
/// tri6 24. Rods: 3 (truss). 2D (in the XY plane): plane stress 12, plane strain 13, both one-point
/// forms on quad4 (written for reduced integration, with hourglass control) and tri3 (exact at one
/// point); quadratic 2D elements and axisymmetric sections have no form written here.
/// What it cannot express is the reason, naming the section.
pub(crate) fn elform(kind: ElementKind, section: &SectionKind, f: Formulation, section_name: &str) -> Result<Elform, String> {
let plain = |elform| Ok(Elform { elform, hourglass: None });
@@ -142,6 +144,18 @@ pub(crate) fn elform(kind: ElementKind, section: &SectionKind, f: Formulation, s
_ => no("a rod section cannot hold"),
},
SectionKind::Beam { .. } => no("beam sections are not written to LS-DYNA decks yet (planned with beam profiles):"),
SectionKind::Axisymmetric {} => {
no("axisymmetric sections are not written to LS-DYNA decks yet (its axisymmetric forms count loads per radian; not verified):")
}
SectionKind::PlaneStress { .. } | SectionKind::PlaneStrain { .. } => {
let form = if matches!(section, SectionKind::PlaneStress { .. }) { 12 } else { 13 };
match kind {
ElementKind::Tri3 => plain(form),
ElementKind::Quad4 if reduced => Ok(Elform { elform: form, hourglass: Some(Hourglass::Shell) }),
ElementKind::Quad4 => no("LS-DYNA's 2D forms integrate at one point (set the section's integration to reduced) for"),
_ => no("LS-DYNA's 2D forms are linear; there is no form for"),
}
}
}
}