Protonic Membrane
+We consider the model of a mixed proton and electron conducting membrane, as described in [VST+19] from 2019.
+diff --git a/_images/runBatteryP2D_01.png b/_images/runBatteryP2D_01.png
index 4239be97..449739ff 100644
Binary files a/_images/runBatteryP2D_01.png and b/_images/runBatteryP2D_01.png differ
diff --git a/_images/runElectrolyser_02.png b/_images/runElectrolyser_02.png
deleted file mode 100644
index 55f766d1..00000000
Binary files a/_images/runElectrolyser_02.png and /dev/null differ
diff --git a/_images/runGasSupply_01.png b/_images/runGasSupply_01.png
index d657e803..ee590c05 100644
Binary files a/_images/runGasSupply_01.png and b/_images/runGasSupply_01.png differ
diff --git a/_images/runGasSupply_02.png b/_images/runGasSupply_02.png
index ca63a6f5..a2f07a50 100644
Binary files a/_images/runGasSupply_02.png and b/_images/runGasSupply_02.png differ
diff --git a/_images/runGasSupply_03.png b/_images/runGasSupply_03.png
index 82b50d50..a63ccbe3 100644
Binary files a/_images/runGasSupply_03.png and b/_images/runGasSupply_03.png differ
diff --git a/_images/runGasSupply_04.png b/_images/runGasSupply_04.png
index d2e6734b..a8f9bc49 100644
Binary files a/_images/runGasSupply_04.png and b/_images/runGasSupply_04.png differ
diff --git a/_images/runGasSupply_05.png b/_images/runGasSupply_05.png
index bb15b47d..83579269 100644
Binary files a/_images/runGasSupply_05.png and b/_images/runGasSupply_05.png differ
diff --git a/_images/runGasSupply_06.png b/_images/runGasSupply_06.png
index 75c02525..ce7b4304 100644
Binary files a/_images/runGasSupply_06.png and b/_images/runGasSupply_06.png differ
diff --git a/_images/runGasSupply_07.png b/_images/runGasSupply_07.png
index b964a88a..ee87492d 100644
Binary files a/_images/runGasSupply_07.png and b/_images/runGasSupply_07.png differ
diff --git a/_images/runGasSupply_08.png b/_images/runGasSupply_08.png
index 8c695b4b..73028eae 100644
Binary files a/_images/runGasSupply_08.png and b/_images/runGasSupply_08.png differ
diff --git a/_images/runGasSupply_09.png b/_images/runGasSupply_09.png
index 42a1a558..722ddc26 100644
Binary files a/_images/runGasSupply_09.png and b/_images/runGasSupply_09.png differ
diff --git a/_images/runProtonicCell_01.png b/_images/runProtonicCell_01.png
new file mode 100644
index 00000000..f668acc7
Binary files /dev/null and b/_images/runProtonicCell_01.png differ
diff --git a/_images/runProtonicCell_02.png b/_images/runProtonicCell_02.png
new file mode 100644
index 00000000..c5a3fffd
Binary files /dev/null and b/_images/runProtonicCell_02.png differ
diff --git a/_images/runProtonicCell_03.png b/_images/runProtonicCell_03.png
new file mode 100644
index 00000000..b0fb15e2
Binary files /dev/null and b/_images/runProtonicCell_03.png differ
diff --git a/_images/runProtonicCell_04.png b/_images/runProtonicCell_04.png
new file mode 100644
index 00000000..a745ad59
Binary files /dev/null and b/_images/runProtonicCell_04.png differ
diff --git a/_images/runProtonicCell_05.png b/_images/runProtonicCell_05.png
new file mode 100644
index 00000000..18e4832a
Binary files /dev/null and b/_images/runProtonicCell_05.png differ
diff --git a/_images/runProtonicCell_06.png b/_images/runProtonicCell_06.png
new file mode 100644
index 00000000..9aa912a5
Binary files /dev/null and b/_images/runProtonicCell_06.png differ
diff --git a/_images/runProtonicCell_07.png b/_images/runProtonicCell_07.png
new file mode 100644
index 00000000..3b8b3152
Binary files /dev/null and b/_images/runProtonicCell_07.png differ
diff --git a/_images/runProtonicCell_08.png b/_images/runProtonicCell_08.png
new file mode 100644
index 00000000..db25d413
Binary files /dev/null and b/_images/runProtonicCell_08.png differ
diff --git a/_images/runProtonicCell_09.png b/_images/runProtonicCell_09.png
new file mode 100644
index 00000000..4a59b2fa
Binary files /dev/null and b/_images/runProtonicCell_09.png differ
diff --git a/_images/runProtonicCell_10.png b/_images/runProtonicCell_10.png
new file mode 100644
index 00000000..8f8e2792
Binary files /dev/null and b/_images/runProtonicCell_10.png differ
diff --git a/_images/runProtonicCell_11.png b/_images/runProtonicCell_11.png
new file mode 100644
index 00000000..e8af335a
Binary files /dev/null and b/_images/runProtonicCell_11.png differ
diff --git a/_images/runProtonicCell_12.png b/_images/runProtonicCell_12.png
new file mode 100644
index 00000000..60955e17
Binary files /dev/null and b/_images/runProtonicCell_12.png differ
diff --git a/_images/runProtonicCell_13.png b/_images/runProtonicCell_13.png
new file mode 100644
index 00000000..73a7968c
Binary files /dev/null and b/_images/runProtonicCell_13.png differ
diff --git a/_images/runProtonicMembrane_01.png b/_images/runProtonicMembrane_01.png
index 1a2f4c9e..be45a088 100644
Binary files a/_images/runProtonicMembrane_01.png and b/_images/runProtonicMembrane_01.png differ
diff --git a/_images/runProtonicMembrane_02.png b/_images/runProtonicMembrane_02.png
index c8471434..0c62e24e 100644
Binary files a/_images/runProtonicMembrane_02.png and b/_images/runProtonicMembrane_02.png differ
diff --git a/_images/runProtonicMembrane_03.png b/_images/runProtonicMembrane_03.png
index 151d42ef..f1bcb96e 100644
Binary files a/_images/runProtonicMembrane_03.png and b/_images/runProtonicMembrane_03.png differ
diff --git a/_images/runProtonicMembrane_04.png b/_images/runProtonicMembrane_04.png
index 23bd8e93..46cd6a70 100644
Binary files a/_images/runProtonicMembrane_04.png and b/_images/runProtonicMembrane_04.png differ
diff --git a/_images/runProtonicMembrane_05.png b/_images/runProtonicMembrane_05.png
index a63825a6..98e28106 100644
Binary files a/_images/runProtonicMembrane_05.png and b/_images/runProtonicMembrane_05.png differ
diff --git a/_images/runProtonicMembrane_06.png b/_images/runProtonicMembrane_06.png
index 71994ae4..35f84a06 100644
Binary files a/_images/runProtonicMembrane_06.png and b/_images/runProtonicMembrane_06.png differ
diff --git a/_images/runProtonicMembrane_07.png b/_images/runProtonicMembrane_07.png
index d55e81ab..f703e27b 100644
Binary files a/_images/runProtonicMembrane_07.png and b/_images/runProtonicMembrane_07.png differ
diff --git a/_sources/index.rst.txt b/_sources/index.rst.txt
index e5d99c58..fcf3a53f 100644
--- a/_sources/index.rst.txt
+++ b/_sources/index.rst.txt
@@ -15,8 +15,7 @@
advancedtopics
juliabridge
Electrolyser simulation
-
-
+
+
-
diff --git a/app.html b/app.html
index e99a9bbf..c94fa830 100644
--- a/app.html
+++ b/app.html
@@ -28,7 +28,7 @@
-
+
@@ -162,36 +162,54 @@
-
-
+
+
-
@@ -300,7 +318,7 @@
BattMoApp
- Previous
+ Previous
Next
diff --git a/app_calculations.html b/app_calculations.html
index 4a9b74e3..bf55b14a 100644
--- a/app_calculations.html
+++ b/app_calculations.html
@@ -161,36 +161,54 @@
-
-
+
+
-
diff --git a/app_features.html b/app_features.html
index 34198afe..d9f8005b 100644
--- a/app_features.html
+++ b/app_features.html
@@ -162,36 +162,54 @@
-
-
+
+
-
diff --git a/app_troubleshooting.html b/app_troubleshooting.html
index f7c4be0a..9adc6e7d 100644
--- a/app_troubleshooting.html
+++ b/app_troubleshooting.html
@@ -162,36 +162,54 @@
-
-
+
+
-
diff --git a/app_unnatural_artifacts.html b/app_unnatural_artifacts.html
index 618e0668..e8b3544c 100644
--- a/app_unnatural_artifacts.html
+++ b/app_unnatural_artifacts.html
@@ -162,36 +162,54 @@
-
-
+
+
-
diff --git a/app_unsuccessful_simulation.html b/app_unsuccessful_simulation.html
index e29556fb..974dcf13 100644
--- a/app_unsuccessful_simulation.html
+++ b/app_unsuccessful_simulation.html
@@ -162,36 +162,54 @@
-
-
+
+
-
diff --git a/architecture.html b/architecture.html
index 22aa9e7b..53a35554 100644
--- a/architecture.html
+++ b/architecture.html
@@ -162,36 +162,54 @@
-
-
+
+
-
diff --git a/basicusage.html b/basicusage.html
index bd2c425c..30c86d67 100644
--- a/basicusage.html
+++ b/basicusage.html
@@ -162,36 +162,54 @@
-
-
+
+
-
diff --git a/bibliography.html b/bibliography.html
index 640433da..64329d0c 100644
--- a/bibliography.html
+++ b/bibliography.html
@@ -161,36 +161,54 @@
-
-
+
+
-
diff --git a/compositeElectrode.html b/compositeElectrode.html
index df001f04..34b05e2e 100644
--- a/compositeElectrode.html
+++ b/compositeElectrode.html
@@ -160,36 +160,54 @@
-
-
+
+
-
diff --git a/computationalGraph/graphdoc.html b/computationalGraph/graphdoc.html
index b9ba1cbd..8b1604d1 100644
--- a/computationalGraph/graphdoc.html
+++ b/computationalGraph/graphdoc.html
@@ -163,36 +163,54 @@
-
-
+
+
-
diff --git a/controlinput.html b/controlinput.html
index bba8e51f..1e36f511 100644
--- a/controlinput.html
+++ b/controlinput.html
@@ -163,36 +163,54 @@
-
-
+
+
-
diff --git a/genindex.html b/genindex.html
index 025cdfe8..118f0014 100644
--- a/genindex.html
+++ b/genindex.html
@@ -159,36 +159,54 @@
-
-
+
+
-
diff --git a/geometryinput.html b/geometryinput.html
index ab5633fd..e434089c 100644
--- a/geometryinput.html
+++ b/geometryinput.html
@@ -162,36 +162,54 @@
-
-
+
+
-
diff --git a/index.html b/index.html
index 4ee649f7..b6852728 100644
--- a/index.html
+++ b/index.html
@@ -161,36 +161,54 @@
-
-
+
+
-
diff --git a/installation.html b/installation.html
index f2be6a1b..d4e7f820 100644
--- a/installation.html
+++ b/installation.html
@@ -162,36 +162,54 @@
-
-
+
+
-
diff --git a/intermediate.html b/intermediate.html
index 0c034f37..a431a2a3 100644
--- a/intermediate.html
+++ b/intermediate.html
@@ -162,36 +162,54 @@
-
-
+
+
-
@@ -379,7 +397,7 @@
File links and insertions with
jsonstruct
that is obtained is equivalent to the one where we would have copied and paste the content of
graphite.json.
"NegativeElectrode": {
"Coating": {
"ActiveMaterial": {
diff --git a/json.html b/json.html
index c08d88a1..bef9386a 100644
--- a/json.html
+++ b/json.html
@@ -162,36 +162,54 @@
In this tutorial we will simulate a lithium-ion battery consisting of a negative electrode, a positive electrode and an electrolyte. BattMo comes with some pre-defined models which can be loaded from JSON files. Here we will load the basic lithium-ion model JSON file which comes with Battmo. We use parseBattmoJson to parse the file, see add link to doc
+In this tutorial we will simulate a lithium-ion battery consisting of a negative electrode, a positive electrode and an electrolyte. BattMo comes with some pre-defined models which can be loaded from JSON files. Here we will load the basic lithium-ion model JSON file which comes with Battmo. We use parseBattmoJson to parse the file.
fname = fullfile('ParameterData','BatteryCellParameters',...
'LithiumIonBatteryCell','lithium_ion_battery_nmc_graphite.json');
jsonstruct = parseBattmoJson(fname);
@@ -314,17 +332,17 @@ Specifying the physical modeljsonstruct.(ne).(am).diffusionModelType = 'full';
To see which other types of diffusion model are available one can view ActiveMaterialInputParams. When running a simulation, BattMo requires that all model parameters are stored in an instance of BatteryInputParams. This class is used to initialize the simulation and is accessed by various parts of the simulator during the simulation. This class is instantiated using the jsonstruct we just created:
-paramobj = BatteryInputParams(jsonstruct);
+To see which other types of diffusion model are available one can view ActiveMaterialInputParams. When running a simulation, BattMo requires that all model parameters are stored in an instance of BatteryInputParams. This class is used to initialize the simulation and is accessed by various parts of the simulator during the simulation. This class is instantiated using the jsonstruct we just created:
+inputparams = BatteryInputParams(jsonstruct);
-It is also possible to update the properties of this paramobj in a similar way to updating the jsonstruct. Here we set the discretisation level for the diffusion model. Other input parameters for the full diffusion model can be found here: FullSolidDiffusionModelInputParams.
-paramobj.(ne).(co).(am).(sd).N = 5;
-paramobj.(pe).(co).(am).(sd).N = 5;
+It is also possible to update the properties of this inputparams in a similar way to updating the jsonstruct. Here we set the discretisation level for the diffusion model. Other input parameters for the full diffusion model can be found here: FullSolidDiffusionModelInputParams.
+inputparams.(ne).(co).(am).(sd).N = 5;
+inputparams.(pe).(co).(am).(sd).N = 5;
% We can also change how the battery is operated, for example setting
% the cut off voltage.
-paramobj.(ctrl).lowerCutoffVoltage = 2.5;
+inputparams.(ctrl).lowerCutoffVoltage = 2.5;
@@ -334,16 +352,16 @@ Setting up the geometrygen = BatteryGeneratorP2D();
-Now, we update the paramobj with the properties of the grid. This function will update relevent parameters in the paramobj object and make sure we have all the required parameters for the model geometry chosen.
-paramobj = gen.updateBatteryInputParams(paramobj);
+Now, we update the inputparams with the properties of the grid. This function will update relevent parameters in the inputparams object and make sure we have all the required parameters for the model geometry chosen.
+inputparams = gen.updateBatteryInputParams(inputparams);
Initialising the battery model object
-The battery model is initialized by sending paramobj to the Battery class constructor. see Battery.
+
The battery model is initialized by sending inputparams to the Battery class constructor. see Battery.
In BattMo a battery model is actually a collection of submodels: Electrolyte, Negative Electrode, Positive Electrode, Thermal Model and Control Model. The battery class contains all of these submodels and various other parameters necessary to run the simulation.
-model = Battery(paramobj);
+model = Battery(inputparams);
@@ -385,17 +403,8 @@ Plotting the OCP curves against state of charge
Controlling the simulation
The control model specifies how the battery is operated, i.e., how the simulation is controlled.
-In the first instance we use CCDischarge control policy. We set the total time scaled by the CRate in the model. The CRate has been set by the json file. We can access it here:
-CRate = model.Control.CRate;
-total = 1.1*hour/CRate;
-
-
-We want to break this total time into 100 timesteps. To begin with we will use equal values for each timestep.
-We create a structure containing the length of each step in seconds (‘val’) and also which control to use for each step (‘control’).
-In this case we use control 1 for all steps. This means that the functions used to setup the control values are the same at each step.
-n = 100;
-dt = total/n;
-step = struct('val', dt*ones(n, 1), 'control', ones(n, 1));
+The input parameters for the control have been given as part of the json structure ParameterData/BatteryCellParameters/LithiumIonBatteryCell/lithium_ion_battery_nmc_graphite.json. The total simulation time is setup for us, computed from the DRate value. We use the method setupScheduleStep
in ControlModel to setup the step
structure.
+step = model.Control.setupScheduleStep();
We create a control structure containing the source function and and a stopping criteria. The control parameters have been given in the json file ParameterData/BatteryCellParameters/LithiumIonBatteryCell/lithium_ion_battery_nmc_graphite.json
@@ -418,7 +427,7 @@
Setting the initial state of the battery
Running the simulation
Once we have the initial state, the model and the schedule, we can call the simulateScheduleAD function which will actually run the simulation.
-The outputs from the simulation are: - sols: which provides the current and voltage of the battery at each timestep. - states: which contains the values of the primary variables in the model at each timestep. - reports: which contains technical information about the steps used in the numerical solvers.
+The outputs from the simulation are: - sols: which provides the current and voltage of the battery at each timestep. - states: which contains the values of the primary variables in the model at each timestep. - reports: which contains technical information about the steps used in the numerical solvers.
[sols, states, report] = simulateScheduleAD(initstate, model, schedule);
@@ -439,7 +448,6 @@ Plotting the resultssubplot(1,2,2)
plot(time/hour, I)
-ylim([0, 0.02])
xlabel('time / h')
ylabel('Cell Current / A')
diff --git a/publishedExamples/battMoTutorial_source.html b/publishedExamples/battMoTutorial_source.html
index 25a701a5..91adb055 100644
--- a/publishedExamples/battMoTutorial_source.html
+++ b/publishedExamples/battMoTutorial_source.html
@@ -160,36 +160,54 @@
- pH distribution plot
-- Protonic Membrane
-- Model overview
-- Governing equations
-- Boundary conditions
+- Protonic Membrane
+- Protonic Membrane
+- Model overview
-- Load and parse input from given json files
-- Input structure setup
-- Model setup
-- Initial state setup
-- Schedule
-- Simulation
-- Plotting
-- Evolution of the Faradic efficiency
+- Load and parse input from given json files
+- Input structure setup
+- Model setup
+- Initial state setup
+- Schedule
+- Simulation
+- Plotting
+- Evolution of the Faradic efficiency
-- Gas Supply
-- Model overview
- BattMoApp
@@ -285,7 +303,7 @@
% negative electrode, a positive electrode and an electrolyte. *BattMo*
% comes with some pre-defined models which can be loaded from JSON files.
% Here we will load the basic lithium-ion model JSON file which comes with
-% Battmo. We use :battmo:`parseBattmoJson` to parse the file, see :todo:`add link to doc`
+% Battmo. We use :battmo:`parseBattmoJson` to parse the file.
fname = fullfile('ParameterData','BatteryCellParameters',...
'LithiumIonBatteryCell','lithium_ion_battery_nmc_graphite.json');
@@ -338,21 +356,21 @@
% various parts of the simulator during the simulation. This class is
% instantiated using the jsonstruct we just created:
-paramobj = BatteryInputParams(jsonstruct);
+inputparams = BatteryInputParams(jsonstruct);
%%
-% It is also possible to update the properties of this paramobj in a
+% It is also possible to update the properties of this inputparams in a
% similar way to updating the jsonstruct. Here we set the discretisation
% level for the diffusion model. Other input parameters for the full diffusion
% model can be found here:
% :battmo:`FullSolidDiffusionModelInputParams`.
-paramobj.(ne).(co).(am).(sd).N = 5;
-paramobj.(pe).(co).(am).(sd).N = 5;
+inputparams.(ne).(co).(am).(sd).N = 5;
+inputparams.(pe).(co).(am).(sd).N = 5;
% We can also change how the battery is operated, for example setting
% the cut off voltage.
-paramobj.(ctrl).lowerCutoffVoltage = 2.5;
+inputparams.(ctrl).lowerCutoffVoltage = 2.5;
%% Setting up the geometry
% Here, we setup the 1D computational grid that will be used for the
@@ -363,14 +381,14 @@
gen = BatteryGeneratorP2D();
%%
-% Now, we update the paramobj with the properties of the grid. This function
-% will update relevent parameters in the paramobj object and make sure we have
+% Now, we update the inputparams with the properties of the grid. This function
+% will update relevent parameters in the inputparams object and make sure we have
% all the required parameters for the model geometry chosen.
-paramobj = gen.updateBatteryInputParams(paramobj);
+inputparams = gen.updateBatteryInputParams(inputparams);
%% Initialising the battery model object
-% The battery model is initialized by sending paramobj to the Battery class
+% The battery model is initialized by sending inputparams to the Battery class
% constructor. see :battmo:`Battery`.
%
% In BattMo a battery model is actually a collection of submodels:
@@ -378,7 +396,7 @@
% Model. The battery class contains all of these submodels and various other
% parameters necessary to run the simulation.
-model = Battery(paramobj);
+model = Battery(inputparams);
%% Plotting the OCP curves against state of charge
% We can inspect the model object to find out which parameters are being
@@ -414,36 +432,22 @@
legend(eldes, 'location', 'nw')
%% Controlling the simulation
-% The control model specifies how the battery is operated, i.e., how
-% the simulation is controlled.
-%
-% In the first instance we use CCDischarge control policy.
-% We set the total time scaled by the CRate in the model.
-% The CRate has been set by the json file. We can access it here:
-
-CRate = model.Control.CRate;
-total = 1.1*hour/CRate;
-
-%%
-% We want to break this total time into 100 timesteps. To begin with we
-% will use equal values for each timestep.
+% The control model specifies how the battery is operated, i.e., how the simulation is controlled.
%
-% We create a structure containing the length of each step in seconds
-% ('val') and also which control to use for each step ('control').
-%
-% In this case we use control 1 for all steps. This means that the functions
-% used to setup the control values are the same at each step.
+% The input parameters for the control have been given as part of the json structure
+% :battmofile:`ParameterData/BatteryCellParameters/LithiumIonBatteryCell/lithium_ion_battery_nmc_graphite.json`. The
+% total simulation time is setup for us, computed from the DRate value. We use the method :code:`setupScheduleStep` in
+% :battmo:`ControlModel` to setup the :code:`step` structure.
-n = 100;
-dt = total/n;
-step = struct('val', dt*ones(n, 1), 'control', ones(n, 1));
+step = model.Control.setupScheduleStep();
%%
% We create a control structure containing the source function and
% and a stopping criteria. The control parameters have been given in the json file
% :battmofile:`ParameterData/BatteryCellParameters/LithiumIonBatteryCell/lithium_ion_battery_nmc_graphite.json`
%
-% The :code:`setupScheduleControl` method contains the code to setup the control structure that is used in the schedule structure setup below.
+% The :code:`setupScheduleControl` method contains the code to setup the control structure that is used in the schedule
+% structure setup below.
control = model.Control.setupScheduleControl();
@@ -464,7 +468,6 @@
initstate = model.setupInitialState();
-
%% Running the simulation
% Once we have the initial state, the model and the schedule, we can call
% the simulateScheduleAD function which will actually run the simulation.
@@ -498,13 +501,12 @@
subplot(1,2,2)
plot(time/hour, I)
-ylim([0, 0.02])
xlabel('time / h')
ylabel('Cell Current / A')
%{
-Copyright 2021-2023 SINTEF Industry, Sustainable Energy Technology
+Copyright 2021-2024 SINTEF Industry, Sustainable Energy Technology
and SINTEF Digital, Mathematics & Cybernetics.
This file is part of The Battery Modeling Toolbox BattMo
diff --git a/publishedExamples/runBatteryP2D.html b/publishedExamples/runBatteryP2D.html
index 3749477c..2e6ee890 100644
--- a/publishedExamples/runBatteryP2D.html
+++ b/publishedExamples/runBatteryP2D.html
@@ -160,36 +160,54 @@
- pH distribution plot
-- Protonic Membrane
-- Model overview
-- Governing equations
-- Boundary conditions
+- Protonic Membrane
+- Protonic Membrane
+- Model overview
-- Load and parse input from given json files
-- Input structure setup
-- Model setup
-- Initial state setup
-- Schedule
-- Simulation
-- Plotting
-- Evolution of the Faradic efficiency
+- Load and parse input from given json files
+- Input structure setup
+- Model setup
+- Initial state setup
+- Schedule
+- Simulation
+- Plotting
+- Evolution of the Faradic efficiency
-- Gas Supply
-- Model overview
- BattMoApp
@@ -276,7 +294,7 @@ Import the required modules from MRST
Setup the properties of Li-ion battery materials and cell design
-The properties and parameters of the battery cell, including the architecture and materials, are set using an instance of BatteryInputParams
. This class is used to initialize the simulation and it propagates all the parameters throughout the submodels. The input parameters can be set manually or provided in json format. All the parameters for the model are stored in the paramobj object.
+The properties and parameters of the battery cell, including the architecture and materials, are set using an instance of BatteryInputParams
. This class is used to initialize the simulation and it propagates all the parameters throughout the submodels. The input parameters can be set manually or provided in json format. All the parameters for the model are stored in the inputparams object.
jsonstruct = parseBattmoJson(fullfile('ParameterData','BatteryCellParameters','LithiumIonBatteryCell','lithium_ion_battery_nmc_graphite.json'));
% We define some shorthand names for simplicity.
@@ -294,19 +312,22 @@ Setup the properties of Li-ion battery materials and cell designjsonstruct.use_thermal = false;
jsonstruct.include_current_collectors = false;
-paramobj = BatteryInputParams(jsonstruct);
+inputparams = BatteryInputParams(jsonstruct);
-use_cccv = false;
+use_cccv = true;
if use_cccv
- cccvstruct = struct( 'controlPolicy' , 'CCCV', ...
- 'initialControl' , 'discharging', ...
- 'CRate' , 1 , ...
- 'lowerCutoffVoltage', 2.4 , ...
- 'upperCutoffVoltage', 4.1 , ...
- 'dIdtLimit' , 0.01 , ...
- 'dEdtLimit' , 0.01);
- cccvparamobj = CcCvControlModelInputParams(cccvstruct);
- paramobj.Control = cccvparamobj;
+ inputparams.SOC = 0;
+ cccvstruct = struct( 'controlPolicy' , 'CCCV' , ...
+ 'initialControl' , 'charging', ...
+ 'numberOfCycles' , 2 , ...
+ 'CRate' , 1.5 , ...
+ 'DRate' , 1 , ...
+ 'lowerCutoffVoltage', 3 , ...
+ 'upperCutoffVoltage', 4 , ...
+ 'dIdtLimit' , 1e-2 , ...
+ 'dEdtLimit' , 1e-4);
+ cccvinputparams = CcCvControlModelInputParams(cccvstruct);
+ inputparams.Control = cccvinputparams;
end
@@ -316,17 +337,15 @@ Setup the geometry and computational gridgen = BatteryGeneratorP2D();
-% Now, we update the paramobj with the properties of the grid.
-paramobj = gen.updateBatteryInputParams(paramobj);
+% Now, we update the inputparams with the properties of the grid.
+inputparams = gen.updateBatteryInputParams(inputparams);
Initialize the battery model.
-The battery model is initialized by sending paramobj to the Battery class constructor. see Battery
.
-model = Battery(paramobj);
-
-model.AutoDiffBackend= AutoDiffBackend();
+The battery model is initialized by sending inputparams to the Battery class constructor. see Battery
.
+model = GenericBattery(inputparams);
inspectgraph = false;
if inspectgraph
@@ -336,31 +355,11 @@ Initialize the battery model.
-Compute the nominal cell capacity and choose a C-Rate
-The nominal capacity of the cell is calculated from the active materials. This value is then combined with the user-defined C-Rate to set the cell operational current.
-CRate = model.Control.CRate;
-
-
-
-
-Setup the time step schedule
-Smaller time steps are used to ramp up the current from zero to its operational value. Larger time steps are then used for the normal operation.
-switch model.(ctrl).controlPolicy
- case 'CCCV'
- total = 3.5*hour/CRate;
- case 'CCDischarge'
- total = 1.4*hour/CRate;
- otherwise
- error('control policy not recognized');
-end
-
-n = 100;
-dt = total/n;
-step = struct('val', dt*ones(n, 1), 'control', ones(n, 1));
-
-% we setup the control by assigning a source and stop function.
+
+Setup the schedule
+timestep.timeStepDuration = 100;
+step = model.Control.setupScheduleStep(timestep);
control = model.Control.setupScheduleControl();
% This control is used to set up the schedule
@@ -404,9 +403,16 @@ Setup the properties of the nonlinear solvernls.maxIterations = 10;
% Change default behavior of nonlinear solver, in case of error
nls.errorOnFailure = false;
-nls.timeStepSelector = StateChangeTimeStepSelector('TargetProps', {{'Control','E'}}, 'targetChangeAbs', 0.03);
+% nls.timeStepSelector = StateChangeTimeStepSelector('TargetProps', {{'Control','E'}}, 'targetChangeAbs', 0.03);
% Change default tolerance for nonlinear solver
-model.nonlinearTolerance = 1e-3*model.Control.Imax;
+nls.maxTimestepCuts = 6;
+
+if use_cccv
+ Imax = (model.(ctrl).ImaxDischarge + model.(ctrl).ImaxCharge);
+else
+ Imax = model.(ctrl).Imax;
+end
+model.nonlinearTolerance = 1e-6*Imax;
% Set verbosity
model.verbose = true;
@@ -430,11 +436,17 @@ Process output and recover the output voltage and current from the output st
time = cellfun(@(x) x.time, states);
figure
-plot(time/hour, E);
+plot(time/hour, E, '*-');
grid on
xlabel 'time / h';
ylabel 'potential / V';
+figure
+plot(time/hour, I, '*-');
+grid on
+xlabel 'time / h';
+ylabel 'Current / A';
+
writeh5 = false;
if writeh5
writeOutput(model, states, 'output.h5');
@@ -444,6 +456,9 @@ Process output and recover the output voltage and current from the output st
+
complete source code can be found here
diff --git a/publishedExamples/runBatteryP2D_source.html b/publishedExamples/runBatteryP2D_source.html
index ac63a9a9..e8d13477 100644
--- a/publishedExamples/runBatteryP2D_source.html
+++ b/publishedExamples/runBatteryP2D_source.html
@@ -160,36 +160,54 @@
- pH distribution plot
-- Protonic Membrane
-- Model overview
-- Governing equations
-- Boundary conditions
+- Protonic Membrane
+- Protonic Membrane
+- Model overview
-- Load and parse input from given json files
-- Input structure setup
-- Model setup
-- Initial state setup
-- Schedule
-- Simulation
-- Plotting
-- Evolution of the Faradic efficiency
+- Load and parse input from given json files
+- Input structure setup
+- Model setup
+- Initial state setup
+- Schedule
+- Simulation
+- Plotting
+- Evolution of the Faradic efficiency
-- Gas Supply
-- Model overview
- BattMoApp
@@ -280,7 +298,7 @@
% used to initialize the simulation and it propagates all the parameters
% throughout the submodels. The input parameters can be set manually or
% provided in json format. All the parameters for the model are stored in
-% the paramobj object.
+% the inputparams object.
jsonstruct = parseBattmoJson(fullfile('ParameterData','BatteryCellParameters','LithiumIonBatteryCell','lithium_ion_battery_nmc_graphite.json'));
@@ -299,19 +317,22 @@
jsonstruct.use_thermal = false;
jsonstruct.include_current_collectors = false;
-paramobj = BatteryInputParams(jsonstruct);
+inputparams = BatteryInputParams(jsonstruct);
-use_cccv = false;
+use_cccv = true;
if use_cccv
- cccvstruct = struct( 'controlPolicy' , 'CCCV', ...
- 'initialControl' , 'discharging', ...
- 'CRate' , 1 , ...
- 'lowerCutoffVoltage', 2.4 , ...
- 'upperCutoffVoltage', 4.1 , ...
- 'dIdtLimit' , 0.01 , ...
- 'dEdtLimit' , 0.01);
- cccvparamobj = CcCvControlModelInputParams(cccvstruct);
- paramobj.Control = cccvparamobj;
+ inputparams.SOC = 0;
+ cccvstruct = struct( 'controlPolicy' , 'CCCV' , ...
+ 'initialControl' , 'charging', ...
+ 'numberOfCycles' , 2 , ...
+ 'CRate' , 1.5 , ...
+ 'DRate' , 1 , ...
+ 'lowerCutoffVoltage', 3 , ...
+ 'upperCutoffVoltage', 4 , ...
+ 'dIdtLimit' , 1e-2 , ...
+ 'dEdtLimit' , 1e-4);
+ cccvinputparams = CcCvControlModelInputParams(cccvstruct);
+ inputparams.Control = cccvinputparams;
end
@@ -321,16 +342,14 @@
% in the class BatteryGeneratorP2D.
gen = BatteryGeneratorP2D();
-% Now, we update the paramobj with the properties of the grid.
-paramobj = gen.updateBatteryInputParams(paramobj);
+% Now, we update the inputparams with the properties of the grid.
+inputparams = gen.updateBatteryInputParams(inputparams);
%% Initialize the battery model.
-% The battery model is initialized by sending paramobj to the Battery class
+% The battery model is initialized by sending inputparams to the Battery class
% constructor. see :class:`Battery <Battery.Battery>`.
-model = Battery(paramobj);
-
-model.AutoDiffBackend= AutoDiffBackend();
+model = GenericBattery(inputparams);
inspectgraph = false;
if inspectgraph
@@ -338,32 +357,13 @@
return
end
-%% Compute the nominal cell capacity and choose a C-Rate
-% The nominal capacity of the cell is calculated from the active materials.
-% This value is then combined with the user-defined C-Rate to set the cell
-% operational current.
-
-CRate = model.Control.CRate;
-
-%% Setup the time step schedule
-% Smaller time steps are used to ramp up the current from zero to its
-% operational value. Larger time steps are then used for the normal
-% operation.
-switch model.(ctrl).controlPolicy
- case 'CCCV'
- total = 3.5*hour/CRate;
- case 'CCDischarge'
- total = 1.4*hour/CRate;
- otherwise
- error('control policy not recognized');
-end
-n = 100;
-dt = total/n;
-step = struct('val', dt*ones(n, 1), 'control', ones(n, 1));
+%% Setup the schedule
+%
-% we setup the control by assigning a source and stop function.
+timestep.timeStepDuration = 100;
+step = model.Control.setupScheduleStep(timestep);
control = model.Control.setupScheduleControl();
% This control is used to set up the schedule
@@ -402,9 +402,16 @@
nls.maxIterations = 10;
% Change default behavior of nonlinear solver, in case of error
nls.errorOnFailure = false;
-nls.timeStepSelector = StateChangeTimeStepSelector('TargetProps', {{'Control','E'}}, 'targetChangeAbs', 0.03);
+% nls.timeStepSelector = StateChangeTimeStepSelector('TargetProps', {{'Control','E'}}, 'targetChangeAbs', 0.03);
% Change default tolerance for nonlinear solver
-model.nonlinearTolerance = 1e-3*model.Control.Imax;
+nls.maxTimestepCuts = 6;
+
+if use_cccv
+ Imax = (model.(ctrl).ImaxDischarge + model.(ctrl).ImaxCharge);
+else
+ Imax = model.(ctrl).Imax;
+end
+model.nonlinearTolerance = 1e-6*Imax;
% Set verbosity
model.verbose = true;
@@ -422,11 +429,17 @@
time = cellfun(@(x) x.time, states);
figure
-plot(time/hour, E);
+plot(time/hour, E, '*-');
grid on
xlabel 'time / h';
ylabel 'potential / V';
+figure
+plot(time/hour, I, '*-');
+grid on
+xlabel 'time / h';
+ylabel 'Current / A';
+
writeh5 = false;
if writeh5
writeOutput(model, states, 'output.h5');
@@ -434,7 +447,7 @@
%{
-Copyright 2021-2023 SINTEF Industry, Sustainable Energy Technology
+Copyright 2021-2024 SINTEF Industry, Sustainable Energy Technology
and SINTEF Digital, Mathematics & Cybernetics.
This file is part of The Battery Modeling Toolbox BattMo
diff --git a/publishedExamples/runElectrolyser.html b/publishedExamples/runElectrolyser.html
index 1c90e98f..4ee3be1f 100644
--- a/publishedExamples/runElectrolyser.html
+++ b/publishedExamples/runElectrolyser.html
@@ -28,7 +28,7 @@
-
+
@@ -163,36 +163,54 @@
- pH distribution plot
-- Protonic Membrane
-- Model overview
-- Governing equations
-- Boundary conditions
+- Protonic Membrane
+- Protonic Membrane
+- Model overview
-- Load and parse input from given json files
-- Input structure setup
-- Model setup
-- Initial state setup
-- Schedule
-- Simulation
-- Plotting
-- Evolution of the Faradic efficiency
+- Load and parse input from given json files
+- Input structure setup
+- Model setup
+- Initial state setup
+- Schedule
+- Simulation
+- Plotting
+- Evolution of the Faradic efficiency
-- Gas Supply
-- Model overview
- BattMoApp
@@ -445,57 +463,59 @@ Visualize the results
pH distribution plot
We consider the three domains and plot the pH in each of those. We setup the helper structures to iterate over each domain for the plot.
-models = {model.(oer).(ptl), ...
- model.(her).(ptl), ...
- model.(inm)};
+doplot = false;
-fields = {{'OxygenEvolutionElectrode', 'PorousTransportLayer', 'concentrations', 2} , ...
- {'HydrogenEvolutionElectrode', 'PorousTransportLayer', 'concentrations', 2}, ...
- {'IonomerMembrane', 'cOH'}};
+if doplot
-h = figure();
-set(h, 'position', [10, 10, 800, 450]);
-hold on
+ models = {model.(oer).(ptl), ...
+ model.(her).(ptl), ...
+ model.(inm)};
-ntime = numel(time);
-times = linspace(1, ntime, 10);
-cmap = cmocean('deep', 10);
+ fields = {{'OxygenEvolutionElectrode', 'PorousTransportLayer', 'concentrations', 2} , ...
+ {'HydrogenEvolutionElectrode', 'PorousTransportLayer', 'concentrations', 2}, ...
+ {'IonomerMembrane', 'cOH'}};
-for ifield = 1 : numel(fields)
+ h = figure();
+ set(h, 'position', [10, 10, 800, 450]);
+ hold on
- fd = fields{ifield};
- submodel = models{ifield};
+ ntime = numel(time);
+ times = linspace(1, ntime, 10);
+ cmap = cmocean('deep', 10);
- x = submodel.grid.cells.centroids;
+ for ifield = 1 : numel(fields)
- for itimes = 1 : numel(times);
+ fd = fields{ifield};
+ submodel = models{ifield};
- itime = floor(times(itimes));
- % The method :code:`getProp` is used to recover the value from the state structure
- val = model.getProp(states{itime}, fd);
- pH = 14 + log10(val/(mol/litre));
+ x = submodel.G.cells.centroids;
- % plot of pH for the current submodel.
- plot(x/(milli*meter), pH, 'color', cmap(itimes, :));
+ for itimes = 1 : numel(times);
- end
+ itime = floor(times(itimes));
+ % The method :code:`getProp` is used to recover the value from the state structure
+ val = model.getProp(states{itime}, fd);
+ pH = 14 + log10(val/(mol/litre));
-end
+ % plot of pH for the current submodel.
+ plot(x/(milli*meter), pH, 'color', cmap(itimes, :));
-xlabel('x / mm');
-ylabel('pH');
-title('pH distribution in electrolyser')
+ end
-colormap(cmap)
-hColorbar = colorbar;
-caxis([0 3]);
-hTitle = get(hColorbar, 'Title');
-set(hTitle, 'string', 'J (A/cm^2)');
+ end
+
+ xlabel('x / mm');
+ ylabel('pH');
+ title('pH distribition in electrolyser')
+
+ colormap(cmap)
+ hColorbar = colorbar;
+ caxis([0 3]);
+ hTitle = get(hColorbar, 'Title');
+ set(hTitle, 'string', 'J (A/cm^2)');
+end
-
complete source code can be found here
@@ -505,7 +525,7 @@ pH distribution plot