Manufacturing variability¶
In this example we will use breathe design to see how variations in cell parameters due the manufacturing process, effect the KPIs of the cells.
We start by import breathe design api, as well as the montecarlo utils
import breathe_design as bd
from breathe_design import api_interface as api
import breathe_design.montecarlo_utils as mc
We'll use the Molicel P45B cell as an example, so lets load up the base design for that cell
base_battery = "Molicel P45B"
base_design = api.get_design_parameters(base_battery)
Lets look in the base dsign to see what parameters we could vary
base_design
{'NPratio': 1.039106051327928,
'Vmax_V': 4.2,
'Vmin_V': 2.5,
'aluminiumThickness_um': 22.2,
'anode': 'molicel_p45b_anode',
'anodeArealLoading_mAhcm2': 3.8996207810294305,
'anodeMassLoading_mgcm2': 8.44896611475494,
'anodePorosity': 0.16663641853607114,
'anodeThickness_um': 48.90000000000002,
'cathode': 'molicel_p45b_cathode',
'cathodeArealLoading_mAhcm2': 3.7528611983790308,
'cathodeMassLoading_mgcm2': 14.188761420434503,
'cathodePorosity': 0.14216134985845785,
'cathodeThickness_um': 37.48333333333334,
'copperThickness_um': 11.2,
'electrolyte': 'lp30',
'electrolyteBuffer_rel': 0.2,
'format': 'molicel_p45b',
'lamne': 0.0,
'lampe': 0.0,
'lli': 0.0,
'separatorThickness_um': 16.8}
We'll use the Montecarlo tools to generate samples where we vary some design parameters.
Essentially, we generate a number of different cell designs, where each design is a slight variation on the base design, to represent a possible deviation from the nominal design, due to variations in the manufacturing process.
We'll choose to vary the porosity and thickness of both electrodes as pairs.
param_pairs = [
("anodePorosity", "cathodePorosity"),
("anodeThickness_um", "cathodeThickness_um"),
]
sigma_fraction = [
0.035, # vary the porosity by 3.5%
0.05, # vary the thickness by 5%
]
bound_range = 0.2 # bound all parameters to within 20% of the base value
changes = mc.make_manufacturing_variations(
base_design=base_design,
n_samples=200,
bound_range=bound_range,
sigma_fraction=sigma_fraction,
seed=42,
param_pairs=param_pairs,
preserve_np_ratio=False,
)
We can visualise the distribution of the samples from design parameter tolernace. This will help us understand the range of possible outcomes from the manufacturing process.
param_keys = [
"anodePorosity",
"cathodePorosity",
"anodeThickness_um",
"cathodeThickness_um",
]
fig_hist = mc.plot_variation_histograms(
base_design, changes, param_keys, title="Parameter distributions"
)
Now, we start to investigate what effect those variations will have on the cell KPIs.
results = api.get_eqm_kpis(base_battery, changes)
var_kpis = results.get_kpis()
Running...: 100%|██████████| 200/200 [02:20<00:00, 1.42 designs/s]
Lets see how the variations have effected the cell capacity.
This could be rather important if you have an absolute minimum capacity required for your system. We might find, using this analysis, that some expected manufacturing variations will result in cell capacities that are below our minimum, which would cause a problem at the system level.
fig = mc.plot_capacity_histogram(var_kpis, bins=15)
We'll now run a DCIR schedule on all of the cell samples. We will run a DCIR schedule with a C rate of 4.5 at 70% SoC
# define the cycler schedule
cycler = bd.Cycler("C", 4.5)
# and submit the simulations
results = api.run_sim(
base_battery=base_battery,
cycler=cycler.dcir(-1, 30, 5, 5, 2.5, 4.2),
designs=changes,
initialSoC=0.7,
initialTemperature_degC=25,
ambientTemperature_degC=25,
)
Running...: 0%| | 0/200 [00:00<?, ? designs/s]
Running...: 100%|██████████| 200/200 [04:52<00:00, 1.46s/ designs]
We now extract the DCIR results from the dynamic simulations.
dcir = bd.extract_dynamic_kpis("DCIR", results.get_dynamic_data())
...and plot them
fig_dcir = mc.plot_dcir_histogram(dcir, bins=15, include_baseline=False)
We can also plot both the capacity and resistance on a heatmap
fig_heat = mc.plot_capacity_resistance_heatmap(
var_kpis,
dcir,
changes=changes,
base_design=base_design,
include_baseline=False,
bins=(30, 30),
title="Capacity vs DCIR",
marker_size=8,
)