完善AMESim组件界面与仿真求解稳定性

This commit is contained in:
ljz committed 2026-08-02 00:57:48 +08:00
1 parent e7177ab03e
commit 410ef535e8
34 files changed
+3340 -251

No files matched your search

@@ -26,7 +26,7 @@ class AmesimPnpl01(AlgebraicComponent):
label="PNPL01 零气动流边界",
library_id="amesim",
category_id="boundary",
symbol="generic",
symbol="amesim_pnpl01",
ports=(PortDisplaySpec("port_1", "left", order=10),),
order=10,
)
@@ -105,7 +105,7 @@ class AmesimPnor001(AlgebraicComponent):
label="PNOR001 常系数气动孔口",
library_id="amesim",
category_id="flow",
symbol="orifice",
symbol="amesim_pnor001",
ports=(
PortDisplaySpec("port_1", "left", order=10),
PortDisplaySpec("port_2", "right", order=20),
@@ -412,7 +412,7 @@ class AmesimPnvo001FixedOpening(AlgebraicComponent):
label="PNVO001 固定开度气动孔口",
library_id="amesim",
category_id="flow",
symbol="orifice",
symbol="amesim_pnvo001_fixed",
ports=(
PortDisplaySpec("port_2", "left", order=10),
PortDisplaySpec("port_3", "right", order=20),
@@ -633,7 +633,7 @@ class AmesimPnvo001SignalOpening(AmesimPnvo001FixedOpening):
label="PNVO001 信号开度气动孔口",
library_id="amesim",
category_id="flow",
symbol="orifice",
symbol="amesim_pnvo001",
ports=(
PortDisplaySpec("res", "left", order=5),
PortDisplaySpec("port_2", "left", order=10),
@@ -105,7 +105,7 @@ class AmesimPnl00r(AlgebraicComponent):
label="PNL00R 气动管路阻力",
library_id="amesim",
category_id="flow",
symbol="pipe",
symbol="amesim_pnl00r",
ports=(
PortDisplaySpec("port_1", "left", order=10),
PortDisplaySpec("port_2", "right", order=20),
@@ -440,7 +440,7 @@ class AmesimPnl0001(ThermodynamicVolumeComponent):
label="PNL0001 C-R 动态管路",
library_id="amesim",
category_id="flow",
symbol="pipe",
symbol="amesim_pnl0001",
ports=(
PortDisplaySpec("port_1", "left", order=10),
PortDisplaySpec("port_2", "right", order=20),
@@ -720,7 +720,7 @@ class AmesimPnl0002(AmesimPnl0001):
label="PNL0002 R-C-R 动态管路",
library_id="amesim",
category_id="flow",
symbol="pipe",
symbol="amesim_pnl0002",
ports=(
PortDisplaySpec("port_1", "left", order=10),
PortDisplaySpec("port_2", "right", order=20),
@@ -920,7 +920,7 @@ class AmesimPnl0003(DynamicComponent):
label="PNL0003 C-R-C 动态管路",
library_id="amesim",
category_id="flow",
symbol="pipe",
symbol="amesim_pnl0003",
ports=(
PortDisplaySpec("port_1", "left", order=10),
PortDisplaySpec("port_2", "right", order=20),
@@ -91,7 +91,7 @@ class AmesimPn3Node2(_AmesimPneumaticNode):
label="PN3NODE2 三端气动节点",
library_id="amesim",
category_id="junctions",
symbol="tee",
symbol="amesim_pn3node2",
ports=(
PortDisplaySpec("port_1", "left", order=10),
PortDisplaySpec("port_2", "right", order=20),
@@ -128,7 +128,7 @@ class AmesimP4Node2(_AmesimPneumaticNode):
label="P4NODE2 四端气动节点",
library_id="amesim",
category_id="junctions",
symbol="generic",
symbol="amesim_p4node2",
ports=(
PortDisplaySpec("port_1", "left", order=10),
PortDisplaySpec("port_2", "right", order=20),
@@ -22,7 +22,7 @@ class AmesimF000(AlgebraicComponent):
label="F000 零力源",
library_id="amesim",
category_id="mechanical",
symbol="generic",
symbol="amesim_f000",
ports=(PortDisplaySpec("port_1", "right", order=10),),
order=10,
)
@@ -73,7 +73,7 @@ class AmesimForc(AlgebraicComponent):
label="FORC 信号转力",
library_id="amesim",
category_id="mechanical",
symbol="signal",
symbol="amesim_forc",
ports=(
PortDisplaySpec("res", "left", order=10),
PortDisplaySpec("port_2", "right", order=20),
@@ -167,7 +167,7 @@ class AmesimMecmas21(DynamicComponent):
label="MECMAS21 一维质量",
library_id="amesim",
category_id="mechanical",
symbol="generic",
symbol="amesim_mecmas21",
ports=(
PortDisplaySpec("port_1", "left", order=10),
PortDisplaySpec("port_2", "right", order=20),
@@ -323,7 +323,7 @@ class AmesimLstp00a(AlgebraicComponent):
label="LSTP00A 弹性接触",
library_id="amesim",
category_id="mechanical",
symbol="generic",
symbol="amesim_lstp00a",
ports=(
PortDisplaySpec("port_1", "left", order=10),
PortDisplaySpec("port_2", "right", order=20),
@@ -425,7 +425,7 @@ class AmesimLmechn1(AlgebraicComponent):
label="LMECHN1 线性机械节点",
library_id="amesim",
category_id="mechanical",
symbol="junction",
symbol="amesim_lmechn1",
ports=tuple(
[PortDisplaySpec(f"port_{index}", "left", order=index * 10) for index in range(1, 9)]
+ [PortDisplaySpec("port_9", "right", order=90)]
@@ -1,6 +1,7 @@
from __future__ import annotations
from collections.abc import Mapping
from math import floor
from app.simulation.core.base import AlgebraicComponent
from app.simulation.core.catalog import ComponentDisplaySpec, PortDisplaySpec
@@ -27,7 +28,7 @@ class AmesimStep0(AlgebraicComponent):
label="STEP0 阶跃信号",
library_id="amesim",
category_id="signals",
symbol="signal",
symbol="amesim_step0",
ports=(PortDisplaySpec("out", "right", order=10),),
order=10,
)
@@ -71,6 +72,15 @@ class AmesimStep0(AlgebraicComponent):
def signal_output_values(self, time: float) -> dict[str, float]:
return {"out": self.output_at(time)}
def signal_event_times(
self,
start_time: float,
stop_time: float,
) -> tuple[float, ...]:
"""Expose the exact STEP0 switch time as an integration split point."""
return (self.time,) if start_time < self.time < stop_time else ()
def component_result_values(self) -> Mapping[str, float]:
return {"y": self.out.signal}
@@ -117,7 +127,7 @@ class AmesimUd00(AlgebraicComponent):
label="UD00 分段线性信号",
library_id="amesim",
category_id="signals",
symbol="signal",
symbol="amesim_ud00",
ports=(PortDisplaySpec("out", "right", order=10),),
order=20,
)
@@ -200,5 +210,58 @@ class AmesimUd00(AlgebraicComponent):
def signal_output_values(self, time: float) -> dict[str, float]:
return {"out": self.output_at(time)}
def signal_event_times(
self,
start_time: float,
stop_time: float,
) -> tuple[float, ...]:
"""Return UD00 start, stage, and repeated cycle boundaries.
The final non-cyclic stage is intentionally not given an end event:
``output_at`` continues that stage's slope after its configured duration.
"""
if stop_time <= start_time:
return ()
active_durations = self.durations[: self.nstages]
stage_offsets = [0.0]
elapsed = 0.0
for duration in active_durations[:-1]:
elapsed += duration
stage_offsets.append(elapsed)
if not self.iscyclic:
return tuple(
sorted(
{
event_time
for offset in stage_offsets
if start_time
< (event_time := self.tstart + offset)
< stop_time
}
)
)
cycle_duration = sum(active_durations)
if cycle_duration <= 0.0:
return ()
events: set[float] = set()
for offset in stage_offsets:
first_boundary = self.tstart + offset
cycle_index = max(
0,
floor((start_time - first_boundary) / cycle_duration) + 1,
)
event_time = first_boundary + cycle_index * cycle_duration
while event_time < stop_time:
if event_time > start_time:
events.add(event_time)
cycle_index += 1
event_time = first_boundary + cycle_index * cycle_duration
return tuple(sorted(events))
def component_result_values(self) -> Mapping[str, float]:
return {"y": self.out.signal}
@@ -100,7 +100,7 @@ class AmesimPnch023(ThermodynamicVolumeComponent):
label="PNCH023 固定容积气室",
library_id="amesim",
category_id="storage",
symbol="tank",
symbol="amesim_pnch023",
ports=(
PortDisplaySpec("port_1", "left", order=10),
PortDisplaySpec("port_2", "right", order=20),
@@ -340,7 +340,7 @@ class AmesimPnch012(ThermodynamicVolumeComponent):
label="PNCH012 变容气室",
library_id="amesim",
category_id="storage",
symbol="tank",
symbol="amesim_pnch012",
ports=(
PortDisplaySpec("port_1", "left", order=10),
PortDisplaySpec("port_2", "right", order=20),