优化压力流量求解并达到四路性能门槛

This commit is contained in:
huojiarong committed 2026-08-15 11:45:22 +00:00
1 parent 6572defaa4
commit 6a064892e2
20 files changed
+711 -175

No files matched your search

+66
View File
@@ -44,6 +44,36 @@ class SolveIVPConfig:
first_step: float | None = None
@dataclass(frozen=True)
class SolverSegmentDiagnostics:
"""Work performed by implicit solver instances inside one event segment."""
start_time: float
requested_stop_time: float
simulated_until: float
nfev: int = 0
njev: int = 0
nlu: int = 0
accepted_step_count: int = 0
solver_start_count: int = 0
state_transition_count: int = 0
recoverable_retry_count: int = 0
def as_dict(self) -> dict[str, float | int]:
return {
"startTime": self.start_time,
"requestedStopTime": self.requested_stop_time,
"simulatedUntil": self.simulated_until,
"nfev": self.nfev,
"njev": self.njev,
"nlu": self.nlu,
"acceptedStepCount": self.accepted_step_count,
"solverStartCount": self.solver_start_count,
"stateTransitionCount": self.state_transition_count,
"recoverableRetryCount": self.recoverable_retry_count,
}
@dataclass(frozen=True)
class ODESolution:
t: list[float]
@@ -52,6 +82,7 @@ class ODESolution:
message: str
status: IntegrationStatus = "completed"
error: Exception | None = None
solver_segments: tuple[SolverSegmentDiagnostics, ...] = ()
def _vector_add(a: list[float], b: list[float], scale: float = 1.0) -> list[float]:
@@ -610,6 +641,7 @@ def _integrate_scipy_stepwise(
same_time_transition_count = 0
integration_progressed = False
last_reported_step: float | None = None
solver_segments: list[SolverSegmentDiagnostics] = []
def cancellation_message() -> str:
return (
@@ -639,9 +671,17 @@ def _integrate_scipy_stepwise(
math.nextafter(segment_end, -math.inf) if is_breakpoint else segment_end
)
has_integration_interval = integration_end > last_accepted_time
segment_start_time = last_accepted_time
segment_max_step = float(config.max_step)
recoverable_retry_count = 0
last_recoverable_error: RecoverableTrialStateError | None = None
segment_nfev = 0
segment_njev = 0
segment_nlu = 0
segment_accepted_steps = 0
segment_solver_starts = 0
segment_state_transitions = 0
segment_recoverable_retries = 0
while has_integration_interval and last_accepted_time < integration_end:
if cancel_check():
@@ -681,6 +721,7 @@ def _integrate_scipy_stepwise(
break
except RecoverableTrialStateError as exc:
recoverable_retry_count += 1
segment_recoverable_retries += 1
last_recoverable_error = exc
next_step = 0.5 * segment_max_step
minimum_step = 64.0 * math.ulp(max(abs(last_accepted_time), 1.0))
@@ -697,6 +738,7 @@ def _integrate_scipy_stepwise(
error = exc
break
segment_solver_starts += 1
restart_at_transition = False
restart_after_recoverable = False
@@ -720,6 +762,7 @@ def _integrate_scipy_stepwise(
break
except RecoverableTrialStateError as exc:
recoverable_retry_count += 1
segment_recoverable_retries += 1
last_recoverable_error = exc
attempted_step = segment_max_step
next_step = 0.5 * attempted_step
@@ -744,6 +787,7 @@ def _integrate_scipy_stepwise(
if solver.status == "failed":
if last_recoverable_error is not None:
recoverable_retry_count += 1
segment_recoverable_retries += 1
next_step = 0.5 * segment_max_step
minimum_step = 64.0 * math.ulp(
max(abs(last_accepted_time), 1.0)
@@ -759,6 +803,7 @@ def _integrate_scipy_stepwise(
message = str(step_message or "Integration step failed.")
break
segment_accepted_steps += 1
step_end_time = float(solver.t)
step_end_state = [float(value) for value in solver.y]
dense_output = (
@@ -807,6 +852,7 @@ def _integrate_scipy_stepwise(
break
if transition is not None:
segment_state_transitions += 1
try:
same_time_transition_count = (
_next_same_time_transition_count(
@@ -896,6 +942,9 @@ def _integrate_scipy_stepwise(
)
report_step(reported_time)
segment_nfev += int(getattr(solver, "nfev", 0))
segment_njev += int(getattr(solver, "njev", 0))
segment_nlu += int(getattr(solver, "nlu", 0))
if status != "completed":
break
if restart_after_recoverable:
@@ -903,6 +952,22 @@ def _integrate_scipy_stepwise(
if not restart_at_transition:
break
solver_segments.append(
SolverSegmentDiagnostics(
start_time=float(segment_start_time),
requested_stop_time=float(segment_end),
simulated_until=float(
segment_end if status == "completed" else last_accepted_time
),
nfev=segment_nfev,
njev=segment_njev,
nlu=segment_nlu,
accepted_step_count=segment_accepted_steps,
solver_start_count=segment_solver_starts,
state_transition_count=segment_state_transitions,
recoverable_retry_count=segment_recoverable_retries,
)
)
if status != "completed":
break
@@ -949,6 +1014,7 @@ def _integrate_scipy_stepwise(
message=message,
status=status,
error=error,
solver_segments=tuple(solver_segments),
)