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

README.md

fluxopt

Energy system optimization with linopy — detailed dispatch, scaled to multi period planning.

PyPI
Downloads
License: MIT
Python 3.12+
Ruff

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-shotoptimize(...) 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


GitHub Events

Total
Last Year

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 Email 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

More stats: https://issues.ecosyste.ms/repositories/lookup?url=https://github.com/fluxopt/fluxopt

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

pyproject.toml pypi
  • 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
.github/workflows/dependabot-auto-merge.yaml actions
  • actions/create-github-app-token v3 composite
  • dependabot/fetch-metadata v2 composite
.github/workflows/ci.yaml actions
  • 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
.github/workflows/pr-title.yaml actions
  • amannn/action-semantic-pull-request v6 composite
.github/workflows/release.yaml actions
  • actions/create-github-app-token v3 composite
  • googleapis/release-please-action v4 composite
.github/workflows/publish.yaml actions
  • actions/checkout v6 composite
  • actions/setup-python v6 composite
  • astral-sh/setup-uv v7 composite
  • pypa/gh-action-pypi-publish release/v1 composite
.github/workflows/label-from-title.yaml actions

Score: 5.817111159963204