diff --git a/CHANGELOG.md b/CHANGELOG.md index 2a043fc56..632fcf7a4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -61,6 +61,8 @@ Please keep the format of the changelog consistent with the other releases, so t ### 📦 Dependencies ### 📝 Docs +- Updated Migration Guide and added missing entries. +- Improved Changelog of v3.0.0 ### 👷 Development @@ -139,17 +141,43 @@ This replaces `specific_share_to_other_effects_*` parameters and inverts the dir ### 💥 Breaking Changes -- `relative_minimum_charge_state` and `relative_maximum_charge_state` don't have an extra timestep anymore. +**API and Behavior Changes:** + +- **Effect system redesigned** (no deprecation): + - **Terminology changes**: Effect domains renamed for clarity: `operation` → `temporal`, `invest`/`investment` → `periodic` + - **Sharing system**: The old `specific_share_to_other_effects_*` parameters were completely replaced with the new `share_from_temporal` and `share_from_periodic` syntax (see 🔥 Removed section) +- **FlowSystem independence**: FlowSystems cannot be shared across multiple Calculations anymore. A copy of the FlowSystem is created instead, making every Calculation independent. Each Subcalculation in `SegmentedCalculation` now has its own distinct `FlowSystem` object +- **Bus and Effect object assignment**: Direct assignment of Bus/Effect objects is no longer supported. Use labels (strings) instead: + - `Flow.bus` must receive a string label, not a Bus object + - Effect shares must use effect labels (strings) in dictionaries, not Effect objects +- **Logging defaults** (from v2.2.0): Console and file logging are now disabled by default. Enable explicitly with `CONFIG.Logging.console = True` and `CONFIG.apply()` + +**Class and Method Renaming:** + - Renamed class `SystemModel` to `FlowSystemModel` - Renamed class `Model` to `Submodel` - Renamed `mode` parameter in plotting methods to `style` -- Renamed investment binary variable `is_invested` to `invested` in `InvestmentModel` -- `Calculation.do_modeling()` now returns the `Calculation` object instead of its `linopy.Model`. Callers that previously accessed the linopy model directly should now use `calculation.do_modeling().model` instead of `calculation.do_modeling()`. +- `Calculation.do_modeling()` now returns the `Calculation` object instead of its `linopy.Model`. Callers that previously accessed the linopy model directly should now use `calculation.do_modeling().model` instead of `calculation.do_modeling()` + +**Variable Renaming in Results:** + +- Investment binary variable: `is_invested` → `invested` in `InvestmentModel` +- Switch tracking variables in `OnOffModel`: + - `switch_on` → `switch|on` + - `switch_off` → `switch|off` + - `switch_on_nr` → `switch|count` +- Effect submodel variables (following terminology changes): + - `Effect(invest)|total` → `Effect(periodic)` + - `Effect(operation)|total` → `Effect(temporal)` + - `Effect(operation)|total_per_timestep` → `Effect(temporal)|per_timestep` + - `Effect|total` → `Effect` + +**Data Structure Changes:** + +- `relative_minimum_charge_state` and `relative_maximum_charge_state` don't have an extra timestep anymore. Use the new `relative_minimum_final_charge_state` and `relative_maximum_final_charge_state` parameters for final state control ### ♻️ Changed -- FlowSystems cannot be shared across multiple Calculations anymore. A copy of the FlowSystem is created instead, making every Calculation independent -- Each Subcalculation in `SegmentedCalculation` now has its own distinct `FlowSystem` object - Type system overhaul - added clear separation between temporal and non-temporal data throughout codebase for better clarity - Enhanced FlowSystem interface with improved `__repr__()` and `__str__()` methods - Improved Model Structure - Views and organisation is now divided into: @@ -164,8 +192,6 @@ This replaces `specific_share_to_other_effects_*` parameters and inverts the dir - The `agg_group` and `agg_weight` parameters of `TimeSeriesData` are deprecated and will be removed in a future version. Use `aggregation_group` and `aggregation_weight` instead. - The `active_timesteps` parameter of `Calculation` is deprecated and will be removed in a future version. Use the new `sel(time=...)` method on the FlowSystem instead. -- The assignment of Bus Objects to Flow.bus is deprecated and will be removed in a future version. Use the label of the Bus instead. -- The usage of Effects objects in Dicts to assign shares to Effects is deprecated and will be removed in a future version. Use the label of the Effect instead. - **InvestParameters** parameters renamed for improved clarity around investment and retirement effects: - `fix_effects` → `effects_of_investment` - `specific_effects` → `effects_of_investment_per_size` diff --git a/docs/user-guide/migration-guide-v3.md b/docs/user-guide/migration-guide-v3.md index 190503dc3..a98824de1 100644 --- a/docs/user-guide/migration-guide-v3.md +++ b/docs/user-guide/migration-guide-v3.md @@ -1,550 +1,233 @@ -# Migration Guide: Upgrading to v3.0.0 - -This guide helps you migrate your flixopt code from v2.x to v3.0.0. Version 3.0.0 introduces powerful new features like multi-period investments and scenario-based stochastic optimization, along with a redesigned effect sharing system. +# Migration Guide: v2.x → v3.0.0 !!! tip "Quick Start" - 1. **Update your installation:** - ```bash - pip install --upgrade flixopt - ``` - 2. **Review breaking changes** in the sections below - 3. **Update deprecated parameters** to their new names - 4. **Test your code** with the new version + ```bash + pip install --upgrade flixopt + ``` + Review [breaking changes](#breaking-changes), update [deprecated parameters](#deprecated-parameters), test thoroughly. --- -## Breaking Changes +## 💥 Breaking Changes -### 1. Effect Sharing System Redesign +### Effect System Redesign -!!! warning "Breaking Change - No Deprecation" - The effect sharing syntax has been inverted and simplified. This change was made WITHOUT deprecation warnings due to the fundamental restructuring. +Terminology changed and sharing system inverted: effects now "pull" shares. -**What changed:** Effects now "pull" shares from other effects instead of "pushing" them. - -=== "v2.x (Old)" +| Concept | Old (v2.x) | New (v3.0.0) | +|---------|------------|--------------| +| Time-varying effects | `operation` | `temporal` | +| Investment effects | `invest` / `investment` | `periodic` | +| Share to other effects (operation) | `specific_share_to_other_effects_operation` | `share_from_temporal` | +| Share to other effects (invest) | `specific_share_to_other_effects_invest` | `share_from_periodic` | +=== "v2.x" ```python - # Effects "pushed" shares to other effects - CO2 = fx.Effect('CO2', 'kg', 'CO2 emissions', + CO2 = fx.Effect('CO2', 'kg', 'CO2', specific_share_to_other_effects_operation={'costs': 0.2}) - - land = fx.Effect('land', 'm²', 'Land usage', - specific_share_to_other_effects_invest={'costs': 100}) - - costs = fx.Effect('costs', '€', 'Total costs') + costs = fx.Effect('costs', '€', 'Total') ``` -=== "v3.0.0 (New)" - +=== "v3.0.0" ```python - # Effects "pull" shares from other effects (clearer direction) - CO2 = fx.Effect('CO2', 'kg', 'CO2 emissions') - - land = fx.Effect('land', 'm²', 'Land usage') - - costs = fx.Effect('costs', '€', 'Total costs', - share_from_temporal={'CO2': 0.2}, # From temporal (operation) effects - share_from_periodic={'land': 100}) # From periodic (investment) effects + CO2 = fx.Effect('CO2', 'kg', 'CO2') + costs = fx.Effect('costs', '€', 'Total', + share_from_temporal={'CO2': 0.2}) # Pull from CO2 ``` -!!! success "Migration Steps" - 1. Find all uses of `specific_share_to_other_effects_operation` and `specific_share_to_other_effects_invest` - 2. Move the share definition to the **receiving** effect - 3. Rename parameters: - - `specific_share_to_other_effects_operation` → `share_from_temporal` - - `specific_share_to_other_effects_invest` → `share_from_periodic` +!!! warning "No deprecation warning" + Move shares to receiving effect and update parameter names throughout your code. --- -### 2. Class and Variable Renaming - -=== "v2.x (Old)" +### Variable Names - ```python - # In optimization results - results.solution['component|is_invested'] - ``` - -=== "v3.0.0 (New)" - - ```python - # In optimization results - results.solution['component|invested'] - ``` +| Category | Old (v2.x) | New (v3.0.0) | +|---------------------------------|------------|--------------| +| Investment | `is_invested` | `invested` | +| Switching | `switch_on` | `switch|on` | +| Switching | `switch_off` | `switch|off` | +| Switching | `switch_on_nr` | `switch|count` | +| Effects | `Effect(invest)|total` | `Effect(periodic)` | +| Effects | `Effect(operation)|total` | `Effect(temporal)` | +| Effects | `Effect(operation)|total_per_timestep` | `Effect(temporal)|per_timestep` | +| Effects | `Effect|total` | `Effect` | --- -### 3. Calculation API Change - -!!! info "Method Chaining Support" - `Calculation.do_modeling()` now returns the Calculation object to enable method chaining. +### String Labels -=== "v2.x (Old)" +| What | Old (v2.x) | New (v3.0.0) | +|------|------------|--------------| +| Bus assignment | `bus=my_bus` (object) | `bus='electricity'` (string) | +| Effect shares | `{CO2: 0.2}` (object key) | `{'CO2': 0.2}` (string key) | +=== "v2.x" ```python - calculation = fx.FullCalculation('my_calc', flow_system) - linopy_model = calculation.do_modeling() # Returned linopy.Model - - # Access model directly from return value - print(linopy_model) + flow = fx.Flow('P_el', bus=my_bus) # ❌ Object + costs = fx.Effect('costs', '€', share_from_temporal={CO2: 0.2}) # ❌ ``` -=== "v3.0.0 (New)" - +=== "v3.0.0" ```python - calculation = fx.FullCalculation('my_calc', flow_system) - calculation.do_modeling() # Returns Calculation object - linopy_model = calculation.model # Access model via property - - # This enables chaining operations - fx.FullCalculation('my_calc', flow_system).do_modeling().solve() + flow = fx.Flow('P_el', bus='electricity') # ✅ String + costs = fx.Effect('costs', '€', share_from_temporal={'CO2': 0.2}) # ✅ ``` -!!! tip "Migration" - If you used the return value of `do_modeling()`, update to access `.model` property instead. - --- -### 4. Storage Charge State Bounds - -!!! warning "Array Dimensions Changed" - `relative_minimum_charge_state` and `relative_maximum_charge_state` no longer have an extra timestep. - -**Impact:** If you provided arrays with `len(timesteps) + 1` elements, reduce to `len(timesteps)`. - -=== "v2.x (Old)" - - ```python - # Array with extra timestep - storage = fx.Storage( - 'storage', - relative_minimum_charge_state=np.array([0.2, 0.2, 0.2, 0.2, 0.2]) # 5 values for 4 timesteps - ) - ``` - -=== "v3.0.0 (New)" +### FlowSystem & Calculation - ```python - # Array matches timesteps - storage = fx.Storage( - 'storage', - relative_minimum_charge_state=np.array([0.2, 0.2, 0.2, 0.2]), # 4 values for 4 timesteps - relative_minimum_final_charge_state=0.3 # Specify the final value directly - ) - ``` - -!!! note "Final State Control" - Use the new `relative_minimum_final_charge_state` and `relative_maximum_final_charge_state` parameters to explicitly control the final charge state. +| Change | Description | +|--------|-------------| +| **FlowSystem copying** | Each `Calculation` gets its own copy (independent) | +| **do_modeling() return** | Returns `Calculation` object (access model via `.model` property) | +| **Storage arrays** | Arrays match timestep count (no extra element) | +| **Final charge state** | Use `relative_minimum_final_charge_state` / `relative_maximum_final_charge_state` | --- -### 5. Plotting Parameter Rename - -=== "v2.x (Old)" - - ```python - results.plot_heatmap('component|variable', mode='line') - ``` +### Other Changes -=== "v3.0.0 (New)" - - ```python - results.plot_heatmap('component|variable', style='line') - ``` +| Category | Old (v2.x) | New (v3.0.0) | +|----------|------------|--------------| +| Plotting parameter | `mode='line'` | `style='line'` | +| System model class | `SystemModel` | `FlowSystemModel` | +| Element submodel | `Model` | `Submodel` | +| Logging default | Enabled | Disabled | +| Enable logging | (default) | `fx.CONFIG.Logging.console = True; fx.CONFIG.apply()` | --- -## Deprecated Parameters (Still Supported) - -!!! info "Gradual Migration" - These parameters still work but will be removed in a future version. Update them at your convenience - deprecation warnings will guide you. +## 🗑️ Deprecated Parameters -### InvestParameters +??? abstract "InvestParameters" -**Parameter Changes:** + | Old (v2.x) | New (v3.0.0) | + |------------|--------------| + | `fix_effects` | `effects_of_investment` | + | `specific_effects` | `effects_of_investment_per_size` | + | `divest_effects` | `effects_of_retirement` | + | `piecewise_effects` | `piecewise_effects_of_investment` | -| Old Parameter (v2.x) | New Parameter (v3.0.0) | -|---------------------|----------------------| -| `fix_effects` | `effects_of_investment` | -| `specific_effects` | `effects_of_investment_per_size` | -| `divest_effects` | `effects_of_retirement` | -| `piecewise_effects` | `piecewise_effects_of_investment` | +??? abstract "Effect" -=== "v2.x (Deprecated)" + | Old (v2.x) | New (v3.0.0) | + |------------|--------------| + | `minimum_investment` | `minimum_periodic` | + | `maximum_investment` | `maximum_periodic` | + | `minimum_operation` | `minimum_temporal` | + | `maximum_operation` | `maximum_temporal` | + | `minimum_operation_per_hour` | `minimum_per_hour` | + | `maximum_operation_per_hour` | `maximum_per_hour` | - ```python - fx.InvestParameters( - fix_effects=1000, - specific_effects={'costs': 10}, - divest_effects=100, - piecewise_effects=my_piecewise, - ) - ``` - -=== "v3.0.0 (Recommended)" - - ```python - fx.InvestParameters( - effects_of_investment=1000, - effects_of_investment_per_size={'costs': 10}, - effects_of_retirement=100, - piecewise_effects_of_investment=my_piecewise, - ) - ``` - -### Effect - -**Parameter Changes:** - -| Old Parameter (v2.x) | New Parameter (v3.0.0) | -|---------------------|----------------------| -| `minimum_investment` | `minimum_periodic` | -| `maximum_investment` | `maximum_periodic` | -| `minimum_operation` | `minimum_temporal` | -| `maximum_operation` | `maximum_temporal` | -| `minimum_operation_per_hour` | `minimum_per_hour` | -| `maximum_operation_per_hour` | `maximum_per_hour` | - -=== "v2.x (Deprecated)" - - ```python - fx.Effect( - 'my_effect', 'unit', 'description', - minimum_investment=10, - maximum_investment=100, - minimum_operation=5, - maximum_operation=50, - minimum_operation_per_hour=1, - maximum_operation_per_hour=10, - ) - ``` +??? abstract "Components" -=== "v3.0.0 (Recommended)" + | Old (v2.x) | New (v3.0.0) | + |------------|--------------| + | `source` (parameter) | `outputs` | + | `sink` (parameter) | `inputs` | + | `prevent_simultaneous_sink_and_source` | `prevent_simultaneous_flow_rates` | - ```python - fx.Effect( - 'my_effect', 'unit', 'description', - minimum_periodic=10, - maximum_periodic=100, - minimum_temporal=5, - maximum_temporal=50, - minimum_per_hour=1, - maximum_per_hour=10, - ) - ``` +??? abstract "TimeSeriesData" -### Component Parameters + | Old (v2.x) | New (v3.0.0) | + |------------|--------------| + | `agg_group` | `aggregation_group` | + | `agg_weight` | `aggregation_weight` | -=== "v2.x (Deprecated)" +??? abstract "Calculation" - ```python - fx.Source('my_source', source=flow) + | Old (v2.x) | New (v3.0.0) | + |------------|--------------| + | `active_timesteps=[0, 1, 2]` | Use `flow_system.sel()` or `flow_system.isel()` | - fx.Sink('my_sink', sink=flow) +--- - fx.SourceAndSink( - 'my_source_sink', - source=flow1, - sink=flow2, - prevent_simultaneous_sink_and_source=True - ) - ``` +## ✨ New Features -=== "v3.0.0 (Recommended)" +??? success "Multi-Period Investments" ```python - fx.Source('my_source', outputs=flow) - - fx.Sink('my_sink', inputs=flow) - - fx.SourceAndSink( - 'my_source_sink', - outputs=flow1, - inputs=flow2, - prevent_simultaneous_flow_rates=True - ) + periods = pd.Index(['2020', '2030']) + flow_system = fx.FlowSystem(time=timesteps, periods=periods) ``` -### TimeSeriesData +??? success "Scenario-Based Optimization" -=== "v2.x (Deprecated)" + | Parameter | Description | Example | + |-----------|-------------|---------| + | `scenarios` | Scenario index | `pd.Index(['low', 'base', 'high'], name='scenario')` | + | `scenario_weights` | Probabilities | `[0.2, 0.6, 0.2]` | + | `scenario_independent_sizes` | Separate capacities per scenario | `True` / `False` (default) | ```python - fx.TimeSeriesData( - agg_group='group1', - agg_weight=2.0 + flow_system = fx.FlowSystem( + time=timesteps, + scenarios=scenarios, + scenario_weights=[0.2, 0.6, 0.2], + scenario_independent_sizes=True ) ``` -=== "v3.0.0 (Recommended)" +??? success "Enhanced I/O" - ```python - fx.TimeSeriesData( - aggregation_group='group1', - aggregation_weight=2.0 - ) - ``` - -### Calculation - -=== "v2.x (Deprecated)" - - ```python - calculation = fx.FullCalculation( - 'calc', - flow_system, - active_timesteps=[0, 1, 2] - ) - ``` + | Method | Description | + |--------|-------------| + | `flow_system.to_netcdf('file.nc')` | Save FlowSystem | + | `fx.FlowSystem.from_netcdf('file.nc')` | Load FlowSystem | + | `flow_system.sel(time=slice(...))` | Select by label | + | `flow_system.isel(time=slice(...))` | Select by index | + | `flow_system.resample(time='D')` | Resample timeseries | + | `flow_system.copy()` | Deep copy | + | `results.flow_system` | Access from results | -=== "v3.0.0 (Recommended)" +??? success "Effects Per Component" ```python - # Use FlowSystem selection methods - flow_system_subset = flow_system.sel(time=slice('2020-01-01', '2020-01-03')) - calculation = fx.FullCalculation('calc', flow_system_subset) + effects_ds = results.effects_per_component - # Or with isel for index-based selection - flow_system_subset = flow_system.isel(time=slice(0, 3)) - calculation = fx.FullCalculation('calc', flow_system_subset) + # Access effect contributions by component + print(effects_ds['total'].sel(effect='costs')) # Total effects + print(effects_ds['temporal'].sel(effect='CO2')) # Temporal effects + print(effects_ds['periodic'].sel(effect='costs')) # Periodic effects ``` ---- - -## New Features in v3.0.0 - -### 1. Multi-Period Investments - -Model transformation pathways with distinct investment decisions in each period: - -```python -import pandas as pd - -# Define multiple investment periods -periods = pd.Index(['2020', '2030']) -flow_system = fx.FlowSystem(time=timesteps, periods=periods) - -# Components can now invest differently in each period -solar = fx.Source( - 'solar', - outputs=[fx.Flow( - 'P_el', - bus='electricity', - size=fx.InvestParameters( - minimum_size=0, - maximum_size=1000, - effects_of_investment_per_size={'costs': 100} - ) - )] -) -``` - -### 2. Scenario-Based Stochastic Optimization - -Model uncertainty with weighted scenarios: - -```python -# Define scenarios with probabilities -scenarios = pd.Index(['low_demand', 'base', 'high_demand'], name='scenario') -scenario_weights = [0.2, 0.6, 0.2] # Probabilities - -flow_system = fx.FlowSystem( - time=timesteps, - scenarios=scenarios, - scenario_weights=scenario_weights -) - -# Define scenario-dependent data -demand = xr.DataArray( - data=[[70, 80, 90], # low_demand scenario - [90, 100, 110], # base scenario - [110, 120, 130]], # high_demand scenario - dims=['scenario', 'time'], - coords={'scenario': scenarios, 'time': timesteps} -) - -``` - -**Control variable independence:** -```python -# By default: investment sizes are shared across scenarios, flow rates vary -# To make sizes scenario-independent: -flow_system = fx.FlowSystem( - time=timesteps, - scenarios=scenarios, - scenario_independent_sizes=True # Each scenario gets its own capacity -) -``` - -### 3. Enhanced I/O and Data Handling - -```python -# Save and load FlowSystem -flow_system.to_netcdf('my_system.nc') -flow_system_loaded = fx.FlowSystem.from_netcdf('my_system.nc') - -# Manipulate FlowSystem -fs_subset = flow_system.sel(time=slice('2020-01', '2020-06')) -fs_resampled = flow_system.resample(time='D') # Resample to daily -fs_copy = flow_system.copy() - -# Access FlowSystem from results (lazily loaded) -results = calculation.results -original_fs = results.flow_system # No manual restoration needed -``` - -### 4. Effects Per Component - -Analyze the impact of each component, including indirect effects through effect shares: - -```python -# Get dataset showing contribution of each component to all effects -effects_ds = calculation.results.effects_per_component() - -print(effects_ds['costs']) # Total costs by component -print(effects_ds['CO2']) # CO2 emissions by component (including indirect) -``` - -### 5. Balanced Storage - -Force charging and discharging capacities to be equal: - -```python -storage = fx.Storage( - 'storage', - charging=fx.Flow('charge', bus='electricity', size=fx.InvestParameters(effects_per_size=100, minimum_size=5)), - discharging=fx.Flow('discharge', bus='electricity', size=fx.InvestParameters(), - balanced=True, # Ensures charge_size == discharge_size - capacity_in_flow_hours=100 -) -``` - -### 6. Final Charge State Control - -Set bounds on the storage state at the end of the optimization: - -```python -storage = fx.Storage( - 'storage', - charging=fx.Flow('charge', bus='electricity', size=100), - discharging=fx.Flow('discharge', bus='electricity', size=100), - capacity_in_flow_hours=10, - relative_minimum_final_charge_state=0.5, # End at least 50% charged - relative_maximum_final_charge_state=0.8 # End at most 80% charged -) -``` - ---- - -## Configuration Changes - -### Logging (v2.2.0+) +??? success "Storage Features" -**Breaking change:** Console and file logging are now disabled by default. - -```python -import flixopt as fx - -# Enable console logging -fx.CONFIG.Logging.console = True -fx.CONFIG.Logging.level = 'INFO' -fx.CONFIG.apply() - -# Enable file logging -fx.CONFIG.Logging.file = 'flixopt.log' -fx.CONFIG.apply() - -# Deprecated: change_logging_level() - will be removed in future -# fx.change_logging_level('INFO') # ❌ Old way -``` + | Feature | Parameter | Description | + |---------|-----------|-------------| + | **Balanced storage** | `balanced=True` | Ensures charge_size == discharge_size | + | **Final state min** | `relative_minimum_final_charge_state=0.5` | End at least 50% charged | + | **Final state max** | `relative_maximum_final_charge_state=0.8` | End at most 80% charged | --- -## Testing Your Migration - -### 1. Check for Deprecation Warnings - -Run your code and watch for deprecation warnings: - -```python -import warnings -warnings.filterwarnings('default', category=DeprecationWarning) +## 🔧 Common Issues -# Run your flixopt code -# Review any DeprecationWarning messages -``` - -### 2. Validate Results - -Compare results from v2.x and v3.0.0 to ensure consistency: - -```python -# Save v2.x results before upgrading -calculation.results.to_file('results_v2.nc') - -# After upgrading, compare -results_v3 = calculation.results -results_v2 = fx.CalculationResults.from_file('results_v2.nc') - -# Check key variables match (within numerical tolerance) -import numpy as np -v2_costs = results_v2['effect_values'].sel(effect='costs') -v3_costs = results_v3['effect_values'].sel(effect='costs') -np.testing.assert_allclose(v2_costs, v3_costs, rtol=1e-5) -``` +| Issue | Solution | +|-------|----------| +| Effect shares not working | See [Effect System Redesign](#effect-system-redesign) | +| Storage dimensions wrong | See [FlowSystem & Calculation](#flowsystem-calculation) | +| Bus assignment error | See [String Labels](#string-labels) | +| KeyError in results | See [Variable Names](#variable-names) | +| `AttributeError: model` | Rename `.model` → `.submodel` | +| No logging | See [Other Changes](#other-changes) | --- -## Common Migration Issues - -### Issue: "Effect share parameters not working" - -**Solution:** Effect sharing was completely redesigned. Move share definitions to the **receiving** effect using `share_from_temporal` and `share_from_periodic`. +## ✅ Checklist -### Issue: "Storage charge state has wrong dimensions" - -**Solution:** Remove the extra timestep from charge state bound arrays. - -### Issue: "Import error with Bus assignment" - -**Solution:** Pass bus labels (strings) instead of Bus objects to `Flow.bus`. - -```python -# Old -my_bus = fx.Bus('electricity') -flow = fx.Flow('P_el', bus=my_bus) # ❌ - -# New -my_bus = fx.Bus('electricity') -flow = fx.Flow('P_el', bus='electricity') # ✅ -``` - -### Issue: "AttributeError: module 'flixopt' has no attribute 'SystemModel'" - -**Solution:** Rename `SystemModel` → `FlowSystemModel` - - ---- - -## Getting Help - -- **Documentation:** [https://flixopt.github.io/flixopt/](https://flixopt.github.io/flixopt/) -- **GitHub Issues:** [https://github.com/flixOpt/flixopt/issues](https://github.com/flixOpt/flixopt/issues) -- **Changelog:** [Full v3.0.0 release notes](https://flixopt.github.io/flixopt/latest/changelog/99984-v3.0.0/) +| Category | Tasks | +|----------|-------| +| **Install** | • `pip install --upgrade flixopt` | +| **Breaking changes** | • Update [effect sharing](#effect-system-redesign)
• Update [variable names](#variable-names)
• Update [string labels](#string-labels)
• Fix [storage arrays](#flowsystem-calculation)
• Update [Calculation API](#flowsystem-calculation)
• Rename plotting `mode` → `style`
• Update [class names](#other-changes) | +| **Configuration** | • Enable [logging](#other-changes) if needed | +| **Deprecated** | • Update [deprecated parameters](#deprecated-parameters) (recommended) | +| **Testing** | • Test thoroughly
• Validate results match v2.x | --- -## Summary Checklist - -- [ ] Update flixopt: `pip install --upgrade flixopt` -- [ ] Update effect sharing syntax (no deprecation warning!) -- [ ] Update `Calculation.do_modeling()` usage -- [ ] Fix storage charge state array dimensions -- [ ] Rename `mode` → `style` in plotting calls -- [ ] Update deprecated parameter names (optional, but recommended) -- [ ] Enable logging explicitly if needed -- [ ] Test your code thoroughly -- [ ] Explore new features (periods, scenarios, enhanced I/O) +:material-book: [Docs](https://flixopt.github.io/flixopt/) • :material-github: [Issues](https://github.com/flixOpt/flixopt/issues) • :material-text-box: [Changelog](https://flixopt.github.io/flixopt/latest/changelog/99984-v3.0.0/) -**Welcome to flixopt v3.0.0!** 🎉 +!!! success "Welcome to flixopt v3.0.0! 🎉" diff --git a/mkdocs.yml b/mkdocs.yml index 72ecbe549..8ed2c4b2c 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -91,6 +91,7 @@ markdown_extensions: line_spans: __span pygments_lang_class: true - pymdownx.inlinehilite + - pymdownx.details - pymdownx.superfences - attr_list - abbr