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

Fix parameter set logic and allow FittingProblem to take init_ocv rather than init_soc #425

Merged
merged 105 commits into from
Aug 7, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
105 commits
Select commit Hold shift + click to select a range
b66a52a
Update default init_soc
NicolaCourtier Jul 24, 2024
157c211
Update CHANGELOG.md
NicolaCourtier Jul 24, 2024
5e60cee
Update check_params
NicolaCourtier Jul 24, 2024
60ae64e
Add pybamm_model as default attribute
NicolaCourtier Jul 24, 2024
c682ace
Ensure predict uses unprocessed_model
NicolaCourtier Jul 25, 2024
914f307
Move rebuild check to model.simulate
NicolaCourtier Jul 25, 2024
367ab12
Align simulate output with predict
NicolaCourtier Jul 25, 2024
4e92192
Replace init_soc with init_ocv for FittingProblem
NicolaCourtier Jul 25, 2024
f799e06
Update notebooks
NicolaCourtier Jul 25, 2024
3f61322
Update test_observers.py
NicolaCourtier Jul 26, 2024
46f31fc
Update descriptions and simplify
NicolaCourtier Jul 26, 2024
28d56fb
Add test_set_initial_state
NicolaCourtier Jul 26, 2024
cba5c36
Update test_problem.py
NicolaCourtier Jul 26, 2024
6e6cb70
Break connection between parameter_sets
NicolaCourtier Jul 26, 2024
d17c728
Allow predict to update initial state
NicolaCourtier Jul 26, 2024
aeba8c4
Fix typo
NicolaCourtier Jul 26, 2024
5e65542
Add nbstripout pre-commit hook
NicolaCourtier Jul 28, 2024
c54ae5b
Add -q and re-run all notebooks
NicolaCourtier Jul 28, 2024
4cba081
Copy parameter sets and remove model.initial_state
NicolaCourtier Jul 28, 2024
01115df
Reset spm_NelderMead.py
NicolaCourtier Jul 28, 2024
08df450
Update CHANGELOG.md
NicolaCourtier Jul 28, 2024
0039d8a
Update CHANGELOG.md
NicolaCourtier Jul 29, 2024
e655ed7
Allow parameter_set is None
NicolaCourtier Jul 29, 2024
b2f389b
Merge branch '427-pre-commit-nbstripout' into 424-fitting-ocv
NicolaCourtier Jul 29, 2024
9a7282c
Re-run notebooks
NicolaCourtier Jul 29, 2024
6223251
Update bounds
NicolaCourtier Jul 30, 2024
a71350e
Update notebooks
NicolaCourtier Jul 30, 2024
37be820
Update notebooks
NicolaCourtier Jul 30, 2024
8591ba7
Set numpy random seed in notebooks
NicolaCourtier Jul 30, 2024
d2c7e68
Re-run with fixed seed
NicolaCourtier Jul 30, 2024
e2410cc
Merge branch '427-pre-commit-nbstripout' into 424-fitting-ocv
NicolaCourtier Jul 30, 2024
9b8d27a
Update bounds
NicolaCourtier Jul 30, 2024
2f73168
Update notebooks to initial_state
NicolaCourtier Jul 30, 2024
80df8fe
Add set_initial_state for ECMs
NicolaCourtier Jul 30, 2024
eda8096
Add init_ocv setter
NicolaCourtier Jul 30, 2024
285777b
Add init_ocv values
NicolaCourtier Jul 30, 2024
aebec3c
Re-run notebooks
NicolaCourtier Jul 30, 2024
8df8618
Add tests for ECM get_initial_state
NicolaCourtier Jul 30, 2024
6f05cda
Add ECM initial state error tests
NicolaCourtier Jul 30, 2024
d18b28f
Remove unused store_optimised_parameters
NicolaCourtier Jul 31, 2024
5d4f2ea
Update parameters.initial_value
NicolaCourtier Jul 31, 2024
eac17cc
Use any Initial SoC from parameter_set
NicolaCourtier Jul 31, 2024
24e40a0
Merge branch 'develop' into 424-fitting-ocv
NicolaCourtier Jul 31, 2024
b9650c3
Update bounds again
NicolaCourtier Jul 31, 2024
7a7d58a
Update init_soc in notebooks
NicolaCourtier Jul 31, 2024
d993632
Move dataset check within unscented_kalman
NicolaCourtier Jul 31, 2024
5059f71
Remove unnecessary lines from spm_UKF
NicolaCourtier Jul 31, 2024
9bc0c0e
Update all parameters for rebuild
NicolaCourtier Jul 31, 2024
daf3f05
Update init_ocv to _init_ocv
NicolaCourtier Jul 31, 2024
b285885
Ensure value updates alongside initial_value
NicolaCourtier Jul 31, 2024
48788af
Update multi_model_identification
NicolaCourtier Jul 31, 2024
7798af5
Merge branch 'develop' into 421-design_init_soc
NicolaCourtier Jul 31, 2024
07644d4
Update spm_electrode_design.ipynb
NicolaCourtier Jul 31, 2024
799329e
Update spm_electrode_design.ipynb
NicolaCourtier Jul 31, 2024
c7ee29b
Merge branch '421-design_init_soc' into 424-fitting-ocv
NicolaCourtier Jul 31, 2024
61d326f
Fix identation
NicolaCourtier Jul 31, 2024
5be532c
Fix test_plots design problem
NicolaCourtier Jul 31, 2024
29e7a67
Move Changelog entry to breaking changes
NicolaCourtier Aug 1, 2024
f999b96
Move Changelog entry
NicolaCourtier Aug 1, 2024
d31ee54
Merge branch 'develop' into 421-design_init_soc
NicolaCourtier Aug 1, 2024
098e3e2
style: pre-commit fixes
pre-commit-ci[bot] Aug 1, 2024
86f1d17
Fix merge mistake
NicolaCourtier Aug 1, 2024
beac8bb
Merge branch '421-design_init_soc' into 424-fitting-ocv
NicolaCourtier Aug 1, 2024
d205dc9
style: pre-commit fixes
pre-commit-ci[bot] Aug 1, 2024
eef8acf
Add tests
NicolaCourtier Aug 1, 2024
5f7761f
Merge branch '421-design_init_soc' into 424-fitting-ocv
NicolaCourtier Aug 1, 2024
cdd4d1c
Update integration tests
NicolaCourtier Aug 1, 2024
b6c8824
Update spm_weighted_cost.py
NicolaCourtier Aug 1, 2024
ebc5114
Fix tests
NicolaCourtier Aug 2, 2024
d4421fe
style: pre-commit fixes
pre-commit-ci[bot] Aug 2, 2024
043ae52
Merge branch 'develop' into 424-fitting-ocv
NicolaCourtier Aug 2, 2024
3bba9c7
Merge branch 'develop' into 424-fitting-ocv
NicolaCourtier Aug 5, 2024
ede6363
Fix model type check
NicolaCourtier Aug 5, 2024
fe1397e
Update _parameter_set to parameter_set
NicolaCourtier Aug 5, 2024
3cb4c4d
style: pre-commit fixes
pre-commit-ci[bot] Aug 5, 2024
e3b1466
Update tests with parameter set
NicolaCourtier Aug 5, 2024
cbda2ef
Add model build description
NicolaCourtier Aug 5, 2024
b19035d
Revert to _parameter_set
NicolaCourtier Aug 5, 2024
eba9def
Apply suggestions from code review
NicolaCourtier Aug 5, 2024
892eb77
Apply suggestions from code review
NicolaCourtier Aug 5, 2024
bf01b7e
Fix syntax
NicolaCourtier Aug 5, 2024
71a95cf
Fix variable name
NicolaCourtier Aug 5, 2024
4484951
Update model type check
NicolaCourtier Aug 5, 2024
08cdc4c
Update parameter_set setter
NicolaCourtier Aug 5, 2024
cd87e83
style: pre-commit fixes
pre-commit-ci[bot] Aug 5, 2024
14e4223
Add parameters.reset_initial_value
NicolaCourtier Aug 5, 2024
8a19542
Add n_outputs property
NicolaCourtier Aug 6, 2024
a67c564
style: pre-commit fixes
pre-commit-ci[bot] Aug 6, 2024
5450f21
Remove public parameter_set setter
NicolaCourtier Aug 6, 2024
676e7ed
Correct integer to float
NicolaCourtier Aug 6, 2024
80ef44e
Convert initial_state to dict
NicolaCourtier Aug 6, 2024
8e67d89
Add guidance
NicolaCourtier Aug 6, 2024
d5f63d0
Remove empty dictionary defaults
NicolaCourtier Aug 6, 2024
d0d1bd2
style: pre-commit fixes
pre-commit-ci[bot] Aug 6, 2024
5c52712
Add warning stacklevels
NicolaCourtier Aug 6, 2024
dacafc3
Catch simulation errors in problem evaluation
NicolaCourtier Aug 6, 2024
bcc7acf
Add pybamm version comment
NicolaCourtier Aug 6, 2024
8607a6b
Add set initial ocv check
NicolaCourtier Aug 6, 2024
605f509
Add model.clear and remove setters
NicolaCourtier Aug 7, 2024
a5be6ee
Merge branch '445-remove-setters' into 424-fitting-ocv
NicolaCourtier Aug 7, 2024
a188c4b
Update unscented_kalman.py
NicolaCourtier Aug 7, 2024
ca2a5b1
Update unscented_kalman.py
NicolaCourtier Aug 7, 2024
a4c0030
Update test_models.py
NicolaCourtier Aug 7, 2024
742f9d4
Update test_set_initial_state
NicolaCourtier Aug 7, 2024
db09455
Merge branch 'develop' into 424-fitting-ocv
NicolaCourtier Aug 7, 2024
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
92 changes: 40 additions & 52 deletions pybop/models/base_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -195,13 +195,13 @@
If the input is not a dictionary with a single, valid key.
"""
if len(initial_state) > 1:
raise ValueError("Expecting only one initial state.")

Check warning on line 198 in pybop/models/base_model.py

View check run for this annotation

Codecov / codecov/patch

pybop/models/base_model.py#L198

Added line #L198 was not covered by tests
elif "Initial SoC" in initial_state.keys():
return initial_state["Initial SoC"]
elif "Initial open-circuit voltage [V]" in initial_state.keys():
return str(initial_state["Initial open-circuit voltage [V]"]) + "V"
else:
raise ValueError("Unrecognised initial state.")

Check warning on line 204 in pybop/models/base_model.py

View check run for this annotation

Codecov / codecov/patch

pybop/models/base_model.py#L204

Added line #L204 was not covered by tests

def set_initial_state(self, initial_state: dict):
"""
Expand Down Expand Up @@ -424,9 +424,9 @@

