Skip to content

[BUG] OPF time_elapsed computed with .seconds and int() — sub-hourly runs silently decouple storage power from energy #693

Description

@joda9

Where

edisgo/io/powermodels_io.py (in to_powermodels):

pm["time_elapsed"] = int(
    (psa_net.snapshots[1] - psa_net.snapshots[0]).seconds / 3600
)  # length of timesteps in hours

This single global value drives all inter-timestep couplings in the Julia OPF (battery,
heat storage, DSM energy balances, EV charging energy).

Three independent defects

  1. .seconds instead of .total_seconds() — .seconds is the seconds component of the
    Timedelta (0–86399), not its total duration. A gap of exactly 1 day yields 0; a gap of
    25 h yields 1 h. Silently wrong.
  2. int(...) truncation — 15-min resolution: int(900/3600) = int(0.25) = 0. With
    time_elapsed = 0 the storage coupling se₂ − se₁ == −0·ps₂ degenerates to 0 == 0 for
    any ps: power and energy are completely decoupled. The battery becomes an
    inexhaustible storage with no energy accounting (results look plausible — power bounds are
    respected — but are physically meaningless). With flexible charging points the model becomes
    infeasible instead (cpe₂ == cpe₁ is forced while the flexibility-band midpoint moves).
    Real 15-min runs have been executed and were affected by this.
  3. Only the first snapshot gap is used, globally — non-equidistant time indices are
    silently mis-scaled for every step after the first.

Suggested fix

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: opfOptimal power flow / Julia side (eDisGo_OPF.jl, powermodels_io)bugcorrectnessSilently produces wrong numeric results (no crash) — high-value to fixpriority: high

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions