Repository navigation
Ensure step and cycle lengths match - #5724
NicolaCourtier wants to merge 12 commits into
Conversation
|
Small fix, ready for review (@rtimms ?) |
rtimms
left a comment
There was a problem hiding this comment.
Diagnosis is right — make_cycle_solution stores the unsliced step solutions on cycle.steps, while cycle.t comes from from_sub_solutions, which drops the duplicated leading sample. Using exact == correctly mirrors that.
1. Cross-cycle boundaries are still off
"Cycle" is built from np.ones_like(cycle.t) with no dedup, but the parent solution is also from_sub_solutions(cycle_solutions), so it drops the repeat at each cycle boundary too. The j > 0 guard skips exactly that case. Two cycles × two steps, all boundaries exactly repeated:
data len : 197 t len: 197
Cycle len: 198
Step len: 198
csv FAILED: ValueError All arrays must be of the same length
Step now agrees with Cycle, and both still disagree with the data. save_data(to_format="csv") is the user-visible failure.
Carrying one boundary across the flattened step list fixes both, and lets "Cycle" inherit the dedup instead of needing its own mechanism:
# Save cycle number and step number if the solution has them
if cycles_and_steps and len(self.cycles) > 0:
cycle_numbers, step_numbers, previous_last_t = [], [], None
for i, cycle in enumerate(self.cycles):
for j, step in enumerate(cycle.steps):
# a step's first point is dropped when it repeats the previous
# step's last point, so don't number it twice
repeated = (
previous_last_t is not None and step.t[0] == previous_last_t
)
previous_last_t = step.t[-1]
length = len(step.t) - repeated
cycle_numbers.append(np.full(length, i, dtype=float))
step_numbers.append(np.full(length, j, dtype=float))
data_short_names["Cycle"] = np.concatenate(cycle_numbers)
data_short_names["Step"] = np.concatenate(step_numbers)Also one np.concatenate at the end rather than one per step, which matters on long cycling runs.
2. The test asserts the wrong invariant
np.zeros(50), np.ones(49) hardcodes the answer. What matters is len(Step) == len(Cycle) == len(data["c"]) — assert that, add a two-cycle case, and the gap above gets caught. As written the test passes on a solution that still can't be written to csv.
3. Nit
np.ones_like(step.t[first]) slices an array purely for its shape.
Worth noting for severity: normal experiments don't hit this. BaseSolver.step nudges each step start with np.nextafter, so real Simulation.solve runs came out consistent in every configuration I tried (event-terminated, fixed period, multi-cycle). It bites when solutions are assembled directly — sol1 + sol2, hand-built cycles, starting_solution — which is exactly what the test does.
|
Thanks @NicolaCourtier ! Just a couple of comments |
|
Thanks Rob, cc. @SarahRo |
rtimms
left a comment
There was a problem hiding this comment.
Thanks @NicolaCourtier @SarahRo, this now handles the boundaries between cycles too. The length check in the test catches the old bug: it fails on main, and save_data(to_format="csv") works on this branch. Approving, with three small things to do before merge:
- Please add a
## Bug fixesentry under# [Unreleased]inCHANGELOG.md, e.g.
- `Solution.get_data_dict` and `save_data` now give the "Cycle" and "Step" columns the same length as the data when a step or cycle repeats the previous one's last time point. ([#5724](https://github.com/pybamm-team/PyBaMM/pull/5724)) tmp_pathisn't used intest_get_data_cycles_steps, so please drop it. To cover the failure users actually see, addsol.save_data(variables=["c"], to_format="csv"). Without a filename it returns the CSV string, so no temp file is needed.- Please swap
pybamm.ScipySolver()forpybamm.IDAKLUSolver()in that test, sinceScipySolveris deprecated.
|
| Project | PyBaMM |
| Branch | step-cycle-numbers |
| Testbed | bare-metal |
🐰 View full continuous benchmarking report in Bencher
⚠️ WARNING: No benchmarks found!
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #5724 +/- ##
=======================================
Coverage 98.12% 98.12%
=======================================
Files 348 348
Lines 35575 35579 +4
=======================================
+ Hits 34909 34913 +4
Misses 666 666 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
@NicolaCourtier @rtimms Thanks! I've updated the test and changelog. |
Description
A one-line fix to ensure that the step length is not longer than the cycle length.
Type of change
Add an entry under
# [Unreleased]in CHANGELOG.md, in one of## Breaking changes,## Deprecated,## Features, or## Bug fixes(include PR number; breaking and deprecation entries need a one-line migration note). Internal-only PRs — refactor, docs, CI, tests — can skip this. See RELEASE.md for the full policy.Important checks:
Please confirm the following before marking the PR as ready for review:
nox -s pre-commitnox -s testsnox -s doctests