Core Solver¶
core_solver
¶
Deterministic time stepping for structured dynamics and field/operator systems.
This solver advances a :class:op_engine.model_core.ModelCore instance over its
configured time grid. In the updated semantics, ModelCore.time_grid is treated
as output times: the times at which the user wants a stored solution state.
Between consecutive output times, the solver may take either:
- one or more fixed steps bounded by RunConfig.fixed_max_step
(adaptive=False), or
- multiple internal adaptive substeps that land exactly on t_{i+1} (adaptive=True).
Supported methods (keyword method=):
- "euler": Explicit Euler (order 1), adaptive via step-doubling.
- "heun": Explicit Heun / RK2 (order 2), embedded Euler estimator.
- "rk4": Classic explicit Runge--Kutta (order 4).
- "dopri5": Dormand--Prince 5(4), embedded adaptive estimator.
- "imex-euler": IMEX Euler: explicit Euler on F(t,y), implicit Euler on A.
Adaptive via step-doubling (IMEX step-doubling).
- "imex-heun-tr": IMEX Heun-Trapezoidal: Heun on F, trapezoidal/CN on A.
Adaptive via step-doubling of the complete split step.
- "imex-trbdf2": IMEX TR-BDF2 (order 2), adaptive via step-doubling.
- "imex-ark3": ARS(4,4,3) additive Runge--Kutta with embedded order 2.
- "implicit-euler": One-linearization Euler approximation (order 1).
- "trapezoidal": One-linearization trapezoidal approximation (order 2).
- "bdf2": One-linearization BDF2 approximation (order 2).
- "ros2": L-stable Rosenbrock-W 2(1).
- "sdirk2": L-stable Alexander SDIRK2 with full nonlinear stages.
IMEX structure
We assume a split system: y' = A(t,y) y + F(t,y) where F is provided by rhs_func(t, y), and A is represented by linear operators applied along a single tensor axis. Operators may be: - None (no supplied implicit split operator), or - provided as tuples (predictor?, L, R), or - provided as factories depending on dt, stage-scale, and context.
Operator application
Operators act along a configured axis (default "state"). All other axes are batched. The solve form is: L @ y_next = R @ x optionally with a preprocessing predictor: x_tilde = predictor @ x
Non-uniform dt
- Explicit methods naturally support non-uniform dt.
- Implicit/IMEX methods require operator factories whenever dt varies across steps (non-uniform output grid or adaptive stepping), because L/R depend on dt.
Performance hygiene
- NumPy paths retain preallocated scratch arrays and in-place operations.
- Immutable namespaces use functional stepping operations.
- Dense implicit solves use Array-API linalg; sparse adapters cache factors.
AdaptiveAdvanceParams(plan, t0, t1, y0, adaptive_cfg, dt_ctrl)
dataclass
¶
Bundle of parameters for adaptive advancement to an output time.
Attributes:
| Name | Type | Description |
|---|---|---|
plan |
RunPlan
|
Resolved run plan. |
t0 |
float
|
Start time. |
t1 |
float
|
End/output time. |
y0 |
NDArray[floating]
|
Initial state at t0. |
adaptive_cfg |
AdaptiveConfig
|
Adaptive stepping configuration. |
dt_ctrl |
DtControllerConfig
|
dt controller configuration. |
AdaptiveConfig(rtol=1e-06, atol=1e-09, dt_init=None, max_reject=25, max_steps=1000000)
dataclass
¶
Configuration for adaptive stepping.
Attributes:
| Name | Type | Description |
|---|---|---|
rtol |
float
|
Relative tolerance. |
atol |
float | Array
|
Absolute tolerance (scalar or array-like). |
dt_init |
float | None
|
Optional initial dt guess; if None, use output dt. |
max_reject |
int
|
Maximum number of rejected attempts per accepted step. |
max_steps |
int
|
Maximum number of internal substeps per output interval. |
__post_init__()
¶
Validate static adaptive-step parameters without coercing arrays.
Raises:
| Type | Description |
|---|---|
ValueError
|
If any static adaptive parameter is invalid. |
Source code in src/op_engine/core_solver.py
345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 | |
AdaptiveScheduleProvenance
¶
Bases: NamedTuple
Static compatibility fields and descriptive adaptive-discovery metadata.
Backend, dtype, discovery controls, and reference regime are descriptive. Replay checks method, state layout, relevant operator/kernel settings, and the caller's structural model identity. Callback semantics are not inferred.
AdaptiveStepSchedule(output_times, step_sizes, provenance=None)
dataclass
¶
Accepted step sizes for replaying one adaptive solve.
The schedule records controller decisions, not array values. Replaying it therefore uses the same numerical kernels and active Array-API namespace as a live solve while keeping loop lengths and step sizes static.
Attributes:
| Name | Type | Description |
|---|---|---|
output_times |
tuple[float, ...]
|
Output grid used to create the schedule. |
step_sizes |
tuple[tuple[float, ...], ...]
|
Accepted internal step sizes for each output interval. |
provenance |
AdaptiveScheduleProvenance | None
|
Optional producing method/layout/configuration metadata. None retains manually constructed/legacy mesh compatibility. |
__post_init__()
¶
Normalize and validate the recorded mesh.
Raises:
| Type | Description |
|---|---|
TypeError
|
If provenance has the wrong record type. |
ValueError
|
If times or step sizes do not define a valid mesh. |
Source code in src/op_engine/core_solver.py
427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 | |
CoreSolver(core, operators=None, *, operator_axis='state')
¶
Semi-implicit solver operating on a ModelCore time/state grid.
Initialize CoreSolver.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
core
|
ModelCore
|
ModelCore instance to solve. |
required |
operators
|
CoreOperators | StageOperatorFactory | None
|
Default operator spec (tuple or factory) for implicit stages. |
None
|
operator_axis
|
str | int
|
Axis along which operators act (name or index). |
'state'
|
Source code in src/op_engine/core_solver.py
1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 | |
last_adaptive_schedule
property
¶
Return the schedule recorded or replayed by the latest adaptive run.
last_nonlinear_diagnostics
property
¶
Return nonlinear diagnostics from the latest SDIRK run or replay.
last_state_diagnostics
property
¶
Return output-state checks from the latest run/replay, if enabled.
adaptive_explicit_step(rhs_func, *, method, t, dt, y, first_stage=None, forcing_breakpoints=())
¶
Attempt one explicit step and return its local-error estimate.
This functional boundary does not mutate :class:ModelCore history
and does not extract host scalars. Provider integrations can compose
it with backend-native adaptive controller loops.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
rhs_func
|
RHSFunction
|
Function computing the explicit RHS F(t, y). |
required |
method
|
str
|
Explicit solver method name. |
required |
t
|
Scalar
|
Step start time as a Python float or backend-native scalar. |
required |
dt
|
Scalar
|
Step size as a Python float or backend-native scalar. |
required |
y
|
Array
|
State at the step start. |
required |
first_stage
|
Array | None
|
Optional cached derivative at |
None
|
forcing_breakpoints
|
tuple[float, ...]
|
Static known jumps. The caller must clip the step at the next jump. RHS times use native one-sided neighbors; declared forcing disables first-stage reuse. |
()
|
Returns:
| Type | Description |
|---|---|
ExplicitStepResult
|
Candidate state, local error estimate, controller order, and |
ExplicitStepResult
|
reusable derivative stages. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Source code in src/op_engine/core_solver.py
3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 | |
fixed_explicit_step(rhs_func, *, method, t, dt, y, first_stage=None, forcing_breakpoints=())
¶
Take one functional fixed step with an explicit method.
This boundary does not mutate :class:ModelCore history, so callers
can compose it with backend-native loop primitives and apply the
completed trajectory once. It is the supported public step kernel
for external drivers such as jax.lax.scan; the method and state
shape are static, while t, dt, y, and RHS parameters may
be traced. RHS results must preserve the configured state shape and
the namespace of y.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
rhs_func
|
RHSFunction
|
Function computing the explicit RHS F(t, y). |
required |
method
|
str
|
Explicit solver method name. |
required |
t
|
Scalar
|
Step start time as a Python float or backend-native scalar. |
required |
dt
|
Scalar
|
Step size as a Python float or backend-native scalar. |
required |
y
|
Array
|
State at the step start. |
required |
first_stage
|
Array | None
|
Optional derivative at |
None
|
forcing_breakpoints
|
tuple[float, ...]
|
Static known jumps. The caller must clip the step at the next jump. RHS times use native one-sided neighbors; declared forcing disables first-stage reuse. |
()
|
Returns:
| Type | Description |
|---|---|
Array
|
Next state and an FSAL derivative for Dormand--Prince, or |
Array | None
|
|
tuple[Array, Array | None]
|
with one step outside the scan so its structure stays fixed. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Source code in src/op_engine/core_solver.py
3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 | |
replay_adaptive_schedule(rhs_func, schedule, *, config)
¶
Replay a recorded adaptive mesh through the configured method.
Replay bypasses error norms and accept/reject decisions while invoking
the same high-order step kernels used by a live adaptive solve. With a
JAX state, the static Python schedule can therefore be traced by
jax.jit and differentiated with respect to array-valued model inputs.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
rhs_func
|
RHSFunction
|
Function computing the explicit RHS F(t, y). |
required |
schedule
|
AdaptiveStepSchedule
|
Accepted step mesh recorded by an adaptive run. |
required |
config
|
RunConfig
|
Matching adaptive run configuration. |
required |
Returns:
| Type | Description |
|---|---|
NonlinearIntegrationDiagnostics | None
|
Array-valued nonlinear diagnostics for SDIRK2, otherwise |
NonlinearIntegrationDiagnostics | None
|
Opt-in output-state checks are available through |
NonlinearIntegrationDiagnostics | None
|
attr: |
Raises:
| Type | Description |
|---|---|
TypeError
|
If schedule has the wrong type or the state changes array ecosystems during replay. |
ValueError
|
If config is not adaptive, the output grid differs, required provenance is absent, or structural provenance differs. |
Source code in src/op_engine/core_solver.py
5089 5090 5091 5092 5093 5094 5095 5096 5097 5098 5099 5100 5101 5102 5103 5104 5105 5106 5107 5108 5109 5110 5111 5112 5113 5114 5115 5116 5117 5118 5119 5120 5121 5122 5123 5124 5125 5126 5127 5128 5129 5130 5131 5132 5133 5134 5135 5136 5137 5138 5139 5140 5141 5142 5143 5144 5145 5146 5147 5148 5149 5150 5151 5152 5153 5154 5155 5156 5157 5158 5159 5160 5161 5162 5163 5164 5165 5166 5167 5168 5169 5170 5171 5172 5173 5174 5175 5176 5177 5178 5179 5180 5181 5182 5183 5184 5185 5186 5187 5188 5189 5190 | |
run(rhs_func, *, config=None)
¶
Advance the ModelCore state through its time grid.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
rhs_func
|
RHSFunction
|
Function computing the explicit RHS F(t, y). |
required |
config
|
RunConfig | None
|
Optional run configuration. If None, defaults are used. |
None
|
Returns:
| Type | Description |
|---|---|
NonlinearIntegrationDiagnostics | None
|
Array-valued nonlinear diagnostics for SDIRK2, otherwise |
NonlinearIntegrationDiagnostics | None
|
Opt-in output-state checks are available through |
NonlinearIntegrationDiagnostics | None
|
attr: |
Raises:
| Type | Description |
|---|---|
TypeError
|
If the state changes array ecosystems during a run. |
ValueError
|
If invalid parameters are provided. |
Examples:
>>> import numpy as np
>>> from op_engine import ModelCore
>>> from op_engine.core_solver import RunConfig
>>> core = ModelCore(1, 1, np.linspace(0.0, 1.0, 11))
>>> core.set_initial_state(np.array([[1.0]]))
>>> def decay(time, state):
... return -state
>>> CoreSolver(core).run(decay, config=RunConfig(method="rk4"))
>>> np.allclose(core.state_array[-1, 0, 0], np.exp(-1.0), rtol=1e-5)
True
Source code in src/op_engine/core_solver.py
5192 5193 5194 5195 5196 5197 5198 5199 5200 5201 5202 5203 5204 5205 5206 5207 5208 5209 5210 5211 5212 5213 5214 5215 5216 5217 5218 5219 5220 5221 5222 5223 5224 5225 5226 5227 5228 5229 5230 5231 5232 5233 5234 5235 5236 5237 5238 5239 5240 5241 5242 5243 5244 5245 5246 5247 5248 5249 5250 5251 5252 5253 5254 5255 5256 5257 5258 5259 5260 5261 5262 5263 5264 5265 5266 5267 5268 5269 5270 5271 5272 5273 5274 5275 5276 5277 5278 5279 5280 5281 5282 5283 5284 5285 5286 5287 5288 5289 5290 5291 5292 5293 5294 5295 5296 5297 5298 5299 5300 5301 | |
DtControllerConfig(dt_min=0.0, dt_max=float('inf'), safety=0.9, fac_min=0.2, fac_max=5.0)
dataclass
¶
Configuration for adaptive timestep control.
Attributes:
| Name | Type | Description |
|---|---|---|
dt_min |
float
|
Minimum allowed dt. |
dt_max |
float
|
Maximum allowed dt. |
safety |
float
|
Safety factor applied to dt updates. |
fac_min |
float
|
Minimum multiplicative change factor. |
fac_max |
float
|
Maximum multiplicative change factor. |
__post_init__()
¶
Validate static timestep-controller parameters.
Raises:
| Type | Description |
|---|---|
ValueError
|
If any controller parameter is outside its valid range. |
Source code in src/op_engine/core_solver.py
298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 | |
ExplicitStepResult(state, error, controller_order, first_stage, last_stage)
dataclass
¶
Result and reusable stages from one explicit adaptive attempt.
Attributes:
| Name | Type | Description |
|---|---|---|
state |
Array
|
Accepted-order candidate state. |
error |
Array
|
Local error estimate. |
controller_order |
int
|
Order supplied to the existing step-size controller. |
first_stage |
Array
|
Derivative at the attempted step's initial state. |
last_stage |
Array | None
|
Derivative reusable by an FSAL method after acceptance. |
ImexEulerOnceParams(t, y, dt, op_spec, out)
dataclass
¶
Bundle of parameters for one IMEX Euler step (non-doubling).
Attributes:
| Name | Type | Description |
|---|---|---|
t |
float
|
Current time. |
y |
NDArray[floating]
|
Current state. |
dt |
float
|
Step size. |
op_spec |
CoreOperators | StageOperatorFactory | None
|
Operator spec for implicit stage. |
out |
NDArray[floating]
|
Output state array (written in-place). |
ImplicitStageParams(spec, dt, scale, t_stage, y_stage, stage, x, out)
dataclass
¶
Bundle of parameters for one implicit operator application.
Attributes:
| Name | Type | Description |
|---|---|---|
spec |
CoreOperators | StageOperatorFactory | None
|
Operator spec (tuple or factory) or None for identity. |
dt |
float
|
Full-step dt for operator factory context. |
scale |
float
|
Stage scaling factor for dt-dependent operators. |
t_stage |
float
|
Stage time. |
y_stage |
NDArray[floating]
|
Stage state proxy for operator factories. |
stage |
str
|
Stage label (e.g., "be", "tr", "bdf2"). |
x |
NDArray[floating]
|
Input array to map. |
out |
NDArray[floating]
|
Output array (written in-place). |
NonlinearIntegrationConvergenceError(diagnostics)
¶
Bases: RuntimeError
Raised after validating failed array-valued integration diagnostics.
Store diagnostics for the invalid integration or frozen mesh.
Source code in src/op_engine/core_solver.py
591 592 593 594 595 596 597 598 599 600 601 | |
NonlinearIntegrationDiagnostics
¶
Bases: NamedTuple
Array-valued nonlinear diagnostics for one integration or replay.
Every field is in the state array's namespace, so the record can cross a
compiled JAX boundary. stages_per_step maps flattened stage fields back
to attempted steps. Rejected adaptive attempts remain present with
step_accepted=False.
require_converged()
¶
Return valid diagnostics or invalidate a failed compiled replay.
Returns:
| Type | Description |
|---|---|
NonlinearIntegrationDiagnostics
|
This unchanged diagnostic record. |
Raises:
| Type | Description |
|---|---|
NonlinearIntegrationConvergenceError
|
If an accepted or replayed step contains a failed nonlinear stage. |
Source code in src/op_engine/core_solver.py
573 574 575 576 577 578 579 580 581 582 583 584 585 | |
NonlinearMethodConfig(rhs_jacobian, solver=DenseNewtonSolver())
dataclass
¶
Configuration for fully nonlinear integration methods.
The Jacobian acts on the entire flattened RHS state. It is deliberately
separate from :attr:RunConfig.jacobian, whose operators act only along
CoreSolver.operator_axis for linearly implicit methods.
Attributes:
| Name | Type | Description |
|---|---|---|
rhs_jacobian |
FullRhsJacobianFunction
|
Dense full-system Jacobian with shape
|
solver |
NonlinearSolver
|
Backend-neutral nonlinear solver implementation. |
__post_init__()
¶
Validate the method boundary without selecting an array backend.
Raises:
| Type | Description |
|---|---|
TypeError
|
If a callback or nonlinear solver is invalid. |
Source code in src/op_engine/core_solver.py
753 754 755 756 757 758 759 760 761 762 763 764 | |
OperatorLike
¶
Bases: Protocol
Minimal operator interface required by CoreSolver.
Implementations are expected to behave like 2D linear operators suitable for implicit_solve(L, R, rhs2d). Only shape is required for validation.
shape
property
¶
Operator shape.
OperatorSpecs(default=None, tr=None, bdf2=None)
dataclass
¶
Operator specifications for implicit/IMEX methods.
Attributes:
| Name | Type | Description |
|---|---|---|
default |
CoreOperators | StageOperatorFactory | None
|
Default operator spec (tuple or factory) used by IMEX Euler/Heun-TR and as a fallback for TR/BDF2 stages. |
tr |
CoreOperators | StageOperatorFactory | None
|
Operator spec for trapezoidal stage of TR-BDF2 (optional). |
bdf2 |
CoreOperators | StageOperatorFactory | None
|
Operator spec for BDF2 stage of TR-BDF2 (optional). |
PredictorLike
¶
Bases: Protocol
Minimal predictor interface required by CoreSolver.
The predictor is an optional preprocessing operator applied as
rhs2d = predictor @ rhs2d
__matmul__(other)
¶
Apply the predictor to a 2D array.
Source code in src/op_engine/core_solver.py
261 262 263 | |
RunConfig(method='heun', adaptive=False, strict=True, dt_controller=DtControllerConfig(), adaptive_cfg=AdaptiveConfig(), operators=OperatorSpecs(), jacobian=None, nonlinear=None, gamma=None, fixed_max_step=None, replay_loop='unroll', replay_checkpoint=False, replay_model_id=None, replay_reference_regime=None, replay_require_provenance=False, forcing_breakpoints=(), fixed_loop='unroll', fixed_checkpoint=False, state_checks=None)
dataclass
¶
Configuration for CoreSolver.run.
Attributes:
| Name | Type | Description |
|---|---|---|
method |
str
|
Method name. |
adaptive |
bool
|
Whether to use adaptive substepping between output times. |
strict |
bool
|
If True, invalid configurations raise; otherwise warnings and method downshifts may occur. |
dt_controller |
DtControllerConfig
|
Parameters for dt controller when adaptive=True. |
adaptive_cfg |
AdaptiveConfig
|
Parameters controlling error tolerances and limits. |
operators |
OperatorSpecs
|
Operator specifications for implicit/IMEX methods. |
jacobian |
JacobianFunction | None
|
Optional Jacobian function for linearly implicit methods. |
nonlinear |
NonlinearMethodConfig | None
|
Full-system Jacobian and backend-neutral nonlinear solver. |
gamma |
float | None
|
Optional TR-BDF2 gamma (if None, uses default). |
fixed_max_step |
float | None
|
Maximum explicit fixed-step size between output times.
|
fixed_loop |
Literal['auto', 'scan', 'unroll']
|
Iteration strategy for fixed explicit solves. |
fixed_checkpoint |
bool
|
Rematerialize the fixed scan body during reverse
mode. Used only when |
state_checks |
OutputStateCheckConfig | None
|
Optional checks for nonnegative/monotone states at requested outputs. Records per-subgroup flags without modifying states; internal substeps and stages are not checked. |
replay_loop |
Literal['auto', 'scan', 'unroll']
|
Iteration strategy for frozen adaptive replay. |
replay_checkpoint |
bool
|
Rematerialize the scan body during reverse mode. Used only when replay selects an adapter. |
replay_model_id |
str | None
|
Optional static structural model label, checked during replay. Keep fitted parameter values out of this identity. |
replay_reference_regime |
str | None
|
Optional descriptive label for the nominal parameter/initial-state regime used to discover a mesh. |
forcing_breakpoints |
tuple[float, ...]
|
Finite, strictly increasing known jumps in a right-continuous RHS. Explicit methods split internal steps here and evaluate incoming endpoint stages from the left. Other deterministic methods reject nonempty declarations. |
replay_require_provenance |
bool
|
Reject manually constructed/legacy meshes without provenance when True. False preserves compatibility. |
__post_init__()
¶
Normalize the method and validate context-free configuration.
Raises:
| Type | Description |
|---|---|
TypeError
|
If a nested configuration has the wrong type. |
ValueError
|
If the method or TR-BDF2 gamma is invalid. |
Source code in src/op_engine/core_solver.py
830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 | |
RunPlan(method, gamma, op_default, op_tr, op_bdf2, jacobian, nonlinear=None)
dataclass
¶
Resolved execution plan derived from RunConfig.
This is the internal, validated form used by the stepping loops.
Attributes:
| Name | Type | Description |
|---|---|---|
method |
MethodName
|
Final method after any strict=False downshifts. |
gamma |
float | None
|
TR-BDF2 gamma, or None for non-TR-BDF2 methods. |
op_default |
CoreOperators | StageOperatorFactory | None
|
Operator spec for IMEX Euler/Heun-TR. |
op_tr |
CoreOperators | StageOperatorFactory | None
|
TR-stage operator spec for TR-BDF2. |
op_bdf2 |
CoreOperators | StageOperatorFactory | None
|
BDF2-stage operator spec for TR-BDF2. |
jacobian |
JacobianFunction | None
|
Optional Jacobian function for linearly implicit methods. |
nonlinear |
NonlinearMethodConfig | None
|
Configuration for fully nonlinear methods. |
StepIO(t, dt, y, out, err_out=None, history=())
dataclass
¶
Bundle of per-step state for stepping kernels.
Attributes:
| Name | Type | Description |
|---|---|---|
t |
float
|
Current time. |
dt |
float
|
Step size. |
y |
NDArray[floating]
|
Current state array (input). |
out |
NDArray[floating]
|
Output state array (written in-place). |
err_out |
NDArray[floating] | None
|
Error estimate array (written in-place) for adaptive methods. |
history |
tuple[NDArray[floating], ...]
|
Older accepted states for multistep methods, newest first. |
Trbdf2OnceParams(t, y, dt, operators_tr, operators_bdf2, gamma, out)
dataclass
¶
Bundle of parameters for one TR-BDF2 step (non-doubling).
Attributes:
| Name | Type | Description |
|---|---|---|
t |
float
|
Current time. |
y |
NDArray[floating]
|
Current state. |
dt |
float
|
Step size. |
operators_tr |
CoreOperators | StageOperatorFactory | None
|
TR stage operator spec. |
operators_bdf2 |
CoreOperators | StageOperatorFactory | None
|
BDF2 stage operator spec. |
gamma |
float
|
TR-BDF2 gamma. |
out |
NDArray[floating]
|
Output state array (written in-place). |
fixed_step_sizes(t0, t1, max_step, *, forcing_breakpoints=())
¶
Partition one output interval into deterministic fixed steps.
The first steps use max_step and the final step absorbs the remainder,
so the partition lands on t1 without changing the stored output grid.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
t0
|
float
|
Output interval start. |
required |
t1
|
float
|
Output interval end. |
required |
max_step
|
float | None
|
Maximum internal step, or |
required |
forcing_breakpoints
|
tuple[float, ...]
|
Additional mandatory internal boundaries. |
()
|
Returns:
| Type | Description |
|---|---|
tuple[float, ...]
|
Positive internal step sizes that sum to |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the interval or maximum step is invalid, or if the partition would be unreasonably large. |
Source code in src/op_engine/core_solver.py
482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 | |
propose_step_size(step_size, error_norm, order, *, config)
¶
Return the next adaptive step size without host scalar extraction.
Returns:
| Type | Description |
|---|---|
Array
|
Scalar array in |
Array
|
controller bounds. |
Source code in src/op_engine/core_solver.py
1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 | |
scaled_error_norm(error, reference, previous, *, rtol, atol, reduction='rms')
¶
Return a backend-native scaled local-error norm.
Unlike the host controller wrapper used by :class:CoreSolver, this
function never extracts a Python scalar. Provider integrations can
therefore compose it with backend loop primitives such as
jax.lax.while_loop while retaining the core solver's error semantics.
Returns:
| Type | Description |
|---|---|
Array
|
Scalar array in |
Array
|
positive infinity so compiled controllers reject the attempted step. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Source code in src/op_engine/core_solver.py
1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 | |