-
-
Notifications
You must be signed in to change notification settings - Fork 563
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
SEI on cracks #2104
SEI on cracks #2104
Conversation
I thought I'd provide more context as to why this is still a draft. If I do the following: parameter_values = pybamm.ParameterValues("Ai2020") I get back a KeyError on line 231 of base_sei.py saying variables["Negative electrode roughness ratio"] is undefined. Presumably this is because this variable comes from a different submodel and was therefore not passed to the variables dictionary, but I have no idea how to fix this! |
This reverts commit 5b321a7.
Update: I have now got the SEI on cracks model to work for the Ai2020 parameter set. I'm now trying to add the degradation parameter set I used for my paper but the crack model fails immediately (t=0) for those parameters, even if there is no SEi on the cracks. This happens for either electrode, so the issue must be with one of the parameters common to both. |
I don't think this closes #1807 ? |
Sorry about the diff coverage. I'm getting an error when I try to test graphite_volume_change_Ai2020.py, so I commented that line out in the test and just dealt with everything else. Project coverage should be increased overall. |
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.
Looks great, some minor comments, including places where you are running up against the horrible mess of different parameter names for the same SEI parameter
T_ref = Parameter("Reference temperature [K]") | ||
Eac_cr = Parameter( | ||
"Negative electrode activation energy for cracking rate [J.mol-1]" | ||
) | ||
arrhenius = exp(Eac_cr / constants.R * (1 / T_dim - 1 / T_ref)) |
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.
Please specify the activation energy and reference temperature here. The data is measured for a specific reference temperature and activation energy, so I don't think it makes sense to define them as separate parameters.
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.
Fixed
T_ref = Parameter("Reference temperature [K]") | ||
Eac_cr = Parameter( | ||
"Positive electrode activation energy for cracking rate [J.mol-1]" | ||
) |
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.
as above
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.
Fixed
# Do not set "sei on cracks" submodel for half-cells | ||
if reaction_loc == "interface": | ||
if self.options["SEI"] == "none": | ||
self.submodels["sei"] = pybamm.sei.NoSEI(self.param, self.options) | ||
elif self.options["SEI"] == "constant": | ||
self.submodels["sei"] = pybamm.sei.ConstantSEI(self.param, self.options) | ||
else: | ||
self.submodels["sei"] = pybamm.sei.SEIGrowth( | ||
self.param, reaction_loc, self.options, cracks=False | ||
) | ||
# For full cells, "sei on cracks" submodel must be set, even if it is zero | ||
else: | ||
self.submodels["sei"] = pybamm.sei.SEIGrowth( | ||
self.param, reaction_loc, self.options | ||
) | ||
if self.options["SEI"] == "none": | ||
self.submodels["sei"] = pybamm.sei.NoSEI(self.param, self.options) | ||
self.submodels["sei on cracks"] = pybamm.sei.NoSEI( | ||
self.param, self.options, cracks=True | ||
) | ||
elif self.options["SEI"] == "constant": | ||
self.submodels["sei"] = pybamm.sei.ConstantSEI(self.param, self.options) | ||
self.submodels["sei on cracks"] = pybamm.sei.NoSEI( | ||
self.param, self.options, cracks=True | ||
) | ||
else: | ||
self.submodels["sei"] = pybamm.sei.SEIGrowth( | ||
self.param, reaction_loc, self.options, cracks=False | ||
) | ||
if self.options["SEI on cracks"] == "true": | ||
self.submodels["sei on cracks"] = pybamm.sei.SEIGrowth( | ||
self.param, reaction_loc, self.options, cracks=True | ||
) | ||
else: | ||
self.submodels["sei on cracks"] = pybamm.sei.NoSEI( | ||
self.param, self.options, cracks=True | ||
) |
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.
I think this does the same thing in fewer lines
if self.options["SEI"] == "none":
self.submodels["sei"] = pybamm.sei.NoSEI(self.param, self.options)
elif self.options["SEI"] == "constant":
self.submodels["sei"] = pybamm.sei.ConstantSEI(self.param, self.options)
else:
self.submodels["sei"] = pybamm.sei.SEIGrowth(
self.param, reaction_loc, self.options, cracks=False
)
# Do not set "sei on cracks" submodel for half-cells
# For full cells, "sei on cracks" submodel must be set, even if it is zero
if reaction_loc != "interface":
if self.options["SEI"] in ["none", "constant"] or self.options["SEI on cracks"] == "false":
self.submodels["sei on cracks"] = pybamm.sei.NoSEI(
self.param, self.options, cracks=True
)
else:
self.submodels["sei on cracks"] = pybamm.sei.SEIGrowth(
self.param, reaction_loc, self.options, cracks=True
)
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.
Fixed
if self.options["SEI"] == "ec reaction limited": | ||
self.initial_conditions = {L_outer: L_inner_0 + L_outer_0} | ||
if self.reaction == "SEI on cracks": | ||
self.initial_conditions = {L_outer: (L_inner_0 + L_outer_0) / 10000} |
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.
why hard-coded to 10000
?
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.
That is what was done in the paper. We had to choose an initial condition that was as close to zero to get the physics right, but didn't cause a division by zero error.
# All SEI growth mechanisms assumed to have Arrhenius dependence | ||
Arrhenius = pybamm.exp(param.E_over_RT_sei * (1 - prefactor)) | ||
|
||
j_inner = alpha * j_sei | ||
j_outer = (1 - alpha) * j_sei | ||
j_inner = alpha * Arrhenius * j_sei | ||
j_outer = (1 - alpha) * Arrhenius * j_sei |
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.
I understand why you've done it this way, but we should reformat the SEI parameters so that the parameter is j_sei(c, T)
to be consistent with intercalation kinetics and plating. The SEI parameters are a mess anyway.
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.
This is a good idea but probably beyond the scope of this PR, which is to allow others to reproduce the results of the O'Kane 2022 paper.
|
||
def graphite_cracking_rate_Ai2020(T_dim): | ||
""" | ||
graphite particle cracking rate as a function of temperature [1, 2]. |
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.
graphite particle cracking rate as a function of temperature [1, 2]. | |
Graphite particle cracking rate as a function of temperature [1, 2]. |
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.
Fixed
domain="negative electrode", | ||
auxiliary_domains={"secondary": "current collector"}, | ||
) | ||
else: |
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.
Does this case include standard SEI only, or a bunch of different cases? If it is standard SEI, would it be better to do an elif
and then keep the else
to throw an error if the argument is weird?
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.
What error should I throw?
@@ -29,6 +29,24 @@ Negative electrode specific heat capacity [J.kg-1.K-1],700,default, | |||
Negative electrode thermal conductivity [W.m-1.K-1],1.7,default, |
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.
Are all these parameters presented in O'Kane 2022? If so, should we rename this set to O'Kane 2022 rather than Chen 2020 plating? We can still keep the ref to Chen 2020 in pybamm.citations()
but I think the new name would make it clearer to the reader which is the main reference.
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.
I've gone further and deleted the entire Chen2020_plating chemistry. It was only there in the first place because none of the existing chemistries worked with the plating submodel. Now that OKane2022 exists, it's not needed anymore. OKane2020_Li_plating is still there as that is a published set of plating parameters, but none of the pre-defined chemistries use it.
|
||
class NoMechanics(BaseMechanics): | ||
""" | ||
Class for swelling only (no cracking) |
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.
Is this right?
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.
Fixed
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.
Looks good to me! Will let @brosaplanella double-check
where m_cr is another Paris' law constant | ||
""" | ||
k_cr = 3.9e-20 | ||
Eac_cr = Parameter( |
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.
this should be hard-coded too
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.
Fixed (currently 0, sorry to disappoint!)
where m_cr is another Paris' law constant | ||
""" | ||
k_cr = 3.9e-20 | ||
Eac_cr = Parameter( |
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.
should be hard-coded
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.
Fixed (currently 0, sorry to disappoint!)
Negative electrode Paris' law constant b,1.12,, | ||
Negative electrode Paris' law constant m,2.2,, | ||
Negative electrode cracking rate,[function]graphite_cracking_rate_Ai2020,Ai2020, | ||
Negative electrode activation energy for cracking rate [J.mol-1],0,, |
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.
these can be removed
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.
Done
Positive electrode Paris' law constant b,1.12,, | ||
Positive electrode Paris' law constant m,2.2,, | ||
Positive electrode cracking rate,[function]cracking_rate_Ai2020,Ai2020, | ||
Positive electrode activation energy for cracking rate [J.mol-1],0,, |
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.
can be removed
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.
Done
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.
Looks good to me!
You just lost to Ferran in the merge race 😢 just fix the changelog conflict and should be good to go |
Description
Adds a new option "SEI on cracks". If set to "true", whichever SEI model is specified by the "SEI" option is run twice; once on the electrode particle surface, and then a second time on the additional surface created by the particle cracking created by the "particle mechanics": "swelling and cracking" option.
Breaking change: "Loss of lithium to SEI on cracks [mol]" is now a summary variable, so a "particle mechanics" submodel must be set, even if it's "none". The examples have been updated to account for this.
Fixes #1695 (in full), #1807 (in part), #2039 (in full)
Type of change
Key checklist:
$ flake8
$ python run-tests.py --unit
$ cd docs
and then$ make clean; make html
You can run all three at once, using
$ python run-tests.py --quick
.Further checks: