87 lines
3.4 KiB
C++
87 lines
3.4 KiB
C++
#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;
|
|
/// @brief Returns immutable positive reference Gauss volume weights.
|
|
/// @note Order is the kernel's fixed eight-point integration order.
|
|
std::array<double, 8> ReferenceWeights() const noexcept;
|
|
|
|
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_
|