feat: adopt lumped mass and reduced-coordinate shell HHT
Integrate Hex8 mass verification and fixed-null-basis shell dynamics with numerical and physics handoff evidence. Preserve interrupted reference and full-validation status; full integration validation is deferred until after performance optimization.
This commit is contained in:
@@ -241,8 +241,24 @@ void DeleteAttribute(const hid_t object, const char* name) {
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief Maps a validated frame's integration semantics to its schema.
|
||||
std::uint64_t SchemaVersion(const DynamicAcceptedFrameState& frame) {
|
||||
return frame.time_integration_formulation ==
|
||||
DynamicTimeIntegrationFormulation::kReducedCoordinateHht
|
||||
? 2U
|
||||
: 1U;
|
||||
}
|
||||
|
||||
/// @brief Returns the explicit integration discriminator without aliases.
|
||||
const char* IntegrationFormulation(const DynamicAcceptedFrameState& frame) {
|
||||
return SchemaVersion(frame) == 2U
|
||||
? "reduced-coordinate-HHT-with-physical-rate-reconstruction"
|
||||
: "full-coordinate-HHT";
|
||||
}
|
||||
|
||||
/// @brief Writes the dynamic procedure identity and fixed time schedule.
|
||||
void WriteMetadata(const hid_t file, const Domain& domain) {
|
||||
void WriteMetadata(const hid_t file, const Domain& domain,
|
||||
const DynamicAcceptedFrameState& frame) {
|
||||
Hdf5Handle metadata{
|
||||
hdf5_internal::RequireHdf5Id(H5Gopen2(file, "/metadata", H5P_DEFAULT),
|
||||
"The model metadata group is missing."),
|
||||
@@ -252,7 +268,7 @@ void WriteMetadata(const hid_t file, const Domain& domain) {
|
||||
"mass_formulation", "internal_formulation", "initial_state",
|
||||
"acceleration_convention", "step_name", "source_step_name",
|
||||
"unit_system_label", "coordinate_convention", "integration_rule",
|
||||
"frame_index"}) {
|
||||
"frame_index", "time_integration_formulation"}) {
|
||||
DeleteAttribute(metadata.Get(), name);
|
||||
}
|
||||
const DynamicStepDefinition* const step = domain.Dynamic();
|
||||
@@ -260,9 +276,13 @@ void WriteMetadata(const hid_t file, const Domain& domain) {
|
||||
"hht-implicit-dynamics");
|
||||
hdf5_internal::WriteStringAttribute(metadata.Get(), "analysis_procedure",
|
||||
"hht-implicit-dynamics");
|
||||
hdf5_internal::WriteUint64Attribute(metadata.Get(), "schema_version", 1U);
|
||||
hdf5_internal::WriteUint64Attribute(metadata.Get(), "schema_version",
|
||||
SchemaVersion(frame));
|
||||
hdf5_internal::WriteStringAttribute(metadata.Get(),
|
||||
"time_integration_formulation",
|
||||
IntegrationFormulation(frame));
|
||||
hdf5_internal::WriteStringAttribute(metadata.Get(), "mass_formulation",
|
||||
"consistent-kinetic");
|
||||
"nodal-lumped-kinetic");
|
||||
hdf5_internal::WriteStringAttribute(metadata.Get(), "internal_formulation",
|
||||
"FESA-MITC4-total-lagrangian");
|
||||
hdf5_internal::WriteStringAttribute(metadata.Get(), "initial_state",
|
||||
@@ -292,7 +312,8 @@ void WriteMetadata(const hid_t file, const Domain& domain) {
|
||||
/// @brief Records exact accepted endpoint identity on a result dataset.
|
||||
void WriteFrameAttributes(const hid_t dataset,
|
||||
const DynamicAcceptedFrameState& frame) {
|
||||
hdf5_internal::WriteUint64Attribute(dataset, "schema_version", 1U);
|
||||
hdf5_internal::WriteUint64Attribute(dataset, "schema_version",
|
||||
SchemaVersion(frame));
|
||||
hdf5_internal::WriteStringAttribute(dataset, "step_name", "Step-1");
|
||||
hdf5_internal::WriteUint64Attribute(dataset, "frame_index",
|
||||
frame.frame_index);
|
||||
@@ -329,7 +350,7 @@ void ProcessDataset(const hid_t file, const std::string& path,
|
||||
string_attribute("source_step_name", source_step);
|
||||
if (readback) {
|
||||
CheckAttribute(dataset.Get(), "schema_version", H5T_STD_U64LE,
|
||||
H5T_NATIVE_UINT64, std::uint64_t{1U});
|
||||
H5T_NATIVE_UINT64, SchemaVersion(frame));
|
||||
CheckString(dataset.Get(), "step_name", "Step-1");
|
||||
CheckAttribute(dataset.Get(), "frame_index", H5T_STD_U64LE,
|
||||
H5T_NATIVE_UINT64, std::uint64_t{frame.frame_index});
|
||||
@@ -354,7 +375,9 @@ void ProcessDataset(const hid_t file, const std::string& path,
|
||||
leaf == "displacement" ? "global-translation-and-total-rotation-vector"
|
||||
: leaf == "velocity" ? "global-translation-rate-and-chart-rate"
|
||||
: leaf == "acceleration" ? "physical-endpoint-chart-acceleration"
|
||||
: "auxiliary-HHT-chart-acceleration");
|
||||
: SchemaVersion(frame) == 2U
|
||||
? "full-chart-HHT-filter-combination-not-predictor-driver"
|
||||
: "auxiliary-HHT-chart-acceleration");
|
||||
}
|
||||
if (leaf == "triad") string_attribute("axis_names", "A,B,D");
|
||||
if (path.find("/element/shell/") != std::string::npos) {
|
||||
@@ -886,7 +909,7 @@ Status SelfCheck(const std::filesystem::path& path, const Domain& domain,
|
||||
const auto& step = *domain.Dynamic();
|
||||
CheckString(metadata.Get(), "feature_id", "hht-implicit-dynamics");
|
||||
CheckString(metadata.Get(), "analysis_procedure", "hht-implicit-dynamics");
|
||||
CheckString(metadata.Get(), "mass_formulation", "consistent-kinetic");
|
||||
CheckString(metadata.Get(), "mass_formulation", "nodal-lumped-kinetic");
|
||||
CheckString(metadata.Get(), "internal_formulation",
|
||||
"FESA-MITC4-total-lagrangian");
|
||||
CheckString(metadata.Get(), "initial_state", "zero-q-v-step-load-0+");
|
||||
@@ -899,7 +922,10 @@ Status SelfCheck(const std::filesystem::path& path, const Domain& domain,
|
||||
CheckString(metadata.Get(), "source_input_identity",
|
||||
hdf5_internal::SourceInputIdentity(domain));
|
||||
CheckAttribute(metadata.Get(), "schema_version", H5T_STD_U64LE,
|
||||
H5T_NATIVE_UINT64, std::uint64_t{1U});
|
||||
H5T_NATIVE_UINT64,
|
||||
SchemaVersion(state.AcceptedFrames().front()));
|
||||
CheckString(metadata.Get(), "time_integration_formulation",
|
||||
IntegrationFormulation(state.AcceptedFrames().front()));
|
||||
CheckAttribute(metadata.Get(), "increment_count", H5T_STD_U64LE,
|
||||
H5T_NATIVE_UINT64, std::uint64_t{step.increment_count});
|
||||
CheckAttribute(metadata.Get(), "maximum_increments", H5T_STD_U64LE,
|
||||
@@ -988,7 +1014,7 @@ Status DynamicHdf5ResultsWriter::Write(
|
||||
H5Fclose};
|
||||
(void)hdf5_internal::CreateGroup(file.Get(), "/model/shell");
|
||||
hdf5_internal::WriteModel(file.Get(), domain, model);
|
||||
WriteMetadata(file.Get(), domain);
|
||||
WriteMetadata(file.Get(), domain, state.AcceptedFrames().front());
|
||||
WriteDensity(file.Get(), domain);
|
||||
(void)hdf5_internal::CreateGroup(file.Get(), "/steps");
|
||||
(void)hdf5_internal::CreateGroup(file.Get(), "/steps/Step-1");
|
||||
|
||||
@@ -349,7 +349,7 @@ Result<SolidPlan> BuildSolidPlan(const Domain& domain, SolidStateView view,
|
||||
: "linear-static"},
|
||||
{"element_formulation", "FESA-Hex8"},
|
||||
{"integration_rule", "gauss-2x2x2"},
|
||||
{"mass_formulation", "consistent-reference"},
|
||||
{"mass_formulation", "lumped-reference"},
|
||||
{"source_input_identity", SourceInputIdentity(domain)},
|
||||
{"source_step_name", domain.Steps()[0].Name()},
|
||||
{"unit_system_label", "user-consistent-unspecified"},
|
||||
|
||||
Reference in New Issue
Block a user