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 <noreply@anthropic.com> 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
@@ -38,7 +38,7 @@ const PART: &str = "mesh.bin";
|
||||
const NO_TAG: u32 = u32::MAX;
|
||||
|
||||
/// The element kind codes of the format.
|
||||
pub const KIND_CODES: [(ElementKind, u8); 12] = [
|
||||
pub const KIND_CODES: [(ElementKind, u8); 13] = [
|
||||
(ElementKind::Rod2, 1),
|
||||
(ElementKind::Beam2, 2),
|
||||
(ElementKind::Tri3, 3),
|
||||
@@ -51,6 +51,7 @@ pub const KIND_CODES: [(ElementKind, u8); 12] = [
|
||||
(ElementKind::Hex8, 10),
|
||||
(ElementKind::Hex20, 11),
|
||||
(ElementKind::Rod3, 12),
|
||||
(ElementKind::Pyramid5, 13),
|
||||
];
|
||||
|
||||
fn kind_code(kind: ElementKind) -> u8 {
|
||||
|
||||
@@ -38,6 +38,7 @@ pub fn cell_type(kind: ElementKind) -> u8 {
|
||||
ElementKind::Tet4 => 10, // VTK_TETRA
|
||||
ElementKind::Tet10 => 24, // VTK_QUADRATIC_TETRA
|
||||
ElementKind::Wedge6 => 13, // VTK_WEDGE
|
||||
ElementKind::Pyramid5 => 14, // VTK_PYRAMID
|
||||
ElementKind::Hex8 => 12, // VTK_HEXAHEDRON
|
||||
ElementKind::Hex20 => 25, // VTK_QUADRATIC_HEXAHEDRON
|
||||
}
|
||||
@@ -347,6 +348,7 @@ mod tests {
|
||||
[0., 0.5, 0.5],
|
||||
],
|
||||
ElementKind::Wedge6 => &[[0., 0., 0.], [1., 0., 0.], [0., 1., 0.], [0., 0., 1.], [1., 0., 1.], [0., 1., 1.]],
|
||||
ElementKind::Pyramid5 => &[[0., 0., 0.], [1., 0., 0.], [1., 1., 0.], [0., 1., 0.], [0.5, 0.5, 1.]],
|
||||
ElementKind::Hex8 => &[[0., 0., 0.], [1., 0., 0.], [1., 1., 0.], [0., 1., 0.], [0., 0., 1.], [1., 0., 1.], [1., 1., 1.], [0., 1., 1.]],
|
||||
ElementKind::Hex20 => &[
|
||||
[0., 0., 0.],
|
||||
@@ -433,8 +435,8 @@ mod tests {
|
||||
assert_eq!(written, e.nodes, "{kind:?}");
|
||||
}
|
||||
let ids: Vec<u8> = ElementKind::ALL.iter().map(|&k| cell_type(k)).collect();
|
||||
// rod2, rod3, beam2, tri3, tri6, quad4, quad8, tet4, tet10, wedge6, hex8, hex20
|
||||
assert_eq!(ids, [3, 21, 3, 5, 22, 9, 23, 10, 24, 13, 12, 25]);
|
||||
// rod2, rod3, beam2, tri3, tri6, quad4, quad8, tet4, tet10, wedge6, pyramid5, hex8, hex20
|
||||
assert_eq!(ids, [3, 21, 3, 5, 22, 9, 23, 10, 24, 13, 14, 12, 25]);
|
||||
}
|
||||
|
||||
/// The points of the one cell as written, in VTK's order.
|
||||
@@ -459,7 +461,7 @@ mod tests {
|
||||
|
||||
/// VTK's convention for each 3D cell, from its parametric coordinates: the base face's
|
||||
/// right-hand normal points to the rest of the cell (tetrahedron 0-1-2 to 3, hexahedron
|
||||
/// 0-1-2-3 to 4-7, wedge 0-1-2 to 3-5). The signed measure is positive when the written cell
|
||||
/// 0-1-2-3 to 4-7, wedge 0-1-2 to 3-5, pyramid 0-1-2-3 to 4). The signed measure is positive when the written cell
|
||||
/// follows it; VTK 9.7's vtkCellSizeFilter and vtkMeshQuality agree (a unit wedge written
|
||||
/// this way measures +0.5, reordered 0-2-1-3-5-4 it measures -0.5).
|
||||
#[test]
|
||||
@@ -470,6 +472,7 @@ mod tests {
|
||||
(ElementKind::Hex8, 4, 4..8),
|
||||
(ElementKind::Hex20, 4, 4..8),
|
||||
(ElementKind::Wedge6, 3, 3..6),
|
||||
(ElementKind::Pyramid5, 4, 4..5),
|
||||
] {
|
||||
let p = cell_points(&write_vtu(&one(kind), &[], &[], Encoding::Ascii).unwrap());
|
||||
let b = &p[..base];
|
||||
|
||||
Reference in new issue
Block a user