Dynamic analysis II¶
In this example we simulate different SOC breakpoints for the baseline and virtual cell with 5% less NPratio, and compare the capacity and DCIR.
from breathe_simulate import api_interface as api
from breathe_simulate import Cycler
from breathe_simulate import enable_notebook_plotly
import plotly.express as px
enable_notebook_plotly()
As before, we first import the necessary modules and define the base battery, cycler, and designs.
base_params = api.get_design_parameters("Molicel P45B")
eqm_results = api.get_eqm_kpis("Molicel P45B")
designs = [{"designName": "Lower NP", "NPratio": base_params["NPratio"] * 0.95}]
baseline_capacity = eqm_results.capacity
cycler = Cycler(selected_unit="C", cell_capacity=baseline_capacity)
We can pass a list of SOC breakpoints to the initialSoC parameter of the run_sim function to simulate different SOCs.
# define some SOC breakpoints we want to simulate
soc_bps = [0.25, 0.5, 0.75]
# run a batch of simulations for different SOC breakpoints
output = api.run_sim(
base_battery="Molicel P45B",
cycler=cycler.cc_chg(1.0, 4.2),
designs=designs,
initialSoC=soc_bps,
initialTemperature_degC=21.0,
)
Running...: 0%| | 0/1 [00:00<?, ? designs/s] Running...: 100%|██████████| 1/1 [00:06<00:00, 6.67s/ designs] Running...: 100%|██████████| 1/1 [00:17<00:00, 17.84s/ designs] Running...: 100%|██████████| 1/1 [00:18<00:00, 18.11s/ designs]
The dynamic output data is now returned as a list of dictionaries, where each dictionary contains the simulation results for a given SOC breakpoint.
output.plot_voltage_response()
Let's also take this a step further and run a DCIR test. Here we can define different arguments that can be tailored to your specific requirements.
cycler_dict = cycler.dcir(
I_app=-1.0, t_dur=60.0, t_rest_before=3.0, t_rest_after=200.0, V_min=2.5, V_max=4.2
)
We will also define the initial voltage instead of the inital SoC.
The simulation is run by finding the starging SoC that corresponds to the requested initialVoltage. We can choose to use either the charge, discharge, or mean (of charge and discharge) OCV curves for this. Here we choose the mean.
output = api.run_sim(
base_battery="Molicel P45B",
cycler=cycler_dict,
designs=designs,
initialVoltage=3.5,
initialVoltageOcvType="mean",
initialTemperature_degC=25.0,
)
Running...: 100%|██████████| 1/1 [00:06<00:00, 6.79s/ designs]
Lets take a look at the current profile, the discharge current for the baseline cell is lower since it has a lower nominal capacity compared to the virtual cell we have decided to call "Lower NP".
output.plot_dynamic_response("Charge current [A]")
output.plot_voltage_response()
output.dynamic_kpis("DCIR")
| Design | Resistance (Ω) | |
|---|---|---|
| 0 | Baseline | -0.025112 |
| 1 | Lower NP | -0.024430 |
Now lets look at the rate capacity for different discharging rates down to 2.6 V, stoarting from 100% SOC.
rate_capacity_results = []
for rate in [1.0, 2.0, 3.0]:
cycler_input = cycler.cc_dch(-1 * rate, 2.6)
output = api.run_sim(
base_battery="Molicel P45B",
cycler=cycler_input,
designs=designs,
initialSoC=1.0,
initialTemperature_degC=50.0,
)
dynamic_kpis = output.dynamic_kpis("RateCap")
rate_capacity_results.append(
{
"Rate": rate,
"Baseline": dynamic_kpis.query("Design == 'Baseline'")[
"Capacity (Ah)"
].values[0],
"Lower NP": dynamic_kpis.query("Design == 'Lower NP'")[
"Capacity (Ah)"
].values[0],
}
)
print(rate_capacity_results)
Running...: 0%| | 0/1 [00:00<?, ? designs/s]
Running...: 100%|██████████| 1/1 [00:06<00:00, 6.71s/ designs] Running...: 100%|██████████| 1/1 [00:06<00:00, 6.63s/ designs] Running...: 100%|██████████| 1/1 [00:06<00:00, 6.36s/ designs]
[{'Rate': 1.0, 'Baseline': np.float64(4.437207460417406), 'Lower NP': np.float64(4.606167420206067)}, {'Rate': 2.0, 'Baseline': np.float64(4.430937494478882), 'Lower NP': np.float64(4.600110445356491)}, {'Rate': 3.0, 'Baseline': np.float64(4.418827133956763), 'Lower NP': np.float64(4.587609971434871)}]
Lets compare the rated capacity over C-Rate
# Create a line plot using Plotly Express
fig = px.line(
rate_capacity_results, x="Rate", y=["Baseline", "Lower NP"], title="Rate Capacity"
)
# Show the plot
fig.show()