Replace Python numerical kernels with native C execution
This commit is contained in:
1 parent
48da6be21c
commit
3b38f73fe0
227 files changed
+16801
-75499
No files matched your search
@@ -0,0 +1,101 @@
|
||||
"""Validate the requested output time grid before starting the C worker."""
|
||||
from __future__ import annotations
|
||||
from math import floor, isfinite
|
||||
from sys import maxsize
|
||||
from app.simulation.config import SolveIVPConfig
|
||||
|
||||
class SimulationSampleTimeError(ValueError):
|
||||
"""Stable failure contract for an unsafe or unrepresentable sample grid."""
|
||||
|
||||
def __init__(self, code: str, message: str) -> None:
|
||||
super().__init__(message)
|
||||
self.code = code
|
||||
|
||||
def simulation_sample_times(
|
||||
config: SolveIVPConfig,
|
||||
step: float,
|
||||
) -> list[float]:
|
||||
t_start = float(config.t_start)
|
||||
t_stop = float(config.t_stop)
|
||||
if not isfinite(t_start) or not isfinite(t_stop):
|
||||
raise SimulationSampleTimeError(
|
||||
"SIMULATION_VALUE_NOT_FINITE",
|
||||
"Simulation start and stop times must be finite.",
|
||||
)
|
||||
if step <= 0.0 or not isfinite(step):
|
||||
raise SimulationSampleTimeError(
|
||||
"SIMULATION_SAMPLE_STEP_INVALID",
|
||||
"Simulation sample step must be finite and greater than zero.",
|
||||
)
|
||||
duration = t_stop - t_start
|
||||
if not isfinite(duration):
|
||||
raise SimulationSampleTimeError(
|
||||
"SIMULATION_TIME_SPAN_NOT_FINITE",
|
||||
"Simulation time span must be finite.",
|
||||
)
|
||||
if duration <= 0.0:
|
||||
raise SimulationSampleTimeError(
|
||||
"SIMULATION_TIME_RANGE_INVALID",
|
||||
"Simulation stop time must be greater than start time.",
|
||||
)
|
||||
|
||||
ratio = duration / step
|
||||
if not isfinite(ratio):
|
||||
raise SimulationSampleTimeError(
|
||||
"SIMULATION_SAMPLE_COUNT_UNREPRESENTABLE",
|
||||
"Simulation sample count cannot be represented by this runtime; "
|
||||
"increase sampleStep.",
|
||||
)
|
||||
interval_count = floor(ratio)
|
||||
# There is no product-level point cap. Still reject a collection that the
|
||||
# Python runtime cannot index before multiplying by the potentially huge
|
||||
# interval count or allocating the output grid.
|
||||
if interval_count > maxsize - 2:
|
||||
raise SimulationSampleTimeError(
|
||||
"SIMULATION_SAMPLE_COUNT_UNREPRESENTABLE",
|
||||
"Simulation sample count cannot be represented by this runtime; "
|
||||
"increase sampleStep.",
|
||||
)
|
||||
last_regular_time = t_start + interval_count * step
|
||||
append_stop = last_regular_time < t_stop
|
||||
requested_point_count = interval_count + 1 + int(append_stop)
|
||||
if requested_point_count > maxsize:
|
||||
raise SimulationSampleTimeError(
|
||||
"SIMULATION_SAMPLE_COUNT_UNREPRESENTABLE",
|
||||
"Simulation sample count cannot be represented by this runtime; "
|
||||
"increase sampleStep.",
|
||||
)
|
||||
|
||||
times = [t_start]
|
||||
for index in range(1, interval_count + 1):
|
||||
candidate = t_start + index * step
|
||||
if not isfinite(candidate):
|
||||
raise SimulationSampleTimeError(
|
||||
"SIMULATION_SAMPLE_TIME_UNREPRESENTABLE",
|
||||
"Simulation sampleStep cannot be represented over the requested "
|
||||
"absolute time range.",
|
||||
)
|
||||
if candidate >= t_stop:
|
||||
candidate = t_stop
|
||||
if candidate <= times[-1]:
|
||||
raise SimulationSampleTimeError(
|
||||
"SIMULATION_SAMPLE_TIME_UNREPRESENTABLE",
|
||||
"Simulation sampleStep is too small to advance floating-point "
|
||||
"time over the requested absolute time range.",
|
||||
)
|
||||
times.append(candidate)
|
||||
if candidate == t_stop:
|
||||
break
|
||||
if times[-1] < t_stop:
|
||||
times.append(t_stop)
|
||||
|
||||
if len(times) < 2 or any(
|
||||
current >= following
|
||||
for current, following in zip(times, times[1:])
|
||||
):
|
||||
raise SimulationSampleTimeError(
|
||||
"SIMULATION_SAMPLE_TIME_UNREPRESENTABLE",
|
||||
"Simulation sample times must contain at least two strictly "
|
||||
"increasing values.",
|
||||
)
|
||||
return times
|
||||
Reference in new issue
Block a user