fix: normalize clustered solution dim order to (cluster, time)#704
Conversation
|
Warning Review limit reached
More reviews will be available in 22 minutes and 45 seconds. Learn how PR review limits work. Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file). ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughIn ChangesCyclic clustering test assertion fix
Estimated code review effort🎯 1 (Trivial) | ⏱️ ~2 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
d2f7faf to
371a9c6
Compare
linopy <0.8 stores the extra-timestep charge_state variable as (time, cluster), because its 'time' coordinate (length n+1) conflicts with the model's 'time' (length n), and 0.7 reorders the conflicting dim to the front. Every other variable is (cluster, time). linopy >=0.8 makes coords the source of truth and is already consistent. flixopt cannot control this from the bounds/coords it passes (0.7 reorders internally), so normalize in the solution property: transpose 'cluster' before 'time'. This is a no-op on linopy >=0.8 and for non-clustered systems, and only touches the cluster/time axis ordering (other dims and scalars are preserved via the ellipsis). Also update the clustering test to access charge_state by label and assert the now-deterministic (cluster, time) order. Unblocks the linopy 0.8 bump in #701. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
371a9c6 to
687e819
Compare
What
Makes the public solution layout deterministic for clustered systems:
charge_state(and everything else) is always(cluster, time), regardlessof the linopy version. Unblocks the linopy 0.8 bump in #701.
Root cause
linopy
<0.8stores the extra-timestepcharge_statevariable as(time, cluster), while every other variable is(cluster, time). The causeis internal to linopy 0.7:
charge_state'stimecoordinate has lengthn+1(the extra SOC boundary), which conflicts with the model's
time(lengthn),and 0.7 reorders the conflicting dim to the front. I confirmed flixopt cannot
fix this from the input side — passing bounds/coords as
(cluster, time)stillcomes back
(time, cluster)on 0.7.linopy
0.8.0(PyPSA/linopy#732,"unify coords-as-truth handling") makes the explicit
coordsthe source oftruth for dim order, so it's already consistent there.
charge_state.dimsflow_rate.dims<0.8(time, cluster)(cluster, time)>=0.8(cluster, time)(cluster, time)Fix
Normalize in
FlowSystemModel.solution:transpose('cluster', 'time', ...).>=0.8and for non-clustered systems.via the ellipsis.
Production code already accesses
charge_statepurely by label, so it wasunaffected either way; this just makes the user-facing solution stable.
The test is updated to access
charge_stateby label and assert thenow-deterministic
(cluster, time). The linopy version bump itself stays in #701.Verification
tests/test_clustering+tests/test_math/test_clustering.py+tests/flow_system/test_flow_system_resample.py: 288 passed.🤖 Generated with Claude Code