Model Battery Cycling Aging
This example shows how to simulate the capacity cycling aging of a battery. Battery aging is a critical factor that affects the performance and lifespan of energy storage systems. As batteries undergo charge and discharge cycles, their components degrade, which leads to a gradual decline in capacity and efficiency. Solid electrolyte interface (SEI), lithium plating, and other side reactions are the main cause of degradation in lithium-ion batteries.
The Battery Equivalent Circuit block enables empirical modeling of the cycling aging. This example highlights the different modeling options of the block for the capacity aging, how to parameterize the block, and how to evaluate the simulation results.
Simulate Capacity Aging with Constant Temperature
You can obtain the necessary data through cycle life tests. During these tests, you charge and discharge the battery according to a specific protocol at a controlled temperature. In this example, different sets of batteries are cycled at 15°C, 25°C, and 35°C and their capacity percentage change is measured every 100 discharge cycles.
% Breakpoints dischargeCycleBreakpoints = [0 100 200 300 400]; temperatureBreakpoints = [288.15,298.15,308.15]; % Measured Capacities percentChange15Deg = [0;-1;-3;-6;-9]; percentChange25Deg = [0;-3;-6;-11;-17]; percentChange35Deg = [0;-6;-13;-20;-28]; percentChange = [percentChange15Deg,percentChange25Deg,percentChange35Deg]; % Visualize capacity percent change surf(temperatureBreakpoints,dischargeCycleBreakpoints,percentChange); xlabel("Cycling Temperature [K]"); ylabel("Number of Discharge Cycles [1]"); zlabel("Change in Cell Capacity [%]"); view(124,16);
![Figure contains an axes object. The axes object with xlabel Cycling Temperature [K], ylabel Number of Discharge Cycles [1] contains an object of type surface.](../../examples/simscapebattery/win64/ModelingBatteryCyclingAgingExample_01.png)
The Battery Equivalent Circuit block supports aging modeling at a constant temperature. When you model aging at constant temperature, you can directly apply the measured data. This modeling option is more efficient than the options to model the aging at variable temperatures.
% Open model modelName = "batteryCyclingAging"; open_system(modelName); % Set aging modeling option and initial capacity blockPath = modelName.append("/Battery Equivalent Circuit"); set_param(blockPath,"CyclingAgingMethod","simscape.battery.enum.cells.CyclingAgingMethod.tableNandT"); % Set aging parameters set_param(blockPath,"CapacityChangeThermal","percentChange"); set_param(blockPath,"AgingTemperatureBreakpoints","temperatureBreakpoints"); set_param(blockPath,"NumDisCyclesBreakpoints","dischargeCycleBreakpoints");
Simulate the cycling behavior of the battery at a constant temperature.
simout = sim(modelName);
To analyze the results, compare the modeled cell capacity with the expected capacity. You calculate the expected capacity percentage change by interpolating data based on the number of discharge cycles at the battery constant temperature. Observe how the expected data aligns with the modeled aging.
% Get the expected capacity batteryLoggingNode = simout.simlog.Battery_Equivalent_Circuit; time = batteryLoggingNode.numCycles.series.time; numberOfDischargeCycles = batteryLoggingNode.numCycles.series.values; expectedCapacityPercentChange = interp1(dischargeCycleBreakpoints,percentChange(:,2),numberOfDischargeCycles); % Get the modeled capacity modeledCapacityPercentChange = batteryLoggingNode.capacityCyclingChange.series.values; % Plot the results plot(time,expectedCapacityPercentChange,time(1:1000:end),modeledCapacityPercentChange(1:1000:end),"*"); xlabel("Time [s]"); ylabel("Capacity Percent Change [%]"); legend(["Expected","Modeled"]);
![Figure contains an axes object. The axes object with xlabel Time [s], ylabel Capacity Percent Change [%] contains 2 objects of type line. One or more of the lines displays its values using only markers These objects represent Expected, Modeled.](../../examples/simscapebattery/win64/ModelingBatteryCyclingAgingExample_02.png)
Simulate Capacity Aging with Variable Temperature
Under normal operation, the battery temperature fluctuates due to external and internal influences. To model these variations in the Battery Equivalent Circuit block, set the Cycling Aging Model parameter to Lookup Tables (temperature-dependent).
set_param(blockPath,"CyclingAgingMethod","simscape.battery.enum.cells.CyclingAgingMethod.tableNandVariableT");
In this experiment, the ambient temperature varied throughout the day. You can approximate this variation as a sinusoidal pattern. To model this variation, set the temperatureVariation variable to true.
temperatureVariation = true;
Simulate the model and generate the plots for both battery temperature and capacity.
simout = sim(modelName,"StopTime","3e5"); batteryLoggingNode = simout.simlog.Battery_Equivalent_Circuit; % Get the modeled capacity percent change under variable temperatures capacityPercentChangeVariableTemperature = batteryLoggingNode.capacityCyclingChange.series.values; timeVariableTemperature = batteryLoggingNode.batteryTemperature.series.time; batteryTemperature = batteryLoggingNode.batteryTemperature.series.values("K"); % Visualize the results variableTemperatureFigure = figure; tiledlayout(variableTemperatureFigure,2,1); nexttile; plot(timeVariableTemperature,capacityPercentChangeVariableTemperature); xlabel("Time [s]"); ylabel("Capacity percent change [%]"); title("Capacity Percent Change"); nexttile; plot(timeVariableTemperature,batteryTemperature); xlabel("Time [s]"); ylabel("Temperature [K]"); title("Temperature");
![Figure contains 2 axes objects. Axes object 1 with title Capacity Percent Change, xlabel Time [s], ylabel Capacity percent change [%] contains an object of type line. Axes object 2 with title Temperature, xlabel Time [s], ylabel Temperature [K] contains an object of type line.](../../examples/simscapebattery/win64/ModelingBatteryCyclingAgingExample_03.png)
Regions with higher temperatures demonstrate accelerated capacity degradation compared to regions with lower temperatures.
Simulate Capacity Aging with Consideration of C-Rate Dependency
In addition to the temperature dependence, the C-rate applied to the battery during cycling also influences the rate of capacity aging. To model the C-rate dependency on the capacity aging, the capacity degradation was measured at 0.5 C-rate, in addition to the previously measured values at 1.5 C-rate. To use the data in the Battery Equivalent Circuit block, you must organize it into a 3-D array. The first dimension must correspond to the number of discharge cycles, the second dimension must correspond to the temperature, and the third dimension must correspond to the discharge current.
capacity = 27;
currentBreakpoints = capacity * [-0.5,-1.5];
% Measured capacity percent change
percentChangeLowCurrent = [0 0 0;-0.5 -1.5 -3;-1.5 -3 -6.5;-3 -5.5 -10;-4.5 -8.5 -14];
percentChangeCurrent = cat(3,percentChangeLowCurrent,percentChange);To model the current dependent aging, set the Cycling Aging Model parameter to Lookup Tables (temperature and current dependent). Set the Current breakpoints for cycling aging data, I and the Percentage change in cell capacity, CapacityChange(N,T,I) parameters to the calculated values.
set_param(blockPath,"CyclingAgingMethod","simscape.battery.enum.cells.CyclingAgingMethod.tableNandVariableTandI"); set_param(blockPath,"CapacityChangeThermalI","percentChangeCurrent"); set_param(blockPath,"AgingCurrentBreakpoints","currentBreakpoints");
To enable the model scenario with a variable current during cycling, set the currentVariation variable to true. Then, simulate the model and visualize the changes in battery capacity percentage and current.
currentVariation = true; simout = sim(modelName,"StopTime","1e6"); % Get the modeled capacity percent change under variable current batteryLoggingNode = simout.simlog.Battery_Equivalent_Circuit; timeVariableCurrent = batteryLoggingNode.capacityCyclingChange.series.time; capacityPercentChangeVariableCurrent = batteryLoggingNode.capacityCyclingChange.series.values; batteryCurrent = batteryLoggingNode.batteryCurrent.series.values("A"); % Visualize the results variableCurrentFigure = figure; tiledlayout(variableCurrentFigure,2,1); nexttile; plot(timeVariableCurrent,capacityPercentChangeVariableCurrent); xlabel("Time [s]"); ylabel("Capacity Percent Change [%]"); title("Capacity Percent Change"); nexttile; plot(timeVariableCurrent,batteryCurrent); xlabel("Time [s]"); ylabel("Current [A]"); title("Current");
![Figure contains 2 axes objects. Axes object 1 with title Capacity Percent Change, xlabel Time [s], ylabel Capacity Percent Change [%] contains an object of type line. Axes object 2 with title Current, xlabel Time [s], ylabel Current [A] contains an object of type line.](../../examples/simscapebattery/win64/ModelingBatteryCyclingAgingExample_04.png)
Regions with higher cycling current demonstrate accelerated capacity degradation compared to regions with lower cycling current.