LSGrid module (doc in progress)
The main class of the lightsim2grid python package is the LSGrid class, that is a python class created from the the c++ LSGrid (thanks fo pybind11).
This class basically represents a powergrid (what elements it is made for, their electro technical properties etc.)
To create such class, for now the only way is to get it from a pandapower grid (and it does not model every elements there !)
For example, you can init it like (NOT RECOMMENDED, though sometimes needed):
from lightsim2grid.network import init
pp_net = ... # any pandapower grid eg. pp_net = pn.case118()
lightsim_grid_model = init(pp_net) # some warnings might be issued as well as some warnings
A better initialization is through the lightsim2grid.LightSimBackend.LightSimBackend class:
from lightsim2grid.network import init
# create a lightsim2grid "gridmodel"
env_name = ... # eg. "l2rpn_case14_test"
env = grid2op.make(env_name, backend=LightSimBackend())
grid_model = env.backend._grid
Warning
We do not recommend to manipulate directly the lightsim2grid.network.LSGrid directy, but to use
it via the backend class. This is much more tested this way.
Bus labelling conventions
A recurring source of confusion is that lightsim2grid manipulates bus ids in
three different conventions. A given integer (say 2) does not refer to
the same bus in all of them, so it is important to know which convention a given
method expects or returns.
Note
Internally (c++ side) these conventions are even distinct types
(LocalBusId, GridModelBusId / GlobalBusId and SolverBusId), so
that an accidental conversion between them is caught at compile time. Python
only sees plain integers, hence this section.
Local bus id — the busbar number inside a substation. It is
-1for a disconnected element, or between1andn_busbar_per_sub. This is the grid2op convention: the value you put in aset_busaction and what you read in grid2op’stopo_vect. It is the convention oflightsim2grid.network.LSGrid.update_topo()(the bulk topology update used bylightsim2grid.LightSimBackend.LightSimBackend), whosenew_valuesarray is indexed by the position in the topology vector (pos_topo_vect) and holds local busbar ids. An element’s substation is given by itssub_idand its slot intopo_vectbypos_topo_vect.GridModel bus id (a.k.a. global bus id) — the index of a bus in the whole
LSGrid, between0andn_sub * n_busbar_per_sub - 1. This is the convention of essentially every “by id” public ``LSGrid`` method (change_bus_*/get_bus_*,deactivate_bus/reactivate_bus,set_gen_regulated_bus, thebus_id/bus1_id/bus2_idfields of the*Infoobjects, …) and of the “user facing” matrices/vectors (get_Ybus,get_Sbus,get_V,get_pv, …).Solver bus id — a compact index (
0…total_bus() - 1) that depends on the current topology: only the buses actually in service get a solver id. It is what is passed to the linear/powerflow solver, so it is the convention of everything with a_solversuffix (get_Ybus_solver,get_V_solver,get_pv_solver,get_J_solver, …) and of the Jacobian-column mappings returned by the solver itself (get_theta_to_J_col/get_vm_to_J_col/get_q_to_J_col, see Use as Pandapower Solver).
The mapping between conventions 2 and 3 is available (as numpy arrays) through:
Method |
Meaning |
|---|---|
|
array indexed by AC solver bus id -> GridModel bus id |
|
array indexed by GridModel bus id -> AC solver bus id |
|
array indexed by DC solver bus id -> GridModel bus id |
|
array indexed by GridModel bus id -> DC solver bus id |
|
number of buses currently seen by the solver |
|
number of connected buses |
Which convention each “by id” method uses:
Method(s) |
get / set |
Bus id convention |
|---|---|---|
|
set (bulk) |
Local (per-substation) |
|
set |
GridModel (global) |
|
set |
GridModel (global) |
|
set |
GridModel (global) |
|
set |
GridModel (global) |
|
get |
GridModel (global) |
|
get (read-only) |
GridModel (global) |
|
get |
GridModel (global) |
|
get |
Solver |
|
get |
Solver |
Elements modeled
Generators (standard)
A generator can also perform remote voltage control, ie regulate the
voltage of a bus different from the one it is connected to. Use
lightsim2grid.network.LSGrid.set_gen_regulated_bus() to set the regulated
bus (it defaults to the generator’s own bus, which corresponds to local control).
This is read automatically when initializing the grid from pypowsybl. The same
mechanism is used by the Static Var Compensators (SVC) below.
Warning
When the grid is read from pypowsybl, the regulated bus is resolved once, at
import time, and stored by its (fixed) lightsim2grid global bus id. If the
regulated element is later moved to another bus inside lightsim2grid (e.g.
through a change_bus_* / topology change), the controller keeps regulating the
bus resolved at import: the lightsim2grid grid and the original pypowsybl grid then
desynchronise. Re-import the grid (or call set_gen_regulated_bus again) if you
need to follow such a topology change.
Static Generators (more exotic)
Loads and Storage Units
Storage units (batteries) are modeled as PQ injections too, but exposed through a
dedicated container. They use the load convention: a positive target_p means
the unit is charging (power drawn from the grid), a negative target_p means it is
discharging (power injected in the grid). Note that this is the opposite of the
PowSyBl / IIDM (generator) convention; lightsim2grid.network.init_from_pypowsybl()
negates the battery setpoints accordingly.
Static Var Compensators (SVC)
Static Var Compensators (SVC) are shunt-connected devices that can regulate
voltage (or reactive power). Each SVC has a regulation_mode:
0(OFF): the device does not regulate anything;1(VOLTAGE): it maintainstarget_vm_puat its regulated bus, possibly with a non-zeroslope_pu(droop);2(REACTIVE_POWER): it injectstarget_q_mvar.
Like generators, an SVC can regulate a remote bus (see regulated_bus_id).
The susceptance limits b_min / b_max are stored for information but are
never enforced by the powerflow.
Shunts
Lines
Transformers
HVDC Lines (more exotic)
HVDC links are modeled inside the AC (Newton-Raphson) and DC powerflow. Each
link is made of two converter stations (VSC or LCC, see
lightsim2grid.elements.ConverterStationInfo) and can operate either at
a fixed active power setpoint or in angle-droop (AC emulation) mode. The droop
regime can be inspected / forced with
lightsim2grid.network.LSGrid.set_status_droop_hvdc() and
lightsim2grid.network.LSGrid.get_status_droop_hvdc().
Note
The container used to be called DCLineContainer (and the info object
DCLineInfo). These names are still importable from
lightsim2grid.elements as deprecated aliases of HvdcLineContainer /
HvdcLineInfo.