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:
KOKO\Mimi
2026-10-13 16:57:19 +09:00
parent ede137c6b4
commit eaa5cbeb21
110 changed files with 15274 additions and 971 deletions
+51 -2
View File
@@ -37,7 +37,7 @@ def artifacts(tmp_path_factory):
metadata = file.create_group("metadata")
metadata.attrs.update({
"feature_id": "hht-implicit-dynamics", "analysis_procedure": "hht-implicit-dynamics",
"mass_formulation": "consistent-kinetic", "internal_formulation": "FESA-MITC4-total-lagrangian",
"mass_formulation": "nodal-lumped-kinetic", "internal_formulation": "FESA-MITC4-total-lagrangian",
"initial_state": "zero-q-v-step-load-0+",
"acceleration_convention": "physical-endpoint-and-auxiliary-separated",
"source_step_name": "Step-1", "step_name": "Step-1", "unit_system_label": "consistent-input-units",
@@ -71,6 +71,55 @@ def changed_result(tmp_path, artifacts):
return target
def reduced_result(tmp_path, artifacts):
path = changed_result(tmp_path, artifacts)
with h5py.File(path, "r+") as file:
file["metadata"].attrs.modify("schema_version", np.uint64(2))
file["metadata"].attrs["time_integration_formulation"] = (
"reduced-coordinate-HHT-with-physical-rate-reconstruction")
for frame in range(101):
root = f"steps/Step-1/frames/{frame}/nodal"
displacement = file[f"{root}/displacement"]
displacement.attrs.modify("schema_version", np.uint64(2))
auxiliary = file.create_dataset(f"{root}/algorithmic_acceleration",
data=np.zeros((729, 6), dtype="<f8"))
for name, value in displacement.attrs.items():
auxiliary.attrs[name] = value
auxiliary.attrs["component_names"] = "AUX1,AUX2,AUX3,AUX4,AUX5,AUX6"
auxiliary.attrs["coordinate_system"] = "fixed-initial-global-chart"
auxiliary.attrs["component_unit_dimensions"] = (
"length/time^2,length/time^2,length/time^2,1/time^2,1/time^2,1/time^2")
auxiliary.attrs["quantity_semantics"] = (
"full-chart-HHT-filter-combination-not-predictor-driver")
return path
def test_reduced_schema_preserves_displacement_comparison(tmp_path, artifacts):
result = comparator.compare(artifacts[0], artifacts[1], reduced_result(tmp_path, artifacts))
assert result["precheck"]["passed"], result["precheck"]
assert result["verdict"] == "passed"
@pytest.mark.parametrize("mutation", ["missing_A", "A_semantics", "A_version", "A_nan", "method"])
def test_reduced_schema_rejects_inconsistent_auxiliary_history(tmp_path, artifacts, mutation):
path = reduced_result(tmp_path, artifacts)
with h5py.File(path, "r+") as file:
auxiliary = file["steps/Step-1/frames/99/nodal/algorithmic_acceleration"]
if mutation == "missing_A":
del file[auxiliary.name]
elif mutation == "A_semantics":
auxiliary.attrs["quantity_semantics"] = "auxiliary-HHT-chart-acceleration"
elif mutation == "A_version":
auxiliary.attrs.modify("schema_version", np.uint64(1))
elif mutation == "A_nan":
auxiliary[0, 0] = float("nan")
else:
file["metadata"].attrs["time_integration_formulation"] = "full-coordinate-HHT"
result = comparator.compare(artifacts[0], artifacts[1], path)
assert not result["precheck"]["passed"]
assert result["families"] == []
def test_original_csv_exact_matching_history_and_deterministic_report(artifacts):
first = comparator.compare(*artifacts)
second = comparator.compare(*artifacts)
@@ -128,7 +177,7 @@ def test_hdf5_precheck_rejects_before_tolerance(tmp_path, artifacts, mutation, c
if mutation in {"procedure", "mass", "coefficient", "initial_convention", "input_content"}:
key, value = {
"procedure": ("analysis_procedure", "linear-static"),
"mass": ("mass_formulation", "lumped"),
"mass": ("mass_formulation", "consistent-kinetic"),
"coefficient": ("alpha", 0.0),
"initial_convention": ("initial_state", "unloaded"),
"input_content": ("source_input_identity", "wrong-content"),