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

Create battery benchmark methods #644

Draft
wants to merge 51 commits into
base: non-uniform-mean
Choose a base branch
from
Draft
Changes from 1 commit
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
2bf16b1
Create ocp_average
NicolaCourtier Jan 28, 2025
ed42681
Update init
NicolaCourtier Jan 28, 2025
6a24894
Add stoichiometric_fit
NicolaCourtier Jan 28, 2025
4e7345f
style: pre-commit fixes
pre-commit-ci[bot] Jan 28, 2025
2cd6d0e
Create test_applications.py
NicolaCourtier Jan 28, 2025
cb1aad0
style: pre-commit fixes
pre-commit-ci[bot] Jan 28, 2025
d64e00b
Rename gitt to gitt_pulse
NicolaCourtier Jan 28, 2025
ff48099
Merge branch 'develop' into 124-battery-benchmarks
NicolaCourtier Jan 28, 2025
83625ce
Add ocp_blend
NicolaCourtier Jan 29, 2025
b8d77b9
Update Weppner & Huggins model
NicolaCourtier Jan 30, 2025
3b8b584
Align model names
NicolaCourtier Jan 30, 2025
82372c1
Create SPDiffusion model
NicolaCourtier Jan 30, 2025
d3a89dd
style: pre-commit fixes
pre-commit-ci[bot] Jan 30, 2025
8f522c4
Update examples
NicolaCourtier Jan 30, 2025
72005d3
Add SPDiffusion to model tests
NicolaCourtier Jan 30, 2025
d5f69dc
Update documentation
NicolaCourtier Jan 30, 2025
0914fb0
Add gitt_methods
NicolaCourtier Jan 30, 2025
fe3f56d
style: pre-commit fixes
pre-commit-ci[bot] Jan 30, 2025
c8fe87e
Update ocp_average
NicolaCourtier Jan 30, 2025
bb85e1a
Add base and rename classes
NicolaCourtier Jan 30, 2025
fd2b3f3
Create GITTFit with example
NicolaCourtier Jan 30, 2025
ed73b27
style: pre-commit fixes
pre-commit-ci[bot] Jan 30, 2025
caf028b
Update stoichiometry_fitting.py
NicolaCourtier Jan 30, 2025
237eb24
Add titles
NicolaCourtier Jan 31, 2025
4cb16e5
Add test_gitt_pulse_fit
NicolaCourtier Jan 31, 2025
67d74d4
Merge branch 'develop' into 124-battery-benchmarks
NicolaCourtier Feb 2, 2025
d656cee
Rename StoichiometricFit
NicolaCourtier Feb 2, 2025
d21c6c7
Align simulation options
NicolaCourtier Feb 3, 2025
603ed9e
Fix examples
NicolaCourtier Feb 3, 2025
83faefe
Try updating IDAKLU rtol
NicolaCourtier Feb 3, 2025
5b8d899
Update geometry and copying
NicolaCourtier Feb 4, 2025
c609523
Merge branch 'align_simulation_options' into 124-battery-benchmarks
NicolaCourtier Feb 4, 2025
481da21
Remove superseded example
NicolaCourtier Feb 4, 2025
aee86dd
Merge branch 'develop' into 124-battery-benchmarks
NicolaCourtier Feb 4, 2025
520bf55
Merge branch 'non-uniform-mean' into 124-battery-benchmarks
NicolaCourtier Feb 14, 2025
5c9df9f
Add Interpolant and InverseOCV
NicolaCourtier Feb 14, 2025
20dedbd
Merge branch '124-battery-benchmarks' of https://github.com/pybop-tea…
NicolaCourtier Feb 14, 2025
896a4b4
Merge branch 'non-uniform-mean' into 124-battery-benchmarks
NicolaCourtier Feb 14, 2025
fb22483
Merge branch 'non-uniform-mean' into 124-battery-benchmarks
NicolaCourtier Feb 18, 2025
c791644
Update OCP methods
NicolaCourtier Feb 18, 2025
f345bc4
Update GITT methods
NicolaCourtier Feb 18, 2025
ca017bf
Fix gitt_fitting and add current check
NicolaCourtier Feb 18, 2025
56bc36d
Add tests on custom models
NicolaCourtier Feb 18, 2025
d5b0750
Add test_gitt_fit
NicolaCourtier Feb 18, 2025
4989a74
Remove working electrode option
NicolaCourtier Feb 18, 2025
5617526
Enable variable tau_d and R0
NicolaCourtier Feb 20, 2025
d97134e
Update gitt parameters and store costs
NicolaCourtier Feb 20, 2025
f82b99b
Add SPDiffusion electrode option
NicolaCourtier Feb 22, 2025
76defa5
Add electrode input
NicolaCourtier Feb 23, 2025
e9d07f2
Merge branch 'non-uniform-mean' into 124-battery-benchmarks
NicolaCourtier Feb 24, 2025
1a15df9
Update Interpolant
NicolaCourtier Feb 24, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add test_gitt_pulse_fit
NicolaCourtier committed Jan 31, 2025

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
commit 4cb16e5bca82b797c2462dce8b1fd45e9e12b8fe
2 changes: 1 addition & 1 deletion pybop/applications/gitt_methods.py
Original file line number Diff line number Diff line change
@@ -47,7 +47,7 @@
)

