diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 8d0d0de1f..4f1edd3e8 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -80,7 +80,7 @@ jobs: name: Run tests needs: [check-preparation] if: needs.check-preparation.outputs.prepared == 'true' - uses: ./.github/workflows/test.yaml + uses: ./.github/workflows/tests.yaml build: name: Build package diff --git a/.github/workflows/test.yaml b/.github/workflows/tests.yaml similarity index 96% rename from .github/workflows/test.yaml rename to .github/workflows/tests.yaml index 395fc766c..5fa245f49 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/tests.yaml @@ -4,9 +4,9 @@ on: push: branches: [main] pull_request: - branches: ["*"] + branches: ["**"] workflow_dispatch: - workflow_call: # Allow release.yaml to call this workflow + workflow_call: # Allow release.yaml to call this workflow. concurrency: group: ${{ github.workflow }}-${{ github.ref }} diff --git a/.gitignore b/.gitignore index cc2179b07..169c1a587 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,7 @@ venv/ .DS_Store lib/ temp-plot.html +.cache +site/ +*.egg-info +uv.lock diff --git a/CHANGELOG.md b/CHANGELOG.md index 7544375ff..914ef2666 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,7 +16,7 @@ This contains all commits, PRs, and contributors. Therefore, the Changelog should focus on the user-facing changes. Please remove all irrelevant sections before releasing. -Please keep the format of the changelog consistent with the other releases, so the extraction for mkdocs works. +Please keep the format of the changelog consistent: ## [VERSION] - YYYY-MM-DD --- ## [Template] - ????-??-?? @@ -49,22 +49,130 @@ If upgrading from v2.x, see the [v3.0.0 release notes](https://github.com/flixOp --- -## [Unreleased] - ????-??-?? +Until here --> -**Summary**: +## [Upcoming] -If upgrading from v2.x, see the [v3.0.0 release notes](https://github.com/flixOpt/flixOpt/releases/tag/v3.0.0) and [Migration Guide](https://flixopt.github.io/flixopt/latest/user-guide/migration-guide-v3/). - -### ✨ Added +**Summary**: Renamed OnOff terminology to Status terminology for better alignment with PyPSA and unit commitment standards. **All deprecated items from v4.x have been removed.** ### 💥 Breaking Changes +**Renamed `OnOffParameters` → `StatusParameters`**: Complete terminology update to align with industry standards (PyPSA, unit commitment). This is a clean breaking change with no backwards compatibility wrapper. + +**Class and Constructor Parameters:** + +| Category | Old Name (OnOffParameters) | New Name (StatusParameters) | Notes | +|----------|---------------------------|----------------------------|-------| +| **Class** | `OnOffParameters` | `StatusParameters` | Main class renamed | +| **Constructor** | `on_variable` | `status` | Model variable parameter | +| **Constructor** | `previous_states` | `previous_status` | Initial state parameter | +| **Parameter** | `effects_per_switch_on` | `effects_per_startup` | Startup costs/impacts | +| **Parameter** | `effects_per_running_hour` | `effects_per_active_hour` | Operating costs/impacts | +| **Parameter** | `on_hours_total_min` | `active_hours_min` | Minimum total operating hours | +| **Parameter** | `on_hours_total_max` | `active_hours_max` | Maximum total operating hours | +| **Parameter** | `consecutive_on_hours_min` | `min_uptime` | UC standard terminology | +| **Parameter** | `consecutive_on_hours_max` | `max_uptime` | UC standard terminology | +| **Parameter** | `consecutive_off_hours_min` | `min_downtime` | UC standard terminology | +| **Parameter** | `consecutive_off_hours_max` | `max_downtime` | UC standard terminology | +| **Parameter** | `switch_on_total_max` | `startup_limit` | Maximum number of startups | +| **Parameter** | `force_switch_on` | `force_startup_tracking` | Force creation of startup variables | + +**Model Classes and Variables:** + +| Category | Old Name (OnOffModel) | New Name (StatusModel) | Notes | +|----------|----------------------|------------------------|-------| +| **Model Class** | `OnOffModel` | `StatusModel` | Feature model class | +| **Variable** | `on` | `status` | Main binary state variable | +| **Variable** | `switch_on` | `startup` | Startup event variable | +| **Variable** | `switch_off` | `shutdown` | Shutdown event variable | +| **Variable** | `switch_on_nr` | `startup_count` | Cumulative startup counter | +| **Variable** | `on_hours_total` | `active_hours` | Total operating hours | +| **Variable** | `consecutive_on_hours` | `uptime` | Consecutive active hours | +| **Variable** | `consecutive_off_hours` | `downtime` | Consecutive inactive hours | +| **Variable** | `off` | `inactive` | Deprecated - use `1 - status` instead | + +**Flow and Component API:** + +| Category | Old Name | New Name | Location | +|----------|----------|----------|----------| +| **Parameter** | `on_off_parameters` | `status_parameters` | `Flow.__init__()` | +| **Parameter** | `on_off_parameters` | `status_parameters` | `Component.__init__()` | +| **Property** | `flow.submodel.on_off` | `flow.submodel.status` | Flow submodel access | +| **Property** | `component.submodel.on_off` | `component.submodel.status` | Component submodel access | + +**Internal Properties:** + +| Old Name | New Name | +|----------|----------| +| `use_switch_on` | `use_startup_tracking` | +| `use_consecutive_on_hours` | `use_uptime_tracking` | +| `use_consecutive_off_hours` | `use_downtime_tracking` | +| `with_on_off` | `with_status` | +| `previous_states` | `previous_status` | + +**Migration Guide**: + +Use find-and-replace to update your code with the mappings above. The functionality is identical - only naming has changed. + +**Important**: This is a complete renaming with no backwards compatibility. The change affects: +- Constructor parameter names +- Model variable names and property access +- Results access patterns + +A partial backwards compatibility wrapper would be misleading, so we opted for a clean breaking change. + +- `Bus.imbalance_penalty_per_flow_hour` now defaults to `None` (strict balance) instead of `1e5` + ### ♻️ Changed +- Renamed `BusModel.excess_input` → `virtual_supply` and `BusModel.excess_output` → `virtual_demand` for clearer semantics +- Renamed `Bus.excess_penalty_per_flow_hour` → `imbalance_penalty_per_flow_hour` +- Renamed `Bus.with_excess` → `allows_imbalance` + ### 🗑️ Deprecated +- `Bus.excess_penalty_per_flow_hour` → use `imbalance_penalty_per_flow_hour` + ### 🔥 Removed +**Modules removed:** +- `calculation.py` module - Use `optimization.py` instead + +**Classes removed:** +- `Calculation`, `FullCalculation` → Use `Optimization` +- `AggregatedCalculation` → Use `ClusteredOptimization` +- `SegmentedCalculation` → Use `SegmentedOptimization` +- `Aggregation` → Use `Clustering` +- `AggregationParameters` → Use `ClusteringParameters` +- `AggregationModel` → Use `ClusteringModel` +- `CalculationResults` → Use `Results` +- `SegmentedCalculationResults` → Use `SegmentedResults` + +**Functions removed:** +- `change_logging_level()` → Use `CONFIG.Logging.enable_console()` + +**Methods removed:** +- `Optimization._perform_aggregation()` → Use `_perform_clustering()` +- `Optimization.calculate_aggregation_weights()` → Use `calculate_clustering_weights()` + +**Parameters removed:** +- `Optimization.active_timesteps` → Use `flow_system.sel(time=...)` or `flow_system.isel(time=...)` +- `TimeSeriesData.from_dataarray()`: `aggregation_group` → Use `clustering_group` +- `TimeSeriesData.from_dataarray()`: `aggregation_weight` → Use `clustering_weight` +- `FlowSystem.weights` → Use `scenario_weights` +- `Results.__init__()`: `flow_system` → Use `flow_system_data` +- `Results` plotting methods: `indexer` → Use `select` +- `Results.plot_heatmap()`: `heatmap_timeframes`, `heatmap_timesteps_per_frame` → Use `reshape_time` +- `Results.plot_heatmap()`: `color_map` → Use `colors` + +**Properties removed:** +- `FlowSystem.all_elements` → Use dict-like interface (`flow_system['label']`, `.keys()`, `.values()`, `.items()`) +- `FlowSystem.weights` → Use `scenario_weights` + +**Features removed:** +- Passing `Bus` objects directly to `Flow` → Pass bus label string instead and add Bus to FlowSystem +- Using `Effect` objects in `EffectValues` → Use effect label strings instead + **Deprecated parameters removed** (all were deprecated in v4.0.0 or earlier): **TimeSeriesData:** @@ -104,22 +212,14 @@ If upgrading from v2.x, see the [v3.0.0 release notes](https://github.com/flixOp - Flow parameters: `Q_fu` → use `fuel_flow`, `P_el` → use `electrical_flow`, `Q_th` → use `thermal_flow`, `Q_ab` → use `heat_source_flow` - Efficiency parameters: `eta` → use `thermal_efficiency`, `eta_th` → use `thermal_efficiency`, `eta_el` → use `electrical_efficiency`, `COP` → use `cop` -### 🐛 Fixed - -### 🔒 Security - -### 📦 Dependencies ### 📝 Docs +- Improve documentation from the ground up -### 👷 Development - -### 🚧 Known Issues +This is not yet publicly released! --- -Until here --> - ## [4.3.5] - 2025-11-29 **Summary**: Fix zenodo again diff --git a/README.md b/README.md index 6d049819d..339a40b41 100644 --- a/README.md +++ b/README.md @@ -96,7 +96,7 @@ boiler = fx.Boiler("Boiler", eta=0.9, ...) ### Key Features **Multi-criteria optimization:** Model costs, emissions, resource use - any custom metric. Optimize single objectives or use weighted combinations and ε-constraints. -→ [Effects documentation](https://flixopt.github.io/flixopt/latest/user-guide/mathematical-notation/effects-penalty-objective/) +→ [Effects documentation](https://flixopt.github.io/flixopt/latest/user-guide/mathematical-notation/effects-and-dimensions/) **Performance at any scale:** Choose optimization modes without changing your model - Optimization, SegmentedOptimization, or ClusteredOptimization (using [TSAM](https://github.com/FZJ-IEK3-VSA/tsam)). → [Optimization modes](https://flixopt.github.io/flixopt/latest/api-reference/optimization/) diff --git a/docs/getting-started.md b/docs/getting-started.md deleted file mode 100644 index 0cdd2a5a7..000000000 --- a/docs/getting-started.md +++ /dev/null @@ -1,65 +0,0 @@ -# Getting Started with FlixOpt - -This guide will help you install FlixOpt, understand its basic concepts, and run your first optimization model. - -## Installation - -### Basic Installation - -Install FlixOpt directly into your environment using pip: - -```bash -pip install flixopt -``` - -This provides the core functionality with the HiGHS solver included. - -### Full Installation - -For all features including interactive network visualizations and time series aggregation: - -```bash -pip install "flixopt[full]" -``` - -## Logging - -FlixOpt uses Python's standard logging module with optional colored output via [colorlog](https://github.com/borntyping/python-colorlog). Logging is silent by default but can be easily configured. - -```python -from flixopt import CONFIG - -# Enable colored console logging -CONFIG.Logging.enable_console('INFO') - -# Or use a preset configuration for exploring -CONFIG.exploring() -``` - -For advanced logging configuration, you can use Python's standard logging module directly: - -```python -import logging -logging.basicConfig(level=logging.DEBUG) -``` - -For more details on logging configuration, see the [`CONFIG.Logging`][flixopt.config.CONFIG.Logging] documentation. - -## Basic Workflow - -Working with FlixOpt follows a general pattern: - -1. **Create a [`FlowSystem`][flixopt.flow_system.FlowSystem]** with a time series -2. **Define [`Effects`][flixopt.effects.Effect]** (costs, emissions, etc.) -3. **Define [`Buses`][flixopt.elements.Bus]** as connection points in your system -4. **Add [`Components`][flixopt.components]** like converters, storage, sources/sinks with their Flows -5. **Run [`Optimizations`][flixopt.optimization]** to optimize your system -6. **Analyze [`Results`][flixopt.results]** using built-in or external visualization tools - -## Next Steps - -Now that you've installed FlixOpt and understand the basic workflow, you can: - -- Learn about the [core concepts of flixopt](user-guide/core-concepts.md) -- Explore some [examples](examples/index.md) -- Check the [API reference](api-reference/index.md) for detailed documentation diff --git a/docs/home/citing.md b/docs/home/citing.md new file mode 100644 index 000000000..6fd1a6020 --- /dev/null +++ b/docs/home/citing.md @@ -0,0 +1,29 @@ +# Citing flixOpt + +If you use flixOpt in your research, please cite it. + +## Citation + +When referencing flixOpt in academic publications, please use look here: [flixopt citation](https://zenodo.org/records/17756895) + +## Publications + +If you've published research using flixOpt, please let us know! We'd love to feature it here. + +### List of Publications + +*Coming soon: A list of academic publications that have used flixOpt* + +## Contributing Back + +If flixOpt helped your research: + +- Share your model as an example +- Report issues or contribute code +- Improve documentation + +See the [Contributing Guide](../contribute.md). + +## License + +flixOpt is released under the MIT License. See [License](license.md) for details. diff --git a/docs/home/installation.md b/docs/home/installation.md new file mode 100644 index 000000000..afb24172b --- /dev/null +++ b/docs/home/installation.md @@ -0,0 +1,91 @@ +# Installation + +This guide covers installing flixOpt and its dependencies. + + +## Basic Installation + +Install flixOpt directly into your environment using pip: + +```bash +pip install flixopt +``` + +This provides the core functionality with the HiGHS solver included. + +## Full Installation + +For all features including interactive network visualizations and time series aggregation: + +```bash +pip install "flixopt[full]" +``` + +## Development Installation + +If you want to contribute to flixOpt or work with the latest development version: + +```bash +git clone https://github.com/flixOpt/flixopt.git +cd flixopt +pip install -e ".[full,dev,docs]" +``` + +## Solver Installation + +### HiGHS (Included) + +The HiGHS solver is included with flixOpt and works out of the box. No additional installation is required. + +### Gurobi (Optional) + +For academic use, Gurobi offers free licenses: + +1. Register for an academic license at [gurobi.com](https://www.gurobi.com/academia/) +2. Install Gurobi: + ```bash + pip install gurobipy + ``` +3. Activate your license following Gurobi's instructions + +## Verification + +Verify your installation by running: + +```python +import flixopt +print(flixopt.__version__) +``` + +## Logging Configuration + +flixOpt uses Python's standard logging module with optional colored output via [colorlog](https://github.com/borntyping/python-colorlog). Logging is silent by default but can be easily configured: + +```python +from flixopt import CONFIG + +# Enable colored console logging +CONFIG.Logging.enable_console('INFO') + +# Or use a preset configuration for exploring +CONFIG.exploring() +``` + +Since flixOpt uses Python's standard logging, you can also configure it directly: + +```python +import logging + +# Get the flixopt logger and configure it +logger = logging.getLogger('flixopt') +logger.setLevel(logging.DEBUG) +logger.addHandler(logging.StreamHandler()) +``` + +For more details on logging configuration, see the [`CONFIG.Logging`][flixopt.config.CONFIG.Logging] documentation. + +## Next Steps + +- Follow the [Quick Start](quick-start.md) guide +- Explore the [Minimal Example](../examples/00-Minimal Example.md) +- Read about [Core Concepts](../user-guide/core-concepts.md) diff --git a/docs/home/license.md b/docs/home/license.md new file mode 100644 index 000000000..d00755a0b --- /dev/null +++ b/docs/home/license.md @@ -0,0 +1,43 @@ +# License + +flixOpt is released under the MIT License. + +## MIT License + +``` +MIT License + +Copyright (c) 2022 Chair of Building Energy Systems and Heat Supply - TU Dresden + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +``` + +## What This Means + +The MIT License is a permissive open-source license that allows you to: + +✅ **Use** flixOpt for any purpose, including commercial applications +✅ **Modify** the source code to fit your needs +✅ **Distribute** copies of flixOpt +✅ **Sublicense** under different terms +✅ **Use privately** without making your modifications public + +## Contributing + +By contributing to flixOpt, you agree that your contributions will be licensed under the MIT License. See our [Contributing Guide](../contribute.md) for more information. diff --git a/docs/home/quick-start.md b/docs/home/quick-start.md new file mode 100644 index 000000000..b0bdef7da --- /dev/null +++ b/docs/home/quick-start.md @@ -0,0 +1,132 @@ +# Quick Start + +Get up and running with flixOpt in 5 minutes! This guide walks you through creating and solving your first energy system optimization. + +## Installation + +First, install flixOpt: + +```bash +pip install "flixopt[full]" +``` + +## Your First Model + +Let's create a simple energy system with a generator, demand, and battery storage. + +### 1. Import flixOpt + +```python +import flixopt as fx +import numpy as np +import pandas as pd +``` + +### 2. Define your time horizon + +```python +# 24h period with hourly timesteps +timesteps = pd.date_range('2024-01-01', periods=24, freq='h') +``` + +### 2. Set Up the Flow System + +```python +# Create the flow system +flow_system = fx.FlowSystem(timesteps) + +# Define an effect to minimize (costs) +costs = fx.Effect('costs', 'EUR', 'Minimize total system costs', is_objective=True) +flow_system.add_elements(costs) +``` + +### 4. Add Components + +```python +# Electricity bus +electricity_bus = fx.Bus('electricity') + +# Solar generator with time-varying output +solar_profile = np.array([0, 0, 0, 0, 0, 0, 0.2, 0.5, 0.8, 1.0, + 1.0, 0.9, 0.8, 0.7, 0.5, 0.3, 0.1, 0, + 0, 0, 0, 0, 0, 0]) + +solar = fx.Source( + 'solar', + outputs=[fx.Flow( + 'power', + bus='electricity', + size=100, # 100 kW capacity + relative_maximum=solar_profile + ) +]) + +# Demand +demand_profile = np.array([30, 25, 20, 20, 25, 35, 50, 70, 80, 75, + 70, 65, 60, 65, 70, 80, 90, 95, 85, 70, + 60, 50, 40, 35]) + +demand = fx.Sink('demand', inputs=[ + fx.Flow('consumption', + bus='electricity', + size=1, + fixed_relative_profile=demand_profile) +]) + +# Battery storage +battery = fx.Storage( + 'battery', + charging=fx.Flow('charge', bus='electricity', size=50), + discharging=fx.Flow('discharge', bus='electricity', size=50), + capacity_in_flow_hours=100, # 100 kWh capacity + initial_charge_state=50, # Start at 50% + eta_charge=0.95, + eta_discharge=0.95, +) + +# Add all components to system +flow_system.add_elements(solar, demand, battery, electricity_bus) +``` + +### 5. Run Optimization + +```python +# Create and run optimization +optimization = fx.Optimization('solar_battery_optimization', flow_system) +optimization.solve(fx.solvers.HighsSolver()) +``` + +### 6. Save Results + +```python +# This includes the modeled FlowSystem. SO you can restore both results and inputs +optimization.results.to_file() +``` + +## What's Next? + +Now that you've created your first model, you can: + +- **Learn the concepts** - Read the [Core Concepts](../user-guide/core-concepts.md) guide +- **Explore examples** - Check out more [Examples](../examples/index.md) +- **Deep dive** - Study the [Mathematical Formulation](../user-guide/mathematical-notation/index.md) +- **Build complex models** - Use [Recipes](../user-guide/recipes/index.md) for common patterns + +## Common Workflow + +Most flixOpt projects follow this pattern: + +1. **Define time series** - Set up the temporal resolution +2. **Create flow system** - Initialize with time series and effects +3. **Add buses** - Define connection points +4. **Add components** - Create generators, storage, converters, loads +5. **Run optimization** - Solve the optimization +6. **Save Results** - For later analysis. Or only extract needed data + +## Tips + +- Start simple and add complexity incrementally +- Use meaningful names for components and flows +- Check solver status before analyzing results +- Enable logging during development for debugging +- Visualize results to verify model behavior diff --git a/docs/home/users.md b/docs/home/users.md new file mode 100644 index 000000000..d27f99576 --- /dev/null +++ b/docs/home/users.md @@ -0,0 +1,27 @@ +# Who Uses flixOpt? + +flixOpt is developed and used primarily in academic research for energy system optimization. + +## Primary Users + +- **Researchers** - Energy system modeling and optimization studies +- **Students** - Master's and PhD thesis projects +- **Engineers** - Feasibility studies and system planning + +## Typical Applications + +- Dispatch optimization with renewable integration +- Capacity expansion planning +- Battery and thermal storage sizing +- District heating network optimization +- Combined heat and power (CHP) systems +- Multi-energy systems and sector coupling + +## Get Involved + +Using flixOpt in your research? Consider: + +- [Citing flixOpt](citing.md) in your publications +- Sharing your model as an example +- Contributing to the codebase +- Joining [discussions](https://github.com/flixOpt/flixopt/discussions) diff --git a/docs/index.md b/docs/index.md index 3467bb394..70fd15bf4 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,8 +1,5 @@ --- title: Home -hide: - - navigation - - toc ---
@@ -16,7 +13,7 @@ hide:

Model, optimize, and analyze complex energy systems with a powerful Python framework designed for flexibility and performance.

- 🚀 Get Started + 🚀 Get Started 💡 View Examples ⭐ GitHub

@@ -25,36 +22,44 @@ hide: ## :material-map-marker-path: Quick Navigation -