Core Solver¶
core_solver
¶
Core semi-implicit solver for time-evolving models (ODE + IMEX multiphysics).
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: - exactly one step of size dt = t_{i+1} - t_i (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.
- "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 embedded low/high (Euler vs Heun) mapped by the
same implicit operator solve.
- "imex-trbdf2": IMEX TR-BDF2 (order 2), adaptive via step-doubling.
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 (ODE-only / explicit-only behavior), 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
- All major scratch arrays are preallocated.
- Inner loops use in-place NumPy ops and np.copyto.
- Implicit solves are delegated to matrix_ops.implicit_solve (cached factorization).
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 | NDArray[floating]
|
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. |
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
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 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 | |
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
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If invalid parameters are provided. |
Source code in src/op_engine/core_solver.py
1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 | |
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. |
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). |
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
¶
Return the 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
123 124 125 | |
RunConfig(method='heun', adaptive=False, strict=True, dt_controller=DtControllerConfig(), adaptive_cfg=AdaptiveConfig(), operators=OperatorSpecs(), gamma=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. |
gamma |
float | None
|
Optional TR-BDF2 gamma (if None, uses default). |
RunPlan(method, gamma, op_default, op_tr, op_bdf2)
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. |
StepIO(t, dt, y, out, err_out=None)
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. |
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). |