Skip to content

Conversation

@FBumann
Copy link
Member

@FBumann FBumann commented Feb 2, 2026

Summary

  • New tests/test_math/ directory with 21 small, analytically verifiable optimization tests
  • Each test has a hand-calculated expected value — any math regression directly changes the result
  • Tests are tiny (2–5 timesteps), isolate one feature each, and run in ~6s total

Test Coverage

Covered (21 tests across 7 files)

File Tests Features
test_conversion.py 3 Boiler efficiency, variable efficiency, CHP dual output
test_storage.py 4 Temporal arbitrage, losses, charge/discharge eta, SOC bounds
test_status.py 4 Startup cost, active_hours_max, min_uptime, min_downtime
test_piecewise.py 2 Segment selection, breakpoint consistency
test_investment.py 3 Optimal sizing, optional invest skipped, minimum_size
test_effects.py 3 effects_per_flow_hour, share_from_temporal, maximum_total
test_bus.py 2 Merit-order dispatch, imbalance penalty

Not Yet Covered (planned)

Flow:

  • relative_minimum / relative_maximum
  • flow_hours_max / flow_hours_min
  • load_factor_min / load_factor_max

Effect:

  • share_from_periodic
  • minimum_total
  • maximum_temporal / minimum_temporal
  • maximum_per_hour / minimum_per_hour

Storage:

  • initial_charge_state='equals_final' (cyclic)
  • minimal_final_charge_state
  • capacity_in_flow_hours as InvestParameters
  • prevent_simultaneous_charge_and_discharge

InvestParameters:

  • fixed_size
  • piecewise_effects_of_investment

StatusParameters:

  • effects_per_active_hour
  • active_hours_min
  • max_downtime
  • startup_limit

Source/Sink:

  • prevent_simultaneous_flow_rates

Test Plan

pytest tests/test_math/ -v

Summary by CodeRabbit

  • Tests
    • Added comprehensive test coverage for flow system optimization, including bus dispatch behavior, conversion efficiency (boiler and CHP), effect accumulation and sharing, investment sizing, piecewise linearization, status constraints (startup, uptime, downtime), and storage capabilities (arbitrage, losses, charge/discharge efficiency, cyclic states, capacity investment).

…0 to eta=0.5. Now the expected cost is 40 (fuel=20/0.5). If investment logic were broken and allowed free

  investment, the optimizer would use the high-efficiency invest boiler instead, yielding cost=20 — a clearly different value.

  test_bus_balance_exact → test_merit_order_dispatch: Renamed to reflect what it actually tests. Added explicit per-source flow assertions (src1=[20,20], src2=[10,10]) instead
  of just checking their sum, which was tautologically true given bus balance is a fundamental model constraint.
  Test: test_storage_soc_bounds
  Category: Storage
  What it proves: relative_maximum_charge_state=0.5 limits usable capacity to 50/100 kWh, forcing 10 kWh from expensive source (cost 1050 vs 60 without limit)
  ────────────────────────────────────────
  Test: test_min_uptime_forces_operation
  Category: Status
  What it proves: min_uptime=2, max_uptime=2 forces boiler into blocks of exactly 2 hours, dictating the on/off pattern [1,1,0,1,1] and total cost 190
  ────────────────────────────────────────
  Test: test_min_downtime_prevents_restart
  Category: Status
  What it proves: min_downtime=3 prevents cheap boiler from restarting at t=2 after shutting down at t=1, forcing expensive backup (cost 60 vs 40 without constraint)
  ────────────────────────────────────────
  Test: test_piecewise_selects_cheap_segment
  Category: Piecewise
  What it proves: Optimizer correctly interpolates within the efficient segment of a 2-piece conversion (cost ≈153.33)
  ────────────────────────────────────────
  Test: test_piecewise_conversion_at_breakpoint
  Category: Piecewise
  What it proves: At segment boundary, fuel=30 exactly matches both segments' definition; verifies breakpoint continuity
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 2, 2026

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

  • 🔍 Trigger a full review
📝 Walkthrough

Walkthrough

This PR introduces a comprehensive test suite for a flow-based optimization framework, covering bus dispatch logic, conversion efficiency (boilers and CHP), effects and constraints, investment sizing, piecewise conversions, temporal status constraints, and storage arbitrage, along with reusable test helpers.

Changes

Cohort / File(s) Summary
Test Infrastructure
tests/test_math/conftest.py
Helper functions make_flow_system() and solve() for constructing minimal FlowSystem instances and performing deterministic optimization with HiGHS solver for test consistency.
Bus and Dispatch Behavior
tests/test_math/test_bus.py
Three tests validating bus balance, merit-order dispatch with cost verification, imbalance penalties, and prevention of simultaneous flow rates to enforce sequential operation.
Conversion Efficiency
tests/test_math/test_conversion.py
Three tests for boiler and CHP conversion behavior, covering constant efficiency, time-varying efficiency per timestep, and dual-output CHP with revenue considerations.
Effects Framework
tests/test_math/test_effects.py
Comprehensive suite validating effects accumulation per flow-hour, temporal and periodic sharing rules, and constraint enforcement (maximum/minimum total, per-hour, and temporal bounds) across diverse components.
Investment Sizing
tests/test_math/test_investment.py
Five tests for investment logic including optimal sizing, optional investment decisions, minimum size enforcement, fixed-size constraints, and piecewise nonlinear cost modeling.
Piecewise Linearization
tests/test_math/test_piecewise.py
Two tests validating correct segment selection and interpolation within two-segment piecewise converter configurations, including behavior at breakpoints.
Status Constraints
tests/test_math/test_status.py
Comprehensive tests for boiler/backup status constraints including startup costs, active-hour limits and minimums, uptime/downtime enforcement, and startup rate limits with cost implications.
Storage Behavior
tests/test_math/test_storage.py
Eight tests covering temporal arbitrage, losses, charge/discharge efficiencies, state-of-charge bounds, cyclic charging, investment sizing, and prevention of simultaneous charge-discharge operations.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

