Tutorial 3 - Modify Structural Parameters

Introduction

In this tutorial, we will use a P2D model to simulate the effects of changing structural parameters (like electrode thickness or porosity) on cell discharge. After completing this tutorial, you should have a working knowledge of:
We'll use the same input parameters set from Tutorial 1.
jsonstruct = parseBattmoJson('Examples/jsondatafiles/sample_input.json');

Explore the Structural Parameters

Structural parameters are defined in the JSON parameter file and parsed into the MATLAB structure. Once the JSON parameter file has been read into MATLAB as a jsonstruct, its properties can be modified programmatically.
Let's begin by exploring the parameters of the negative electrode (Graphite) coating with the following command:
disp(jsonstruct.NegativeElectrode.Coating)
thickness: 6.4000e-05 N: 10 effectiveDensity: 1900 bruggemanCoefficient: 1.5000 ActiveMaterial: [1×1 struct] Binder: [1×1 struct] ConductingAdditive: [1×1 struct]
Here, we can see that the structural and material properties of the coating are defined. Let's try increasing the thickness of the negative electrode from 64 µm to 72 µm.
jsonstruct.NegativeElectrode.Coating.thickness = 72*micro;
Now we can run the simulation and plot the discharge curve against the discharged capacity of the cell.
% instantiate an empty figure
figure()
output = runBatteryJson(jsonstruct);
Solving timestep 01/45: -> 3 Seconds, 937 Milliseconds Solving timestep 02/45: 3 Seconds, 937 Milliseconds -> 7 Seconds, 875 Milliseconds Solving timestep 03/45: 7 Seconds, 875 Milliseconds -> 15 Seconds, 750 Milliseconds Solving timestep 04/45: 15 Seconds, 750 Milliseconds -> 31 Seconds, 500 Milliseconds Solving timestep 05/45: 31 Seconds, 500 Milliseconds -> 63 Seconds Solving timestep 06/45: 63 Seconds -> 126 Seconds Solving timestep 07/45: 126 Seconds -> 252 Seconds Solving timestep 08/45: 252 Seconds -> 378 Seconds Solving timestep 09/45: 378 Seconds -> 504 Seconds Solving timestep 10/45: 504 Seconds -> 630 Seconds Solving timestep 11/45: 630 Seconds -> 756 Seconds Solving timestep 12/45: 756 Seconds -> 882 Seconds Solving timestep 13/45: 882 Seconds -> 1008 Seconds Solving timestep 14/45: 1008 Seconds -> 1134 Seconds Solving timestep 15/45: 1134 Seconds -> 1260 Seconds Solving timestep 16/45: 1260 Seconds -> 1386 Seconds Solving timestep 17/45: 1386 Seconds -> 1512 Seconds Solving timestep 18/45: 1512 Seconds -> 1638 Seconds Solving timestep 19/45: 1638 Seconds -> 1764 Seconds Solving timestep 20/45: 1764 Seconds -> 1890 Seconds Solving timestep 21/45: 1890 Seconds -> 2016 Seconds Solving timestep 22/45: 2016 Seconds -> 2142 Seconds Solving timestep 23/45: 2142 Seconds -> 2268 Seconds Solving timestep 24/45: 2268 Seconds -> 2394 Seconds Solving timestep 25/45: 2394 Seconds -> 2520 Seconds Solving timestep 26/45: 2520 Seconds -> 2646 Seconds Solving timestep 27/45: 2646 Seconds -> 2772 Seconds Solving timestep 28/45: 2772 Seconds -> 2898 Seconds Solving timestep 29/45: 2898 Seconds -> 3024 Seconds Solving timestep 30/45: 3024 Seconds -> 3150 Seconds Solving timestep 31/45: 3150 Seconds -> 3276 Seconds Solving timestep 32/45: 3276 Seconds -> 3402 Seconds Solving timestep 33/45: 3402 Seconds -> 3528 Seconds Solving timestep 34/45: 3528 Seconds -> 1 Hour, 54 Seconds *** Simulation complete. Solved 34 control steps in 2 Seconds, 408 Milliseconds (termination triggered by stopFunction) ***
Retrieve the states from the simulation result
states = output.states;
 
