Add test_mql structural Python model

This commit is contained in:
huojiarong committed 2026-07-15 08:59:59 +00:00
1 parent 2c38da16b5
commit c745fd2a5c
5 files changed
+4053

No files matched your search

+16
View File
@@ -0,0 +1,16 @@
# test_mql
Model name used in this repository: `test_mql`.
Source AMESim archive: `AmesimModels/test_mql.ame`.
Python port files added for this model:
- `PythonModels/systems/test_mql.py`
- `PythonModels/scripts/run_test_mql.py`
Current status: structural port scaffold. It records the AMESim component
inventory, global parameters, submodel counts, connection topology, and the
AMESim modelinfo state counts. Existing PythonModels code is not modified.
Detailed physical equations should be filled in incrementally per AMESim
submodel family.
+74
View File
@@ -0,0 +1,74 @@
from __future__ import annotations
from dataclasses import dataclass, field
from datetime import UTC, datetime
from pathlib import Path
from PythonModels.systems.test_mql import TestMqlRunConfig, TestMqlSystem
@dataclass(frozen=True)
class TestMqlPathConfig:
output_dir: Path | None = None
@dataclass(frozen=True)
class TestMqlExecutionConfig:
write_summary: bool = True
@dataclass(frozen=True)
class TestMqlScriptConfig:
run: TestMqlRunConfig = field(default_factory=TestMqlRunConfig)
paths: TestMqlPathConfig = field(default_factory=TestMqlPathConfig)
execution: TestMqlExecutionConfig = field(default_factory=TestMqlExecutionConfig)
def _default_output_dir() -> Path:
pythonmodels_root = Path(__file__).resolve().parents[1]
timestamp = datetime.now(UTC).strftime("test_mql_%Y%m%d_%H%M%S_%f")
return pythonmodels_root / "runs" / timestamp
def format_test_mql_summary(system: TestMqlSystem) -> str:
snapshot = system.snapshot()
lines = [
"Model: test_mql",
f"Source archive: {system.archive_path}",
f"Components: {snapshot.component_count}",
f"Connections: {snapshot.connection_count}",
f"Continuous states in AMESim modelinfo: {snapshot.continuous_state_count}",
f"Discrete states in AMESim modelinfo: {snapshot.discrete_state_count}",
"Global parameters:",
]
for name, value in sorted(snapshot.global_parameters.items()):
lines.append(f" - {name}: {value}")
lines.append("Component submodels:")
for name, count in sorted(snapshot.submodel_counts.items()):
lines.append(f" - {name}: {count}")
return "\n".join(lines) + "\n"
def run_test_mql(config: TestMqlScriptConfig | None = None):
config = config or TestMqlScriptConfig()
system = TestMqlSystem()
result = system.simulate(config.run)
output_dir = config.paths.output_dir or _default_output_dir()
if config.execution.write_summary:
output_dir.mkdir(parents=True, exist_ok=True)
(output_dir / "test_mql_model_summary.txt").write_text(
format_test_mql_summary(system),
encoding="utf-8",
)
return system, result, output_dir
def main() -> None:
system, result, output_dir = run_test_mql()
print(format_test_mql_summary(system), end="")
print(f"Samples: {len(result.t)}")
print(f"Output directory: {output_dir}")
if __name__ == "__main__":
main()
File diff suppressed because it is too large. Load diff
View File
Whitespace-only changes.
+46
View File
@@ -0,0 +1,46 @@
from __future__ import annotations
import unittest
from PythonModels.systems.test_mql import GLOBAL_PARAMETERS, SUBMODEL_COUNTS, TestMqlSystem
class TestMqlStructuralTest(unittest.TestCase):
def test_snapshot_matches_amesim_archive_metadata(self) -> None:
snapshot = TestMqlSystem().snapshot()
self.assertEqual(snapshot.model_name, "test_mql")
self.assertEqual(snapshot.component_count, 117)
self.assertEqual(snapshot.connection_count, 84)
self.assertEqual(snapshot.continuous_state_count, 132)
self.assertEqual(snapshot.discrete_state_count, 24)
self.assertEqual(snapshot.global_parameters["P0"], "153")
self.assertEqual(snapshot.global_parameters["cf"], "0.45")
def test_network_preserves_component_and_connection_counts(self) -> None:
system = TestMqlSystem()
self.assertEqual(len(system.network.components), 117)
self.assertEqual(len(system.network.connections), 84)
self.assertIn("pn_brp2_8", system.network.components)
self.assertIn("pn_gas_data", system.network.components)
def test_submodel_counts_keep_key_amesim_families(self) -> None:
self.assertEqual(SUBMODEL_COUNTS["PNRP17"], 8)
self.assertEqual(SUBMODEL_COUNTS["PNCH012"], 8)
self.assertEqual(SUBMODEL_COUNTS["PNOR001"], 8)
self.assertEqual(SUBMODEL_COUNTS["PNVO001"], 8)
self.assertEqual(SUBMODEL_COUNTS["PNGD00"], 1)
self.assertEqual(GLOBAL_PARAMETERS["V"], "15")
def test_structural_simulation_shape(self) -> None:
result = TestMqlSystem().simulate()
self.assertEqual(len(result.t), 101)
self.assertEqual(len(result.y), 132)
self.assertEqual(result.series["component_count"][0], 117.0)
self.assertEqual(result.series["connection_count"][0], 84.0)
if __name__ == "__main__":
unittest.main()