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

Release v24.6.1 #415

Merged
merged 15 commits into from
Jul 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -314,3 +314,6 @@ $RECYCLE.BIN/
# Airspeed Velocity
*.asv/
results/

# Pycharm
*.idea/
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@

## Features

## Bug Fixes

## Breaking Changes

# [v24.6.1](https://github.com/pybop-team/PyBOP/tree/v24.6.1) - 2024-07-31

## Features
- [#313](https://github.com/pybop-team/PyBOP/pull/313/) - Fixes for PyBaMM v24.5, drops support for PyBaMM v23.9, v24.1

## Bug Fixes

Expand Down
2 changes: 1 addition & 1 deletion CITATION.cff
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@ authors:
family-names: Courtier
- given-names: David
family-names: Howey
version: "24.6" # Update this when you release a new version
version: "24.6.1" # Update this when you release a new version
repository-code: 'https://www.github.com/pybop-team/pybop'
2 changes: 1 addition & 1 deletion docs/_static/switcher.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
{
"name": "v24.6 (stable)",
"version": "v24.6",
"url": "https://pybop-docs.readthedocs.io/en/v24.6/",
"url": "https://pybop-docs.readthedocs.io/en/v24.6.1/",
"preferred": true
},
{
Expand Down
4 changes: 2 additions & 2 deletions examples/scripts/gitt.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,10 @@
model = pybop.lithium_ion.WeppnerHuggins(parameter_set=parameter_set)

parameters = pybop.Parameter(
"Positive electrode diffusivity [m2.s-1]",
"Positive particle diffusivity [m2.s-1]",
prior=pybop.Gaussian(5e-14, 1e-13),
bounds=[1e-16, 1e-11],
true_value=parameter_set["Positive electrode diffusivity [m2.s-1]"],
true_value=parameter_set["Positive particle diffusivity [m2.s-1]"],
)

problem = pybop.FittingProblem(
Expand Down
7 changes: 2 additions & 5 deletions examples/scripts/parameters/example_BPX.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"Header": {
"BPX": 0.1,
"Title": "Parameterisation example of an LFP|graphite 2 Ah cylindrical 18650 cell.",
"BPX": 0.4,
"Title": "Parameterisation example of an LFP|graphite 2 Ah cylindrical 18650 cell. File downloaded on 19/3/24 from https://github.com/FaradayInstitution/BPX/blob/main/examples/lfp_18650_cell_BPX.json",
"Description": "LFP|graphite 2 Ah cylindrical 18650 cell. Parameterisation by About:Energy Limited (aboutenergy.io), December 2022, based on cell cycling data, and electrode data gathered after cell teardown. Electrolyte properties from Nyman et al. 2008 (doi:10.1016/j.electacta.2008.04.023). Negative electrode entropic coefficient data are from O'Regan et al. 2022 (doi:10.1016/j.electacta.2022.140700). Positive electrode entropic coefficient data are from Gerver and Meyers 2011 (doi:10.1149/1.3591799). Other thermal properties are estimated.",
"Model": "DFN"
},
Expand Down Expand Up @@ -70,9 +70,6 @@
"Thickness [m]": 2e-05,
"Porosity": 0.47,
"Transport efficiency": 0.3222
},
"User-defined": {
"Source:": "An example BPX json file downloaded on 19/3/24 from https://github.com/FaradayInstitution/BPX/blob/main/examples/lfp_18650_cell_BPX.json"
}
}
}
6 changes: 3 additions & 3 deletions examples/scripts/spm_UKF.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

# Make a prediction with measurement noise
sigma = 0.001
t_eval = np.arange(0, 300, 2)
t_eval = np.arange(0, 900, 0.5)
values = model.predict(t_eval=t_eval)
corrupt_values = values["Voltage [V]"].data + np.random.normal(0, sigma, len(t_eval))

