Skip to content

Add FlowSystemStatus enum and restructure validation architecture#598

Merged
FBumann merged 9 commits intofeature/element-data-classesfrom
feature/element-data-classes+validation
Feb 5, 2026
Merged

Add FlowSystemStatus enum and restructure validation architecture#598
FBumann merged 9 commits intofeature/element-data-classesfrom
feature/element-data-classes+validation

Conversation

@FBumann
Copy link
Member

@FBumann FBumann commented Feb 3, 2026

Description

This PR introduces explicit lifecycle status tracking for FlowSystem and restructures the validation architecture for better separation of concerns.

Key Changes

  1. FlowSystemStatus Enum (flow_system_status.py)

    • New FlowSystemStatus IntEnum with 5 lifecycle states: INITIALIZED, CONNECTED, MODEL_CREATED, MODEL_BUILT, SOLVED
    • Status-based invalidation via invalidate_to_status() that clears appropriate caches when status drops
    • Replaced boolean flags (is_locked, _connected_and_transformed) with derived properties from status
  2. Validation Architecture Split

    • validate_config() on Element classes (Flow, Storage, Component, Bus, Effect, etc.) - simple checks that don't require DataArrays (None checks, isinstance, basic constraints)
    • validate() on *Data classes (FlowsData, StoragesData, etc.) - batched DataArray validation checks
  3. BatchedAccessor Caching

    • All *Data objects (flows, storages, buses, effects, components, converters, transmissions) are now cached in BatchedAccessor
    • Cached instances are reused in both _run_validation() and build_model(), avoiding duplicate creation
    • Cache is cleared via _reset() during status invalidation
  4. Bug Fix: Validation Order (commit a5157a2)

    • Fixed regression where Bus with no flows caused cryptic TypeError instead of clear ValueError
    • Reordered validation: buses validated before flows to catch "no flows" error early
    • Added guard in FlowsData.validate() for empty flows edge case

Type of Change

  • Code refactoring
  • New feature
  • Bug fix

Testing

  • I have tested my changes
  • Existing tests still pass
  • All 188 core element tests pass
  • Validation regression tests verify all checks are preserved

Checklist

  • My code follows the project style
  • I have updated documentation if needed
  • I have added tests for new functionality (if applicable)

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 3, 2026

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

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 implements a comprehensive validation architecture refactoring by introducing validate_config methods across element and component classes, adding batch-level validation to data containers, and establishing a cached BatchedAccessor for efficient batched data access. The validation flow shifts from per-element checks to a centralized, batched approach integrated within FlowSystem.

Changes

Cohort / File(s) Summary
Validation API Standardization
flixopt/elements.py, flixopt/components.py, flixopt/effects.py
Added validate_config() methods to Component, Bus, Flow, Storage, LinearConverter, Transmission, Effect, EffectsModel, and EffectCollection classes. Existing _plausibility_checks() now delegate to validate_config() for backward compatibility, centralizing configuration-level validation logic.
Batched Data Validation
flixopt/batched.py
Added validate() methods to StoragesData, FlowsData, EffectsData, BusesData, ComponentsData, ConvertersData, and TransmissionsData for batch-level plausibility checks. Introduced BatchedAccessor with cached properties (storages, intercluster_storages, buses, effects, components, converters, transmissions) and a unified validate() entry point. Added module-level logger setup.
Validation & Data Access Integration
flixopt/flow_system.py, flixopt/structure.py
Replaced per-element plausibility check loops with batched validation via BatchedAccessor. Consolidated data object creation by using cached batched.* properties instead of creating separate data containers, reducing redundant instantiations in model building.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • Feature/simplify structure #464: Complements this PR's validation architecture by refactoring _set_flow_system and transform_data plumbing that coordinates element linking to FlowSystem alongside the new batched validate/BatchedAccessor patterns.

Suggested labels

v3.0.0

Poem

🐰 Hop! Hop! Validation's reformed,
From scattered checks to batches warmed,
AccessData cached and true,
Old _plausibility delegates too!
A cleaner flow, more organized so!

🚥 Pre-merge checks | ✅ 1 | ❌ 2
❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 78.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ⚠️ Warning The title mentions 'FlowSystemStatus enum' but the raw_summary shows no changes to flow_system_status.py file or enum creation; actual changes focus on validation architecture restructuring. Update title to accurately reflect the main change: 'Restructure validation architecture with separate validate_config and validate methods' or similar.
✅ Passed checks (1 passed)
Check name Status Explanation
Description check ✅ Passed The pull request description is comprehensive and well-structured, covering all key changes, type of change, testing status, and checklist items.

