Skip to content

MEME 0.2.0-alpha

Pre-release
Pre-release

Choose a tag to compare

@AndreasWillibaldWeber AndreasWillibaldWeber released this 25 Oct 01:32
· 1 commit to main since this release
v0.2.0-alpha
f0f289f

Added

  • Power flow as a PyPSA run mode (ADR-0008): experiment.mode: power_flow
    solves the AC network for a fixed dispatch with lpf() and pf() instead
    of optimizing. The canonical model describes the network itself —
    node.electrical.v_nom, transmission.electrical (kind line or
    transformer, r, x, s_nom, num_parallel, tap_ratio) and
    technology.dispatch (overridable per node) — and experiment.power_flow
    names the slack, the method (newton_raphson or linear),
    distribute_slack and the tolerance. The run writes output/power_flow/:
    convergence.csv, per-bus voltage magnitude, angle and power, per-line and
    per-transformer flows and loading, generator dispatch and a summary.json;
    a snapshot that does not converge fails the run. The API consumer chains a
    plan and a power flow as two calls; MEME holds no state between them.

  • Gates around the new inputs: the mode routes through the power_flow
    capability (PyPSA only); power-flow inputs in an optimization mode (a
    dispatch, the electrical blocks) are kept and named in one warning
    while the arcs stay transport links (see Changed); in mode power_flow
    expandable capacities, trade,
    constraints, emission limits and scenarios are rejected, and
    distribute_slack requires a dispatch on the slack technology (PyPSA
    shares the balance in proportion to each generator's set-point, so a slack
    without one would receive none of it).

  • Scenario pypsa_power_flow, the example payloads
    examples/pypsa_power_flow*.json (the reference network, the smallest
    valid power flow, a meshed ring with per-node dispatch, and the options:
    linear method, distributed slack, storage sign, a second carrier) and E2E
    checks for convergence, the linear method and a diverging load. The
    examples walkthrough documents the options, the result files and the
    rejected requests.

  • Reactive power, voltage control, shunts and controlled transfers for the
    power flow (ADR-0009): technology.electrical with reactive_dispatch
    or power_factor (+ leading), control: pv and voltage_setpoint;
    node.electrical.shunt; transmission.dispatch as a controlled HVDC
    transfer on an arc without impedance; b, g, phase_shift and
    r_per_length/x_per_length on transmission.electrical. The result
    folder gains the reactive tables, the load and link tables and the shunt
    tables. Gates: one way to give Q, voltage set-points for pv generators
    and the slack only and agreeing per bus, an electricity arc needs an
    impedance or a transfer, every AC island needs a generator (an island
    without the named slack is reported as balanced by PyPSA), and the linear
    method says what it ignores. Scenario and example payload
    pypsa_power_flow_reactive, E2E-pinned on the held voltages.

  • The electrical network inside the optimization (ADR-0010):
    experiment.network.model: linear_power_flow makes PyPSA solve under
    Kirchhoff's voltage law with Lines and Transformers (expansion from the
    arc's capacity, electrical.max_loading as s_max_pu), and
    network.security.outages runs the security-constrained solve; other
    targets reject the model like a mode. Transmission gains lifetime,
    interest_rate and cost_basis, and PyPSA prices the arc's investment
    and fixed O&M on Links and Lines. Every optimization run writes
    output/results/ (dispatch, flows, storage states, marginal prices,
    capacities.csv, statistics.csv, summary.json).

  • PyPSA optimization completeness (ADR-0011): an energy-sized storage
    (storage.energy_capacity) is a Store with charger and discharger Links,
    which honors independent rates, depth of discharge and the energy-capacity
    cost (_storage.json carries the equal-power and rate constraints);
    storage.soc_profile pins a StorageUnit's state of charge;
    capacity.per_unit builds integer modules; decommission.mode: continuous retires existing capacity at its fixed O&M and builds new
    capacity above it; allow_unmet_demand adds priced slack generators;
    copperplate joins every node through a free hub; operation.ramp_start_up,
    ramp_shut_down, standby_cost, initial_uptime, initial_downtime and
    costs.<class>.variable_om_quadratic map onto PyPSA's unit-commitment and
    cost attributes; model.periods with years are investment periods with
    build_year, lifetime and new builds per period. Scenarios and goldens
    for every claim, E2E on the real framework, and the example
    examples/pypsa_planning.json.

Changed

  • PyPSA no longer rejects independent storage rates, depth of discharge,
    continuous retirement, unmet demand or copperplate; the energy-capacity
    cost is priced instead of dropped. Calliope and AdOpT-NET0 keep every
    mapping they had; the new fields they have no slot for (soc_profile,
    the unit-commitment extras, the quadratic cost, investment periods) are
    ignored there with a warning. The validation matrix records every verdict
    that moved.
  • time.subset and costs.<class>.purchase are rejected on PyPSA and
    AdOpT-NET0 instead of being dropped without a word: neither target has a
    slot (narrow time.start/end; fold the purchase cost into
    investment_per_capacity). Calliope 0.7 warns that area.per_capacity
    is not emitted (0.6 emits resource_area_per_energy_cap). The validation
    matrix records the moved verdicts.
  • Power-flow inputs — dispatch, the electrical blocks on technologies,
    arcs and nodes — are ignored with one warning wherever no power flow runs:
    on Calliope and AdOpT-NET0 and in PyPSA's optimization modes alike. A
    dispatch in an optimization mode was rejected before; now one payload
    serves the planning call and the power-flow call (ADR-0009).
  • The PyPSA driver parses its run configuration as JSON (json.loads)
    instead of pasting the JSON in as a Python literal, which broke on the
    first boolean setting.

Fixed

  • PyPSA state_of_charge_initial is absolute (MWh), but the canonical
    fraction storage.initial_soc was written into it unchanged, so a
    half-full 24 MWh unit started at 0.5 MWh. The fraction is now applied to
    the installed energy (p_nom × max_hours); an expandable storage is
    told it starts from its existing capacity.