% extract the time, voltage, and current quantities
time = cellfun(@(state) state.time, states);
voltage = cellfun(@(state) state.('Control').E, states);
current = cellfun(@(state) state.('Control').I, states);
 
% calculate the capacity
capacity = time .* current;
 
% plot the discharge curve in the figure
plot((capacity/(hour*milli)), voltage, '-', 'linewidth', 3)
xlabel('Capacity / mA \cdot h')
ylabel('Voltage / V')
legend('t_{NE} = 72 µm')

Setup and Run a Parameter Sweep

Now we can setup another parameter sweep to explore the effects of reducing the thickness of the negative electrode coating. Let's try simuating the cell performance with coating thickness values of 16 µm, 32 µm, and 64 µm. As in the previous tutorial, we will first create a vector contianing the desired thickness values. Then we will use a for-loop to iterate through the thickness values, modify the value in the jsonstruct, and run the simulation. We will then plot the results together for comparison.
% create a vector of diffent thickness values
thickness = [16, 32, 64].*micro;
 
% instantiate and empty cell array to store the outputs of the simulations
output = cell(size(thickness));
 
% instantiate an empty figure
figure()
 
% use a for-loop to iterate through the vector of c-rates
for i = 1 : numel(thickness)
% modify the value for the coating thickness for the negative electrode
jsonstruct.NegativeElectrode.Coating.thickness = thickness(i);
% run the simulation and store the results in the output cell array
output{i} = runBatteryJson(jsonstruct);
% retrieve the states from the simulation result
states = output{i}.states;
% extract the time and voltage quantities
time = cellfun(@(state) state.time, states);
voltage = cellfun(@(state) state.('Control').E, states);
current = cellfun(@(state) state.('Control').I, states);
% calculate the capacity
capacity = time .* current;
% plot the discharge curve in the figure
plot((capacity/(hour*milli)), voltage, '-', 'linewidth', 3)
hold on
end
Solving timestep 01/45: -> 3 Seconds, 937 Milliseconds Solving timestep 02/45: 3 Seconds, 937 Milliseconds -> 7 Seconds, 875 Milliseconds Solving timestep 03/45: 7 Seconds, 875 Milliseconds -> 15 Seconds, 750 Milliseconds Solving timestep 04/45: 15 Seconds, 750 Milliseconds -> 31 Seconds, 500 Milliseconds Solving timestep 05/45: 31 Seconds, 500 Milliseconds -> 63 Seconds Solving timestep 06/45: 63 Seconds -> 126 Seconds Solving timestep 07/45: 126 Seconds -> 252 Seconds Solving timestep 08/45: 252 Seconds -> 378 Seconds Solving timestep 09/45: 378 Seconds -> 504 Seconds Solving timestep 10/45: 504 Seconds -> 630 Seconds Solving timestep 11/45: 630 Seconds -> 756 Seconds Solving timestep 12/45: 756 Seconds -> 882 Seconds Solving timestep 13/45: 882 Seconds -> 1008 Seconds Solving timestep 14/45: 1008 Seconds -> 1134 Seconds Solving timestep 15/45: 1134 Seconds -> 1260 Seconds Solving timestep 16/45: 1260 Seconds -> 1386 Seconds Solving timestep 17/45: 1386 Seconds -> 1512 Seconds Solving timestep 18/45: 1512 Seconds -> 1638 Seconds Solving timestep 19/45: 1638 Seconds -> 1764 Seconds Solving timestep 20/45: 1764 Seconds -> 1890 Seconds Solving timestep 21/45: 1890 Seconds -> 2016 Seconds Solving timestep 22/45: 2016 Seconds -> 2142 Seconds Solving timestep 23/45: 2142 Seconds -> 2268 Seconds Solving timestep 24/45: 2268 Seconds -> 2394 Seconds Solving timestep 25/45: 2394 Seconds -> 2520 Seconds Solving timestep 26/45: 2520 Seconds -> 2646 Seconds Solving timestep 27/45: 2646 Seconds -> 2772 Seconds Solving timestep 28/45: 2772 Seconds -> 2898 Seconds Solving timestep 29/45: 2898 Seconds -> 3024 Seconds Solving timestep 30/45: 3024 Seconds -> 3150 Seconds Solving timestep 31/45: 3150 Seconds -> 3276 Seconds Solving timestep 32/45: 3276 Seconds -> 3402 Seconds Solving timestep 33/45: 3402 Seconds -> 3528 Seconds Solving timestep 34/45: 3528 Seconds -> 1 Hour, 54 Seconds Solving timestep 35/45: 1 Hour, 54 Seconds -> 1 Hour, 180 Seconds Solving timestep 36/45: 1 Hour, 180 Seconds -> 1 Hour, 306 Seconds Solving timestep 37/45: 1 Hour, 306 Seconds -> 1 Hour, 432 Seconds Solving timestep 38/45: 1 Hour, 432 Seconds -> 1 Hour, 558 Seconds Solving timestep 39/45: 1 Hour, 558 Seconds -> 1 Hour, 684 Seconds *** Simulation complete. Solved 39 control steps in 2 Seconds, 224 Milliseconds (termination triggered by stopFunction) *** Solving timestep 01/45: -> 3 Seconds, 937 Milliseconds Solving timestep 02/45: 3 Seconds, 937 Milliseconds -> 7 Seconds, 875 Milliseconds Solving timestep 03/45: 7 Seconds, 875 Milliseconds -> 15 Seconds, 750 Milliseconds Solving timestep 04/45: 15 Seconds, 750 Milliseconds -> 31 Seconds, 500 Milliseconds Solving timestep 05/45: 31 Seconds, 500 Milliseconds -> 63 Seconds Solving timestep 06/45: 63 Seconds -> 126 Seconds Solving timestep 07/45: 126 Seconds -> 252 Seconds Solving timestep 08/45: 252 Seconds -> 378 Seconds Solving timestep 09/45: 378 Seconds -> 504 Seconds Solving timestep 10/45: 504 Seconds -> 630 Seconds Solving timestep 11/45: 630 Seconds -> 756 Seconds Solving timestep 12/45: 756 Seconds -> 882 Seconds Solving timestep 13/45: 882 Seconds -> 1008 Seconds Solving timestep 14/45: 1008 Seconds -> 1134 Seconds Solving timestep 15/45: 1134 Seconds -> 1260 Seconds Solving timestep 16/45: 1260 Seconds -> 1386 Seconds Solving timestep 17/45: 1386 Seconds -> 1512 Seconds Solving timestep 18/45: 1512 Seconds -> 1638 Seconds Solving timestep 19/45: 1638 Seconds -> 1764 Seconds Solving timestep 20/45: 1764 Seconds -> 1890 Seconds Solving timestep 21/45: 1890 Seconds -> 2016 Seconds Solving timestep 22/45: 2016 Seconds -> 2142 Seconds Solving timestep 23/45: 2142 Seconds -> 2268 Seconds Solving timestep 24/45: 2268 Seconds -> 2394 Seconds Solving timestep 25/45: 2394 Seconds -> 2520 Seconds Solving timestep 26/45: 2520 Seconds -> 2646 Seconds Solving timestep 27/45: 2646 Seconds -> 2772 Seconds Solving timestep 28/45: 2772 Seconds -> 2898 Seconds Solving timestep 29/45: 2898 Seconds -> 3024 Seconds Solving timestep 30/45: 3024 Seconds -> 3150 Seconds Solving timestep 31/45: 3150 Seconds -> 3276 Seconds Solving timestep 32/45: 3276 Seconds -> 3402 Seconds Solving timestep 33/45: 3402 Seconds -> 3528 Seconds Solving timestep 34/45: 3528 Seconds -> 1 Hour, 54 Seconds Solving timestep 35/45: 1 Hour, 54 Seconds -> 1 Hour, 180 Seconds Solving timestep 36/45: 1 Hour, 180 Seconds -> 1 Hour, 306 Seconds Solving timestep 37/45: 1 Hour, 306 Seconds -> 1 Hour, 432 Seconds Solving timestep 38/45: 1 Hour, 432 Seconds -> 1 Hour, 558 Seconds Solving timestep 39/45: 1 Hour, 558 Seconds -> 1 Hour, 684 Seconds *** Simulation complete. Solved 39 control steps in 2 Seconds, 114 Milliseconds (termination triggered by stopFunction) *** Solving timestep 01/45: -> 3 Seconds, 937 Milliseconds Solving timestep 02/45: 3 Seconds, 937 Milliseconds -> 7 Seconds, 875 Milliseconds Solving timestep 03/45: 7 Seconds, 875 Milliseconds -> 15 Seconds, 750 Milliseconds Solving timestep 04/45: 15 Seconds, 750 Milliseconds -> 31 Seconds, 500 Milliseconds Solving timestep 05/45: 31 Seconds, 500 Milliseconds -> 63 Seconds Solving timestep 06/45: 63 Seconds -> 126 Seconds Solving timestep 07/45: 126 Seconds -> 252 Seconds Solving timestep 08/45: 252 Seconds -> 378 Seconds Solving timestep 09/45: 378 Seconds -> 504 Seconds Solving timestep 10/45: 504 Seconds -> 630 Seconds Solving timestep 11/45: 630 Seconds -> 756 Seconds Solving timestep 12/45: 756 Seconds -> 882 Seconds Solving timestep 13/45: 882 Seconds -> 1008 Seconds Solving timestep 14/45: 1008 Seconds -> 1134 Seconds Solving timestep 15/45: 1134 Seconds -> 1260 Seconds Solving timestep 16/45: 1260 Seconds -> 1386 Seconds Solving timestep 17/45: 1386 Seconds -> 1512 Seconds Solving timestep 18/45: 1512 Seconds -> 1638 Seconds Solving timestep 19/45: 1638 Seconds -> 1764 Seconds Solving timestep 20/45: 1764 Seconds -> 1890 Seconds Solving timestep 21/45: 1890 Seconds -> 2016 Seconds Solving timestep 22/45: 2016 Seconds -> 2142 Seconds Solving timestep 23/45: 2142 Seconds -> 2268 Seconds Solving timestep 24/45: 2268 Seconds -> 2394 Seconds Solving timestep 25/45: 2394 Seconds -> 2520 Seconds Solving timestep 26/45: 2520 Seconds -> 2646 Seconds Solving timestep 27/45: 2646 Seconds -> 2772 Seconds Solving timestep 28/45: 2772 Seconds -> 2898 Seconds Solving timestep 29/45: 2898 Seconds -> 3024 Seconds Solving timestep 30/45: 3024 Seconds -> 3150 Seconds Solving timestep 31/45: 3150 Seconds -> 3276 Seconds Solving timestep 32/45: 3276 Seconds -> 3402 Seconds Solving timestep 33/45: 3402 Seconds -> 3528 Seconds Solving timestep 34/45: 3528 Seconds -> 1 Hour, 54 Seconds *** Simulation complete. Solved 34 control steps in 2 Seconds, 403 Milliseconds (termination triggered by stopFunction) ***
hold off
xlabel('Capacity / mA \cdot h')
ylabel('Voltage / V')
legend('t_{NE} = 16 µm', 't_{NE} = 32 µm', 't_{NE} = 64 µm')
The results of this parameter sweep show that reducing the thickness of the negative electrode to 32 µm and 16 µm reduces its capacity such that it becomes the limiting factor in the overall capacity of the cell. Note that in real Li-ion batteries, the capacity of the negative electrode is usually oversized with respect to the capacity of the positive electrode to avoid dangerous lithium plating [1].

Summary

In this tutorial, we explored how to modify structural parameters in BattMo. We first learned that structural properties of the electrodes are defined in the structure (e.g. NegativeElectrode.Coating). From there, it is possible to change individual parameter values and simulate the effects on the cell discharge. We then reviewed how to setup a parameter sweep and explored how changing the thickness of the negative electrode coating affects the overall capacity of the cell.

References

[1] Karin Kleiner, Peter Jakes, Sebastian Scharner, Verena Liebau, Helmut Ehrenberg, "Changes of the balancing between anode and cathode due to fatigue in commercial lithium-ion cells," Journal of Power Sources, Volume 317, 2016, Pages 25-34, ISSN 0378-7753, https://doi.org/10.1016/j.jpowsour.2016.03.049. (https://www.sciencedirect.com/science/article/pii/S0378775316302506)