# 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: ```python 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: ```python 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: ```python simulation = client.simulation.wait_for_completion( result.simulation_id, timeout=60, poll_interval=2, verbose=True, ) ``` ### Retrieve results ```python 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: ```python 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: ```python 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: ```python config = { "parameterized_model": { "quick_model": {"capacity": 1.0, "chemistry": "NMC/Graphite"}, }, "protocol_experiment": { "protocol": protocol_yaml, "name": "Electrode Potentials", }, "extra_variables": [ "Anode potential [V]", "Cathode potential [V]", ], } result = client.simulation.protocol(config) ``` ## Listing simulations ```python simulations = client.simulation.list() ``` ## Next steps See {doc}`error_handling` for how the client reports problems.