Repository navigation
Release 1.2.0
lightsim2grid 1.2.0
This release adds a light environment: a grid2op-like reset / step loop that runs entirely
in C++. It also lets ScenarioSweep apply one topological action per row while keeping a
single symbolic factorization. OpenLoadFlow's bounded distributed-slack redistribution is now
available on the grid and on the batch algorithms. The physical checks now also report the
decisions OpenLoadFlow's outer loops would revisit. Many fixes come with it, mostly in the DC
batch path and in contingencies that split the grid.
Highlights
- Light environment:
lightsim2grid.lightEnv.LightEnvis a (very) limited grid2op
environment. It replays a time series of injections, plays registered topological actions
(init_actions, thenstep(act_id)) with grid2op-like cooldowns and protections, and
returnsLightEnvObservation, read-only views with no copy. It can be copied cheaply, which
is what a tree or beam search needs. It is header-only C++ (src/core/light_env/) and is
also usable without python. It is new and its interface may still change. See
docs/light_env.rstandbenchmarks/light_env.py. - Topological actions in
ScenarioSweep:set_topo_actionsgives each row its own
topological action: disconnections, reconnections, or a bus split or merged. The whole batch
still runs on one symbolic analysis. Batch results follow each row's action. A few cases are
still refused; they are listed in the changelog. - Bounded slack redistribution, OpenLoadFlow style:
LSGrid.redistribute_active_power
shares a known imbalance across the units of the distributed slack. It respects their
[min_p, max_p]bounds and never changes the sign of a unit's injection.
ContingencyAnalysis/ScenarioSweepgainredistribute_slack, which redistributes the
power a row loses (a generator contingency or an island) before solving.
LSGrid.cap_slack_at_active_limitsapplies OpenLoadFlow's slack rule to a solved grid. - Richer batch results:
compute_branch_results()gives P and Q at both ends of every
branch, per row.compute_gen_results()/get_gen_nd Q per row, by the same rules asLSGrid. Also new:get_rb_iter(),get_Ybus(row)/get_dcYbus(row), andLSGrid.get - Violation checks on the grid itself:
LSGrid.getLSGrid.get_physical_violations()run the batch cheac_pf/dc_pf`. - New physical checks: these report what an OpenLoadFlow outer loop would change. They
cover a PQ unit that would regulate again (generators, SVCs and VSC stations:
LOW_VOLTAGE_AT_MIN_Q/HIGH_VOLTAGE_AT_MAX_Q), amaton would
switch it on, a remote voltage control held from an unrealistic voltage, and an hvdc line
frozen at its AC-emulation limit.bake_outer_loopsreturns what it froze, and
init_from_pypowsyblflags it. They are reported, n - KLU by default: the
init_from_*loaders selectNR_KLU/DC_KLUwhen KLU is compiled
in (previouslyNR_SparseLU/DC_SparseLU).
Breaking changes
BINARY_FORMAT_VERSIONgoes from 10 to 18. Generatoerter
stations, hvdc lines and the grid carry new state, so files saved with 1.1.0 no longer load
and must be re-exported.LSGrid.consider_only_main_component()now redistri takes out
by default, and returns aSlackRedistributionReport. Passredistribute_slack=Falsefor
the previous behaviour. The grid2op backend and `inis it.LSGrid.get_Ybus_solver()/get_dcYbus_solver()return a read-only view instead of a copy.
It stays valid until a powerflow rebuilds the matrixor to pass
it tocompute_pf.- Operational limit checks now ignore a value that sit
violation_rel_tol(default1e-9). Before, the last bit of rounding decided. - (C++ / plugins)
BaseAlgogains the virtualdistriset_voltage_control_v_setnow takes anEigen::Refd their
overrides updated.
Fixes
DC batch algorithms
- A threaded DC
ContingencyAnalysis/ScenarioSweep(nb_thread > 1) no longer segfaults. - A row that edits no admittance, right after one thatthe previous
row's matrix. - Phase-shifter flows had the wrong sign and no `sn_mvase shifter
also kept its shift injections. - With
handle_disconnected_grid, rows no longer use - Disconnecting a half-open branch no longer edits Bbus. A bus whose regulating generators are
disconnected no longer keeps their setpoint as its m get_error()reportsNoErrorafter a converged `d
**Contingencies that split the grid (`handle_disconnec
- The reference slack bus was chosen with grid and soland the
choice never reached the solver. A reference forced ` is no
longer lost. - A contingency that strands every controller of a mul group no
longer diverges. One that strands the bus a group regulates is skipped (NOT_SIMULATED)
instead of running every iteration. - Stranded HVDC converter stations now count in the power an islanding takes out.
consider_only_main_componentleft stranded units ihe next
powerflow raised "One of the slack bus is disconnectContingencyAnalysis: changinghandle_disconnectedafter a
computation returned the previous results.
ScenarioSweep
set_contingency_gensno longer turns a bus PQ when a voltage-regulating storage unit still
holds it.- With
modify_gen_v, a disconnected generator no lonpoint of the
generators left on its bus.
**OpenLoadFlow comparison (bake_outer_loops / `init_
- Closer agreement on reactive-limit freezing, the SVC its
b0),
hvdc operator active power ranges, VSC capability curves, and units dispatched at their
active limits.
Misc
LSGridpickling no longer breaks the build on MSVCy with gcc 8.- The light environment's protections no longer loop fonnection,
and the reward is no longer an integer division.
Performance
LSGrid.get_Ybus(),get_dcYbus()andget_Bf()rne pass
instead of re-sorting it.- The sparse matrices returned by the getters (includi reach
python without a copy. bake_outer_loopsandinit_from_pypowsyblare muccially grids
with batteries. Results are unchanged.
Other additions
LSGrid.set_keep_vinit_at_group_controlled_busesan`.- Docs: the light environment, reusing one `ScenarioSwreads vs
processes. - Design notes on outer loops and control limits under
(docs/dev_notes/).
The full list is in CHANGELOG.rst.