forked from 1b-agent/fieldcraft-upstream
fem: pyramid5 element (solver, quality, decks, VTK)
A five-node pyramid, the conforming transition between a hexahedron's face and tetrahedra: Bedrosian's rational shape functions with a collapsed (Duffy) Gauss rule, a certified Jacobian on the base square with exact volume, a scaled Jacobian, C3D5 / CPYRAM / LS-DYNA degenerate solid, VTK_PYRAMID and the binary mesh code 13. A distorted hex8-pyramid5-tet4 transition mesh passes the patch test and uniaxial tension exactly. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
This commit is contained in:
1 parent
4e6fd59409
commit
3a5a8213a1
28 files changed
+325
-28
No files matched your search
@@ -85,6 +85,7 @@
|
||||
//! | tet4 | C3D4 (H) | | | |
|
||||
//! | tet10 | C3D10 (H) | | | |
|
||||
//! | wedge6 | C3D6 (H) | | | |
|
||||
//! | pyramid5 | C3D5 (H) | | | |
|
||||
//! | hex8 | C3D8, C3D8R, C3D8I (H) | | | |
|
||||
//! | hex20 | C3D20, C3D20R (H) | | | |
|
||||
//! | tri3, quad4 | | S3 / S3R, S4 / S4R | | |
|
||||
@@ -231,11 +232,12 @@ pub fn element_type(kind: ElementKind, section: &Section) -> std::result::Result
|
||||
(S::Solid {}, _, true, true) => return Err("incompatible modes with reduced integration".into()),
|
||||
(S::Solid {}, _, _, true) => return Err(format!("incompatible modes on {} elements (hex8 only)", kind.name())),
|
||||
(S::Solid {}, K::Tet4, ..) => "C3D4",
|
||||
(S::Solid {}, K::Tet10 | K::Wedge6, true, _) => {
|
||||
(S::Solid {}, K::Tet10 | K::Wedge6 | K::Pyramid5, true, _) => {
|
||||
return Err(format!("reduced integration of {} elements (Abaqus has no reduced-integration variant)", kind.name()));
|
||||
}
|
||||
(S::Solid {}, K::Tet10, ..) => "C3D10",
|
||||
(S::Solid {}, K::Wedge6, ..) => "C3D6",
|
||||
(S::Solid {}, K::Pyramid5, ..) => "C3D5",
|
||||
(S::Solid {}, K::Hex8, r, _) => ["C3D8", "C3D8R"][usize::from(r)],
|
||||
(S::Solid {}, K::Hex20, r, _) => ["C3D20", "C3D20R"][usize::from(r)],
|
||||
(S::Shell { .. }, K::Tri3, r, _) => ["S3", "S3R"][usize::from(r)],
|
||||
|
||||
@@ -36,7 +36,7 @@ impl Keyword {
|
||||
pub(crate) fn of(kind: ElementKind) -> Keyword {
|
||||
match kind {
|
||||
ElementKind::Hex20 => Keyword::SolidH20,
|
||||
ElementKind::Tet4 | ElementKind::Tet10 | ElementKind::Wedge6 | ElementKind::Hex8 => Keyword::Solid,
|
||||
ElementKind::Tet4 | ElementKind::Tet10 | ElementKind::Wedge6 | ElementKind::Pyramid5 | ElementKind::Hex8 => Keyword::Solid,
|
||||
ElementKind::Tri3 | ElementKind::Tri6 | ElementKind::Quad4 | ElementKind::Quad8 => Keyword::Shell,
|
||||
ElementKind::Rod2 | ElementKind::Rod3 | ElementKind::Beam2 => Keyword::Beam,
|
||||
}
|
||||
@@ -64,6 +64,8 @@ pub(crate) fn order(kind: ElementKind) -> &'static [usize] {
|
||||
ElementKind::Tet4 => &[0, 1, 2, 3, 3, 3, 3, 3],
|
||||
ElementKind::Tet10 => &[0, 1, 2, 3, 4, 5, 6, 8, 9, 7],
|
||||
ElementKind::Wedge6 => &[1, 0, 3, 4, 2, 2, 5, 5],
|
||||
// The degenerate hexahedron: the base, then the apex four times.
|
||||
ElementKind::Pyramid5 => &[0, 1, 2, 3, 4, 4, 4, 4],
|
||||
ElementKind::Hex8 => &[0, 1, 2, 3, 4, 5, 6, 7],
|
||||
ElementKind::Hex20 => &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19],
|
||||
}
|
||||
@@ -95,7 +97,7 @@ pub(crate) struct Elform {
|
||||
///
|
||||
/// Solids: hex8 2 (eight-point), reduced 1 (one-point) with hourglass control, incompatible
|
||||
/// modes −18 (eight-point enhanced strain with incompatible modes); wedges 2 (as degenerate
|
||||
/// hexahedra), reduced 15 (two-point pentahedron); tet4 10 (one point, exact for a linear
|
||||
/// hexahedra), reduced 15 (two-point pentahedron); pyramids 2 (as degenerate hexahedra); 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). 2D (in the XY plane): plane stress 12, plane strain 13, both one-point
|
||||
@@ -122,6 +124,8 @@ pub(crate) fn elform(kind: ElementKind, section: &SectionKind, f: Formulation, s
|
||||
ElementKind::Hex8 => plain(2),
|
||||
ElementKind::Wedge6 if reduced => plain(15),
|
||||
ElementKind::Wedge6 => plain(2),
|
||||
ElementKind::Pyramid5 if reduced => no("there is no reduced-integration form of"),
|
||||
ElementKind::Pyramid5 => plain(2),
|
||||
ElementKind::Tet4 => plain(10),
|
||||
_ if reduced && kind.is_quadratic() => no("there is no reduced-integration form of"),
|
||||
ElementKind::Tet10 => plain(16),
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
//! data (the entries). What the model holds becomes:
|
||||
//!
|
||||
//! - nodes and reference points: `GRID`;
|
||||
//! - solids: `CTETRA` (tet4, tet10), `CPENTA` (wedge6), `CHEXA` (hex8, hex20) with `PSOLID`;
|
||||
//! - solids: `CTETRA` (tet4, tet10), `CPENTA` (wedge6), `CPYRAM` (pyramid5), `CHEXA` (hex8, hex20) with `PSOLID`;
|
||||
//! shells: `CTRIA3`, `CQUAD4`, `CTRIA6`, `CQUAD8` with `PSHELL`; beams: `CBEAM` with `PBEAML`;
|
||||
//! rods: `CROD` with `PROD`. Nastran numbers a 20-node hexahedron's mid-side nodes bottom
|
||||
//! edges, vertical edges, top edges, where the model has bottom, top, vertical
|
||||
@@ -113,6 +113,7 @@ pub fn element_card(kind: ElementKind) -> &'static str {
|
||||
ElementKind::Quad8 => "CQUAD8",
|
||||
ElementKind::Tet4 | ElementKind::Tet10 => "CTETRA",
|
||||
ElementKind::Wedge6 => "CPENTA",
|
||||
ElementKind::Pyramid5 => "CPYRAM",
|
||||
ElementKind::Hex8 | ElementKind::Hex20 => "CHEXA",
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user