{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "# Tutorial 2 \\- Change the Control Protocol\n", "\n", "## Introduction\n", "\n", "In this tutorial, we will use a P2D model to simulate the discharge of an NMC\\-Graphite cell at different rates. After completing this tutorial, you should have a working knowledge of:\n", "\n", "- Basics of the control protocol definitions in BattMo\n", "- The link between battery discharge rate and simulation time\n", "- How to setup and execute a parameter sweep\n", "\n", "We'll use the same model from Tutorial 1.\n", "" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "source": [ "jsonstruct = parseBattmoJson('Examples/jsondatafiles/sample_input.json');" ], "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Explore the Control Protocol\n", "\n", "The control protocol is 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.\n", "\n", "\n", "Let's begin by exploring the control protocol definition with the following command:\n", "" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "source": [ "disp(jsonstruct.Control)" ], "outputs": [ { "data": { "text/plain": [ " controlPolicy: 'CCDischarge'\n", " DRate: 1\n", " lowerCutoffVoltage: 3\n", " upperCutoffVoltage: 4.1000\n", " dIdtLimit: 0.0100\n", " dEdtLimit: 0.0100\n", " rampupTime: 0.1000" ] }, "metadata": {}, "execution_count": 2, "output_type": "execute_result" } ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "Here, we can see that the control policy follows the schema for a constant current discharge (CCDischarge). The three main control parameters in this schema are the CRate, lowerCutoffVoltage, and upperCutoffVoltage. Let's first try changing the protocol to discharge at a rate of C/10 to a lower cutoff voltage of 3 V.\n", "" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "source": [ "jsonstruct.Control.CRate = 0.1;\n", "jsonstruct.Control.lowerCutoffVoltage = 3.0;" ], "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "Remember that if we change the rate of the discharge then we also need to change the duration of the simulation. To do this we can explore the TimeStepping property of the structure.\n", "" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "source": [ "disp(jsonstruct.TimeStepping)" ], "outputs": [ { "data": { "text/plain": [ " totalTime: 5040\n", " numberOfTimeSteps: 150\n", " useRampup: 1" ] }, "metadata": {}, "execution_count": 4, "output_type": "execute_result" } ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "The total duration of the simulation is given by the totalTime property. We can adjust it to an appropriate duration using the following command.\n", "" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "source": [ "jsonstruct.TimeStepping.totalTime = (1./jsonstruct.Control.CRate) .* 3600 .* 1.1;" ], "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "This sets the total time of the simulation to be 10% longer than the expected duration based on the C\\-Rate. We can then run the simulation and plot the discharge curve.\n", "" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "source": [ "output = runBatteryJson(jsonstruct);" ], "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "retrieve the states from the simulation result\n", "" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "source": [ "states = output.states;\n", "\n", "% extract the time and voltage quantities\n", "time = cellfun(@(state) state.time, states);\n", "voltage = cellfun(@(state) state.('Control').E, states);\n", "\n", "% plot the discharge curve in a new figure\n", "figure();\n", "plot((time/hour), voltage, '-', 'linewidth', 3)\n", "xlabel('Time / h')\n", "ylabel('Cell Voltage / V')\n", "title('Cell Discharge at C/10')" ], "outputs": [ { "data": { "text/html": [ "
\"figure_0.png\"
" ] }, "metadata": {}, "execution_count": 7, "output_type": "execute_result" } ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Setup and Run a Parameter Sweep\n", "\n", "Now, let's setup and run a paramter sweep that simulates the performance of the cell at many different rates. To do this, we can define the different rates that we want to simulate in a vector and then use a for\\-loop to simulate the cell discharge at each value from the vector. We can also store the outputs of the various simulations as elements in a MATLAB cell array so that they are accessible at the end of the sweep.\n", "" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "source": [ "% create a vector of different c-rates for the parameter sweep\n", "CRates = [1, 2, 3];\n", "\n", "% instantiate and empty cell array to store the outputs of the simulations\n", "output = cell(size(CRates));\n", "\n", "% instantiate an empty figure\n", "figure()\n", "\n", "% use a for-loop to iterate through the vector of c-rates\n", "for i = 1 : numel(CRates)\n", " % modify the value for the c-rate in the control definition and update\n", " % the total duration of the simulation accordingly\n", " jsonstruct.Control.CRate = CRates(i);\n", " jsonstruct.TimeStepping.totalTime = (1./jsonstruct.Control.CRate) .* 3600 .* 1.2;\n", "\n", " % run the simulation and store the results in the output cell array\n", " output{i} = runBatteryJson(jsonstruct);\n", "\n", " % retrieve the states from the simulation result\n", " states = output{i}.states;\n", "\n", " % extract the time and voltage quantities\n", " time = cellfun(@(state) state.time, states);\n", " voltage = cellfun(@(state) state.('Control').E, states);\n", "\n", " % plot the discharge curve in the figure\n", " plot((time/hour), voltage, '-', 'linewidth', 3)\n", " hold on\n", "end" ], "outputs": [] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "source": [ "hold off\n", "xlabel('Time / h')\n", "ylabel('Voltage / V')\n", "legend('1C', '2C', '3C')" ], "outputs": [ { "data": { "text/html": [ "
\"figure_1.png\"
" ] }, "metadata": {}, "execution_count": 9, "output_type": "execute_result" } ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "Often, it is a more direct comparison of the discharge curves to plot against an x\\-axis of capacity rather than time. We can use the following commands to make such a plot.\n", "" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "source": [ "% instantiate an empty figure\n", "figure()\n", "\n", "% use a for-loop to iterate through the vector of c-rates\n", "for i = 1 : numel(output)\n", " % modify the value for the c-rate in the control definition and update\n", " % the total duration of the simulation accordingly\n", " jsonstruct.Control.CRate = CRates(i);\n", " jsonstruct.TimeStepping.totalTime = (1./jsonstruct.Control.CRate) .* 3600 .* 1.2;\n", "\n", " % run the simulation and store the results in the output cell array\n", " output{i} = runBatteryJson(jsonstruct);\n", "\n", " % retrieve the states from the simulation result\n", " states = output{i}.states;\n", "\n", " % extract the time, voltage, and current quantities\n", " time = cellfun(@(state) state.time, states);\n", " voltage = cellfun(@(state) state.('Control').E, states);\n", " current = cellfun(@(state) state.('Control').I, states);\n", "\n", " % calculate the capacity\n", " capacity = time .* current;\n", "\n", " % plot the discharge curve in the figure\n", " plot((capacity/(hour*milli)), voltage, '-', 'linewidth', 3)\n", " hold on\n", "end" ], "outputs": [] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "source": [ "hold off\n", "xlabel('Capacity / mA \\cdot h')\n", "ylabel('Voltage / V')\n", "legend('1C', '2C', '3C')" ], "outputs": [ { "data": { "text/html": [ "
\"figure_2.png\"
" ] }, "metadata": {}, "execution_count": 11, "output_type": "execute_result" } ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Summary\n", "\n", "In this tutorial, we explored the basic structure of the control protocol definition and made changes to simulate cell discharge at a variety of rates. We showed that the control protocol is defined as part of the overall BattMo parameter structure. It can be modified by changing the properties of the Control structure. We learned that the total duration of the simulation is dependent on the rate of the battery discharge, and should be updated accordingly. Finally, we showed how to setup and execute a basic parameter sweep by defining a vector with different C\\-rates and using a for\\-loop to simulate the cell discharge at each rate.\n", "\n", "" ] } ], "metadata": { "kernelspec": { "display_name": "MATLAB (matlabkernel)", "language": "matlab", "name": "matlab" }, "language_info": { "file_extension": ".m", "mimetype": "text/matlab", "name": "matlab", "nbconvert_exporter": "matlab", "pygments_lexer": "matlab", "version": "24.1.0.2689473" } }, "nbformat": 4, "nbformat_minor": 4 }