Files
OneCAD-Simulation/crates/fem/src/lib.rs
T
e900f41ce3 FEM foundation B: heat transfer and thermal stress (solids, 2D, explicit), coupled temperature–displacement, solve.heat (#45)
* Heat transfer and thermal stress: thermal materials, temperature BCs, heat loads, heat transfer and coupled temperature–displacement steps, solve.heat

Model: Material.thermal (conductivity, specific heat, expansion, isotropic or
per axis; reference temperature), BoundaryCondition::Temperature (dof 11),
loads SurfaceFlux, Convection, HeatSource and Temperature (a field in static
steps), procedures HeatTransfer { transient (θ-method) } and
CoupledTemperatureDisplacement; checks for missing conductivity/specific
heat/expansion. fem: heat conduction kernels (conductivity, capacity,
source, face flux/film, heat flux) on the DofLayout (one T per node), thermal
strain load and stress D(ε − ε_th) for every solid formulation incl.
incompatible modes. Solver: steady and transient heat transfer, thermal loads
in static steps, coupled steps (exact one-way coupling). Engine: solve.heat,
temperature/heat-flux result fields, probes. Decks refuse heat transfer by
name. Analytic verification: slab, source+convection/flux, thick cylinder,
erfc semi-infinite solid, free/constrained expansion, bimetal strip, coupled
step.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01NmAttHhUZTokgPeEJia8sm

* thermal: strains in 2D elements and explicit dynamics

Plane::thermal_load and stresses_with for plane stress (εzz free), plane
strain (σzz = −D₃·ε_th) and axisymmetric elements, incompatible modes
included; the solver's 2D kernels take them. Explicit dynamics turns a
step's temperature loads into a per-element thermal strain rate (reached
linearly over the step) subtracted from each strain increment, so it feeds
J2 and Johnson–Cook updates. Verified: free expansion in every 2D theory
and element, a biaxially held plate, an explicit free bar (ΔL = αΔT L,
stress-free) and a clamped bar at −EαΔT, capped at the yield stress with
perfect plasticity.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01NmAttHhUZTokgPeEJia8sm

* clippy

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01NmAttHhUZTokgPeEJia8sm

* thermal: trusses take the axial thermal strain; keep the roadmap's M7 line

Truss::thermal_load and stresses_with project the thermal strain on the
member's tangent (Σ αₖ tₖ² ΔT); the static solver applies them to rod2/rod3
(#38). Explicit trusses take none yet and a warning says so.

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]>
2026-10-13 22:15:03 -04:00

87 lines
4.0 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//! Finite element kernels shared by ModelCraft's structural solvers.
//!
//! Pure functions over element geometry and material constants, with no solver loop and no
//! global state, so the implicit solver (`modelcraft-solver`) and the explicit solver that follows
//! it use the same element technology:
//! - [`dof`]: degree-of-freedom kinds, what elements declare, and the global numbering
//! ([`DofLayout`]) every solver assembles on;
//! - [`quadrature`]: Gauss–Legendre and tetrahedron rules;
//! - [`basis`]: the shape-function library of every family (lines, triangles, quadrilaterals,
//! tetrahedra, wedges, pyramids, hexahedra) with first and second derivatives and their
//! physical gradients, Hessians and Laplacians; [`jet`] is the automatic differentiation behind
//! the second derivatives;
//! - [`shape`]: the hand-written first-order functions of tet4, tet10, wedge6, hex8, hex20 that
//! the solid kernels evaluate;
//! - [`material`]: isotropic and orthotropic elasticity matrices, von Mises stress;
//! - [`element`]: the element table, stiffness (full, reduced, incompatible modes), consistent
//! and lumped mass, body forces, integration-point stresses and their extrapolation to nodes;
//! - [`plane`]: 2D elements (plane stress, plane strain, axisymmetric) on tri3, tri6, quad4 and
//! quad8, with two displacement components per node;
//! - [`shell`]: flat MITC4 quadrilateral and MITC3 triangle shells with a drilling rotation, six
//! degrees of freedom per node;
//! - [`beam`]: two-node Timoshenko beams with profile section properties;
//! - [`frame`]: local axes of shells and beams and the rotation of their matrices;
//! - [`face`]: consistent nodal forces of pressure on element faces;
//! - [`heat`]: heat conduction (conductivity, capacity, sources, surface flux and convection,
//! heat flux); thermal strain loads and stresses are in [`element`];
//! - [`uniform`]: uniform-strain (one-point) hexahedron and tetrahedron kinematics, hourglass
//! shape vectors and element frequency bounds for explicit dynamics;
//! - [`rotation`]: incrementally objective stress updates (Hughes–Winget Jaumann, Flanagan–Taylor
//! Green–Naghdi);
//! - [`plasticity`]: J2 radial return with isotropic, kinematic and Johnson–Cook hardening,
//! Johnson–Cook damage;
//! - [`truss`]: two- and three-node trusses (straight or curved), their stiffness, mass, body
//! force and axial stress;
//! - [`dense`]: the small dense linear algebra inside an element.
//!
//! Conventions: element matrices are ordered node by node, each node's degrees of freedom in
//! [`DofKind`] order (three translations for solids, six for shells and beams; docs/fem.md); stress
//! and strain 6-vectors in the order xx, yy, zz, xy, xz, yz with engineering shear strains.
#![deny(clippy::unwrap_used, clippy::expect_used, clippy::panic, clippy::unimplemented, clippy::todo, clippy::unreachable)]
#![forbid(unsafe_code)]
// Matrix kernels over fixed small dimensions read as the textbook formulas with index loops.
#![allow(clippy::needless_range_loop)]
pub mod basis;
pub mod beam;
pub mod dense;
pub mod dof;
pub mod element;
pub mod face;
pub mod frame;
pub mod heat;
pub mod jet;
pub mod material;
pub mod plane;
pub mod plasticity;
pub mod quadrature;
pub mod rotation;
pub mod shape;
pub mod shell;
pub mod truss;
pub mod uniform;
pub use basis::Basis;
pub use dof::{DofKind, DofLayout, DofSet, ElementDofs};
pub use element::{ELEMENT_TYPES, ElementType, Family, Formulation, PointStress, Solid, ThermalStrain, element_type};
pub use material::{Elasticity, elasticity, principal, von_mises};
#[derive(Debug, Clone, PartialEq, thiserror::Error)]
pub enum Error {
#[error("invalid input: {0}")]
Invalid(String),
#[error("not supported yet: {0}")]
NotSupported(String),
/// An element's geometry is inverted or collapsed.
#[error("{0}")]
Degenerate(String),
/// A matrix that must be positive definite is not.
#[error("{0}")]
Singular(String),
}
pub type Result<T> = std::result::Result<T, Error>;
#[cfg(test)]
mod tests;