feat(elements): implement certified full-integration Hex8 kernel

This commit is contained in:
KOKO\Mimi
2026-10-09 01:03:43 +09:00
parent df0388ae2f
commit 9088af7b32
8 changed files with 1337 additions and 2 deletions
+3 -1
View File
@@ -11,6 +11,7 @@
#include "fesa/math/matrix.h"
#include "fesa/math/vector.h"
#include "fesa/results/result_records.h"
#include "fesa/results/solid_result_records.h"
namespace fesa {
@@ -52,7 +53,8 @@ struct ShellElementResultRows {
/// @brief Selects the physical recovery shape of one runtime element.
using ElementResultPayload =
std::variant<BeamElementResultRows, ShellElementResultRows>;
std::variant<BeamElementResultRows, ShellElementResultRows,
SolidElementResultRows>;
/// @brief Carries stable source identity with one typed recovery payload.
struct ElementResultBundle {
+83
View File
@@ -0,0 +1,83 @@
#ifndef FESA_ELEMENTS_HEX8_ELEMENT_H_
#define FESA_ELEMENTS_HEX8_ELEMENT_H_
#include <array>
#include <optional>
#include "fesa/elements/element.h"
#include "fesa/materials/isotropic_linear_elastic_material.h"
#include "fesa/results/solid_result_records.h"
namespace fesa {
/// @brief Owns all local quantities from one validated linear or TL trial.
struct Hex8Response {
Vector internal_force{24U};
Matrix material_tangent{24U, 24U};
Matrix geometric_tangent{24U, 24U};
Matrix tangent{24U, 24U};
double strain_energy{0.0};
std::array<SolidIntegrationPointRow, 8> points{};
};
/// @brief Implements full-integration C3D8 linear and TL StVK mechanics.
/// @note Reference geometry is owned and immutable; no trial is committed.
class Hex8Element final : public Element {
public:
using Coordinates = std::array<std::array<double, 3>, 8>;
/// @brief Validates identity, isotropic material and whole reference cell.
/// @param coordinates Reference global coordinates in source node order.
/// @param density Optional reference mass per volume, positive if present.
/// @note All inputs are copied; no Domain or section lifetime is required.
static Result<Hex8Element> Create(
EntityIndex element_index, ElementDofLayout layout,
Coordinates coordinates, const LinearElasticMaterial& material,
std::optional<double> density = std::nullopt,
SourceLocation location = {});
const ElementDofLayout& DofLayout() const noexcept override;
Result<ElementStiffnessContribution> ComputeStiffness() const override;
Result<ElementResultBundle> Recover(
const Vector& displacement) const override;
/// @brief Returns f=K0*u and infinitesimal tensor strain at eight points.
Result<Hex8Response> EvaluateLinear(const Vector& displacement) const;
/// @brief Returns one certified StVK trial and its analytic energy Hessian.
Result<Hex8Response> EvaluateNonlinear(const Vector& displacement) const;
/// @brief Returns the constant reference consistent mass; density required.
Result<ElementStiffnessContribution> ComputeMass() const;
private:
/// @brief Caches shape, reference gradients and positive volume weights.
struct ReferencePoint {
std::array<double, 8> shape{};
std::array<std::array<double, 3>, 8> gradients{};
std::array<double, 3> natural{};
std::array<double, 3> position{};
double weight{0.0};
};
/// @brief Constructs an owned candidate before reference validation.
Hex8Element(EntityIndex element_index, ElementDofLayout layout,
Coordinates coordinates, double lambda, double mu,
std::optional<double> density, SourceLocation location);
/// @brief Evaluates without mutating the cached reference or previous values.
Result<Hex8Response> Evaluate(const Vector& displacement,
bool nonlinear) const;
/// @brief Attaches stable source context to a model failure.
Status Failure(const char* message) const;
EntityIndex element_index_;
ElementDofLayout layout_;
Coordinates coordinates_;
double lambda_;
double mu_;
std::optional<double> density_;
SourceLocation location_;
std::array<ReferencePoint, 8> points_{};
Matrix stiffness_{24U, 24U};
};
} // namespace fesa
#endif // FESA_ELEMENTS_HEX8_ELEMENT_H_
@@ -0,0 +1,31 @@
#ifndef FESA_RESULTS_SOLID_RESULT_RECORDS_H_
#define FESA_RESULTS_SOLID_RESULT_RECORDS_H_
#include <array>
#include <vector>
#include "fesa/core/source_identity.h"
namespace fesa {
/// @brief Stores one unaveraged global solid integration-point result.
/// @note Tensor order is [11,22,33,12,13,23], with tensor shear strain.
struct SolidIntegrationPointRow {
EntityIndex element;
int integration_point;
std::array<double, 3> natural_coordinates;
std::array<double, 3> reference_coordinates;
std::array<double, 6> cauchy_stress;
// Infinitesimal strain for linear response; reference Green strain for TL.
std::array<double, 6> strain;
};
/// @brief Keeps eight physical solid rows and their reference-volume energy.
struct SolidElementResultRows {
std::vector<SolidIntegrationPointRow> rows;
double physical_strain_energy{0.0};
};
} // namespace fesa
#endif // FESA_RESULTS_SOLID_RESULT_RECORDS_H_