Added InputParameter support in PyBamm experiments - #4826
Conversation
valentinsulzer
left a comment
There was a problem hiding this comment.
Thanks for taking this on but this isn't quite what I had in mind, the interface should be:
step = pybamm.step.current(pybamm.InputParameter("I_app"), termination="2.5 V")
experiment = pybamm.Experiment([step])
sim = pybamm.Simulation(..., experiment=experiment)
sim.solve(inputs={"I_app": 1})
|
made changes, now user can pass input params like this: step = pybamm.step.current(pybamm.InputParameter("I_app"), termination="2.5 V")
experiment = pybamm.Experiment([step])
sim = pybamm.Simulation(..., experiment=experiment)
sim.solve(inputs={"I_app": 1}) |
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## develop #4826 +/- ##
========================================
Coverage 98.70% 98.70%
========================================
Files 304 304
Lines 23432 23452 +20
========================================
+ Hits 23129 23149 +20
Misses 303 303 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
Just a follow up anything else I need to change? |
MarcBerliner
left a comment
There was a problem hiding this comment.
@Rishab87 thanks for putting this PR together! I left a few comments
|
The So for this PR, we need to ensure that any termination has an operator, because we cannot make the assumption. We probably want to keep the string parsing available, so a nice syntax would be "{operator} {value} {unit}", e.g. "< 2.5 V". But the operator must be in the termination, not the step. |
|
@aabills I've made changes accordingly just as you told now operator gets passed in termination like "< 2.5 V". And thanks for explaining about why we need directions in first place and why we need an operator now it helped me a lot while making changes |
|
@aabills thanks for the review I've added the callable case and also added few test cases accordingly to ensure full coverage |
aabills
left a comment
There was a problem hiding this comment.
So close! Just one more change and this is good from my side
|
@aabills I've changed the code and added a check to see if symbol has input params |
|
Looks good! Fix coverage and you're good to go from my side. @MarcBerliner @valentinsulzer anything else from y'all? |
|
Oh and don't forget to add something to the CHANGELOG.md |
|
Also fix this failing integration test. |
9084495
|
@aabills added my PR to changelog and tests for full coverage. Also fixed the integration test |
MarcBerliner
left a comment
There was a problem hiding this comment.
Thanks @Rishab87! Looks great
…om termination check
When pybamm.step.current/voltage/power/resistance is
called with a Python callable value(t) that genuinely depends on
t, BaseStep.__init__ rewrites self.value as
value(pybamm.t - pybamm.InputParameter('start time')) so that the
runtime start time injected by Simulation can offset time at
solve. That InputParameter is an implementation detail — its name
is reserved by Simulation._START_TIME_INPUT — but
_check_input_params was walking the symbol tree and reporting
True for *any* InputParameter leaf, including this internal one.
That breaks two downstream assumptions:
1. _parse_termination then raises
ValueError: Termination must include an operator when using
InputParameter. against plain string terminations like
'4.3 V' even though the user never passed an InputParameter.
This is the regression reported in pybamm-team#5018, where code that worked
in 25.1 stops working in 25.4+ (the operator-or-bust check was
added by pybamm-team#4826).
2. value_based_charge_or_discharge returns None for every
callable-driven step, so direction inference silently goes away.
The fix narrows _check_input_params to user-supplied
InputParameters by filtering out leaves whose name is 'start time'.
Genuine user inputs (e.g. pybamm.InputParameter('I_app') or
I_coeff * pybamm.t) still trigger the check, so the operator
requirement introduced by pybamm-team#4826 is preserved.
Tests cover the helper directly, both branches of the filter
(internal-only vs mixed with a user input), the operator-free string
termination path, the [CustomTermination, '4.3 V'] shape from
the OP's reproducer, the restored direction inference, and a
non-regression on the existing 'must include an operator' guard for
true InputParameter values.
…om termination check
When pybamm.step.current/voltage/power/resistance is
called with a Python callable value(t) that genuinely depends on
t, BaseStep.__init__ rewrites self.value as
value(pybamm.t - pybamm.InputParameter('start time')) so that the
runtime start time injected by Simulation can offset time at
solve. That InputParameter is an implementation detail — its name
is reserved by Simulation._START_TIME_INPUT — but
_check_input_params was walking the symbol tree and reporting
True for *any* InputParameter leaf, including this internal one.
That breaks two downstream assumptions:
1. _parse_termination then raises
ValueError: Termination must include an operator when using
InputParameter. against plain string terminations like
'4.3 V' even though the user never passed an InputParameter.
This is the regression reported in pybamm-team#5018, where code that worked
in 25.1 stops working in 25.4+ (the operator-or-bust check was
added by pybamm-team#4826).
2. value_based_charge_or_discharge returns None for every
callable-driven step, so direction inference silently goes away.
The fix narrows _check_input_params to user-supplied
InputParameters by filtering out leaves whose name is 'start time'.
Genuine user inputs (e.g. pybamm.InputParameter('I_app') or
I_coeff * pybamm.t) still trigger the check, so the operator
requirement introduced by pybamm-team#4826 is preserved.
Tests cover the helper directly, both branches of the filter
(internal-only vs mixed with a user input), the operator-free string
termination path, the [CustomTermination, '4.3 V'] shape from
the OP's reproducer, the restored direction inference, and a
non-regression on the existing 'must include an operator' guard for
true InputParameter values.
…om termination check
When pybamm.step.current/voltage/power/resistance is
called with a Python callable value(t) that genuinely depends on
t, BaseStep.__init__ rewrites self.value as
value(pybamm.t - pybamm.InputParameter('start time')) so that the
runtime start time injected by Simulation can offset time at
solve. That InputParameter is an implementation detail — its name
is reserved by Simulation._START_TIME_INPUT — but
_check_input_params was walking the symbol tree and reporting
True for *any* InputParameter leaf, including this internal one.
That breaks two downstream assumptions:
1. _parse_termination then raises
ValueError: Termination must include an operator when using
InputParameter. against plain string terminations like
'4.3 V' even though the user never passed an InputParameter.
This is the regression reported in pybamm-team#5018, where code that worked
in 25.1 stops working in 25.4+ (the operator-or-bust check was
added by pybamm-team#4826).
2. value_based_charge_or_discharge returns None for every
callable-driven step, so direction inference silently goes away.
The fix narrows _check_input_params to user-supplied
InputParameters by filtering out leaves whose name is 'start time'.
Genuine user inputs (e.g. pybamm.InputParameter('I_app') or
I_coeff * pybamm.t) still trigger the check, so the operator
requirement introduced by pybamm-team#4826 is preserved.
Tests cover the helper directly, both branches of the filter
(internal-only vs mixed with a user input), the operator-free string
termination path, the [CustomTermination, '4.3 V'] shape from
the OP's reproducer, the restored direction inference, and a
non-regression on the existing 'must include an operator' guard for
true InputParameter values.
…om termination check
When pybamm.step.current/voltage/power/resistance is
called with a Python callable value(t) that genuinely depends on
t, BaseStep.__init__ rewrites self.value as
value(pybamm.t - pybamm.InputParameter('start time')) so that the
runtime start time injected by Simulation can offset time at
solve. That InputParameter is an implementation detail — its name
is reserved by Simulation._START_TIME_INPUT — but
_check_input_params was walking the symbol tree and reporting
True for *any* InputParameter leaf, including this internal one.
That breaks two downstream assumptions:
1. _parse_termination then raises
ValueError: Termination must include an operator when using
InputParameter. against plain string terminations like
'4.3 V' even though the user never passed an InputParameter.
This is the regression reported in pybamm-team#5018, where code that worked
in 25.1 stops working in 25.4+ (the operator-or-bust check was
added by pybamm-team#4826).
2. value_based_charge_or_discharge returns None for every
callable-driven step, so direction inference silently goes away.
The fix narrows _check_input_params to user-supplied
InputParameters by filtering out leaves whose name is 'start time'.
Genuine user inputs (e.g. pybamm.InputParameter('I_app') or
I_coeff * pybamm.t) still trigger the check, so the operator
requirement introduced by pybamm-team#4826 is preserved.
Tests cover the helper directly, both branches of the filter
(internal-only vs mixed with a user input), the operator-free string
termination path, the [CustomTermination, '4.3 V'] shape from
the OP's reproducer, the restored direction inference, and a
non-regression on the existing 'must include an operator' guard for
true InputParameter values.
…om termination check
When pybamm.step.current/voltage/power/resistance is
called with a Python callable value(t) that genuinely depends on
t, BaseStep.__init__ rewrites self.value as
value(pybamm.t - pybamm.InputParameter('start time')) so that the
runtime start time injected by Simulation can offset time at
solve. That InputParameter is an implementation detail — its name
is reserved by Simulation._START_TIME_INPUT — but
_check_input_params was walking the symbol tree and reporting
True for *any* InputParameter leaf, including this internal one.
That breaks two downstream assumptions:
1. _parse_termination then raises
ValueError: Termination must include an operator when using
InputParameter. against plain string terminations like
'4.3 V' even though the user never passed an InputParameter.
This is the regression reported in pybamm-team#5018, where code that worked
in 25.1 stops working in 25.4+ (the operator-or-bust check was
added by pybamm-team#4826).
2. value_based_charge_or_discharge returns None for every
callable-driven step, so direction inference silently goes away.
The fix narrows _check_input_params to user-supplied
InputParameters by filtering out leaves whose name is 'start time'.
Genuine user inputs (e.g. pybamm.InputParameter('I_app') or
I_coeff * pybamm.t) still trigger the check, so the operator
requirement introduced by pybamm-team#4826 is preserved.
Tests cover the helper directly, both branches of the filter
(internal-only vs mixed with a user input), the operator-free string
termination path, the [CustomTermination, '4.3 V'] shape from
the OP's reproducer, the restored direction inference, and a
non-regression on the existing 'must include an operator' guard for
true InputParameter values.
Description
Added InputParameter support in experiments, now you can pass them something like this:
Fixes #4799
Type of change
Please add a line in the relevant section of CHANGELOG.md to document the change (include PR #) - note reverse order of PR #s. If necessary, also add to the list of breaking changes.
Key checklist:
$ pre-commit run(or$ nox -s pre-commit) (see CONTRIBUTING.md for how to set this up to run automatically when committing locally, in just two lines of code)$ python -m pytest(or$ nox -s tests)$ python -m pytest --doctest-plus src(or$ nox -s doctests)You can run integration tests, unit tests, and doctests together at once, using
$ nox -s quick.Further checks: