85 lines
3.4 KiB
Python
85 lines
3.4 KiB
Python
from __future__ import annotations
|
|
|
|
from copy import deepcopy
|
|
import subprocess
|
|
import unittest
|
|
from xml.etree import ElementTree as ET
|
|
|
|
from app.main import run_system_xml_simulation
|
|
from app.simulation.native_codegen.build import toolchain
|
|
from app.simulation.native_codegen.input import project_xml
|
|
from app.system_xml import validate_system_xml_document
|
|
from tests.test_amesim_pnch012_xml import amesim_pnch012_project
|
|
|
|
|
|
def pressure_project(value: float | str, unit: str = "bar") -> dict:
|
|
project = amesim_pnch012_project().model_dump(mode="json")
|
|
chamber = project["nodes"][0]["data"]
|
|
chamber["parameters"]["p0"] = value
|
|
chamber["parameterUnits"]["p0"] = unit
|
|
return project
|
|
|
|
|
|
class PressureUnitInputTests(unittest.TestCase):
|
|
def test_absolute_bar_expression_exports_si_without_atmospheric_offset(self) -> None:
|
|
project = pressure_project("= 0.25 + 0.75")
|
|
original = deepcopy(project)
|
|
xml = project_xml(project)
|
|
root = ET.fromstring(xml)
|
|
self.assertEqual(root.attrib["unitSystem"], "SI")
|
|
parameter = root.find(
|
|
"./Components/Component[@id='chamber_1']/Parameter[@name='p0']"
|
|
)
|
|
self.assertIsNotNone(parameter)
|
|
self.assertEqual(float(parameter.attrib["value"]), 100000.0)
|
|
self.assertNotIn("unit", parameter.attrib)
|
|
report = validate_system_xml_document(xml)
|
|
self.assertTrue(report.valid, report.as_dict())
|
|
self.assertEqual(project, original)
|
|
|
|
def test_saved_numeric_values_are_already_si_with_absolute_bar_display(self) -> None:
|
|
for value in (250000.0, "250000"):
|
|
with self.subTest(value=value):
|
|
self.assertEqual(
|
|
project_xml(pressure_project(value)),
|
|
project_xml(pressure_project(250000.0, "Pa")),
|
|
)
|
|
|
|
def test_absolute_bar_and_existing_pressure_expression_units_are_equivalent(self) -> None:
|
|
expected = project_xml(pressure_project(250000.0, "Pa"))
|
|
for unit, expression in (
|
|
("bar", "2 + 0.5"),
|
|
("kPa", "200 + 50"),
|
|
("MPa", "0.2 + 0.05"),
|
|
("Pa", "200000 + 50000"),
|
|
):
|
|
with self.subTest(unit=unit):
|
|
self.assertEqual(project_xml(pressure_project(expression, unit)), expected)
|
|
|
|
def test_absolute_bar_and_pa_simulations_return_identical_si_pressure(self) -> None:
|
|
try:
|
|
toolchain()
|
|
except (OSError, RuntimeError, subprocess.SubprocessError) as exc:
|
|
self.skipTest(f"Native toolchain unavailable: {exc}")
|
|
absolute_bar = run_system_xml_simulation(
|
|
project_xml(pressure_project("2 + 0.5", "bar"))
|
|
)
|
|
pascals = run_system_xml_simulation(
|
|
project_xml(pressure_project(250000.0, "Pa"))
|
|
)
|
|
self.assertTrue(absolute_bar["success"], absolute_bar["message"])
|
|
self.assertTrue(pascals["success"], pascals["message"])
|
|
self.assertEqual(absolute_bar["series"], pascals["series"])
|
|
self.assertEqual(absolute_bar["series"]["time"], [0.0, 0.001, 0.002])
|
|
for pressure in absolute_bar["series"]["chamber_1.p"]:
|
|
self.assertAlmostEqual(pressure, 250000.0, places=6)
|
|
pressure_metadata = next(
|
|
variable for variable in absolute_bar["variables"]
|
|
if variable["key"] == "chamber_1.p"
|
|
)
|
|
self.assertEqual(pressure_metadata["unit"], "Pa")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|