-
-
Notifications
You must be signed in to change notification settings - Fork 553
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
MSMR model #3116
Merged
MSMR model #3116
Changes from 18 commits
Commits
Show all changes
53 commits
Select commit
Hold shift + click to select a range
e60ec43
basic MSMR model with fast diffusion
rtimms 094f2b6
run test simulation
rtimms 6387858
particle problem in basic SP MSMR
rtimms d1b20a7
update example
rtimms 318f6d3
merge develop
rtimms e0e42d1
MSMR submodels for diffusion and ocp
rtimms c644be8
MSMR model options + example
rtimms e7f9c18
fix options test
rtimms 8d92c18
merge develop
rtimms dbf2018
esoh for msmr mostly working
rtimms 3a7c39f
start cleaning up esoh
rtimms ac821e8
fix eSOH
rtimms 0c61222
improve esoh
rtimms f9a92be
Use .diff to get dx/dU
rtimms 86c4184
esoh tests
rtimms c49e36f
merge develop
rtimms 42c7438
fix diff for broadcasts
rtimms 4c0758d
start msmr notebook
rtimms c94d842
improve coverage
rtimms 75835b5
update esoh
rtimms 0f7c2ab
clean up notebook
rtimms 51702ca
merge develop
rtimms ab61213
add helper function for msmr reactions
rtimms 7b12a61
docs and notebook
rtimms a33c3af
fix initial soc at solve
rtimms d88dfb8
merge develop
rtimms 8396295
update notebook
rtimms 917a53b
fix test
rtimms 9af984d
merge develop
rtimms 8c95a6d
add individual reaction params
rtimms 085543f
fix setting by reaction index
rtimms 899067f
add MSMR model class
rtimms e9148ae
add paramaters by reaction index
rtimms 986d171
debugging current density
rtimms 10bec45
fix exchange current parameters
rtimms e549a4e
fix PSD
rtimms f7f8741
merge develop
rtimms 78d2776
esoh coverage
rtimms 925a04e
merge develop
rtimms fc0d71e
update notebook
rtimms c4953df
merge 'develop' into 'msmr'
rtimms d73a1eb
style: pre-commit fixes
pre-commit-ci[bot] 32b73e5
fix tests
rtimms 54a06e0
merge conflicts
rtimms d8dace3
debug half cell
rtimms 9e513bf
merge develop
rtimms d1cd977
relax option check
rtimms d3d921d
merge develop
rtimms c030b88
ferran msmr comments
rtimms f8a0fbc
update docs
rtimms c330ffa
fix example notebooks
rtimms cb36b35
merge develop
rtimms 77a62c1
update bib in docs
rtimms File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,295 @@ | ||
{ | ||
"cells": [ | ||
{ | ||
"attachments": {}, | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"# Multi-Species Multi-Reaction model" | ||
] | ||
}, | ||
{ | ||
"attachments": {}, | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"## Model Equations" | ||
] | ||
}, | ||
{ | ||
"attachments": {}, | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [] | ||
}, | ||
{ | ||
"attachments": {}, | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"## Example solving MSMR using PyBaMM" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 1, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"#%pip install pybamm -q # install PyBaMM if it is not installed\n", | ||
"import pybamm\n", | ||
"import numpy as np" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 2, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"model = pybamm.lithium_ion.SPM(\n", | ||
" {\n", | ||
" \"open-circuit potential\": \"MSMR\",\n", | ||
" \"particle\": \"MSMR\",\n", | ||
" }\n", | ||
")\n", | ||
"\n", | ||
"parameter_values = pybamm.ParameterValues(\"MSMR_Example\")" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 3, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"# x_n\n", | ||
"U_n = model.variables[\"Negative electrode open-circuit potential [V]\"]\n", | ||
"T = model.variables[\"Negative electrode temperature [K]\"]\n", | ||
"f = pybamm.constants.F / (pybamm.constants.R * T)\n", | ||
"for i in range(6):\n", | ||
" U0 = pybamm.Parameter(f\"U0_n_{i}\")\n", | ||
" w = pybamm.Parameter(f\"w_n_{i}\")\n", | ||
" Xj = pybamm.Parameter(f\"Xj_n_{i}\")\n", | ||
"\n", | ||
" x_n = Xj / (1 + pybamm.exp(f * (U_n - U0) / w))\n", | ||
" model.variables[f\"x{i}_n\"] = x_n\n", | ||
" model.variables[f\"X-averaged x{i}_n\"] = pybamm.x_average(x_n)\n", | ||
" \n", | ||
"\n", | ||
"# x_p\n", | ||
"U_p = model.variables[\"Positive electrode open-circuit potential [V]\"]\n", | ||
"T = model.variables[\"Positive electrode temperature [K]\"]\n", | ||
"f = pybamm.constants.F / (pybamm.constants.R * T)\n", | ||
"for i in range(4):\n", | ||
" U0 = pybamm.Parameter(f\"U0_p_{i}\")\n", | ||
" w = pybamm.Parameter(f\"w_p_{i}\")\n", | ||
" Xj = pybamm.Parameter(f\"Xj_p_{i}\")\n", | ||
"\n", | ||
" x_p = Xj / (1 + pybamm.exp(f * (U_p - U0) / w))\n", | ||
" model.variables[f\"x{i}_p\"] = x_p\n", | ||
" model.variables[f\"X-averaged x{i}_p\"] = pybamm.x_average(x_p)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 4, | ||
"metadata": {}, | ||
"outputs": [ | ||
{ | ||
"data": { | ||
"text/plain": [ | ||
"<pybamm.solvers.solution.Solution at 0x14be066a0>" | ||
] | ||
}, | ||
"execution_count": 4, | ||
"metadata": {}, | ||
"output_type": "execute_result" | ||
} | ||
], | ||
"source": [ | ||
"experiment = pybamm.Experiment(\n", | ||
" [\n", | ||
" (\n", | ||
" \"Discharge at 1C for 1 hour or until 3 V\",\n", | ||
" \"Rest for 1 hour\",\n", | ||
" \"Charge at C/3 until 4 V\",\n", | ||
" \"Hold at 4 V until 10 mA\",\n", | ||
" \"Rest for 1 hour\",\n", | ||
" ),\n", | ||
" ]\n", | ||
")\n", | ||
"sim = pybamm.Simulation(model, parameter_values=parameter_values, experiment=experiment)\n", | ||
"sim.solve()" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 5, | ||
"metadata": {}, | ||
"outputs": [ | ||
{ | ||
"data": { | ||
"application/vnd.jupyter.widget-view+json": { | ||
"model_id": "a2be754ae444465a9b5c413582e703f1", | ||
"version_major": 2, | ||
"version_minor": 0 | ||
}, | ||
"text/plain": [ | ||
"interactive(children=(FloatSlider(value=0.0, description='t', max=5.86646556905814, step=0.0586646556905814), …" | ||
] | ||
}, | ||
"metadata": {}, | ||
"output_type": "display_data" | ||
}, | ||
{ | ||
"data": { | ||
"text/plain": [ | ||
"<pybamm.plotting.quick_plot.QuickPlot at 0x14fb3bcd0>" | ||
] | ||
}, | ||
"execution_count": 5, | ||
"metadata": {}, | ||
"output_type": "execute_result" | ||
} | ||
], | ||
"source": [ | ||
"sim.plot(\n", | ||
" [\n", | ||
" \"X-averaged negative particle stoichiometry\",\n", | ||
" \"X-averaged positive particle stoichiometry\",\n", | ||
" \"X-averaged negative particle potential [V]\",\n", | ||
" \"X-averaged positive particle potential [V]\",\n", | ||
" [f\"X-averaged x{i}_n\" for i in range(6)],\n", | ||
" [f\"X-averaged x{i}_p\" for i in range(4)],\n", | ||
" \"X-averaged negative electrode open-circuit potential [V]\",\n", | ||
" \"X-averaged positive electrode open-circuit potential [V]\",\n", | ||
" \"Current [A]\",\n", | ||
" \"Voltage [V]\",\n", | ||
" ]\n", | ||
")" | ||
] | ||
}, | ||
{ | ||
"attachments": {}, | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"## Comparison with ideal diffusion and \"standard\" OCV model" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 162, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"def U_n(sto):\n", | ||
" u_eq = (\n", | ||
" 0.3635 * pybamm.exp(-439.3 * sto)\n", | ||
" + 0.6908\n", | ||
" + 0.5489 * pybamm.tanh(-30.07 * sto)\n", | ||
" - 0.0344 * pybamm.tanh(25.46 * (sto - 0.1713))\n", | ||
" - 0.0276 * pybamm.tanh(14.27 * (sto - 0.5270))\n", | ||
"\n", | ||
" )\n", | ||
" return u_eq\n", | ||
"\n", | ||
"def U_p(sto):\n", | ||
" u_eq = (\n", | ||
" -0.3415 * sto\n", | ||
" + 4.116\n", | ||
" - 0.2835 * pybamm.tanh(4.181 * (sto - 0.2324))\n", | ||
" - 0.1020 * pybamm.tanh(29.61 * (sto - 1))\n", | ||
" )\n", | ||
" return u_eq" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"parameter_values_2 = parameter_values.copy()\n", | ||
"parameter_values_2.update({\n", | ||
" \"Negative electrode OCP [V]\": U_n,\n", | ||
" \"Positive electrode OCP [V]\": U_p,\n", | ||
"})" | ||
] | ||
}, | ||
{ | ||
"attachments": {}, | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"## References\n", | ||
"\n", | ||
"The relevant papers for this notebook are:" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 12, | ||
"metadata": {}, | ||
"outputs": [ | ||
{ | ||
"name": "stdout", | ||
"output_type": "stream", | ||
"text": [ | ||
"[1] Joel A. E. Andersson, Joris Gillis, Greg Horn, James B. Rawlings, and Moritz Diehl. CasADi – A software framework for nonlinear optimization and optimal control. Mathematical Programming Computation, 11(1):1–36, 2019. doi:10.1007/s12532-018-0139-4.\n", | ||
"[2] Daniel R Baker and Mark W Verbrugge. Multi-species, multi-reaction model for porous intercalation electrodes: part i. model formulation and a perturbation solution for low-scan-rate, linear-sweep voltammetry of a spinel lithium manganese oxide electrode. Journal of The Electrochemical Society, 165(16):A3952, 2018.\n", | ||
"[3] Charles R. Harris, K. Jarrod Millman, Stéfan J. van der Walt, Ralf Gommers, Pauli Virtanen, David Cournapeau, Eric Wieser, Julian Taylor, Sebastian Berg, Nathaniel J. Smith, and others. Array programming with NumPy. Nature, 585(7825):357–362, 2020. doi:10.1038/s41586-020-2649-2.\n", | ||
"[4] Scott G. Marquis, Valentin Sulzer, Robert Timms, Colin P. Please, and S. Jon Chapman. An asymptotic derivation of a single particle model with electrolyte. Journal of The Electrochemical Society, 166(15):A3693–A3706, 2019. doi:10.1149/2.0341915jes.\n", | ||
"[5] Peyman Mohtat, Suhak Lee, Jason B Siegel, and Anna G Stefanopoulou. Towards better estimability of electrode-specific state of health: decoding the cell expansion. Journal of Power Sources, 427:101–111, 2019.\n", | ||
"[6] Valentin Sulzer, Scott G. Marquis, Robert Timms, Martin Robinson, and S. Jon Chapman. Python Battery Mathematical Modelling (PyBaMM). Journal of Open Research Software, 9(1):14, 2021. doi:10.5334/jors.309.\n", | ||
"[7] Pauli Virtanen, Ralf Gommers, Travis E. Oliphant, Matt Haberland, Tyler Reddy, David Cournapeau, Evgeni Burovski, Pearu Peterson, Warren Weckesser, Jonathan Bright, and others. SciPy 1.0: fundamental algorithms for scientific computing in Python. Nature Methods, 17(3):261–272, 2020. doi:10.1038/s41592-019-0686-2.\n", | ||
"[8] Andrew Weng, Jason B Siegel, and Anna Stefanopoulou. Differential voltage analysis for battery manufacturing process control. arXiv preprint arXiv:2303.07088, 2023.\n", | ||
"\n" | ||
] | ||
} | ||
], | ||
"source": [ | ||
"pybamm.print_citations()" | ||
] | ||
} | ||
], | ||
"metadata": { | ||
"kernelspec": { | ||
"display_name": "dev", | ||
"language": "python", | ||
"name": "python3" | ||
}, | ||
"language_info": { | ||
"codemirror_mode": { | ||
"name": "ipython", | ||
"version": 3 | ||
}, | ||
"file_extension": ".py", | ||
"mimetype": "text/x-python", | ||
"name": "python", | ||
"nbconvert_exporter": "python", | ||
"pygments_lexer": "ipython3", | ||
"version": "3.9.16" | ||
}, | ||
"vscode": { | ||
"interpreter": { | ||
"hash": "bca2b99bfac80e18288b793d52fa0653ab9b5fe5d22e7b211c44eb982a41c00c" | ||
} | ||
} | ||
}, | ||
"nbformat": 4, | ||
"nbformat_minor": 2 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import pybamm | ||
|
||
pybamm.set_logging_level("DEBUG") | ||
model = pybamm.lithium_ion.SPM( | ||
{ | ||
"open-circuit potential": "MSMR", | ||
"particle": "MSMR", | ||
} | ||
) | ||
|
||
|
||
parameter_values = pybamm.ParameterValues("MSMR_Example") | ||
experiment = pybamm.Experiment( | ||
[ | ||
( | ||
"Discharge at 1C for 1 hour or until 3 V", | ||
"Rest for 1 hour", | ||
"Charge at C/3 until 4 V", | ||
"Hold at 4 V until 10 mA", | ||
"Rest for 1 hour", | ||
), | ||
] | ||
) | ||
sim = pybamm.Simulation(model, parameter_values=parameter_values, experiment=experiment) | ||
sim.solve() | ||
sim.plot() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -45,6 +45,27 @@ def _sympy_operator(self, child): | |
"""Override :meth:`pybamm.UnaryOperator._sympy_operator`""" | ||
return child | ||
|
||
def diff(self, variable): | ||
""" | ||
Override :meth:`pybamm.SpatialOperator.diff()` to reinstate behaviour of | ||
:meth:`pybamm.Symbol.diff()`. | ||
""" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. probably cleaner to just get rid of the NotImplementedError for spatial operators |
||
if variable == self: | ||
return pybamm.Scalar(1) | ||
elif any(variable == x for x in self.pre_order()): | ||
return self._diff(variable) | ||
elif variable == pybamm.t and self.has_symbol_of_classes( | ||
(pybamm.VariableBase, pybamm.StateVectorBase) | ||
): | ||
return self._diff(variable) | ||
else: | ||
return pybamm.Scalar(0) | ||
|
||
def _diff(self, variable): | ||
"""See :meth:`pybamm.Symbol._diff()`.""" | ||
# Differentiate the child and broadcast the result in the same way | ||
return self._unary_new_copy(self.child.diff(variable)) | ||
|
||
|
||
class PrimaryBroadcast(Broadcast): | ||
""" | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Picky comment, can you delete the empty cells at the end of the notebook?