feat(solid): add Hex8 input and three-DOF semantics

This commit is contained in:
KOKO\Mimi
2026-10-09 01:12:30 +09:00
parent df0388ae2f
commit 9acf18db4b
16 changed files with 1468 additions and 98 deletions
+21
View File
@@ -112,6 +112,13 @@ class StepDefinition {
/// @brief Returns the static maximum-increment provenance value.
double MaximumIncrement() const noexcept;
/// @brief Reports the source STATIC DIRECT fixed-schedule selection.
bool IsDirectStatic() const noexcept;
/// @brief Returns the fixed Solid static increment count, or zero otherwise.
std::uint32_t IncrementCount() const noexcept;
/// @brief Returns the source static INC limit.
std::uint32_t MaximumIncrements() const noexcept;
/// @brief Returns the source location of the step declaration.
const SourceLocation& Location() const noexcept;
@@ -145,6 +152,9 @@ class StepDefinition {
SourceLocation location_;
std::optional<FrequencyStepDefinition> frequency_;
std::optional<DynamicStepDefinition> dynamic_;
bool direct_static_{false};
std::uint32_t increment_count_{0U};
std::uint32_t maximum_increments_{100U};
};
/// @brief Owns the complete immutable semantic model definition.
@@ -176,6 +186,15 @@ class Domain {
const DomainCollectionView<Mitc4ShellDefinition>& ShellElements()
const noexcept;
/// @brief Returns C3D8 definitions in stable source order.
const DomainCollectionView<Hex8Definition>& SolidElements() const noexcept;
/// @brief Returns homogeneous Solid section assignments.
const DomainCollectionView<SolidSection>& SolidSections() const noexcept;
/// @brief Reports whether this model has exclusively Solid elements.
bool IsSolid() const noexcept;
/// @brief Returns immutable model-level amplitude curves in source order.
const std::vector<TabularAmplitudeDefinition>& Amplitudes() const noexcept;
/// @brief Returns all materials in stable Domain index order.
const DomainCollectionView<Material>& Materials() const noexcept;
@@ -262,6 +281,8 @@ class Domain {
DomainCollectionView<ElementDefinition> elements_view_;
DomainCollectionView<EulerBeam3DDefinition> beam_elements_view_;
DomainCollectionView<Mitc4ShellDefinition> shell_elements_view_;
DomainCollectionView<Hex8Definition> solid_elements_view_;
DomainCollectionView<SolidSection> solid_sections_view_;
DomainCollectionView<ElementProperty> properties_view_;
DomainCollectionView<GeneralBeamSection> sections_view_;
DomainCollectionView<ShellSection> shell_sections_view_;
+35
View File
@@ -1,6 +1,7 @@
#ifndef FESA_MODEL_MODEL_TYPES_H_
#define FESA_MODEL_MODEL_TYPES_H_
#include <algorithm>
#include <array>
#include <cstdint>
#include <filesystem>
@@ -14,11 +15,13 @@
#include "fesa/core/source_identity.h"
#include "fesa/elements/ds4_thermal.h"
#include "fesa/elements/euler_beam_3d.h"
#include "fesa/elements/hex8_definition.h"
#include "fesa/elements/mitc4_shell.h"
#include "fesa/materials/isotropic_linear_elastic_material.h"
#include "fesa/materials/isotropic_thermal_material.h"
#include "fesa/properties/general_beam_section.h"
#include "fesa/properties/shell_section.h"
#include "fesa/properties/solid_section.h"
namespace fesa {
@@ -47,12 +50,37 @@ struct PrescribedDisplacementDefinition {
SourceLocation location;
};
/// @brief Owns a validated TABULAR STEP TIME RELATIVE load curve.
struct TabularAmplitudeDefinition {
std::string name_raw;
std::string name_canonical;
SourceLocation location;
std::vector<std::array<double, 2>> points;
/// @brief Evaluates exact knots, linear interiors, and endpoint holds.
/// @pre Time is finite; points are finite, nonempty, strictly increasing.
double Evaluate(double time) const {
if (time <= points.front()[0]) return points.front()[1];
if (time >= points.back()[0]) return points.back()[1];
const auto upper = std::lower_bound(
points.begin(), points.end(), time,
[](const auto& point, double t) { return point[0] < t; });
if ((*upper)[0] == time) return (*upper)[1];
const auto& lower = *(upper - 1);
const double weight = (time - lower[0]) / ((*upper)[0] - lower[0]);
return (1.0 - weight) * lower[1] + weight * (*upper)[1];
}
};
/// @brief Stores one concentrated nodal load component.
struct NodalLoad {
std::string target;
int dof;
double magnitude;
SourceLocation location;
std::optional<EntityIndex> amplitude_index;
std::string amplitude_name_raw;
SourceLocation amplitude_location;
};
/// @brief Identifies the selected exterior shell surface side.
@@ -169,6 +197,9 @@ struct StaticStepDefinition {
std::vector<PrescribedDisplacementDefinition> boundaries;
std::vector<NodalLoad> loads;
std::vector<SurfacePressureLoadDefinition> surface_pressure_loads;
bool direct{false};
std::uint32_t increment_count{0U};
std::uint32_t maximum_increments{100U};
StaticProcedureKind procedure_kind;
bool nlgeom;
double initial_increment;
@@ -226,6 +257,7 @@ struct DynamicStepDefinition {
double gamma{0.55};
std::vector<PrescribedDisplacementDefinition> boundaries;
std::vector<NodalLoad> loads;
bool nlgeom{true};
};
/// @brief Stores homogeneous isotropic thermal material source data.
@@ -374,10 +406,13 @@ struct ModelDefinition {
std::vector<Node> nodes;
std::vector<EulerBeam3DDefinition> elements;
std::vector<Mitc4ShellDefinition> shell_elements;
std::vector<Hex8Definition> solid_elements;
std::vector<LinearElasticMaterial> materials;
std::vector<ThermalMaterialDefinition> thermal_materials;
std::vector<GeneralBeamSection> sections;
std::vector<ShellSection> shell_sections;
std::vector<SolidSection> solid_sections;
std::vector<TabularAmplitudeDefinition> amplitudes;
std::vector<ThermalShellSectionDefinition> thermal_sections;
std::vector<Ds4ThermalElementDefinition> thermal_elements;
std::vector<ShellNodeInitialFrame> shell_node_initial_frames;