✏️ 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/element-data-classes+validation

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.

  Classes Updated with validate_config()
  ┌──────────────────┬───────────────┬────────────────────────────────────────────────────────────────────────────┐
  │      Class       │   Location    │                               Config Checks                                │
  ├──────────────────┼───────────────┼────────────────────────────────────────────────────────────────────────────┤
  │ Component        │ elements.py   │ unique flow labels, status→flows.size                                      │
  ├──────────────────┼───────────────┼────────────────────────────────────────────────────────────────────────────┤
  │ Bus              │ elements.py   │ no flows connected                                                         │
  ├──────────────────┼───────────────┼────────────────────────────────────────────────────────────────────────────┤
  │ Flow             │ elements.py   │ status→size, fixed_profile→size, load_factor→size, previous_flow_rate type │
  ├──────────────────┼───────────────┼────────────────────────────────────────────────────────────────────────────┤
  │ Effect           │ effects.py    │ period dimension for over_periods constraints                              │
  ├──────────────────┼───────────────┼────────────────────────────────────────────────────────────────────────────┤
  │ EffectCollection │ effects.py    │ circular loops, unknown effect refs                                        │
  ├──────────────────┼───────────────┼────────────────────────────────────────────────────────────────────────────┤
  │ LinearConverter  │ components.py │ conversion_factors XOR piecewise, degrees_of_freedom, flow refs            │
  ├──────────────────┼───────────────┼────────────────────────────────────────────────────────────────────────────┤
  │ Storage          │ components.py │ initial_charge_state string, balanced→InvestParams, final_charge→capacity  │
  ├──────────────────┼───────────────┼────────────────────────────────────────────────────────────────────────────┤
  │ Transmission     │ components.py │ bus consistency, balanced→InvestParams                                     │
  └──────────────────┴───────────────┴────────────────────────────────────────────────────────────────────────────┘
  *Data Classes with validate()
  ┌───────────────────┬────────────┬─────────────────────────────────────────────────────────────────────────┐
  │       Class       │  Location  │                            DataArray Checks                             │
  ├───────────────────┼────────────┼─────────────────────────────────────────────────────────────────────────┤
  │ FlowsData         │ batched.py │ relative_min ≤ max, size required for bounds                            │
  ├───────────────────┼────────────┼─────────────────────────────────────────────────────────────────────────┤
  │ StoragesData      │ batched.py │ capacity for relative bounds, initial vs capacity, balanced size compat │
  ├───────────────────┼────────────┼─────────────────────────────────────────────────────────────────────────┤
  │ BusesData         │ batched.py │ imbalance_penalty == 0 warning                                          │
  ├───────────────────┼────────────┼─────────────────────────────────────────────────────────────────────────┤
  │ TransmissionsData │ batched.py │ balanced size compatibility                                             │
  ├───────────────────┼────────────┼─────────────────────────────────────────────────────────────────────────┤
  │ EffectsData       │ batched.py │ delegates to validate_config()                                          │
  ├───────────────────┼────────────┼─────────────────────────────────────────────────────────────────────────┤
  │ ComponentsData    │ batched.py │ delegates to validate_config()                                          │
  ├───────────────────┼────────────┼─────────────────────────────────────────────────────────────────────────┤
  │ ConvertersData    │ batched.py │ delegates to validate_config()                                          │
  └───────────────────┴────────────┴─────────────────────────────────────────────────────────────────────────┘
  Updated FlowSystem

  _run_plausibility_checks() now creates temporary *Data instances and calls validate() on each, which handles both config and DataArray checks in a centralized way.
  What Changed

  *1. BatchedAccessor now caches all Data classes:
  class BatchedAccessor:
      @Property
      def flows(self) -> FlowsData: ...
      @Property
      def storages(self) -> StoragesData: ...
      @Property
      def intercluster_storages(self) -> StoragesData: ...
      @Property
      def buses(self) -> BusesData: ...
      @Property
      def effects(self) -> EffectsData: ...
      @Property
      def components(self) -> ComponentsData: ...
      @Property
      def converters(self) -> ConvertersData: ...
      @Property
      def transmissions(self) -> TransmissionsData: ...

  2. FlowSystemModel.build_model() now uses cached instances:
  batched = self.flow_system.batched
  self.effects = EffectsModel(self, batched.effects)  # reuses cached
  self._flows_model = FlowsModel(self, batched.flows)  # reuses cached
  # etc.

  3. _run_plausibility_checks() simplified:
  batched = self.batched
  batched.flows.validate()
  batched.buses.validate()
  # etc.

  Benefits

  - No duplicate creation: Same *Data objects used for validation AND model building
  - Early validation: Errors caught during connect_and_transform()
  - Proper invalidation: _batched = None when status drops below CONNECTED
  - Cleaner code: No temporary object creation in validation or build_model
@FBumann
Copy link
Member Author

FBumann commented Feb 3, 2026

@coderabbitai review

@FBumann FBumann marked this pull request as ready for review February 3, 2026 21:34
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 3, 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.

@FBumann FBumann changed the title Move validation to FlowsData mostly Add FlowSystemStatus enum and restructure validation architecture Feb 3, 2026
  When a Bus has no flows connected, FlowsData.validate() crashed with a cryptic TypeError instead of raising a clear ValueError message.

  Root Cause

  In _run_validation(), the validation order was:
  1. batched.flows.validate() ← crashed on empty DataArray operations
  2. batched.buses.validate() ← would have caught the error
@FBumann
Copy link
Member Author

FBumann commented Feb 4, 2026

@coderabbitai review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 4, 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.

@FBumann FBumann merged commit 0b4a395 into feature/element-data-classes Feb 5, 2026
4 of 8 checks passed
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