🐰 Hops through the test suite, nose twitching with glee,
Effects and storage, investments so free!
From buses to boilers, with constraints so tight,
These tests ensure optimization runs right!
Piecewise and periodic, status so keen—
The finest-tuned flow system ever seen!

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title directly describes the main change: adding a comprehensive mathematical correctness test suite with 21 tests across 7 test files.
Description check ✅ Passed The description is well-structured with a summary, detailed test coverage table, planned features, and test plan. It provides clear context on what was added and what remains to be covered.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/test-math

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@FBumann FBumann changed the title Feature/test math Add mathematical correctness test suite Feb 2, 2026
…─────────────────────────────────────────────────────────────────────────────┐

  │           File           │  New tests   │                                           Features covered                                           │
  ├──────────────────────────┼──────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ test_flow_constraints.py │ 6 (new file) │ relative_minimum, relative_maximum, flow_hours_max, flow_hours_min, load_factor_max, load_factor_min │
  ├──────────────────────────┼──────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ test_effects.py          │ +3           │ minimum_total, maximum_per_hour, minimum_per_hour                                                    │
  ├──────────────────────────┼──────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ test_storage.py          │ +3           │ initial_charge_state='equals_final', minimal_final_charge_state, capacity_in_flow_hours as invest    │
  ├──────────────────────────┼──────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ test_investment.py       │ +1           │ fixed_size                                                                                           │
  ├──────────────────────────┼──────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ test_status.py           │ +4           │ effects_per_active_hour, active_hours_min, max_downtime, startup_limit                               │
  ├──────────────────────────┼──────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ test_bus.py              │ +1           │ prevent_simultaneous_flow_rates                                                                      │
  Final: 44 tests across 8 files (~19s)
  File: test_conversion.py
  Tests: 3
  Features: boiler eta, variable eta, CHP dual output
  ────────────────────────────────────────
  File: test_bus.py
  Tests: 3
  Features: merit order, imbalance penalty, prevent_simultaneous_flow_rates
  ────────────────────────────────────────
  File: test_effects.py
  Tests: 9
  Features: effects_per_flow_hour, share_from_temporal, share_from_periodic, maximum/minimum_total, maximum/minimum_per_hour, maximum/minimum_temporal
  ────────────────────────────────────────
  File: test_flow_constraints.py
  Tests: 6
  Features: relative_minimum/maximum, flow_hours_min/max, load_factor_min/max
  ────────────────────────────────────────
  File: test_investment.py
  Tests: 5
  Features: optimal sizing, optional skip, minimum_size, fixed_size, piecewise_effects_of_investment
  ────────────────────────────────────────
  File: test_status.py
  Tests: 8
  Features: startup cost, active_hours_min/max, min/max_uptime, min/max_downtime, startup_limit, effects_per_active_hour
  ────────────────────────────────────────
  File: test_storage.py
  Tests: 8
  Features: arbitrage, losses, eta charge/discharge, SOC bounds, cyclic, final charge state, invest capacity, prevent simultaneous
  ────────────────────────────────────────
  File: test_piecewise.py
  Tests: 2
  Features: segment selection, breakpoint consistency
@FBumann
Copy link
Member Author

FBumann commented Feb 2, 2026

@coderabbitai review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 2, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

  - mandatory=True/False - forces vs optional investment
  - effects_of_retirement - penalty for NOT investing
  - InvestParameters + StatusParameters - combined sizing with on/off behavior
  - previous_flow_rate - scalar and array forms for uptime/downtime carry-over
  - Piecewise with gaps - forbidden operating regions

  All tests assert on cost differences to ensure they fail on regression.
…tatusParameters tests added:

  ┌───────────────────────────────────────────────┬────────────────────────────┬──────────────────────────────────────────────┐
  │                     Test                      │      StatusParameter       │                What it proves                │
  ├───────────────────────────────────────────────┼────────────────────────────┼──────────────────────────────────────────────┤
  │ test_component_status_effects_per_active_hour │ effects_per_active_hour=50 │ Adds 50€/hour cost when component is ON      │
  ├───────────────────────────────────────────────┼────────────────────────────┼──────────────────────────────────────────────┤
  │ test_component_status_active_hours_min        │ active_hours_min=2         │ Forces component to run minimum 2 hours      │
  ├───────────────────────────────────────────────┼────────────────────────────┼──────────────────────────────────────────────┤
  │ test_component_status_max_uptime              │ max_uptime=2, min_uptime=2 │ Limits continuous operation to 2-hour blocks │
  ├───────────────────────────────────────────────┼────────────────────────────┼──────────────────────────────────────────────┤
  │ test_component_status_min_downtime            │ min_downtime=3             │ Prevents restart for 3 hours after shutdown  │
  ├───────────────────────────────────────────────┼────────────────────────────┼──────────────────────────────────────────────┤
  │ test_component_status_max_downtime            │ max_downtime=1             │ Forces restart after maximum 1 hour off      │
  ├───────────────────────────────────────────────┼────────────────────────────┼──────────────────────────────────────────────┤
  │ test_component_status_startup_limit           │ startup_limit=1            │ Caps number of startups to 1                 │
  └───────────────────────────────────────────────┴────────────────────────────┴──────────────────────────────────────────────┘
  Previously we had 3 component-level status tests (startup_cost, min_uptime, active_hours_max). Now we have 9 tests covering all StatusParameters options at the component
  level.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant