Skip to content
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

Merged
merged 42 commits into from
Jul 27, 2022
Merged

SEI on cracks #2104

merged 42 commits into from
Jul 27, 2022

Conversation

DrSOKane
Copy link
Contributor

@DrSOKane DrSOKane commented Jun 15, 2022

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

  • New feature (non-breaking change which adds functionality)
  • Optimization (back-end change that speeds up the code)
  • Bug fix (non-breaking change which fixes an issue)

Key checklist:

  • No style issues: $ flake8
  • All tests pass: $ python run-tests.py --unit
  • The documentation builds: $ cd docs and then $ make clean; make html

You can run all three at once, using $ python run-tests.py --quick.

Further checks:

  • Code is commented, particularly in hard-to-understand areas
  • Tests added that prove fix is effective or that feature works

@DrSOKane
Copy link
Contributor Author

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")
spm = pybamm.lithium_ion.SPM({
"particle mechanics": "swelling and cracking",
"SEI": "solvent-diffusion limited",
"SEI on cracks": "true",
})

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!

@DrSOKane
Copy link
Contributor Author

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.

@valentinsulzer
Copy link
Member

I don't think this closes #1807 ?

@DrSOKane
Copy link
Contributor Author

I don't think this closes #1807 ?

#1807 is a wide-ranging issue that will take many PRs to close completely. SEI growth on cracks was mentioned, but not O'Kane et al. 2022.

@codecov
Copy link

codecov bot commented Jul 19, 2022

Codecov Report

Merging #2104 (5276a9b) into develop (a5f8687) will increase coverage by 0.00%.
The diff coverage is 100.00%.

@@            Coverage Diff            @@
##           develop    #2104    +/-   ##
=========================================
  Coverage    99.35%   99.36%            
=========================================
  Files          347      355     +8     
  Lines        19310    19451   +141     
=========================================
+ Hits         19186    19327   +141     
  Misses         124      124            
Impacted Files Coverage Δ
...ls/LGM50_ORegan2022/aluminium_heat_capacity_CRC.py 100.00% <ø> (ø)
...cells/LGM50_ORegan2022/copper_heat_capacity_CRC.py 100.00% <ø> (ø)
...GM50_ORegan2022/copper_thermal_conductivity_CRC.py 100.00% <ø> (ø)
...e_OKane2022/graphite_LGM50_diffusivity_Chen2020.py 100.00% <ø> (ø)
...0_electrolyte_exchange_current_density_Chen2020.py 100.00% <ø> (ø)
.../graphite_OKane2022/graphite_LGM50_ocp_Chen2020.py 100.00% <ø> (ø)
...graphite_ORegan2022/graphite_LGM50_ocp_Chen2020.py 100.00% <ø> (ø)
...lectrodes/nmc_ORegan2022/nmc_LGM50_ocp_Chen2020.py 100.00% <ø> (ø)
...amm/models/full_battery_models/lithium_ion/spme.py 100.00% <ø> (ø)
...raphite_OKane2022/graphite_cracking_rate_Ai2020.py 100.00% <100.00%> (ø)
... and 31 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 468b39f...5276a9b. Read the comment docs.

@DrSOKane DrSOKane marked this pull request as ready for review July 21, 2022 15:10
@DrSOKane
Copy link
Contributor Author

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.

Copy link
Member

@valentinsulzer valentinsulzer left a 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

Comment on lines 30 to 34
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))
Copy link
Member

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

Comment on lines 30 to 33
T_ref = Parameter("Reference temperature [K]")
Eac_cr = Parameter(
"Positive electrode activation energy for cracking rate [J.mol-1]"
)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as above

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

Comment on lines 239 to 272
# 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
)
Copy link
Member

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
                )

Copy link
Contributor Author

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}
Copy link
Member

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?

Copy link
Contributor Author

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.

Comment on lines +178 to +182
# 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
Copy link
Member

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.

Copy link
Contributor Author

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.

CHANGELOG.md Show resolved Hide resolved

def graphite_cracking_rate_Ai2020(T_dim):
"""
graphite particle cracking rate as a function of temperature [1, 2].
Copy link
Sponsor Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
graphite particle cracking rate as a function of temperature [1, 2].
Graphite particle cracking rate as a function of temperature [1, 2].

Copy link
Contributor Author

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:
Copy link
Sponsor Member

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?

Copy link
Contributor Author

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,
Copy link
Sponsor Member

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.

Copy link
Contributor Author

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.

pybamm/parameters/lithium_ion_parameters.py Show resolved Hide resolved

class NoMechanics(BaseMechanics):
"""
Class for swelling only (no cracking)
Copy link
Sponsor Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

Copy link
Member

@valentinsulzer valentinsulzer left a 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(
Copy link
Member

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

Copy link
Contributor Author

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(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be hard-coded

Copy link
Contributor Author

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,,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these can be removed

Copy link
Contributor Author

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,,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can be removed

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Copy link
Sponsor Member

@brosaplanella brosaplanella left a 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!

@valentinsulzer
Copy link
Member

You just lost to Ferran in the merge race 😢 just fix the changelog conflict and should be good to go

@valentinsulzer valentinsulzer merged commit 58194b0 into pybamm-team:develop Jul 27, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Temperature dependence in SEI models
3 participants