June 1, 2026
Ionworks solver replaces IDAKLU as the default, structured error details on failed pipelines and optimizations, Wasserstein weighted mode and MSMRFullCell dQ/dU output
Ionworks solver
A newIonworksSolver is now the default solver inside
ionworkspipeline.Simulation. It is a drop-in replacement for
pybamm.IDAKLUSolver that detects DAE structural properties
(quadrature, linear-constant / linear-varying, block-constant /
block-varying) and substitutes exact analytical solutions where the
structure allows, falling back to IDAKLU for non-analytical models.
Runtime C codegen via CasADi’s CodeGenerator plus Numba-JIT
integration kernels reduce per-step cost on the analytical paths.
Piecewise interpolation now also accepts smoothing=0 so a hard step
function can be modelled directly.Structured error details on failed pipelines and optimizations
Pipeline element and optimization failures now carry a structurederror_detail with the exception type and a Sentry deep-link. Two new
job error codes — CONFIGURATION_ERROR and SOLVER_ERROR — separate
user-fixable config mistakes from solver-side failures. Inside the
pipeline package, FuzzyDict / ParameterStore raise the new
ParameterNotFoundError (instead of bare KeyError) and
ConfigurationError distinguishes invalid configs from runtime
errors, so the classifier attaches the right code. In Studio, failed
optimizations now show a View in Sentry button (superadmin only)
that opens the captured event directly; the exception message itself
is stripped before serialization so user-visible diagnostics stay safe
to share.Wasserstein weighted-point-cloud mode and MSMRFullCell dQ/dU output
iws.costs.Wasserstein / iwp.costs.Wasserstein gain optional
position_variable and weight_variable fields. When both are set,
the cost computes one Wasserstein-1 distance per objective comparing
two weighted point clouds — useful for full-cell MSMR fits where
peak-location error in Voltage [V] should be measured by the
|dQ/dV| weights instead of sample-by-sample. MSMRFullCell also
now emits Differential capacity [Ah/V] when listed in
objective variables, derived from Full voltage [V] /
Full capacity [A.h] and interpolated to the data voltage grid.Pipelines documentation moved to schema-first Docs section
The runnable “how do I actually run this” pipelines content has moved out of the Guide into a new schema-first Pipelines section under the Documentation tab, with every code sample rewritten to useionworks-schema + ionworks-api. The Guide retains the theory —
equations, parameter tables, intuition — and its existing “Pipelines”
group is renamed to Parameterization. The Japanese tab mirrors
the new section.Studio
Studio
Fixes
- Project-scoped ECM fitting from existing measurements no longer
returns 422: the frontend now sends the nested
{measurements: [{id, initial_soc?}], ecm_options: {...}}payload the backend has expected since the per-measurement SOC change, and shows a per-measurement initial-SOC input next to each selected measurement.
Pipeline
Pipeline
Improvements
client.simulation.protocol(...)acceptsdesign_parametersagain as a flat dict — the single-simulation convenience that was accidentally removed when the protocol-template flow landed. Supplying bothdesign_parametersanddesign_parameters_doe, or a DOE that expands to more than one simulation, now raises explicitly instead of silently billing for the extra runs.- BioLogic
.mpsprotocols with large embedded drive-cycle tables (e.g. ~96k-row Urban Profile traces inlined as YAML block scalars) no longer time out at the edge proxy on/protocols/parse-to-template— the modified YAML is no longer re-parsed with the slow PyYAML path. iws.direct_entries.DirectEntryaccepts apybamm.ParameterValuesdirectly. Callable values (concentration- / temperature-dependent interpolants) are serialized to symbol-JSON viaParameterValues.to_json()automatically, and the in-pipelineDirectEntry.from_schemapath deserializes them back into pybamm symbols so local and API consumption paths behave the same.
- Child-module loggers under
ionworkspipeline.*(e.g.ionworkspipeline.data_fits.*) are now governed byset_logging_level— the package logger was previously a sibling rather than the parent, so submodule records propagated past it.
Python API
Python API
Improvements
client.simple_pipeline.create(...)accepts aPipelineOptions(e.g.live_progress_updates=False) — the worker already honouredpipeline_optionsin job params, this wires the request model, service layer, and SDK client through.
- Outbound JSON payloads no longer raise
TypeErrorwhen a request body contains a pandas DataFrame with datetime columns.pd.Timestampis serialized viaisoformat()andpd.NaTbecomesnull.
Protocol Simulator
Protocol Simulator
Fixes
- BioLogic
.mpsparser no longer hangs on protocols likelfp_gr_cccv.mpswherelim*_seqstores an internal sub-cycle pointer ≤Ns+1. Only forward jumps (seq > Ns+1) emit gotos; backward or equal values are treated as plain step-ends.
Skills
Skills
Improvements
- Ionworks skills can now be installed as a Gemini CLI extension via
gemini extensions install ~/ionworks-skills; aGEMINI.mdcontext file loads all eight skills as passive context on every session. The Coding agents docs page is updated to cover Gemini CLI, Cursor, and GitHub Copilot install paths alongside Codex and Claude Code. - New half-cell MSMR template (
assets/half_cell_msmr_template.py) plusdiscover_half_cell.py,inspect_half_cell_data.py, andvalidate_half_cell_fit.pyhelpers in the parameterize skill. The reference page mandates the template and lays out a discover → inspect → scaffold → dry-run → submit → validate workflow so every half-cell OCP fit uses the same canonical priors, multistarts, and Xj method.
- The process-data skill now documents the platform’s actual current
sign convention (
positive = discharge), matches the validator andset_positive_current_for_dischargetransform, and calls out the double-flip trap.