{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "# Tutorial 4 \\- Modify Material Parameters\n", "\n", "## Introduction\n", "\n", "In this tutorial, we will use a P2D model to simulate the effects of changing material parameters on cell discharge. After completing this tutorial, you should have a working knowledge of:\n", "\n", "- Basics of how material properties are defined in BattMo\n", "- How to make some simple changes to material property definitions\n", "- How to change material models from the BattMo material library\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": [ "\n", "Parameters are defined in the JSON parameter file and parsed into the MATLAB structure. Once the JSON file has been read into MATLAB as a jsonstruct, its properties can be modified programmatically.\n", "\n", "## Explore the Material Parameters\n", "\n", "Let's begin by exploring the active material of the positive electrode coating with the following command:\n", "" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "source": [ "disp(jsonstruct.PositiveElectrode.Coating.ActiveMaterial)" ], "outputs": [ { "data": { "text/plain": [ " massFraction: 0.9500\n", " density: 4650\n", " specificHeatCapacity: 700\n", " thermalConductivity: 2.1000\n", " electronicConductivity: 100\n", " Interface: [1x1 struct]\n", " diffusionModelType: 'full'\n", " SolidDiffusion: [1x1 struct]" ] }, "metadata": {}, "execution_count": 2, "output_type": "execute_result" } ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "We can see that a variety of parameters are defined that determine the physicochemical properties of the material. Many of the parameters that describe the electrochemical reactions that take place at the active material \\- electrolyte interface are contained in the Interface structure, which we can explore with the command:\n", "" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "source": [ "disp(jsonstruct.PositiveElectrode.Coating.ActiveMaterial.Interface)" ], "outputs": [ { "data": { "text/plain": [ " saturationConcentration: 55554\n", " volumetricSurfaceArea: 885000\n", " density: 4650\n", " numberOfElectronsTransferred: 1\n", " activationEnergyOfReaction: 5000\n", " reactionRateConstant: 2.3300e-11\n", " guestStoichiometry100: 0.4955\n", " guestStoichiometry0: 0.9917\n", " chargeTransferCoefficient: 0.5000\n", " openCircuitPotential: [1x1 struct]" ] }, "metadata": {}, "execution_count": 3, "output_type": "execute_result" } ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "Furthermore, it is well known that the diffusion of lithium in the active materials can be a limiting factor in Li\\-ion battery performance. The diffusion model used in this simulation can be explored with the following command:\n", "" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "source": [ "disp(jsonstruct.PositiveElectrode.Coating.ActiveMaterial.SolidDiffusion)" ], "outputs": [ { "data": { "text/plain": [ " activationEnergyOfDiffusion: 5000\n", " referenceDiffusionCoefficient: 1.0000e-14\n", " particleRadius: 1.0000e-06\n", " N: 10" ] }, "metadata": {}, "execution_count": 4, "output_type": "execute_result" } ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "We can see there that the solid diffusion model includes a reference diffusion coefficient, activation energy of diffusion, and the effective particle radius.\n", "\n", "## Make a Simple Change\n", "\n", "Let's make a simple change to the positive electrode active material properties in our model and see how it affects the results. Let's compare how c\n", "" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "source": [ "% create a vector of diffent thickness values\n", "radius = [1, 5, 10].*micro;\n", "\n", "% instantiate and empty cell array to store the outputs of the simulations\n", "output = cell(size(radius));\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(radius)\n", " % modify the value for the c-rate in the control definition and update\n", " % the total duration of the simulation accordingly\n", " jsonstruct.PositiveElectrode.Coating.ActiveMaterial.SolidDiffusion.particleRadius = radius(i);\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", " 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/(milli*hour)), voltage, '-', 'linewidth', 3)\n", " hold on\n", "end" ], "outputs": [] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "source": [ "hold off\n", "\n", "% add plot annotations\n", "xlabel('Capacity / mA \\cdot h')\n", "ylabel('Cell Voltage / V')\n", "\n", "% we can pull the radius values directly from the vector to make the plot\n", "% annotations more resilient to changes in the code\n", "legend(strcat('r=', num2str(radius(1)/micro), ' µm'), strcat('r=', num2str(radius(2)/micro), ' µm'), strcat('r=', num2str(radius(3)/micro), ' µm'))" ], "outputs": [ { "data": { "text/html": [ "
\"figure_0.png\"
" ] }, "metadata": {}, "execution_count": 6, "output_type": "execute_result" } ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Swap Active Materials\n", "\n", "Now let's try to replace the active material with a different material from the BattMo library. In this example, we will replace the NMC material with LFP. First, let's re\\-load our baseline example parameter set to get rid of the changes from the previous sections.\n", "" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "source": [ "clear\n", "jsonstruct = parseBattmoJson('Examples/jsondatafiles/sample_input.json');" ], "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "Now we load and parse the LFP material parameters from the **BattMo** library and move it to the right place in the model hierarchy:\n", "" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "source": [ "lfp = parseBattmoJson('ParameterData/MaterialProperties/LFP/LFP.json');\n", "jsonstruct_lfp.PositiveElectrode.Coating.ActiveMaterial.Interface = lfp;" ], "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "To merge new parameter data into our existing model, we can use the **BattMo** function mergeJsonStructs.\n", "" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "source": [ "jsonstruct = mergeJsonStructs({jsonstruct_lfp, ...\n", " jsonstruct});" ], "outputs": [ { "data": { "text/plain": [ "mergeJsonStructs: Parameter PositiveElectrode.Coating.ActiveMaterial.Interface.saturationConcentration is assigned twice with different values. Value from first jsonstruct is used.\n", "mergeJsonStructs: Parameter PositiveElectrode.Coating.ActiveMaterial.Interface.volumetricSurfaceArea is assigned twice with different values. Value from first jsonstruct is used.\n", "mergeJsonStructs: Parameter PositiveElectrode.Coating.ActiveMaterial.Interface.density is assigned twice with different values. Value from first jsonstruct is used.\n", "mergeJsonStructs: Parameter PositiveElectrode.Coating.ActiveMaterial.Interface.activationEnergyOfReaction is assigned twice with different values. Value from first jsonstruct is used.\n", "mergeJsonStructs: Parameter PositiveElectrode.Coating.ActiveMaterial.Interface.reactionRateConstant is assigned twice with different values. Value from first jsonstruct is used.\n", "mergeJsonStructs: Parameter PositiveElectrode.Coating.ActiveMaterial.Interface.guestStoichiometry100 is assigned twice with different values. Value from first jsonstruct is used.\n", "mergeJsonStructs: Parameter PositiveElectrode.Coating.ActiveMaterial.Interface.guestStoichiometry0 is assigned twice with different values. Value from first jsonstruct is used.\n", "mergeJsonStructs: Parameter PositiveElectrode.Coating.ActiveMaterial.Interface.openCircuitPotential.functionname is assigned twice with different values. Value from first jsonstruct is used." ] }, "metadata": {}, "execution_count": 9, "output_type": "execute_result" } ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "We need to be sure that the parameters are consistent across the hierarchy:\n", "" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "source": [ "jsonstruct.PositiveElectrode.Coating.ActiveMaterial.density = jsonstruct.PositiveElectrode.Coating.ActiveMaterial.Interface.density;\n", "jsonstruct.PositiveElectrode.Coating.effectiveDensity = 900;" ], "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "And now, we can run the simulation and plot the discharge curve:\n", "" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "source": [ "% run the simulation\n", "output = runBatteryJson(jsonstruct);" ], "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "get the states\n", "" ] }, { "cell_type": "code", "execution_count": 12, "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", "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/(milli*hour)), voltage, '-', 'linewidth', 3)\n", "\n", "% add plot annotations\n", "xlabel('Capacity / mA \\cdot h')\n", "ylabel('Cell Voltage / V')" ], "outputs": [ { "data": { "text/html": [ "
\"figure_1.png\"
" ] }, "metadata": {}, "execution_count": 12, "output_type": "execute_result" } ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Summary\n", "\n", "In this tutorial, we explored how to modify material parameters in BattMo. We first explored the material parameter structure. Then we modified the effective particle radius and simulated its affect on the cell discharge curve. Finally we swapped out the NMC active material for a LFP material and simulated the new performance of the cell.\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 }