Simulations#
The simulation API runs forward battery simulations on the Ionworks cloud. You define a parameterized model and a cycling protocol in Universal Cycler Protocol (UCP) YAML format, and the server returns time-series results.
Running a simulation#
Define a protocol#
Protocols are written in YAML. Each protocol has a global section for initial
conditions and a steps list describing the cycling sequence:
protocol_yaml = """global:
initial_state_type: soc_percentage
initial_state_value: 50
initial_temperature: 25.0
steps:
- Charge:
mode: C-rate
value: "0.6"
ends:
- Voltage > 4.2
- Rest:
duration: 3600
- Discharge:
mode: C-rate
value: "0.5"
ends:
- Voltage < 2.5
"""
Submit the simulation#
Use client.simulation.protocol() with a quick model or a full parameterized
model:
result = client.simulation.protocol({
"parameterized_model": {
"quick_model": {"capacity": 1.0, "chemistry": "NMC/Graphite"},
},
"protocol_experiment": {
"protocol": protocol_yaml,
"name": "NMC Charge Discharge Protocol",
},
})
print(f"Simulation ID: {result.simulation_id}")
print(f"Job ID: {result.job_id}")
Wait for completion#
wait_for_completion() polls the server and returns the finished simulation
object:
simulation = client.simulation.wait_for_completion(
result.simulation_id,
timeout=60,
poll_interval=2,
verbose=True,
)
Retrieve results#
data = client.simulation.get_result(result.simulation_id)
time_series = data.get("time_series", {})
Batch simulations#
Run a design-of-experiments (DOE) sweep by replacing design_parameters with
design_parameters_doe. Each combination of parameter values produces a
separate simulation:
batch_config = {
"parameterized_model": {
"quick_model": {"capacity": 1.0, "chemistry": "NMC/Graphite"},
},
"protocol_experiment": {
"protocol": protocol_yaml,
"name": "DOE Simulation",
},
"design_parameters_doe": {
"sampling": "grid", # or "random", "latin_hypercube"
"rows": [
{"type": "range", "name": "capacity", "min": 0.8, "max": 1.2, "count": 3},
],
},
}
results = client.simulation.protocol_batch(batch_config)
for r in results:
print(f"Simulation: {r.simulation_id}, Job: {r.job_id}")
Wait for the entire batch:
simulation_ids = [r.simulation_id for r in results]
completed = client.simulation.wait_for_completion(simulation_ids, timeout=120)
Extra variables#
By default simulations return voltage and current. To request additional output
variables, add extra_variables to the config:
config = {
"parameterized_model": {
"quick_model": {"capacity": 1.0, "chemistry": "NMC/Graphite"},
},
"protocol_experiment": {
"protocol": protocol_yaml,
"name": "Electrode Potentials",
},
"extra_variables": [
"Negative electrode potential [V]",
"Positive electrode potential [V]",
],
}
result = client.simulation.protocol(config)
Listing simulations#
simulations = client.simulation.list()
Next steps#
See Error Handling for how the client reports problems.