公开更多 AMESim 组件并接入信号机械闭环
This commit is contained in:
1 parent
db4bdb4b70
commit
3f51a124d6
28 files changed
+3397
-58
No files matched your search
@@ -0,0 +1,166 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import unittest
|
||||
|
||||
from app.main import (
|
||||
ReactFlowProjectPayload,
|
||||
build_reactflow_system_xml,
|
||||
compile_reactflow_network,
|
||||
run_system_xml_simulation,
|
||||
)
|
||||
from app.system_xml import validate_system_xml_document
|
||||
from tests.test_amesim_pnvo001_signal_xml import signal_edge, signal_port
|
||||
from tests.test_generic_system_xml_simulation import component_node, physical_edge
|
||||
from tests.test_system_xml_protocol import physical_port
|
||||
|
||||
|
||||
MECMAS21_DEFAULTS = {
|
||||
"mass": 2.0,
|
||||
"fstick": 0.0,
|
||||
"fcoul": 0.0,
|
||||
"rvisc": 0.0,
|
||||
"wind": 0.0,
|
||||
"dvel": 1.0e-6,
|
||||
"restdvel": 1.0e-6,
|
||||
"restcoeff": 0.65,
|
||||
"astrib": 1.0e-3,
|
||||
"xmin": -1.0,
|
||||
"Kbmin": 1.0e9,
|
||||
"Dbmin": 1.0e4,
|
||||
"Pdmin": 1.0e-4,
|
||||
"xmax": 1.0,
|
||||
"Kbmax": 1.0e9,
|
||||
"Dbmax": 1.0e4,
|
||||
"Pdmax": 1.0e-4,
|
||||
"theta": 0.0,
|
||||
"useFriction": 1.0,
|
||||
"stoptype": 4.0,
|
||||
"discContactOption": 1.0,
|
||||
"strib": 1.0,
|
||||
"frictionType": 1.0,
|
||||
"v0": 0.0,
|
||||
"x0": 0.0,
|
||||
}
|
||||
|
||||
|
||||
def mechanical_port(name: str, side: str) -> dict[str, str]:
|
||||
return physical_port(name, "bidirectional", side, domain="mechanical")
|
||||
|
||||
|
||||
def zero_force_mass_project() -> ReactFlowProjectPayload:
|
||||
return ReactFlowProjectPayload(
|
||||
name="amesim-mechanical-zero-force-smoke",
|
||||
nodes=[
|
||||
component_node("zero_left", "amesim_f000", [mechanical_port("port_1", "right")]),
|
||||
component_node(
|
||||
"mass_1",
|
||||
"amesim_mecmas21",
|
||||
[mechanical_port("port_1", "left"), mechanical_port("port_2", "right")],
|
||||
MECMAS21_DEFAULTS,
|
||||
),
|
||||
component_node("zero_right", "amesim_f000", [mechanical_port("port_1", "left")]),
|
||||
],
|
||||
edges=[
|
||||
physical_edge("edge-1", "zero_left", "port_1", "mass_1", "port_1"),
|
||||
physical_edge("edge-2", "mass_1", "port_2", "zero_right", "port_1"),
|
||||
],
|
||||
simulation={"t_start": 0.0, "t_stop": 0.02, "step": 0.01, "max_step": 0.01, "method": "BDF"},
|
||||
)
|
||||
|
||||
|
||||
def signal_force_mass_project() -> ReactFlowProjectPayload:
|
||||
parameters = dict(MECMAS21_DEFAULTS)
|
||||
parameters["mass"] = 2.0
|
||||
return ReactFlowProjectPayload(
|
||||
name="amesim-mechanical-signal-force-smoke",
|
||||
nodes=[
|
||||
component_node(
|
||||
"force_signal",
|
||||
"amesim_ud00",
|
||||
[signal_port("out", "output", "right")],
|
||||
{
|
||||
"tstart": 0.0,
|
||||
"start1": 10.0,
|
||||
"end1": 10.0,
|
||||
"t1": 1.0,
|
||||
"start2": 10.0,
|
||||
"end2": 10.0,
|
||||
"t2": 0.0,
|
||||
"start3": 10.0,
|
||||
"end3": 10.0,
|
||||
"t3": 0.0,
|
||||
"start4": 10.0,
|
||||
"end4": 10.0,
|
||||
"t4": 0.0,
|
||||
"start5": 10.0,
|
||||
"end5": 10.0,
|
||||
"t5": 0.0,
|
||||
"start6": 10.0,
|
||||
"end6": 10.0,
|
||||
"t6": 0.0,
|
||||
"start7": 10.0,
|
||||
"end7": 10.0,
|
||||
"t7": 0.0,
|
||||
"start8": 10.0,
|
||||
"end8": 10.0,
|
||||
"t8": 0.0,
|
||||
"nstages": 1.0,
|
||||
"iscyclic": 0.0,
|
||||
},
|
||||
),
|
||||
component_node(
|
||||
"force_1",
|
||||
"amesim_forc",
|
||||
[signal_port("res", "input", "left"), mechanical_port("port_2", "right")],
|
||||
),
|
||||
component_node(
|
||||
"mass_1",
|
||||
"amesim_mecmas21",
|
||||
[mechanical_port("port_1", "left"), mechanical_port("port_2", "right")],
|
||||
parameters,
|
||||
),
|
||||
component_node("zero_right", "amesim_f000", [mechanical_port("port_1", "left")]),
|
||||
],
|
||||
edges=[
|
||||
signal_edge("signal-1", "force_signal", "out", "force_1", "res"),
|
||||
physical_edge("edge-1", "force_1", "port_2", "mass_1", "port_1"),
|
||||
physical_edge("edge-2", "mass_1", "port_2", "zero_right", "port_1"),
|
||||
],
|
||||
simulation={"t_start": 0.0, "t_stop": 0.02, "step": 0.01, "max_step": 0.005, "method": "BDF"},
|
||||
)
|
||||
|
||||
|
||||
class AmesimMechanicalXmlTests(unittest.TestCase):
|
||||
def test_zero_force_mechanical_project_compiles_and_simulates(self) -> None:
|
||||
xml = build_reactflow_system_xml(zero_force_mass_project())
|
||||
report = validate_system_xml_document(xml)
|
||||
|
||||
self.assertTrue(report.valid, report.as_dict())
|
||||
network = compile_reactflow_network(zero_force_mass_project())
|
||||
self.assertTrue(network.pressure_flow_structure_dict()["isSquare"])
|
||||
result = run_system_xml_simulation(xml)
|
||||
|
||||
self.assertTrue(result["success"], result["message"])
|
||||
self.assertEqual(result["series"]["time"], [0.0, 0.01, 0.02])
|
||||
self.assertEqual(result["series"]["mass_1.v"], [0.0, 0.0, 0.0])
|
||||
self.assertEqual(result["series"]["mass_1.x"], [0.0, 0.0, 0.0])
|
||||
|
||||
def test_signal_force_mechanical_project_compiles_and_simulates(self) -> None:
|
||||
xml = build_reactflow_system_xml(signal_force_mass_project())
|
||||
report = validate_system_xml_document(xml)
|
||||
|
||||
self.assertTrue(report.valid, report.as_dict())
|
||||
network = compile_reactflow_network(signal_force_mass_project())
|
||||
self.assertTrue(network.pressure_flow_structure_dict()["isSquare"])
|
||||
result = run_system_xml_simulation(xml)
|
||||
|
||||
self.assertTrue(result["success"], result["message"])
|
||||
self.assertEqual(result["series"]["force_signal.out.signal"], [10.0, 10.0, 10.0])
|
||||
self.assertEqual(result["series"]["force_1.res.signal"], [10.0, 10.0, 10.0])
|
||||
self.assertAlmostEqual(result["series"]["mass_1.a"][0], 5.0)
|
||||
self.assertGreater(result["series"]["mass_1.v"][-1], 0.0)
|
||||
self.assertGreater(result["series"]["mass_1.x"][-1], 0.0)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in new issue
Block a user