fluxopt
Energy system optimization with linopy — detailed dispatch, scaled to multi period planning.
https://github.com/fluxopt/fluxopt
Category: Energy Systems
Sub Category: Energy System Modeling Frameworks
Last synced: about 5 hours ago
JSON representation
Repository metadata
Successor of flixopt with a new datamodel
- Host: GitHub
- URL: https://github.com/fluxopt/fluxopt
- Owner: fluxopt
- License: mit
- Created: 2026-02-12T22:54:29.000Z (6 months ago)
- Default Branch: main
- Last Pushed: 2026-07-31T23:43:47.000Z (11 days ago)
- Last Synced: 2026-08-01T01:05:10.595Z (11 days ago)
- Language: Python
- Homepage: https://fluxopt.readthedocs.io/
- Size: 3.94 MB
- Stars: 2
- Watchers: 0
- Forks: 0
- Open Issues: 54
- Releases: 8
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: .github/CONTRIBUTING.md
- License: LICENSE
- Agents: AGENTS.md
README.md
fluxopt
Energy system optimization with linopy — detailed dispatch, scaled to multi period planning.
Early development — the API may change between releases.
Planned features and progress are tracked in Issues.
Installation
pip install fluxopt
Includes the HiGHS solver out of the box.
Quick Start
# A gas boiler covers a heat demand, minimizing fuel cost
from datetime import datetime
from fluxopt import Carrier, Converter, Effect, Flow, Port, optimize
result = optimize(
timesteps=[datetime(2024, 1, 1, h) for h in range(4)],
carriers=[Carrier(id='gas'), Carrier(id='heat')],
effects=[Effect(id='cost')],
ports=[
Port(id='grid', imports=[Flow(carrier='gas', size=500, effects_per_flow_hour={'cost': 0.04})]),
Port(id='demand', exports=[Flow(carrier='heat', size=100, fixed_relative_profile=[0.4, 0.7, 0.5, 0.6])]),
],
converters=[
Converter.boiler(
'boiler',
thermal_efficiency=0.9,
fuel_flow=Flow(carrier='gas', size=300),
thermal_flow=Flow(carrier='heat', size=200),
)
],
objective='cost',
)
print(f'Total cost: {result.objective:.2f}')
print(result.flow_rates)
One API, four levels of control
Every level returns the same Result; each one only adds control — pick the
lowest rung that does the job.
1. One-shot — optimize(...) as above. Elements in, Result out, with
fail-fast validation of ids and references.
2. Declarative — gather the same arguments into a reusable, serializable
system. Time series can stay out of the structure as ProfileRefs and be
supplied at solve time via profiles:
spec = fx.FlowSystem.from_yaml('system.yaml') # or FlowSystem(...) in Python
result = spec.optimize(profiles={'load': demand_ds})
spec.to_yaml('system.yaml') # round-trips
3. Inspectable — materialize the solver model without solving, inspect or
extend the underlying linopy model, retarget the objective, then solve:
model = spec.build_model(profiles={'load': demand_ds}) # unbuilt FlowSystemModel
model.build()
model.m.add_constraints(...) # full linopy access
result = model.solve()
model.objective = {'cost': 1, 'co2': 50} # retarget…
model.build() # …and rebuild
For a one-off tweak, stay on level 1/2 and pass
customize=lambda m: m.m.add_constraints(...) instead.
4. Data-level — build or load the xarray ModelData yourself and edit it
before modeling:
data = fx.ModelData.build(...) # or ModelData.from_netcdf(path)
data.flows.fixed_profile.loc[{'flow': 'demand(heat)'}] = 0.7
result = fx.FlowSystemModel(data, objective='cost').optimize()
Results close the loop: result.flow_rates, result.effect_totals,
result.stats (KPIs, effect contributions), result.plot, netCDF round-trip,
and result.data — the exact ModelData the solution came from.
Roadmap
fluxopt is evolving into a family of packages with a lean core and optional companions:
┌──────────────┐
│ fluxopt │ core: model building, solving, results, IO
└──────┬───────┘
┌──────────────┬─────────┼──────────────┬──────────────┐
│ │ │ │ │
fluxopt-plot fluxopt-yaml fluxopt-tsam fluxopt-marimo (examples)
plotting YAML+CSV time series interactive cross-package
(plotly) loader aggregation apps notebooks
Companion packages depend on core — core has no knowledge of companions.
Companion packages
| Package | Role | Versioning · Tier | fluxopt pin |
Status |
|---|---|---|---|---|
fluxopt-plot |
Result visualization (Plotly) | Semver · Experimental — method signatures may change | Tight (>=A.B,<A.C), validated per release |
Scaffolded — docs · #51 |
fluxopt-yaml |
Declarative model loader (YAML + CSV → Elements) |
Semver · Experimental — YAML schema may change | Tight (>=A.B,<A.C), validated per release |
Scaffolded — docs · #52 |
fluxopt-tsam |
Time series aggregation — input pre-processing, possibly result disaggregation | Semver · Experimental — round-trip schema may evolve | Undecided — depends on whether representative-period primitives live in core (→ loose) or in this package (→ tight) | Planned |
fluxopt-marimo |
Interactive exploration & dashboards (marimo apps) | CalVer (YYYY.MM.PATCH) · Experimental — apps are templates |
Tight (>=A.B,<A.C), validated per release |
Planned |
Tight-pinned companions release on every fluxopt minor; validation is
automated via scheduled CI. fluxopt-tsam's pin policy is blocked on an
architectural decision — if representative-period primitives live in core, tsam stays
a thin adapter (loose pin); if they live in tsam, the package owns deep
round-trip behavior (tight pin).
Milestones
Cross-cutting work not tied to a single companion package:
| Milestone | Description | Status | Issue |
|---|---|---|---|
Result.stats accessor |
Cached xarray properties for post-processing | Planned | #49 |
.plot stub on Result |
Discoverable property, helpful error if plot package absent | Planned | #50 |
| ReadTheDocs migration | Automatic versioned docs from git tags | Planned | #53 |
| Remove plotly from core | Keep core lean — plotting deps in fluxopt-plot only |
Planned | #54 |
Stability Tiers
| Component | Tier | Policy |
|---|---|---|
| Core modeling API | Stable | Semver. Deprecation warnings before removal. |
| Stats accessor | Semi-stable | Breaking changes allowed between minor versions with changelog entry. |
Companion packages have their own stability policies — see the table above.
See #47 for the full architecture discussion.
Development
Requires uv and Python >= 3.12.
uv sync --group dev # Install deps
uv run pytest -v # Run tests
uv run ruff check . # Lint
uv run ruff format . # Format
License
MIT
Owner metadata
- Name: fluxopt
- Login: fluxopt
- Email:
- Kind: organization
- Description:
- Website:
- Location:
- Twitter:
- Company:
- Icon url: https://avatars.githubusercontent.com/u/291020290?v=4
- Repositories: 1
- Last ynced at: 2026-06-05T14:12:27.310Z
- Profile URL: https://github.com/fluxopt
GitHub Events
Total
- Delete event: 1
- Push event: 28
- Create event: 19
Last Year
- Delete event: 1
- Push event: 28
- Create event: 19
Committers metadata
Last synced: 6 days ago
Total Commits: 177
Total Committers: 6
Avg Commits per committer: 29.5
Development Distribution Score (DDS): 0.192
Commits in past year: 177
Committers in past year: 6
Avg Commits per committer in past year: 29.5
Development Distribution Score (DDS) in past year: 0.192
| Name | Commits | |
|---|---|---|
| Felix | 1****n | 143 |
| dependabot[bot] | 4****] | 25 |
| fluxopt-release[bot] | 2****] | 6 |
| fluxopt-release-bot[bot] | 3****] | 1 |
| Shaan Satsangi | 1****a | 1 |
| GitButler | g****r@g****m | 1 |
Committer domains:
Issue and Pull Request metadata
Last synced: 1 day ago
Total issues: 50
Total pull requests: 115
Average time to close issues: 2 months
Average time to close pull requests: 5 days
Total issue authors: 1
Total pull request authors: 4
Average comments per issue: 0.18
Average comments per pull request: 1.77
Merged pull request: 90
Bot issues: 0
Bot pull requests: 33
Past year issues: 50
Past year pull requests: 115
Past year average time to close issues: 2 months
Past year average time to close pull requests: 5 days
Past year issue authors: 1
Past year pull request authors: 4
Past year average comments per issue: 0.18
Past year average comments per pull request: 1.77
Past year merged pull request: 90
Past year bot issues: 0
Past year bot pull requests: 33
Top Issue Authors
- FBumann (50)
Top Pull Request Authors
- FBumann (82)
- dependabot[bot] (30)
- fluxopt-release-bot[bot] (2)
- fluxopt-release[bot] (1)
Top Issue Labels
- type:feat (37)
- area:multi-period (15)
- area:effects (14)
- area:sizing (12)
- area:status (6)
- area:storage (6)
- area:flow (5)
- area:api (5)
- type:fix (5)
- area:converter (4)
- not in focus (2)
- type:perf (2)
- type:refac (2)
- type:chore (2)
- area:new (2)
- area:io (2)
Top Pull Request Labels
- dependencies (32)
- type:feat (26)
- type:docs (14)
- area:effects (11)
- type:fix (11)
- area:api (5)
- area:sizing (5)
- area:status (4)
- area:multi-period (3)
- type:perf (2)
- autorelease: tagged (2)
- area:converter (2)
- autorelease: pending (1)
- area:io (1)
- type:chore (1)
- area:new (1)
- area:flow (1)
- area:storage (1)
- trigger:benchmark (1)
Dependencies
- highspy >=1.13.1
- linopy @ git+https://github.com/PyPSA/linopy.git@f53d1968e53d70962eb208b01c3f938f693f0083
- netcdf4 >=1.6.0
- numpy >=1.26
- pandas >=2.1
- xarray >=2024.1.0
- actions/create-github-app-token v3 composite
- dependabot/fetch-metadata v2 composite
- actions/checkout v6 composite
- actions/setup-python v6 composite
- astral-sh/ruff-action v3 composite
- astral-sh/setup-uv v7 composite
- codecov/codecov-action v5 composite
- amannn/action-semantic-pull-request v6 composite
- actions/create-github-app-token v3 composite
- googleapis/release-please-action v4 composite
- actions/checkout v6 composite
- actions/setup-python v6 composite
- astral-sh/setup-uv v7 composite
- pypa/gh-action-pypi-publish release/v1 composite
Score: 5.817111159963204