Expand All @@ -42,8 +42,8 @@
signal = ["Voltage [V]"]
n_states = model.n_states
n_signals = len(signal)
covariance = np.diag([0] * 19 + [sigma**2] + [0] * 19 + [sigma**2])
process_noise = np.diag([0] * 19 + [1e-6] + [0] * 19 + [1e-6])
covariance = np.diag([0] * 20 + [sigma**2] + [0] * 20 + [sigma**2])
process_noise = np.diag([0] * 20 + [1e-6] + [0] * 20 + [1e-6])
measurement_noise = np.diag([sigma**2])
observer = pybop.UnscentedKalmanFilterObserver(
parameters,
Expand Down
2 changes: 0 additions & 2 deletions pybop/_experiment.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,4 @@ def __init__(
period,
temperature,
termination,
drive_cycles,
cccv_handling,
)
2 changes: 1 addition & 1 deletion pybop/costs/fitting_costs.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ def _evaluate(self, inputs: Inputs, grad=None):

e = np.asarray(
[
np.sum(((prediction[signal] - self._target[signal]) ** 2))
np.sum((prediction[signal] - self._target[signal]) ** 2)
for signal in self.signal
]
)
Expand Down
18 changes: 13 additions & 5 deletions pybop/models/base_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@


@dataclass
class TimeSeriesState(object):
class TimeSeriesState:
"""
The current state of a time series model that is a pybamm model.
"""
Expand Down Expand Up @@ -119,9 +119,13 @@ def build(
self.set_params()

self._mesh = pybamm.Mesh(self.geometry, self.submesh_types, self.var_pts)
self._disc = pybamm.Discretisation(self.mesh, self.spatial_methods)
self._disc = pybamm.Discretisation(
mesh=self.mesh,
spatial_methods=self.spatial_methods,
check_model=check_model,
)
self._built_model = self._disc.process_model(
self._model_with_set_params, inplace=False, check_model=check_model
self._model_with_set_params, inplace=False
)

# Clear solver and setup model
Expand Down Expand Up @@ -230,9 +234,13 @@ def rebuild(

self.set_params(rebuild=True)
self._mesh = pybamm.Mesh(self.geometry, self.submesh_types, self.var_pts)
self._disc = pybamm.Discretisation(self.mesh, self.spatial_methods)
self._disc = pybamm.Discretisation(
mesh=self.mesh,
spatial_methods=self.spatial_methods,
check_model=check_model,
)
self._built_model = self._disc.process_model(
self._model_with_set_params, inplace=False, check_model=check_model
self._model_with_set_params, inplace=False
)

# Clear solver and setup model
Expand Down
4 changes: 2 additions & 2 deletions pybop/models/lithium_ion/weppner_huggins.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ def __init__(self, name="Weppner & Huggins model", **model_kwargs):
# Model kwargs (build, options) are not implemented, keeping here for consistent interface
if model_kwargs is not dict(build=True):
unused_kwargs_warning = "The input model_kwargs are not currently used by the Weppner & Huggins model."
warnings.warn(unused_kwargs_warning, UserWarning)
warnings.warn(unused_kwargs_warning, UserWarning, stacklevel=2)

super().__init__({}, name)

Expand Down Expand Up @@ -65,7 +65,7 @@ def __init__(self, name="Weppner & Huggins model", **model_kwargs):
# Parameters
######################

d_s = Parameter("Positive electrode diffusivity [m2.s-1]")
d_s = Parameter("Positive particle diffusivity [m2.s-1]")

c_s_max = Parameter("Maximum concentration in positive electrode [mol.m-3]")

Expand Down
4 changes: 2 additions & 2 deletions pybop/observers/unscented_kalman.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ def get_current_covariance(self) -> Covariance:


@dataclass
class SigmaPoint(object):
class SigmaPoint:
"""
A sigma point is a point in the state space that is used to estimate the mean and covariance of a random variable.
"""
Expand All @@ -162,7 +162,7 @@ class SigmaPoint(object):
w_c: float


class SquareRootUKF(object):
class SquareRootUKF:
"""
van der Menve, R., & Wan, E. A. (2001). THE SQUARE-ROOT UNSCENTED KALMAN FILTER FOR STATE AND PARAMETER-ESTIMATION.
https://doi.org/10.1109/ICASSP.2001.940586
Expand Down
2 changes: 1 addition & 1 deletion pybop/parameters/parameter_set.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ def import_parameters(self, json_path=None):

# Read JSON file
if not self.params and self.json_path:
with open(self.json_path, "r") as file:
with open(self.json_path) as file:
self.params = json.load(file)
else:
raise ValueError(
Expand Down
5 changes: 3 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ classifiers = [
]
requires-python = ">=3.9, <3.13"
dependencies = [
"pybamm>=23.9",
"pybamm>=24.5",
"numpy>=1.16, <2.0",
"scipy>=1.3",
"pints>=0.5",
Expand Down Expand Up @@ -73,14 +73,15 @@ Homepage = "https://github.com/pybop-team/PyBOP"
Documentation = "https://pybop-docs.readthedocs.io"
Repository = "https://github.com/pybop-team/PyBOP"
Releases = "https://github.com/pybop-team/PyBOP/releases"
Changelog = "https://github.com/pybop-team/PyBOP/CHANGELOG.md"
Changelog = "https://github.com/pybop-team/PyBOP/blob/develop/CHANGELOG.md"

[tool.pytest.ini_options]
addopts = "--showlocals -v -n auto"

[tool.ruff]
extend-include = ["*.ipynb"]
extend-exclude = ["__init__.py"]
fix = true

[tool.ruff.lint]
extend-select = ["I"]
Expand Down
11 changes: 7 additions & 4 deletions scripts/ci/build_matrix.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,11 @@

python_version=("3.9" "3.10" "3.11" "3.12")
os=("ubuntu-latest" "windows-latest" "macos-13" "macos-14")
# This command fetches the last two PyBaMM versions excluding release candidates from PyPI
pybamm_version=($(curl -s https://pypi.org/pypi/pybamm/json | jq -r '.releases | keys[]' | grep -v rc | tail -n 2 | paste -sd " " -))
# This command fetches the last PyBaMM version excluding release candidates from PyPI
pybamm_version=($(curl -s https://pypi.org/pypi/pybamm/json | jq -r '.releases | keys[]' | grep -v rc | tail -n 1 | paste -sd " " -))

# This command fetches the last PyBaMM versions including release candidates from PyPI
#pybamm_version=($(curl -s https://pypi.org/pypi/pybamm/json | jq -r '.releases | keys[]' | tail -n 1 | paste -sd " " -))

# open dict
json='{
Expand Down Expand Up @@ -40,7 +43,7 @@ json+='
]
}'

# Filter out incompatible combinations
json=$(echo "$json" | jq -c 'del(.include[] | select(.pybamm_version == "23.9" and .python_version == "3.12"))')
# Example for filtering out incompatible combinations
#json=$(echo "$json" | jq -c 'del(.include[] | select(.pybamm_version == "23.9" and .python_version == "3.12"))')

echo "$json" | jq -c .
2 changes: 1 addition & 1 deletion tests/integration/test_model_experiment_changes.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class TestModelAndExperimentChanges:
),
pybop.Parameters(
pybop.Parameter( # non-geometric parameter
"Positive electrode diffusivity [m2.s-1]",
"Positive particle diffusivity [m2.s-1]",
prior=pybop.Gaussian(3.43e-15, 1e-15),
bounds=[1e-15, 5e-15],
true_value=4e-15,
Expand Down
5 changes: 3 additions & 2 deletions tests/unit/test_cost.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,8 @@ def test_costs(self, cost):
cost([1.1])

# Test option setting
cost.set_fail_gradient(1)
cost.set_fail_gradient(10)
assert cost._de == 10

if isinstance(cost, pybop.SumSquaredError):
e, de = cost.evaluateS1([0.5])
Expand Down Expand Up @@ -263,4 +264,4 @@ def test_design_costs(

# Compute after updating nominal capacity
cost = cost_class(problem, update_capacity=True)
cost([0.4])
assert np.isfinite(cost([0.4]))
6 changes: 3 additions & 3 deletions tests/unit/test_experiment.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ def test_experiment(self):
pybop_experiment = pybop.Experiment(protocol)
pybamm_experiment = pybamm.Experiment(protocol)

assert [
step.to_dict() for step in pybop_experiment.operating_conditions_steps
] == [step.to_dict() for step in pybamm_experiment.operating_conditions_steps]
assert [step.to_dict() for step in pybop_experiment.steps] == [
step.to_dict() for step in pybamm_experiment.steps
]

assert pybop_experiment.cycle_lengths == pybamm_experiment.cycle_lengths

Expand Down
12 changes: 7 additions & 5 deletions tests/unit/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -358,11 +358,13 @@ def test_non_converged_solution(self):
"Voltage [V]": np.zeros(100),
}
)

problem = pybop.FittingProblem(model, parameters=parameters, dataset=dataset)
res = problem.evaluate([-0.2, -0.2])
_, res_grad = problem.evaluateS1([-0.2, -0.2])

# Simulate the DFN with active material values of 0.
# The solution elements will not change as the solver will not converge.
output = problem.evaluate([0, 0])
output_S1, _ = problem.evaluateS1([0, 0])

for key in problem.signal:
assert np.isinf(res.get(key, [])).any()
assert np.isinf(res_grad).any()
assert np.allclose(output.get(key, [])[0], output.get(key, []))
assert np.allclose(output_S1.get(key, [])[0], output_S1.get(key, []))
14 changes: 14 additions & 0 deletions tests/unit/test_observer_unscented_kalman.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,15 @@ def test_cholupdate(self):
SquareRootUKF.cholupdate(R1_, u.copy(), 1.0)
np.testing.assert_array_almost_equal(R1, R1_)

# Test hypot
f = 10.0
j = 20.0
out_1 = f * np.sqrt(1 + 1.0 * f**2 / j**2)
np.testing.assert_allclose(SquareRootUKF.hypot(f, j, 1.0), out_1)

j = 10.0
np.testing.assert_allclose(SquareRootUKF.hypot(f, j, 1.0), float(0))

@pytest.mark.unit
def test_unscented_kalman_filter(self, dataset, observer):
t_eval = dataset["Time [s]"]
Expand All @@ -116,6 +125,11 @@ def test_unscented_kalman_filter(self, dataset, observer):
decimal=4,
)

# Test get covariance
cov = observer.get_current_measure()
assert cov.shape == (1, 1)
assert float(0) <= cov[0]

@pytest.mark.unit
def test_observe_no_measurement(self, observer):
with pytest.raises(ValueError):
Expand Down
Loading