# Define the cost to optimise
self.parameter_set = parameter_set
self.parameter_set = parameter_set.copy()
self.model = pybop.lithium_ion.SPDiffusion(
parameter_set=self.parameter_set, build=True
)
@@ -92,14 +92,14 @@
verbose: bool = False,
):
# Preallocate outputs
self.pulses = []
stoichiometry = []
diffusion_time = []
series_resistance = []

Check warning on line 98 in pybop/applications/gitt_methods.py

Codecov / codecov/patch

pybop/applications/gitt_methods.py#L95-L98

Added lines #L95 - L98 were not covered by tests

for pulse_index in gitt_pulse_index:

Check warning on line 100 in pybop/applications/gitt_methods.py

Codecov / codecov/patch

pybop/applications/gitt_methods.py#L100

Added line #L100 was not covered by tests
# Estimate the parameters for this pulse
self.pulses.append(

Check warning on line 102 in pybop/applications/gitt_methods.py

Codecov / codecov/patch

pybop/applications/gitt_methods.py#L102

Added line #L102 was not covered by tests
pybop.GITTPulseFit(
gitt_pulse=gitt_dataset.get_subset(pulse_index),
parameter_set=parameter_set,
@@ -110,16 +110,16 @@
)

# Log and update the parameter estimates for the next iteration
parameter_set.update(

Check warning on line 113 in pybop/applications/gitt_methods.py

Codecov / codecov/patch

pybop/applications/gitt_methods.py#L113

Added line #L113 was not covered by tests
{
"Particle diffusion time scale [s]": self.pulses[-1].results.x[0],
"Series resistance [Ohm]": self.pulses[-1].results.x[1],
}
)
diffusion_time.append(parameter_set["Particle diffusion time scale [s]"])
series_resistance.append(parameter_set["Series resistance [Ohm]"])
stoichiometry.append(parameter_set["Initial stoichiometry"])
parameter_set.update(

Check warning on line 122 in pybop/applications/gitt_methods.py

Codecov / codecov/patch

pybop/applications/gitt_methods.py#L119-L122

Added lines #L119 - L122 were not covered by tests
{
"Initial stoichiometry": stoichiometry[-1]
+ (
@@ -130,7 +130,7 @@
}
)

self.parameter_data = pybop.Dataset(

Check warning on line 133 in pybop/applications/gitt_methods.py

Codecov / codecov/patch

pybop/applications/gitt_methods.py#L133

Added line #L133 was not covered by tests
{
"Stoichiometry": np.asarray(stoichiometry),
"Particle diffusion time scale [s]": np.asarray(diffusion_time),
46 changes: 46 additions & 0 deletions tests/integration/test_applications.py
Original file line number Diff line number Diff line change
@@ -2,6 +2,9 @@
import pytest

import pybop
from pybop.models.lithium_ion.basic_SP_diffusion import (
convert_physical_to_electrode_parameters,
)


class TestApplications:
@@ -96,3 +99,46 @@ def test_stoichiometry_fit(self, parameter_set):
np.testing.assert_allclose(
ocv_fit.shift, 0.1 * nom_capacity, rtol=5e-3, atol=5e-3
)

@pytest.fixture
def half_cell_model(self):
parameter_set = pybop.ParameterSet("Xu2019")
return pybop.lithium_ion.SPMe(
parameter_set=parameter_set, options={"working electrode": "positive"}
)

@pytest.fixture
def pulse_data(self, half_cell_model):
sigma = 1e-3
initial_state = {"Initial SoC": 0.9}
experiment = pybop.Experiment(
[
"Rest for 1 second",
"Discharge at 1C for 10 minutes (10 second period)",
"Rest for 20 minutes",
]
)
values = half_cell_model.predict(
initial_state=initial_state, experiment=experiment
)
corrupt_values = values["Voltage [V]"].data + np.random.normal(
0, sigma, len(values["Voltage [V]"].data)
)
return pybop.Dataset(
{
"Time [s]": values["Time [s]"].data,
"Current function [A]": values["Current [A]"].data,
"Discharge capacity [A.h]": values["Discharge capacity [A.h]"].data,
"Voltage [V]": corrupt_values,
}
)

def test_gitt_pulse_fit(self, half_cell_model, pulse_data):
parameter_set = convert_physical_to_electrode_parameters(
half_cell_model.parameter_set, "positive"
)
diffusion_time = parameter_set["Particle diffusion time scale [s]"]

gitt_fit = pybop.GITTPulseFit(pulse_data, parameter_set)

np.testing.assert_allclose(gitt_fit.results.x[0], diffusion_time, rtol=5e-2)

Unchanged files with check annotations Beta

unused_keys = []
for key in model_kwargs.keys():
if key not in ["build", "parameter_set", "options"]:
unused_keys.append(key)

Check warning on line 57 in pybop/models/lithium_ion/basic_SP_diffusion.py

Codecov / codecov/patch

pybop/models/lithium_ion/basic_SP_diffusion.py#L57

Added line #L57 was not covered by tests
if model_kwargs.get("build", True) is False:
unused_keys.append("build")
options = {"working electrode": "positive"}
if model_kwargs.get("options", None) is not None:
for key, value in model_kwargs["options"].items():
if key in ["working electrode"]:
options[key] = value

Check warning on line 64 in pybop/models/lithium_ion/basic_SP_diffusion.py

Codecov / codecov/patch

pybop/models/lithium_ion/basic_SP_diffusion.py#L62-L64

Added lines #L62 - L64 were not covered by tests
else:
unused_keys.append("options[" + key + "]")

Check warning on line 66 in pybop/models/lithium_ion/basic_SP_diffusion.py

Codecov / codecov/patch

pybop/models/lithium_ion/basic_SP_diffusion.py#L66

Added line #L66 was not covered by tests
if any(unused_keys):
unused_kwargs_warning = f"The input model_kwargs {unused_keys} are not currently used by the SP Diffusion Model."
warnings.warn(unused_kwargs_warning, UserWarning, stacklevel=2)
# Unpack model options
electrode = self.options["working electrode"]
if electrode not in ["positive", "negative"]:
raise ValueError(

Check warning on line 76 in pybop/models/lithium_ion/basic_SP_diffusion.py

Codecov / codecov/patch

pybop/models/lithium_ion/basic_SP_diffusion.py#L76

Added line #L76 was not covered by tests
f"Unrecognised electrode type: {electrode}, "
'expecting either "positive" or "negative".'
)
if electrode == "positive":
j = -I / (3 * Q_th)
else:
j = I / (3 * Q_th)

Check warning on line 145 in pybop/models/lithium_ion/basic_SP_diffusion.py

Codecov / codecov/patch

pybop/models/lithium_ion/basic_SP_diffusion.py#L145

Added line #L145 was not covered by tests
self.boundary_conditions[sto] = {
"left": (Scalar(0), "Neumann"),
if electrode == "positive":
U = self.U(sto_surf, electrode)
else:
U = -self.U(sto_surf, electrode)

Check warning on line 160 in pybop/models/lithium_ion/basic_SP_diffusion.py

Codecov / codecov/patch

pybop/models/lithium_ion/basic_SP_diffusion.py#L160

Added line #L160 was not covered by tests
V = U - R0 * I
# Save the initial OCV
out = u_ref + 1e-6 * (1 / sto + 1 / (sto - 1))
if domain == "negative":
out.print_name = r"U_\mathrm{n}(c^\mathrm{surf}_\mathrm{s,n})"

Check warning on line 202 in pybop/models/lithium_ion/basic_SP_diffusion.py

Codecov / codecov/patch

pybop/models/lithium_ion/basic_SP_diffusion.py#L202

Added line #L202 was not covered by tests
elif domain == "positive":
out.print_name = r"U_\mathrm{p}(c^\mathrm{surf}_\mathrm{s,p})"
return out
Build model variables and equations
Credit: PyBaMM
"""
self._build_model()

Check warning on line 212 in pybop/models/lithium_ion/basic_SP_diffusion.py

Codecov / codecov/patch

pybop/models/lithium_ion/basic_SP_diffusion.py#L212

Added line #L212 was not covered by tests
self._built = True
pybamm.logger.info(f"Finish building {self.name}")

Check warning on line 215 in pybop/models/lithium_ion/basic_SP_diffusion.py

Codecov / codecov/patch

pybop/models/lithium_ion/basic_SP_diffusion.py#L214-L215

Added lines #L214 - L215 were not covered by tests
@property
def default_parameter_values(self):
@property
def default_quick_plot_variables(self):
return [

Check warning on line 232 in pybop/models/lithium_ion/basic_SP_diffusion.py

Codecov / codecov/patch

pybop/models/lithium_ion/basic_SP_diffusion.py#L232

Added line #L232 was not covered by tests
"Particle stoichiometry",
"Particle surface stoichiometry",
"Current [A]",
/ c_max
)
ocp = parameter_set["Positive electrode OCP [V]"]
elif electrode == "negative":
alpha = parameter_set["Negative electrode active material volume fraction"]
c_max = parameter_set["Maximum concentration in negative electrode [mol.m-3]"]
L = parameter_set["Negative electrode thickness [m]"]
R = parameter_set["Negative particle radius [m]"]
D = parameter_set["Negative particle diffusivity [m2.s-1]"]
sto_init = (

Check warning on line 296 in pybop/models/lithium_ion/basic_SP_diffusion.py

Codecov / codecov/patch

pybop/models/lithium_ion/basic_SP_diffusion.py#L290-L296

Added lines #L290 - L296 were not covered by tests
parameter_set["Initial concentration in negative electrode [mol.m-3]"]
/ c_max
)
ocp = parameter_set["Negative electrode OCP [V]"]

Check warning on line 300 in pybop/models/lithium_ion/basic_SP_diffusion.py

Codecov / codecov/patch

pybop/models/lithium_ion/basic_SP_diffusion.py#L300

Added line #L300 was not covered by tests
else:
raise ValueError(

Check warning on line 302 in pybop/models/lithium_ion/basic_SP_diffusion.py

Codecov / codecov/patch

pybop/models/lithium_ion/basic_SP_diffusion.py#L302

Added line #L302 was not covered by tests
f"Unrecognised electrode type: {electrode}, "
'expecting either "positive" or "negative".'
)
unused_keys = []
for key in model_kwargs.keys():
if key not in ["build", "parameter_set", "options"]:
unused_keys.append(key)

Check warning on line 33 in pybop/models/lithium_ion/weppner_huggins.py

Codecov / codecov/patch

pybop/models/lithium_ion/weppner_huggins.py#L33

Added line #L33 was not covered by tests
options = {"working electrode": "positive"}
if model_kwargs.get("options", None) is not None:
for key, value in model_kwargs["options"].items():
if key in ["working electrode"]:
options[key] = value

Check warning on line 38 in pybop/models/lithium_ion/weppner_huggins.py

Codecov / codecov/patch

pybop/models/lithium_ion/weppner_huggins.py#L36-L38

Added lines #L36 - L38 were not covered by tests
else:
unused_keys.append("options[" + key + "]")

Check warning on line 40 in pybop/models/lithium_ion/weppner_huggins.py

Codecov / codecov/patch

pybop/models/lithium_ion/weppner_huggins.py#L40

Added line #L40 was not covered by tests
if any(unused_keys):
unused_kwargs_warning = f"The input model_kwargs {unused_keys} are not currently used by the Weppner & Huggins model."

Check warning on line 42 in pybop/models/lithium_ion/weppner_huggins.py

Codecov / codecov/patch

pybop/models/lithium_ion/weppner_huggins.py#L42

Added line #L42 was not covered by tests
warnings.warn(unused_kwargs_warning, UserWarning, stacklevel=2)
super().__init__(options=options, name=name, build=True)
dict
A dictionary of the grouped parameters.
"""
parameter_set = ParameterSet.to_pybamm(parameter_set)

Check warning on line 150 in pybop/models/lithium_ion/weppner_huggins.py

Codecov / codecov/patch

pybop/models/lithium_ion/weppner_huggins.py#L150

Added line #L150 was not covered by tests
# Unpack physical parameters
F = parameter_set["Faraday constant [C.mol-1]"]
if electrode == "positive":
alpha = parameter_set["Positive electrode active material volume fraction"]
c_max = parameter_set["Maximum concentration in positive electrode [mol.m-3]"]
L = parameter_set["Positive electrode thickness [m]"]
R = parameter_set["Positive particle radius [m]"]
D = parameter_set["Positive particle diffusivity [m2.s-1]"]
elif electrode == "negative":
alpha = parameter_set["Negative electrode active material volume fraction"]
c_max = parameter_set["Maximum concentration in negative electrode [mol.m-3]"]
L = parameter_set["Negative electrode thickness [m]"]
R = parameter_set["Negative particle radius [m]"]
D = parameter_set["Negative particle diffusivity [m2.s-1]"]

Check warning on line 165 in pybop/models/lithium_ion/weppner_huggins.py

Codecov / codecov/patch

pybop/models/lithium_ion/weppner_huggins.py#L153-L165

Added lines #L153 - L165 were not covered by tests
else:
raise ValueError(

Check warning on line 167 in pybop/models/lithium_ion/weppner_huggins.py

Codecov / codecov/patch

pybop/models/lithium_ion/weppner_huggins.py#L167

Added line #L167 was not covered by tests
f"Unrecognised electrode type: {electrode}, "
'expecting either "positive" or "negative".'
)
# Compute the cell area
A = parameter_set["Electrode height [m]"] * parameter_set["Electrode width [m]"]

Check warning on line 173 in pybop/models/lithium_ion/weppner_huggins.py

Codecov / codecov/patch

pybop/models/lithium_ion/weppner_huggins.py#L173

Added line #L173 was not covered by tests
# Grouped parameters
Q_th = F * alpha * c_max * L * A
tau_d = R**2 / D

Check warning on line 177 in pybop/models/lithium_ion/weppner_huggins.py

Codecov / codecov/patch

pybop/models/lithium_ion/weppner_huggins.py#L176-L177

Added lines #L176 - L177 were not covered by tests
return {

Check warning on line 179 in pybop/models/lithium_ion/weppner_huggins.py

Codecov / codecov/patch

pybop/models/lithium_ion/weppner_huggins.py#L179

Added line #L179 was not covered by tests
"Current function [A]": parameter_set["Current function [A]"],
"Reference voltage [V]": 4,
"Derivative of the OCP wrt stoichiometry [V]": -1,