初版:实现 AMESim 机械因果化与事件求解
初步支持 MECMAS21 刚性质量状态归并、端止事件、恢复系数,以及 LSTP 接触和压力流量显式因果化。 已知问题:显式传播仍会重复扫描全网方程,长时刚性仿真性能待优化;自适应积分器遇到越出物理域的试探状态时,尚未实现恢复并缩步重试。
This commit is contained in:
1 parent
de265cdde6
commit
971e8f2336
9 files changed
+2808
-169
No files matched your search
@@ -8,6 +8,7 @@ from typing import Literal
|
||||
from app.simulation.core.base import DynamicComponent
|
||||
from app.simulation.core.metadata import ResultVariableMetadata
|
||||
from app.simulation.solvers.algebraic import PressureFlowSolver
|
||||
from app.simulation.solvers.mechanical import MechanicalStateReducer
|
||||
from app.simulation.solvers.pneumatic_volume import PneumaticVolumeResolver
|
||||
from app.simulation.solvers.solver import ODESolution, SolveIVPConfig, integrate_ode
|
||||
from app.simulation.solvers.signal import SignalResolver
|
||||
@@ -233,6 +234,10 @@ class GenericFluidSystem:
|
||||
raise SimulationPreparationError(issues)
|
||||
self.network = network
|
||||
self.dynamic_components = network.dynamic_components()
|
||||
self.mechanical_state_reducer = MechanicalStateReducer(
|
||||
network,
|
||||
self.dynamic_components,
|
||||
)
|
||||
self.pressure_flow_solver = PressureFlowSolver(network)
|
||||
self.pneumatic_volume_resolver = PneumaticVolumeResolver(network)
|
||||
self.signal_resolver = SignalResolver(network)
|
||||
@@ -245,10 +250,10 @@ class GenericFluidSystem:
|
||||
self.pneumatic_volume_propagation_count = 0
|
||||
|
||||
def initial_state_vector(self) -> list[float]:
|
||||
return self.network.initial_state_vector()
|
||||
return self.mechanical_state_reducer.initial_state_vector()
|
||||
|
||||
def apply_state_vector(self, values: list[float]) -> None:
|
||||
self.network.apply_state_vector(values)
|
||||
self.mechanical_state_reducer.apply_state_vector(values)
|
||||
|
||||
def _close_current_state(self, time: float) -> dict[str, dict[str, float]]:
|
||||
signal = self.signal_resolver.solve(time)
|
||||
@@ -263,6 +268,7 @@ class GenericFluidSystem:
|
||||
component.refresh_thermodynamic_ports()
|
||||
algebraic = self.pressure_flow_solver.solve()
|
||||
stream, connected_h = self.stream_resolver.solve()
|
||||
self.mechanical_state_reducer.update_constraint_accelerations()
|
||||
self.algebraic_solve_count += 1 + int(bool(pneumatic_volume.propagated))
|
||||
self.max_algebraic_residual = max(
|
||||
self.max_algebraic_residual,
|
||||
@@ -278,21 +284,16 @@ class GenericFluidSystem:
|
||||
)
|
||||
return connected_h
|
||||
|
||||
def consistent_initial_state_vector(self) -> list[float]:
|
||||
def consistent_initial_state_vector(self, time: float = 0.0) -> list[float]:
|
||||
state = self.initial_state_vector()
|
||||
self.apply_state_vector(state)
|
||||
self._close_current_state(0.0)
|
||||
self._close_current_state(time)
|
||||
return state
|
||||
|
||||
def rhs(self, _time: float, state_vector: list[float]) -> list[float]:
|
||||
self.apply_state_vector(state_vector)
|
||||
connected_h = self._close_current_state(_time)
|
||||
derivatives: list[float] = []
|
||||
for component in self.dynamic_components:
|
||||
derivatives.extend(
|
||||
component.state_derivative_from_ports(connected_h[component.name])
|
||||
)
|
||||
return derivatives
|
||||
return self.mechanical_state_reducer.state_derivatives(connected_h)
|
||||
|
||||
def _append_current_state(self, series: dict[str, list[float]]) -> None:
|
||||
for component in self.network.components.values():
|
||||
@@ -340,7 +341,7 @@ class GenericFluidSystem:
|
||||
config.t_start,
|
||||
config.t_stop,
|
||||
)
|
||||
initial_state = self.consistent_initial_state_vector()
|
||||
initial_state = self.consistent_initial_state_vector(config.t_start)
|
||||
report_progress(0.0, "integrating", force=True)
|
||||
duration = config.t_stop - config.t_start
|
||||
furthest_solver_time = config.t_start
|
||||
@@ -370,6 +371,11 @@ class GenericFluidSystem:
|
||||
report_solver_time if cancel_check is not None else None
|
||||
),
|
||||
breakpoints=signal_event_times,
|
||||
state_transition_handler=(
|
||||
self.mechanical_state_reducer.state_transition
|
||||
if self.mechanical_state_reducer.has_state_events
|
||||
else None
|
||||
),
|
||||
)
|
||||
if isinstance(solution, ODESolution):
|
||||
run_status: SimulationRunStatus = solution.status
|
||||
@@ -387,6 +393,7 @@ class GenericFluidSystem:
|
||||
times = [float(value) for value in solution.t]
|
||||
series: dict[str, list[float]] = {"time": []}
|
||||
postprocessing_error: Exception | None = None
|
||||
self.mechanical_state_reducer.reset_constraint_modes()
|
||||
for time_index in range(len(times)):
|
||||
if (
|
||||
run_status == "completed"
|
||||
|
||||
Reference in new issue
Block a user