Use cases

In the repository or docker image, several use cases are included together with corresponding literature datasets used in the examples. It is recommended to go through the jupyter notebooks that can be found within the examples/notebooks folder.

Datasets

  • Chen_2020: Graphite-SiliconOxide vs NMC811 cell based on [10]

    Electrochemical parameters

  • Ai_2020: Graphite vs LCO cell based on [11]

    Electrochemical and thermal parameters

  • Safari_2009: Graphite vs LCO cell based on [5]

    Electrochemical and SEI parameters

Examples

Single discharge

This is one of the most basic use cases of cideMOD, to simulate a single discharge using the low-level Problem interface.

from cideMOD import (
    CellParser,
    ErrorCheck,
    Problem,
    SolverCrashed,
    Trigger,
    get_model_options,
)

case = "Ai_2020"
data_path = f"data/data_{case}"
params = "params.json"

model_options = get_model_options(model='P2D', save_path=f"{case}_discharge", overwrite=False)
cell = CellParser(params, data_path, model_options)
problem = Problem(cell, model_options)
problem.set_cell_state(SoC=1, T_ini=273 + 25, T_ext=273 + 25)
problem.setup()
C_rate = -1
I_app = C_rate * cell.ref_capacity
t_f = 3600 / abs(C_rate) * 1.25

v_min = Trigger(3, "v")
status = problem.solve(
    min_step=10, i_app=I_app, t_f=t_f, store_delay=10, adaptive=False, triggers=[v_min]
)
err = ErrorCheck(problem, status)

if isinstance(status, SolverCrashed):
    raise status.args[0]

Storage

In this case, using the CSI interface, we can simulate the degradation under rest conditions.

import os

from cideMOD import CSI, ErrorCheck, get_model_options

EVENT1 = {
    "type": "Voltage",  # Voltage, Current, Ah, Wh
    "value": 2,  # Number
    "unit": "V",  #
    "atol": 1e-2,  # Absolute tolerance
    "rtol": 1e-2,  # Relative tolerance
    "goto": "Next",  # Next, End or CV
}

REST = {
    "name": "Storage",
    "type": "Rest",  # 'Current' or 'Voltage' or 'CC' or 'CV' or Rest
    "t_max": {"value": 31, "unit": "day"},  # Maximum duration of step
    "store_delay": -1,  # Store frequency (in timesteps) of internal variables, -1 to deactivate
    "min_step": 10,  # Minimum time step
    "max_step": 3600,  # Maximum time step
    "events": [EVENT1],
}

REST_TEST_PLAN = {
    "initial_state": {
        "SOC": 1,   # State Of Charge (from 0 to 1)
        "exterior_temperature": 298.15  # in K
    },
    "steps": [REST] * 1,
}

case = "Safari_2009"
data_path = f"../data/data_{case}"

SIMULATION_OPTIONS = get_model_options(model='P4D', SEI_model='solvent_diffusion',
                                       save_path=f"{case}_storage")
cell_data = os.path.join(data_path, "params_cycling.json")

csi = CSI(cell_data, SIMULATION_OPTIONS, REST_TEST_PLAN)
status = csi.run_test_plan()

err = ErrorCheck(csi.problem, status)

Cycling

Using a different test plan, we can simulate a cycling protocol:

import os

from cideMOD import CSI, ErrorCheck, get_model_options

EVENT1 = {
    "type": "Voltage",  # Voltage, Current, Ah, Wh
    "value": 2.8,  # Number
    "unit": "V",  #
    "atol": 1e-2,  # Absolute tolerance
    "rtol": 1e-2,  # Relative tolerance
    "goto": "Next",  # Next, End or CV
}
EVENT2 = {
    "type": "Voltage",  # Voltage, Current, Ah, Wh
    "value": 4.1,  # Number
    "unit": "V",  #
    "atol": 1e-2,  # Absolute tolerance
    "rtol": 1e-2,  # Relative tolerance
    "goto": "CV",  # Next, End or CV
}

INPUT1 = {
    "name": "Discharge",
    "type": "Current",  # 'Current' or 'Voltage' or 'CC' or 'CV' or Rest or Cycle
    "value": -1,  # Must be float, int or string
    "unit": "C",  # One of 'A', 'V', 'mA', 'mV', C
    "t_max": {"value": 60, "unit": "min"},  # Maximum duration of step
    "store_delay": 10,  # Store frequency (in timesteps) of internal variables, -1 to deactivate
    "min_step": 10,  # Minimum time step
    # 'adaptive': False, # Wether to adapt timestep or not
    "events": [EVENT1],
}
INPUT2 = {
    "name": "Charge",
    "type": "Current",  # 'Current' or 'Voltage' or 'CC' or 'CV' or Rest or Cycle
    "value": 0.5,  # Must be float, int or string
    "unit": "C",  # One of 'A', 'V', 'mA', 'mV', C
    "t_max": {"value": 120, "unit": "min"},  # Maximum duration of step
    "store_delay": 10,  # Store frequency (in timesteps) of internal variables, -1 to deactivate
    "min_step": 10,  # Minimum time step
    # 'adaptive': False, # Wether to adapt timestep or not
    "events": [EVENT2],
}

CYCLE_INPUT = {
    "name": "Cycling",
    "type": "Cycle",
    "count": 10,  # Number of cycles
    "steps": [INPUT1, INPUT2]  # Steps to be repeated each cycle
}

TEST_PLAN = {
    "initial_state": {
        "SOC": 1,
        "exterior_temperature": 298.15
    },
    "steps": [CYCLE_INPUT],
}

case = "Safari_2009"
data_path = f"../data/data_{case}"

SIMULATION_OPTIONS = get_model_options(model='P2D', SEI_model='solvent_diffusion',
                                       save_path=f"{case}_cycling")

cell_data = os.path.join(data_path, "params_cycling.json")

csi = CSI(cell_data, SIMULATION_OPTIONS, TEST_PLAN)
status = csi.run_test_plan()

err = ErrorCheck(csi.problem, status)