Returns
-------
pybamm.Solution or [np.inf]
The solution object returned by a PyBaMM simulation, or [np.inf] in the case where
the parameter values are infeasible and infeasible solutions are not allowed.
pybamm.Solution
The solution object returned by a PyBaMM simulation, or a pybamm error in the case
where the parameter values are infeasible and infeasible solutions are not allowed.

Raises
------
Expand All @@ -452,19 +452,13 @@
self.parameters.update(values=list(inputs.values()))
self.rebuild(parameters=self.parameters, initial_state=initial_state)

if self.check_params(
if not self.check_params(
inputs=inputs,
allow_infeasible_solutions=self.allow_infeasible_solutions,
):
try:
return self.solver.solve(
self._built_model, inputs=inputs, t_eval=t_eval
)
except Exception as e:
print(f"Error: {e}")
return [np.inf]
else:
return [np.inf]
raise ValueError("These parameter values are infeasible.")

return self.solver.solve(self._built_model, inputs=inputs, t_eval=t_eval)

def simulateS1(
self, inputs: Inputs, t_eval: np.array, initial_state: Optional[dict] = None
Expand All @@ -486,9 +480,9 @@

Returns
-------
pybamm.Solution or [np.inf]
The solution object returned by a PyBaMM simulation, or [np.inf] in the case where
the parameter values are infeasible and infeasible solutions are not allowed.
pybamm.Solution
The solution object returned by a PyBaMM simulation, or a pybamm error in the case
where the parameter values are infeasible and infeasible solutions are not allowed.

Raises
------
Expand All @@ -505,23 +499,18 @@
"Cannot use sensitivies for parameters which require a model rebuild"
)

if self.check_params(
if not self.check_params(
inputs=inputs,
allow_infeasible_solutions=self.allow_infeasible_solutions,
):
try:
return self._solver.solve(
self._built_model,
inputs=inputs,
t_eval=t_eval,
calculate_sensitivities=True,
)

except Exception as e:
print(f"Error: {e}")
return [np.inf]
else:
return [np.inf]
raise ValueError("These parameter values are infeasible.")

return self._solver.solve(
self._built_model,
inputs=inputs,
t_eval=t_eval,
calculate_sensitivities=True,
)

def predict(
self,
Expand Down Expand Up @@ -559,9 +548,9 @@

Returns
-------
pybamm.Solution or [np.inf]
The solution object returned by a PyBaMM simulation, or [np.inf] in the case where
the parameter values are infeasible and infeasible solutions are not allowed.
pybamm.Solution
The solution object returned by a PyBaMM simulation, or a pybamm error in the case
where the parameter values are infeasible and infeasible solutions are not allowed.

Raises
------
Expand Down Expand Up @@ -591,29 +580,28 @@
parameter_set["Initial SoC"] = self._parameter_set["Initial SoC"]
initial_state = None

if self.check_params(
if not self.check_params(
parameter_set=parameter_set,
allow_infeasible_solutions=self.allow_infeasible_solutions,
):
if experiment is not None:
return pybamm.Simulation(
model=self._unprocessed_model,
experiment=experiment,
parameter_values=parameter_set,
).solve(initial_soc=initial_state)
elif t_eval is not None:
return pybamm.Simulation(
model=self._unprocessed_model,
parameter_values=parameter_set,
).solve(t_eval=t_eval, initial_soc=initial_state)
else:
raise ValueError(
"The predict method requires either an experiment or "
"t_eval to be specified."
)

raise ValueError("These parameter values are infeasible.")

if experiment is not None:
return pybamm.Simulation(
model=self._unprocessed_model,
experiment=experiment,
parameter_values=parameter_set,
).solve(initial_soc=initial_state)
elif t_eval is not None:
return pybamm.Simulation(
model=self._unprocessed_model,
parameter_values=parameter_set,
).solve(t_eval=t_eval, initial_soc=initial_state)
else:
return [np.inf]
raise ValueError(
"The predict method requires either an experiment or t_eval "
"to be specified."
)

def check_params(
self,
Expand Down
67 changes: 34 additions & 33 deletions pybop/problems/fitting_problem.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,18 +104,19 @@
"""
inputs = self.parameters.verify(inputs)

sol = self._model.simulate(
inputs=inputs, t_eval=self._time_data, initial_state=self.initial_state
)

if sol == [np.inf]:
try:
sol = self._model.simulate(
inputs=inputs, t_eval=self._time_data, initial_state=self.initial_state
)
except Exception as e:
if self.verbose:
print(f"Simulation error: {e}")

Check warning on line 113 in pybop/problems/fitting_problem.py

View check run for this annotation

Codecov / codecov/patch

pybop/problems/fitting_problem.py#L113

Added line #L113 was not covered by tests
return {signal: [np.inf] for signal in self.signal}

else:
return {
signal: sol[signal].data
for signal in (self.signal + self.additional_variables)
}
return {
signal: sol[signal].data
for signal in (self.signal + self.additional_variables)
}

def evaluateS1(self, inputs: Inputs):
"""
Expand All @@ -134,32 +135,32 @@
"""
inputs = self.parameters.verify(inputs)

sol = self._model.simulateS1(
inputs=inputs, t_eval=self._time_data, initial_state=self.initial_state
)

if sol == [np.inf]:
try:
NicolaCourtier marked this conversation as resolved.
Show resolved Hide resolved
sol = self._model.simulateS1(
inputs=inputs, t_eval=self._time_data, initial_state=self.initial_state
)
except Exception as e:
print(f"Error: {e}")
return {signal: [np.inf] for signal in self.signal}, [np.inf]

else:
y = {signal: sol[signal].data for signal in self.signal}
y = {signal: sol[signal].data for signal in self.signal}

# Extract the sensitivities and stack them along a new axis for each signal
dy = np.empty(
(
sol[self.signal[0]].data.shape[0],
self.n_outputs,
self._n_parameters,
)
# Extract the sensitivities and stack them along a new axis for each signal
dy = np.empty(
(
sol[self.signal[0]].data.shape[0],
self.n_outputs,
self._n_parameters,
)
)

for i, signal in enumerate(self.signal):
dy[:, i, :] = np.stack(
[
sol[signal].sensitivities[key].toarray()[:, 0]
for key in self.parameters.keys()
],
axis=-1,
)
for i, signal in enumerate(self.signal):
dy[:, i, :] = np.stack(
[
sol[signal].sensitivities[key].toarray()[:, 0]
for key in self.parameters.keys()
],
axis=-1,
)

return (y, np.asarray(dy))
return (y, np.asarray(dy))
6 changes: 4 additions & 2 deletions tests/unit/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,10 @@ def test_predict_without_allow_infeasible_solutions(self, model):
"Positive electrode active material volume fraction": 0.9,
}

res = model.predict(t_eval=t_eval, inputs=inputs)
assert np.isinf(res).any()
with pytest.raises(
ValueError, match="These parameter values are infeasible."
):
model.predict(t_eval=t_eval, inputs=inputs)

@pytest.mark.unit
def test_build(self, model):
Expand Down
Loading