LSGrid module

The main class of the lightsim2grid python package is the LSGrid class, that is a python class created from the c++ LSGrid (thanks fo pybind11).

This class basically represents a powergrid (what elements it is made for, their electro technical properties etc.)

Supported source formats

An LSGrid can be built from several source formats, each with a dedicated init_from_* function in lightsim2grid.network (none of them model every element the source format itself supports):

Function

Source format

init_from_pandapower()

a pandapower network (pandapowerNet)

init_from_pypowsybl()

a pypowsybl network (iidm format)

init_from_matpower()

a MATPOWER case (.m or .mat file, or an already-parsed dict)

init_from_powermodels()

a PowerModels.jl network data dictionary

init_from_pf_delta()

a row of the PFΔ dataset (either already parsed into a dict, or a path to its .json file) – wraps a PowerModels network dict under a "network" key and delegates to init_from_powermodels

See the “Detailed documentation” section below for the full signature and caveats of each.

For example, you can init it from a pandapower grid like (NOT RECOMMENDED, though sometimes needed):

from lightsim2grid.network import init_from_pandapower
pp_net = ...  # any pandapower grid eg. pp_net = pn.case118()

lightsim_grid_model = init_from_pandapower(pp_net)  # some warnings might be issued as well as some warnings

A better initialization is through the lightsim2grid.lightSimBackend.LightSimBackend class:

import grid2op
from lightsim2grid import LightSimBackend
# create a lightsim2grid "LSGrid"
env_name = ... # eg. "l2rpn_case14_sandbox"
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.

  1. Local bus id — the busbar number inside a substation. It is -1 for a disconnected element, or between 1 and n_busbar_per_sub. This is the grid2op convention: the value you put in a set_bus action and what you read in grid2op’s topo_vect. It is the convention of lightsim2grid.network.LSGrid.update_topo() (the bulk topology update used by lightsim2grid.lightSimBackend.LightSimBackend), whose new_values array is indexed by the position in the topology vector (pos_topo_vect) and holds local busbar ids. An element’s substation is given by its sub_id and its slot in topo_vect by pos_topo_vect.

  2. GridModel bus id (a.k.a. global bus id) — the index of a bus in the whole LSGrid, between 0 and n_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, the bus_id / bus1_id / bus2_id fields of the *Info objects, …) and of the “user facing” matrices/vectors (get_Ybus, get_Sbus, get_V, get_pv, …).

  3. Solver bus id — a compact index (0nb_connected_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 _solver suffix (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

lsgrid.id_ac_solver_to_me()

array indexed by AC solver bus id -> GridModel bus id

lsgrid.id_me_to_ac_solver()

array indexed by GridModel bus id -> AC solver bus id

lsgrid.id_dc_solver_to_me()

array indexed by DC solver bus id -> GridModel bus id

lsgrid.id_me_to_dc_solver()

array indexed by GridModel bus id -> DC solver bus id

lsgrid.total_bus()

total number of buses (n_sub * n_busbar_per_sub)

lsgrid.nb_connected_bus()

number of buses currently seen by the solver

Which convention each “by id” method uses:

Method(s)

get / set

Bus id convention

update_topo(has_changed, new_values)

set (bulk)

Local (per-substation)

change_bus_load / change_bus_gen / change_bus_sgen / change_bus_shunt / change_bus_storage / change_bus_svc

set

GridModel (global)

change_bus1_powerline / change_bus2_powerline / change_bus1_trafo / change_bus2_trafo / change_bus1_dcline / change_bus2_dcline

set

GridModel (global)

deactivate_bus / reactivate_bus

set

GridModel (global)

set_gen_regulated_bus(gen_id, regulated_bus)

set

GridModel (global)

get_bus_load / get_bus_gen / get_bus_sgen / get_bus_shunt / get_bus_storage / get_bus_svc / get_bus1_powerline / get_bus2_powerline / …

get

GridModel (global)

LoadInfo.bus_id (and bus1_id / bus2_id / …, regulated_bus_id of the *Info objects)

get (read-only)

GridModel (global)

get_Ybus / get_Sbus / get_V / get_Va / get_Vm / get_pv / get_pq / get_slack_ids

get

GridModel (global)

get_Ybus_solver / get_Sbus_solver / get_V_solver / get_pv_solver / get_pq_solver / get_slack_ids_solver / get_J_solver

get

Solver

solver.get_J / solver.get_theta_to_J_col / solver.get_vm_to_J_col / solver.get_q_to_J_col

get

Solver

Elements modeled

Substations

get_substations() (alias get_voltage_levels) returns a lightsim2grid.elements.SubstationContainer: like every other *Container on this page it supports len(...), indexing and iteration over lightsim2grid.elements.SubstationInfo objects.

class lightsim2grid.elements.SubstationContainer

This class allows to iterate through the substations of the lightsim2grid.network.LSGrid easily, as if they were in a python list.

A substation is not itself an electrical element: it is the group of candidate buses (busbars) that the elements connected “at” a given site can be assigned to (see Bus labelling conventions and lightsim2grid.elements.SubstationInfo.nb_max_busbars).

Examples

import grid2op
from lightsim2grid import LightSimBackend

env_name = ... # eg. "l2rpn_case14_test"
env = grid2op.make(env_name, backend=LightSimBackend())

grid_model = env.backend._grid

for sub in grid_model.get_substations():
    # sub is a `SubstationInfo`
    sub.vn_kv

Methods:

load_binary(path)

Load an object previously saved with save_binary().

save_binary(self, path[, atomic])

Save this object's state to a fast custom binary file (additive alternative to pickle).

staticmethod load_binary(path: str) lightsim2grid.lightsim2grid_cpp.SubstationContainer

Load an object previously saved with save_binary(). Raises RuntimeError on an incompatible binary format, a wrong object type, or a corrupted / truncated file (including corrupted internal sizes: no attempt is made to allocate more data than the file actually contains). Loading a whole grid additionally validates its consistency (see check_grid): a byte-wise well-formed but inconsistent grid raises IndexError (out-of-range index) or RuntimeError (structural inconsistency).

save_binary(self: lightsim2grid.lightsim2grid_cpp.SubstationContainer, path: str, atomic: bool = True) None

Save this object’s state to a fast custom binary file (additive alternative to pickle). By default (atomic=True) the write is atomic: an existing file at that path is only replaced once the new content has been written completely (an interrupted save never destroys a previous file). Pass atomic=False to write the destination directly instead – marginally faster (skips one temporary file + rename), without that protection. The file stays readable by any lightsim2grid version sharing the same binary format number.

class lightsim2grid.elements.SubstationInfo

This class represents what you get from retrieving some elements from lightsim2grid.elements.SubstationContainer.

It allows to read information from each substation of the powergrid.

Warning

Data can only be accessed from this element. You cannot modify (yet) the grid using this class.

Examples

import grid2op
from lightsim2grid import LightSimBackend

env_name = ... # eg. "l2rpn_case14_test"
env = grid2op.make(env_name, backend=LightSimBackend())

grid_model = env.backend._grid

first_substation = grid_model.get_substations()[0]  # first substation is a `SubstationInfo`

Attributes:

id

Get the id of the element.

name

Get the name of this substation.

nb_max_busbars

Maximum number of busbars (independent buses) allowed at this substation (int, > 0).

vn_kv

Nominal voltage of this substation, in kV (float).

property id

Get the id of the element. Ids are integer from 0 to n-1 (if n denotes the number of such elements on the grid.)

Examples

We give the example only for generators, but it works similarly for every other types of objects in a lightsim2grid.network.LSGrid.

This gives something like:

import grid2op
from lightsim2grid import LightSimBackend

env_name = ... # eg. "l2rpn_case14_test"
env = grid2op.make(env_name, backend=LightSimBackend())

grid_model = env.backend._grid

first_gen = grid_model.get_generators()[0]  # or get_loads for loads, etc.
first_gen.id  # should be 0
property name

Get the name of this substation. Names are optional and might not be set when reading the grid.

Read-only here; set in bulk (every substation at once), via lightsim2grid.network.LSGrid.set_substation_names().

property nb_max_busbars

Maximum number of busbars (independent buses) allowed at this substation (int, > 0).

This is the per-substation value of what lightsim2grid.network.LSGrid.set_max_nb_bus_per_sub() sets grid-wide: the substation has exactly this many candidate buses, some of which may be unused (disconnected) at any given time.

property vn_kv

Nominal voltage of this substation, in kV (float).

Generators (standard)

class lightsim2grid.elements.GeneratorContainer

This class allows to iterate through the generators of the lightsim2grid.network.LSGrid easily, as if they were in a python list.

In lightsim2grid they are modeled as “pv” meanings you give the active production setpoint and voltage magnitude setpoint (see lightsim2grid.elements.SGenContainer for more exotic PQ generators).

The active production value setpoint are modified only for the generators participating to the slack buses (see lightsim2grid.elements.GenInfo.is_slack and lightsim2grid.elements.GenInfo.slack_weight).

Generators are modeled as in pandapower and can be represented a the pandapower generators .

Examples

import grid2op
from lightsim2grid import LightSimBackend

env_name = ... # eg. "l2rpn_case14_test"
env = grid2op.make(env_name, backend=LightSimBackend())

grid_model = env.backend._grid

for gen in grid_model.get_generators():
    # do something with gen !
    gen.bus_id

print(f"There are {len(grid_model.get_generators())} generators on the grid.")

first_generator = grid_model.get_generators()[0]

You can have a look at lightsim2grid.elements.GenInfo for properties of these elements.

Methods:

get_bus_id(self)

bus_id (see the field of the same name on this container's element type, eg lightsim2grid.elements.GenInfo) for every element of this container, as a single array: element i of the result is that element's bus id, -1 if disconnected.

load_binary(path)

Load an object previously saved with save_binary().

save_binary(self, path[, atomic])

Save this object's state to a fast custom binary file (additive alternative to pickle).

get_bus_id(self: lightsim2grid.lightsim2grid_cpp.GeneratorContainer) Annotated[numpy.typing.NDArray[numpy.int32], '[m, 1]']

bus_id (see the field of the same name on this container’s element type, eg lightsim2grid.elements.GenInfo) for every element of this container, as a single array: element i of the result is that element’s bus id, -1 if disconnected.

staticmethod load_binary(path: str) lightsim2grid.lightsim2grid_cpp.GeneratorContainer

Load an object previously saved with save_binary(). Raises RuntimeError on an incompatible binary format, a wrong object type, or a corrupted / truncated file (including corrupted internal sizes: no attempt is made to allocate more data than the file actually contains). Loading a whole grid additionally validates its consistency (see check_grid): a byte-wise well-formed but inconsistent grid raises IndexError (out-of-range index) or RuntimeError (structural inconsistency).

save_binary(self: lightsim2grid.lightsim2grid_cpp.GeneratorContainer, path: str, atomic: bool = True) None

Save this object’s state to a fast custom binary file (additive alternative to pickle). By default (atomic=True) the write is atomic: an existing file at that path is only replaced once the new content has been written completely (an interrupted save never destroys a previous file). Pass atomic=False to write the destination directly instead – marginally faster (skips one temporary file + rename), without that protection. The file stays readable by any lightsim2grid version sharing the same binary format number.

class lightsim2grid.elements.GenInfo

This class represents what you get from retrieving some elements from lightsim2grid.elements.GeneratorContainer

It allows to read information from each generator of the powergrid.

Warning

Data ca only be accessed from this element. You cannot modify (yet) the grid using this class.

Examples

import grid2op
from lightsim2grid import LightSimBackend

env_name = ... # eg. "l2rpn_case14_test"
env = grid2op.make(env_name, backend=LightSimBackend())

grid_model = env.backend._grid

first_generator = grid_model.get_generators()[0]  # first generator is a `GenInfo`

for gen in grid_model.get_generators():
    # gen is a `GenInfo`
    gen.bus_id

Attributes:

bus_id

Get the bus id (as an integer) at which this generator is connected.

connected

Get the status (True = connected, False = disconnected) of this generator.

has_res

This property specify whether or not a given element contains some "result" information.

id

Get the id of the element.

is_slack

Tells whether or not this generator paticipated to the distributed slack bus.

max_q_mvar

Maximum reactive value that can be produced / absorbed by this generator, in MVAr.

min_q_mvar

Minimum reactive value that can be produced / absorbed by this generator, in MVAr.

name

Get the name of the element.

pos_topo_vect

Get the position of this generator in the grid2op "topo_vect" vector (-1 if never set).

regulated_bus_id

The grid bus id whose voltage this element regulates, when voltage_regulator_on is True.

res_p_mw

Get the active production (or consumption) in MW for element of the grid supporting this feature.

res_q_mvar

Get the reactive production (or consumption) in MVAr for element of the grid supporting this feature.

res_theta_deg

Get the angle of the complex voltage (in degree, not in radian) of the bus at which this object is connected.

res_v_kv

Get the magnitude of the complex voltage (in kV) of the bus at which this object is connected.

slack_weight

For each generators, gives the participation (for the distributed slack) of this particular generator.

sub_id

Get the substation id of this generator (-1 if never set; called "voltage level" in pypowsybl).

target_p_mw

Get the active power setpoint (MW, generator convention -- positive = power is injected to the grid) of this generator.

target_q_mvar

Get the reactive production (or consumption) setpoint in MVAr for element of the grid supporting this feature.

target_vm_pu

Get the voltage magnitude setpoint (pu, NOT kV) of this generator.

voltage_level_id

Get the substation id of this generator (-1 if never set; called "voltage level" in pypowsybl).

voltage_regulator_on

Whether this element tries to regulate a bus voltage (PV-like behaviour, following target_vm_pu) or applies a fixed reactive setpoint instead (PQ-like behaviour, following target_q_mvar).

property bus_id

Get the bus id (as an integer) at which this generator is connected. If -1 is returned it means the generator is disconnected.

(This is the gridmodel / global bus id, not the solver bus id – see lightsim2grid.network.LSGrid.id_me_to_ac_solver() to convert.)

Read-only here; equivalent to lightsim2grid.network.LSGrid.get_bus_gen(). To move this generator to another bus, call lightsim2grid.network.LSGrid.change_bus_gen().

property connected

Get the status (True = connected, False = disconnected) of this generator.

Read-only here. To disconnect / reconnect it, call lightsim2grid.network.LSGrid.deactivate_gen() / lightsim2grid.network.LSGrid.reactivate_gen().

property has_res

This property specify whether or not a given element contains some “result” information. If set to True then the fields starting with res_ (eg res_p_mw) are filled otherwise they are initialized with an arbitrary (and meaningless) value.

property id

Get the id of the element. Ids are integer from 0 to n-1 (if n denotes the number of such elements on the grid.)

Examples

We give the example only for generators, but it works similarly for every other types of objects in a lightsim2grid.network.LSGrid.

This gives something like:

import grid2op
from lightsim2grid import LightSimBackend

env_name = ... # eg. "l2rpn_case14_test"
env = grid2op.make(env_name, backend=LightSimBackend())

grid_model = env.backend._grid

first_gen = grid_model.get_generators()[0]  # or get_loads for loads, etc.
first_gen.id  # should be 0
property is_slack

Tells whether or not this generator paticipated to the distributed slack bus.

Note

Depending on the solver used, it is possible that a generator we asked to participate to the distributed slack bus do not participate to it (for example if there is a more than one generator where is_slack is True but the model used to computed the powerflow do not support distributed slack buses - eg lightsim2grid.algorithm.NRSing_SparseLU)

This is why we recommend to use the (slower) but more accurate lightsim2grid.algorithm.NR_SparseLU or lightsim2grid.algorithm.NR_KLU for example.

Read-only here, together with slack_weight. To make this generator participate (or stop participating) in the distributed slack, call lightsim2grid.network.LSGrid.add_gen_slackbus() / lightsim2grid.network.LSGrid.remove_gen_slackbus().

property max_q_mvar

Maximum reactive value that can be produced / absorbed by this generator, in MVAr. See min_q_mvar for when (and how) this is actually used.

property min_q_mvar

Minimum reactive value that can be produced / absorbed by this generator, in MVAr.

Note

On a lightsim2grid.elements.GenInfo or lightsim2grid.elements.ConverterStationInfo that is locally voltage-regulating (voltage_regulator_on is True and it does not regulate a remote bus), this is genuinely used at every solve: when several such units share the same bus, their reactive-power mismatch is split between them proportionally to max_q_mvar - min_q_mvar. It is also used, in the same case, by lightsim2grid.network.LSGrid.check_solution() when check_q_limits is True, to report any part of the mismatch that falls outside [min_q_mvar, max_q_mvar] instead of masking it.

On a “PQ” generator (voltage_regulator_on is False), a remotely-regulating one, or a lightsim2grid.elements.SGenInfo (static generators never regulate voltage), this value is NOT used anywhere by lightsim2grid: it is pure metadata carried over from the source model.

property name

Get the name of the element. Names are string that should be unique. But if you really want things unique, use the id

Warning

Names are optional and might not be set when reading the grid.

Examples

We give the example only for generators, but it works similarly for every other types of objects in a lightsim2grid.network.LSGrid.

This gives something like:

import grid2op
from lightsim2grid import LightSimBackend

env_name = ... # eg. "l2rpn_case14_test"
env = grid2op.make(env_name, backend=LightSimBackend())

grid_model = env.backend._grid

first_gen = grid_model.get_generators()[0]  # or get_loads for loads, etc.
first_gen.name
property pos_topo_vect

Get the position of this generator in the grid2op “topo_vect” vector (-1 if never set).

Read-only here; this is set once, by the grid loaders, via lightsim2grid.network.LSGrid.set_gen_pos_topo_vect().

property regulated_bus_id

The grid bus id whose voltage this element regulates, when voltage_regulator_on is True.

Defaults to this element’s own bus_id (“local” voltage control). When it differs from bus_id, the element performs “remote voltage control”: instead of behaving as an ordinary PV bus itself, it acts as a controller contributing (jointly with any other element regulating the same bus) to holding that bus’s voltage magnitude at target_vm_pu.

See also

lightsim2grid.network.LSGrid.set_gen_regulated_bus() to change it for a generator.

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.

property res_p_mw

Get the active production (or consumption) in MW for element of the grid supporting this feature.

For generators (and static generators) it is given following the “generator convention” (positive = power is injected to the grid)

For loads (and storage units) it is given following the “load convention” (positive = power is absorbed from the grid)

Read-only powerflow result, no LSGrid setter – also available in bulk, for every element of this container at once, via the corresponding LSGrid.get_*_res() method.

Warning

This feature is only relevant if the results have been computed (for example if a powerflow has successfully run)

property res_q_mvar

Get the reactive production (or consumption) in MVAr for element of the grid supporting this feature.

For generators (and static generators) it is given following the “generator convention” (positive = power is injected to the grid)

For loads (and storage units) it is given following the “load convention” (positive = power is absorbed from the grid)

Read-only powerflow result, no LSGrid setter – also available in bulk, for every element of this container at once, via the corresponding LSGrid.get_*_res() method.

Warning

This feature is only relevant if the results have been computed (for example if a powerflow has successfully run)

property res_theta_deg

Get the angle of the complex voltage (in degree, not in radian) of the bus at which this object is connected.

Note

All elements (load, generators, side of powerline etc.) connected at the same bus have the same “res_theta_deg”

Read-only powerflow result, no LSGrid setter – also available in bulk, for every element of this container at once, via the corresponding LSGrid.get_*_theta() method.

Warning

This feature is only relevant if the results have been computed (for example if a powerflow has successfully run)

property res_v_kv

Get the magnitude of the complex voltage (in kV) of the bus at which this object is connected.

Note

All elements (load, generators, side of powerline etc.) connected at the same bus have the same “res_v_kv”

Read-only powerflow result, no LSGrid setter – also available in bulk, for every element of this container at once, via the corresponding LSGrid.get_*_res() method.

Warning

This feature is only relevant if the results have been computed (for example if a powerflow has successfully run)

property slack_weight

For each generators, gives the participation (for the distributed slack) of this particular generator.

Note

Weights do not scale to one for this variable thus this number has no meaning by itself and should be compared with the others.

Read-only here, see is_slack for how to change it (the weight is set together with slack participation, via lightsim2grid.network.LSGrid.add_gen_slackbus()).

property sub_id

Get the substation id of this generator (-1 if never set; called “voltage level” in pypowsybl).

Read-only here; this is set once, by the grid loaders, via lightsim2grid.network.LSGrid.set_gen_to_subid().

property target_p_mw

Get the active power setpoint (MW, generator convention – positive = power is injected to the grid) of this generator.

Read-only here. To change it, call lightsim2grid.network.LSGrid.change_p_gen().

property target_q_mvar

Get the reactive production (or consumption) setpoint in MVAr for element of the grid supporting this feature.

For generators (and static generators) it is given following the “generator convention” (positive = power is injected to the grid)

For loads (and storage units) it is given following the “load convention” (positive = power is absorbed from the grid)

Note

For elements that can regulate a voltage instead of applying a fixed reactive setpoint (see lightsim2grid.elements.GenInfo.voltage_regulator_on / lightsim2grid.elements.ConverterStationInfo.voltage_regulator_on), this value is only actually used when voltage regulation is OFF. When it is ON, the reactive power is computed by the powerflow instead and this setpoint is ignored.

On GenInfo and ConverterStationInfo (the remaining users of this generic docstring): read-only, there is no LSGrid method exposed to change this value directly.

property target_vm_pu

Get the voltage magnitude setpoint (pu, NOT kV) of this generator.

Read-only here. To change it, call lightsim2grid.network.LSGrid.change_v_gen().

property voltage_level_id

Get the substation id of this generator (-1 if never set; called “voltage level” in pypowsybl).

Read-only here; this is set once, by the grid loaders, via lightsim2grid.network.LSGrid.set_gen_to_subid().

property voltage_regulator_on

Whether this element tries to regulate a bus voltage (PV-like behaviour, following target_vm_pu) or applies a fixed reactive setpoint instead (PQ-like behaviour, following target_q_mvar).

When True, the reactive power is not an independent input: it is computed by the powerflow so that the regulated bus’s voltage magnitude matches target_vm_pu (within min_q_mvar / max_q_mvar). When False, target_q_mvar is used directly and target_vm_pu / min_q_mvar / max_q_mvar are ignored.

Note

On a lightsim2grid.elements.GenInfo, the regulated bus is not necessarily this generator’s own bus – see lightsim2grid.elements.GenInfo.regulated_bus_id (“remote voltage control”).

On a lightsim2grid.elements.ConverterStationInfo, this is only meaningful for VSC stations (lightsim2grid.elements.ConverterStationInfo.converter_type == 0): LCC stations (converter_type == 1) always have it False and instead consume reactive power following lightsim2grid.elements.ConverterStationInfo.power_factor.

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)

class lightsim2grid.elements.SGenContainer

This class allows to iterate through the static generators of the lightsim2grid.network.LSGrid easily, as if they were in a python list.

In lightsim2grid they are two types of generators the more standard PV generators (see lightsim2grid.elements.GeneratorContainer). These are more exotic generators known as PQ, where you give the active production value and reactive production value. It’s basically like loads, but using the generator convention (if the value is positive, it means power is taken from the grid to the element)

They cannot participate to the distributed slack bus.

Static generators are modeled as in pandapower and can be represented a the pandapower static generators .

Examples

import grid2op
from lightsim2grid import LightSimBackend

# create a lightsim2grid "gridmodel"
env_name = ... # eg. "l2rpn_case14_test"
env = grid2op.make(env_name, backend=LightSimBackend())
grid_model = env.backend._grid

# manipulate the static generators
for sgen in grid_model.get_static_generators():
    # do something with sgen !
    sgen.bus_id

print(f"There are {len(grid_model.get_static_generators())} static generators on the grid.")

first_static_generator = grid_model.get_static_generators()[0]

You can have a look at lightsim2grid.elements.SGenInfo for properties of these elements.

Methods:

get_bus_id(self)

bus_id (see the field of the same name on this container's element type, eg lightsim2grid.elements.GenInfo) for every element of this container, as a single array: element i of the result is that element's bus id, -1 if disconnected.

load_binary(path)

Load an object previously saved with save_binary().

save_binary(self, path[, atomic])

Save this object's state to a fast custom binary file (additive alternative to pickle).

get_bus_id(self: lightsim2grid.lightsim2grid_cpp.SGenContainer) Annotated[numpy.typing.NDArray[numpy.int32], '[m, 1]']

bus_id (see the field of the same name on this container’s element type, eg lightsim2grid.elements.GenInfo) for every element of this container, as a single array: element i of the result is that element’s bus id, -1 if disconnected.

staticmethod load_binary(path: str) lightsim2grid.lightsim2grid_cpp.SGenContainer

Load an object previously saved with save_binary(). Raises RuntimeError on an incompatible binary format, a wrong object type, or a corrupted / truncated file (including corrupted internal sizes: no attempt is made to allocate more data than the file actually contains). Loading a whole grid additionally validates its consistency (see check_grid): a byte-wise well-formed but inconsistent grid raises IndexError (out-of-range index) or RuntimeError (structural inconsistency).

save_binary(self: lightsim2grid.lightsim2grid_cpp.SGenContainer, path: str, atomic: bool = True) None

Save this object’s state to a fast custom binary file (additive alternative to pickle). By default (atomic=True) the write is atomic: an existing file at that path is only replaced once the new content has been written completely (an interrupted save never destroys a previous file). Pass atomic=False to write the destination directly instead – marginally faster (skips one temporary file + rename), without that protection. The file stays readable by any lightsim2grid version sharing the same binary format number.

class lightsim2grid.elements.SGenInfo

This class represents what you get from retrieving some elements from lightsim2grid.elements.SGenContainer

It allows to read information from each static generator of the powergrid.

Warning

Data ca only be accessed from this element. You cannot modify (yet) the grid using this class.

Examples

import grid2op
from lightsim2grid import LightSimBackend

# create a lightsim2grid "gridmodel"
env_name = ... # eg. "l2rpn_case14_test"
env = grid2op.make(env_name, backend=LightSimBackend())
grid_model = env.backend._grid

# do something with the static generators
first_static_generator = grid_model.get_static_generators()[0]  # first static generator is a `SGenInfo`

for sgen in grid_model.get_static_generators():
    # sgen is a `SGenInfo`
    sgen.bus_id

Attributes:

bus_id

Get the bus id (as an integer) at which this static generator is connected.

connected

Get the status (True = connected, False = disconnected) of this static generator.

has_res

This property specify whether or not a given element contains some "result" information.

id

Get the id of the element.

max_p_mw

Maximum active value that can be produced / absorbed by this static generator, in MW.

max_q_mvar

Maximum reactive value that can be produced / absorbed by this generator, in MVAr.

min_p_mw

Minimum active value that can be produced / absorbed by this static generator, in MW.

min_q_mvar

Minimum reactive value that can be produced / absorbed by this generator, in MVAr.

name

Get the name of the element.

pos_topo_vect

Get the position of this static generator in the grid2op "topo_vect" vector (-1 if never set).

res_p_mw

Get the active production (or consumption) in MW for element of the grid supporting this feature.

res_q_mvar

Get the reactive production (or consumption) in MVAr for element of the grid supporting this feature.

res_theta_deg

Get the angle of the complex voltage (in degree, not in radian) of the bus at which this object is connected.

res_v_kv

Get the magnitude of the complex voltage (in kV) of the bus at which this object is connected.

sub_id

Get the substation id of this static generator (-1 if never set; called "voltage level" in pypowsybl).

target_p_mw

Get the active power setpoint (MW, generator convention) of this static generator.

target_q_mvar

Get the reactive power setpoint (MVAr, generator convention) of this static generator.

voltage_level_id

Get the substation id of this static generator (-1 if never set; called "voltage level" in pypowsybl).

property bus_id

Get the bus id (as an integer) at which this static generator is connected. If -1 is returned it means the static generator is disconnected.

(This is the gridmodel / global bus id, not the solver bus id – see lightsim2grid.network.LSGrid.id_me_to_ac_solver() to convert.)

Read-only here; equivalent to lightsim2grid.network.LSGrid.get_bus_sgen(). To move this static generator to another bus, call lightsim2grid.network.LSGrid.change_bus_sgen().

property connected

Get the status (True = connected, False = disconnected) of this static generator.

Read-only here. To disconnect / reconnect it, call lightsim2grid.network.LSGrid.deactivate_sgen() / lightsim2grid.network.LSGrid.reactivate_sgen().

property has_res

This property specify whether or not a given element contains some “result” information. If set to True then the fields starting with res_ (eg res_p_mw) are filled otherwise they are initialized with an arbitrary (and meaningless) value.

property id

Get the id of the element. Ids are integer from 0 to n-1 (if n denotes the number of such elements on the grid.)

Examples

We give the example only for generators, but it works similarly for every other types of objects in a lightsim2grid.network.LSGrid.

This gives something like:

import grid2op
from lightsim2grid import LightSimBackend

env_name = ... # eg. "l2rpn_case14_test"
env = grid2op.make(env_name, backend=LightSimBackend())

grid_model = env.backend._grid

first_gen = grid_model.get_generators()[0]  # or get_loads for loads, etc.
first_gen.id  # should be 0
property max_p_mw

Maximum active value that can be produced / absorbed by this static generator, in MW. See min_p_mw.

property max_q_mvar

Maximum reactive value that can be produced / absorbed by this generator, in MVAr. See min_q_mvar for when (and how) this is actually used.

property min_p_mw

Minimum active value that can be produced / absorbed by this static generator, in MW.

Note

This is NOT used anywhere by lightsim2grid today: it is not enforced by the solver, and lightsim2grid.network.LSGrid.check_solution() does not examine static generators at all (only lightsim2grid.elements.GenInfo / lightsim2grid.elements.ConverterStationInfo, see min_q_mvar). It is pure metadata carried over from the source model.

property min_q_mvar

Minimum reactive value that can be produced / absorbed by this generator, in MVAr.

Note

On a lightsim2grid.elements.GenInfo or lightsim2grid.elements.ConverterStationInfo that is locally voltage-regulating (voltage_regulator_on is True and it does not regulate a remote bus), this is genuinely used at every solve: when several such units share the same bus, their reactive-power mismatch is split between them proportionally to max_q_mvar - min_q_mvar. It is also used, in the same case, by lightsim2grid.network.LSGrid.check_solution() when check_q_limits is True, to report any part of the mismatch that falls outside [min_q_mvar, max_q_mvar] instead of masking it.

On a “PQ” generator (voltage_regulator_on is False), a remotely-regulating one, or a lightsim2grid.elements.SGenInfo (static generators never regulate voltage), this value is NOT used anywhere by lightsim2grid: it is pure metadata carried over from the source model.

property name

Get the name of the element. Names are string that should be unique. But if you really want things unique, use the id

Warning

Names are optional and might not be set when reading the grid.

Examples

We give the example only for generators, but it works similarly for every other types of objects in a lightsim2grid.network.LSGrid.

This gives something like:

import grid2op
from lightsim2grid import LightSimBackend

env_name = ... # eg. "l2rpn_case14_test"
env = grid2op.make(env_name, backend=LightSimBackend())

grid_model = env.backend._grid

first_gen = grid_model.get_generators()[0]  # or get_loads for loads, etc.
first_gen.name
property pos_topo_vect

Get the position of this static generator in the grid2op “topo_vect” vector (-1 if never set).

Static generators have no dedicated LSGrid position setter – unlike other elements, they are not part of grid2op’s topology vector.

property res_p_mw

Get the active production (or consumption) in MW for element of the grid supporting this feature.

For generators (and static generators) it is given following the “generator convention” (positive = power is injected to the grid)

For loads (and storage units) it is given following the “load convention” (positive = power is absorbed from the grid)

Read-only powerflow result, no LSGrid setter – also available in bulk, for every element of this container at once, via the corresponding LSGrid.get_*_res() method.

Warning

This feature is only relevant if the results have been computed (for example if a powerflow has successfully run)

property res_q_mvar

Get the reactive production (or consumption) in MVAr for element of the grid supporting this feature.

For generators (and static generators) it is given following the “generator convention” (positive = power is injected to the grid)

For loads (and storage units) it is given following the “load convention” (positive = power is absorbed from the grid)

Read-only powerflow result, no LSGrid setter – also available in bulk, for every element of this container at once, via the corresponding LSGrid.get_*_res() method.

Warning

This feature is only relevant if the results have been computed (for example if a powerflow has successfully run)

property res_theta_deg

Get the angle of the complex voltage (in degree, not in radian) of the bus at which this object is connected.

Note

All elements (load, generators, side of powerline etc.) connected at the same bus have the same “res_theta_deg”

Read-only powerflow result, no LSGrid setter – also available in bulk, for every element of this container at once, via the corresponding LSGrid.get_*_theta() method.

Warning

This feature is only relevant if the results have been computed (for example if a powerflow has successfully run)

property res_v_kv

Get the magnitude of the complex voltage (in kV) of the bus at which this object is connected.

Note

All elements (load, generators, side of powerline etc.) connected at the same bus have the same “res_v_kv”

Read-only powerflow result, no LSGrid setter – also available in bulk, for every element of this container at once, via the corresponding LSGrid.get_*_res() method.

Warning

This feature is only relevant if the results have been computed (for example if a powerflow has successfully run)

property sub_id

Get the substation id of this static generator (-1 if never set; called “voltage level” in pypowsybl).

Static generators have no dedicated LSGrid substation-id setter.

property target_p_mw

Get the active power setpoint (MW, generator convention) of this static generator.

Read-only here. To change it, call lightsim2grid.network.LSGrid.change_p_sgen().

property target_q_mvar

Get the reactive power setpoint (MVAr, generator convention) of this static generator.

Read-only here. To change it, call lightsim2grid.network.LSGrid.change_q_sgen().

property voltage_level_id

Get the substation id of this static generator (-1 if never set; called “voltage level” in pypowsybl).

Static generators have no dedicated LSGrid substation-id setter.

Loads and Storage Units

class lightsim2grid.elements.LoadContainer

This class allows to iterate through the loads and storage units of the lightsim2grid.network.LSGrid easily, as if they were in a python list.

They cannot participate to the distributed slack bus yet. If you want this feature, fill free to send us a github issue.

Loads are modeled as in pandapower and can be represented a the pandapower loads .

Note

lightsim2grid Storages are modeled as load.

Examples

import grid2op
from lightsim2grid import LightSimBackend

# create a lightsim2grid "gridmodel"
env_name = ... # eg. "l2rpn_case14_test"
env = grid2op.make(env_name, backend=LightSimBackend())
grid_model = env.backend._grid

# manipulate the load
for load in grid_model.get_loads():
    # do something with load !
    load.bus_id

print(f"There are {len(grid_model.get_loads())} loads on the grid.")

first_load = grid_model.get_loads()[0]

# or the storage units
for storage in grid_model.get_storages():
    # do something with storage !
    storage.bus_id

print(f"There are {len(grid_model.get_storages())} storage units on the grid.")

first_storage_unit = grid_model.get_storages()[0]

You can have a look at lightsim2grid.elements.LoadInfo for properties of these elements.

Methods:

get_bus_id(self)

bus_id (see the field of the same name on this container's element type, eg lightsim2grid.elements.GenInfo) for every element of this container, as a single array: element i of the result is that element's bus id, -1 if disconnected.

load_binary(path)

Load an object previously saved with save_binary().

save_binary(self, path[, atomic])

Save this object's state to a fast custom binary file (additive alternative to pickle).

get_bus_id(self: lightsim2grid.lightsim2grid_cpp.LoadContainer) Annotated[numpy.typing.NDArray[numpy.int32], '[m, 1]']

bus_id (see the field of the same name on this container’s element type, eg lightsim2grid.elements.GenInfo) for every element of this container, as a single array: element i of the result is that element’s bus id, -1 if disconnected.

staticmethod load_binary(path: str) lightsim2grid.lightsim2grid_cpp.LoadContainer

Load an object previously saved with save_binary(). Raises RuntimeError on an incompatible binary format, a wrong object type, or a corrupted / truncated file (including corrupted internal sizes: no attempt is made to allocate more data than the file actually contains). Loading a whole grid additionally validates its consistency (see check_grid): a byte-wise well-formed but inconsistent grid raises IndexError (out-of-range index) or RuntimeError (structural inconsistency).

save_binary(self: lightsim2grid.lightsim2grid_cpp.LoadContainer, path: str, atomic: bool = True) None

Save this object’s state to a fast custom binary file (additive alternative to pickle). By default (atomic=True) the write is atomic: an existing file at that path is only replaced once the new content has been written completely (an interrupted save never destroys a previous file). Pass atomic=False to write the destination directly instead – marginally faster (skips one temporary file + rename), without that protection. The file stays readable by any lightsim2grid version sharing the same binary format number.

class lightsim2grid.elements.LoadInfo

This class represents what you get from retrieving some elements from lightsim2grid.elements.LoadContainer. We remind the reader that storage units are also modeled as load in lightsim2grid.

It allows to read information from each load / storage unit of the powergrid.

Warning

Data ca only be accessed from this element. You cannot modify (yet) the grid using this class.

Note

lightsim2grid Storages are modeled as load.

Examples

import grid2op
from lightsim2grid import LightSimBackend

# create a lightsim2grid "gridmodel"
env_name = ... # eg. "l2rpn_case14_test"
env = grid2op.make(env_name, backend=LightSimBackend())
grid_model = env.backend._grid

# for loads
first_load = grid_model.get_loads()[0]  # first static generator is a `LoadInfo`
for load in grid_model.get_loads():
    # load is a `LoadInfo`
    load.bus_id

# for loads
first_storage_unit = grid_model.get_storages()[0]  # first static generator is a `LoadInfo`
for storage in grid_model.get_storages():
    # storage is a `LoadInfo`
    storage.bus_id

Attributes:

bus_id

Get the bus id (as an integer) at which this load is connected.

connected

Get the status (True = connected, False = disconnected) of this load.

has_res

This property specify whether or not a given element contains some "result" information.

id

Get the id of the element.

name

Get the name of the element.

pos_topo_vect

Get the position of this load in the grid2op "topo_vect" vector (-1 if never set).

res_p_mw

Get the active production (or consumption) in MW for element of the grid supporting this feature.

res_q_mvar

Get the reactive production (or consumption) in MVAr for element of the grid supporting this feature.

res_theta_deg

Get the angle of the complex voltage (in degree, not in radian) of the bus at which this object is connected.

res_v_kv

Get the magnitude of the complex voltage (in kV) of the bus at which this object is connected.

sub_id

Get the substation id of this load (-1 if never set; called "voltage level" in pypowsybl).

target_p_mw

Get the active power setpoint (MW, load convention -- positive = power is absorbed from the grid) of this load.

target_q_mvar

Get the reactive power setpoint (MVAr, load convention) of this load.

voltage_level_id

Get the substation id of this load (-1 if never set; called "voltage level" in pypowsybl).

property bus_id

Get the bus id (as an integer) at which this load is connected. If -1 is returned it means the load is disconnected.

(This is the gridmodel / global bus id, not the solver bus id – see lightsim2grid.network.LSGrid.id_me_to_ac_solver() to convert.)

Read-only here; equivalent to lightsim2grid.network.LSGrid.get_bus_load(). To move this load to another bus, call lightsim2grid.network.LSGrid.change_bus_load().

property connected

Get the status (True = connected, False = disconnected) of this load.

Read-only here. To disconnect / reconnect it, call lightsim2grid.network.LSGrid.deactivate_load() / lightsim2grid.network.LSGrid.reactivate_load().

property has_res

This property specify whether or not a given element contains some “result” information. If set to True then the fields starting with res_ (eg res_p_mw) are filled otherwise they are initialized with an arbitrary (and meaningless) value.

property id

Get the id of the element. Ids are integer from 0 to n-1 (if n denotes the number of such elements on the grid.)

Examples

We give the example only for generators, but it works similarly for every other types of objects in a lightsim2grid.network.LSGrid.

This gives something like:

import grid2op
from lightsim2grid import LightSimBackend

env_name = ... # eg. "l2rpn_case14_test"
env = grid2op.make(env_name, backend=LightSimBackend())

grid_model = env.backend._grid

first_gen = grid_model.get_generators()[0]  # or get_loads for loads, etc.
first_gen.id  # should be 0
property name

Get the name of the element. Names are string that should be unique. But if you really want things unique, use the id

Warning

Names are optional and might not be set when reading the grid.

Examples

We give the example only for generators, but it works similarly for every other types of objects in a lightsim2grid.network.LSGrid.

This gives something like:

import grid2op
from lightsim2grid import LightSimBackend

env_name = ... # eg. "l2rpn_case14_test"
env = grid2op.make(env_name, backend=LightSimBackend())

grid_model = env.backend._grid

first_gen = grid_model.get_generators()[0]  # or get_loads for loads, etc.
first_gen.name
property pos_topo_vect

Get the position of this load in the grid2op “topo_vect” vector (-1 if never set).

Read-only here; this is set once, by the grid loaders, via lightsim2grid.network.LSGrid.set_load_pos_topo_vect().

property res_p_mw

Get the active production (or consumption) in MW for element of the grid supporting this feature.

For generators (and static generators) it is given following the “generator convention” (positive = power is injected to the grid)

For loads (and storage units) it is given following the “load convention” (positive = power is absorbed from the grid)

Read-only powerflow result, no LSGrid setter – also available in bulk, for every element of this container at once, via the corresponding LSGrid.get_*_res() method.

Warning

This feature is only relevant if the results have been computed (for example if a powerflow has successfully run)

property res_q_mvar

Get the reactive production (or consumption) in MVAr for element of the grid supporting this feature.

For generators (and static generators) it is given following the “generator convention” (positive = power is injected to the grid)

For loads (and storage units) it is given following the “load convention” (positive = power is absorbed from the grid)

Read-only powerflow result, no LSGrid setter – also available in bulk, for every element of this container at once, via the corresponding LSGrid.get_*_res() method.

Warning

This feature is only relevant if the results have been computed (for example if a powerflow has successfully run)

property res_theta_deg

Get the angle of the complex voltage (in degree, not in radian) of the bus at which this object is connected.

Note

All elements (load, generators, side of powerline etc.) connected at the same bus have the same “res_theta_deg”

Read-only powerflow result, no LSGrid setter – also available in bulk, for every element of this container at once, via the corresponding LSGrid.get_*_theta() method.

Warning

This feature is only relevant if the results have been computed (for example if a powerflow has successfully run)

property res_v_kv

Get the magnitude of the complex voltage (in kV) of the bus at which this object is connected.

Note

All elements (load, generators, side of powerline etc.) connected at the same bus have the same “res_v_kv”

Read-only powerflow result, no LSGrid setter – also available in bulk, for every element of this container at once, via the corresponding LSGrid.get_*_res() method.

Warning

This feature is only relevant if the results have been computed (for example if a powerflow has successfully run)

property sub_id

Get the substation id of this load (-1 if never set; called “voltage level” in pypowsybl).

Read-only here; this is set once, by the grid loaders, via lightsim2grid.network.LSGrid.set_load_to_subid().

property target_p_mw

Get the active power setpoint (MW, load convention – positive = power is absorbed from the grid) of this load.

Read-only here. To change it, call lightsim2grid.network.LSGrid.change_p_load().

property target_q_mvar

Get the reactive power setpoint (MVAr, load convention) of this load.

Read-only here. To change it, call lightsim2grid.network.LSGrid.change_q_load().

property voltage_level_id

Get the substation id of this load (-1 if never set; called “voltage level” in pypowsybl).

Read-only here; this is set once, by the grid loaders, via lightsim2grid.network.LSGrid.set_load_to_subid().

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.

class lightsim2grid.elements.StorageContainer

This class allows to iterate through the loads and storage units of the lightsim2grid.network.LSGrid easily, as if they were in a python list.

They cannot participate to the distributed slack bus yet. If you want this feature, fill free to send us a github issue.

Loads are modeled as in pandapower and can be represented a the pandapower loads .

Note

lightsim2grid Storages are modeled as load.

Examples

import grid2op
from lightsim2grid import LightSimBackend

# create a lightsim2grid "gridmodel"
env_name = ... # eg. "l2rpn_case14_test"
env = grid2op.make(env_name, backend=LightSimBackend())
grid_model = env.backend._grid

# manipulate the load
for load in grid_model.get_loads():
    # do something with load !
    load.bus_id

print(f"There are {len(grid_model.get_loads())} loads on the grid.")

first_load = grid_model.get_loads()[0]

# or the storage units
for storage in grid_model.get_storages():
    # do something with storage !
    storage.bus_id

print(f"There are {len(grid_model.get_storages())} storage units on the grid.")

first_storage_unit = grid_model.get_storages()[0]

You can have a look at lightsim2grid.elements.LoadInfo for properties of these elements.

Methods:

get_bus_id(self)

bus_id (see the field of the same name on this container's element type, eg lightsim2grid.elements.GenInfo) for every element of this container, as a single array: element i of the result is that element's bus id, -1 if disconnected.

load_binary(path)

Load an object previously saved with save_binary().

save_binary(self, path[, atomic])

Save this object's state to a fast custom binary file (additive alternative to pickle).

get_bus_id(self: lightsim2grid.lightsim2grid_cpp.StorageContainer) Annotated[numpy.typing.NDArray[numpy.int32], '[m, 1]']

bus_id (see the field of the same name on this container’s element type, eg lightsim2grid.elements.GenInfo) for every element of this container, as a single array: element i of the result is that element’s bus id, -1 if disconnected.

staticmethod load_binary(path: str) lightsim2grid.lightsim2grid_cpp.StorageContainer

Load an object previously saved with save_binary(). Raises RuntimeError on an incompatible binary format, a wrong object type, or a corrupted / truncated file (including corrupted internal sizes: no attempt is made to allocate more data than the file actually contains). Loading a whole grid additionally validates its consistency (see check_grid): a byte-wise well-formed but inconsistent grid raises IndexError (out-of-range index) or RuntimeError (structural inconsistency).

save_binary(self: lightsim2grid.lightsim2grid_cpp.StorageContainer, path: str, atomic: bool = True) None

Save this object’s state to a fast custom binary file (additive alternative to pickle). By default (atomic=True) the write is atomic: an existing file at that path is only replaced once the new content has been written completely (an interrupted save never destroys a previous file). Pass atomic=False to write the destination directly instead – marginally faster (skips one temporary file + rename), without that protection. The file stays readable by any lightsim2grid version sharing the same binary format number.

class lightsim2grid.elements.StorageInfo

This class represents what you get from retrieving some elements from lightsim2grid.elements.LoadContainer. We remind the reader that storage units are also modeled as load in lightsim2grid.

It allows to read information from each load / storage unit of the powergrid.

Warning

Data ca only be accessed from this element. You cannot modify (yet) the grid using this class.

Note

lightsim2grid Storages are modeled as load.

Examples

import grid2op
from lightsim2grid import LightSimBackend

# create a lightsim2grid "gridmodel"
env_name = ... # eg. "l2rpn_case14_test"
env = grid2op.make(env_name, backend=LightSimBackend())
grid_model = env.backend._grid

# for loads
first_load = grid_model.get_loads()[0]  # first static generator is a `LoadInfo`
for load in grid_model.get_loads():
    # load is a `LoadInfo`
    load.bus_id

# for loads
first_storage_unit = grid_model.get_storages()[0]  # first static generator is a `LoadInfo`
for storage in grid_model.get_storages():
    # storage is a `LoadInfo`
    storage.bus_id

Attributes:

bus_id

Get the bus id (as an integer) at which this storage unit is connected.

connected

Get the status (True = connected, False = disconnected) of this storage unit.

has_res

This property specify whether or not a given element contains some "result" information.

id

Get the id of the element.

name

Get the name of the element.

pos_topo_vect

Get the position of this storage unit in the grid2op "topo_vect" vector (-1 if never set).

res_p_mw

Get the active production (or consumption) in MW for element of the grid supporting this feature.

res_q_mvar

Get the reactive production (or consumption) in MVAr for element of the grid supporting this feature.

res_theta_deg

Get the angle of the complex voltage (in degree, not in radian) of the bus at which this object is connected.

res_v_kv

Get the magnitude of the complex voltage (in kV) of the bus at which this object is connected.

sub_id

Get the substation id of this storage unit (-1 if never set; called "voltage level" in pypowsybl).

target_p_mw

Get the active power setpoint (MW, load convention) of this storage unit.

target_q_mvar

Get the reactive power setpoint (MVAr, load convention) of this storage unit.

voltage_level_id

Get the substation id of this storage unit (-1 if never set; called "voltage level" in pypowsybl).

property bus_id

Get the bus id (as an integer) at which this storage unit is connected. If -1 is returned it means the storage unit is disconnected.

(This is the gridmodel / global bus id, not the solver bus id – see lightsim2grid.network.LSGrid.id_me_to_ac_solver() to convert.)

Read-only here; equivalent to lightsim2grid.network.LSGrid.get_bus_storage(). To move this storage unit to another bus, call lightsim2grid.network.LSGrid.change_bus_storage().

property connected

Get the status (True = connected, False = disconnected) of this storage unit.

Read-only here. To disconnect / reconnect it, call lightsim2grid.network.LSGrid.deactivate_storage() / lightsim2grid.network.LSGrid.reactivate_storage().

property has_res

This property specify whether or not a given element contains some “result” information. If set to True then the fields starting with res_ (eg res_p_mw) are filled otherwise they are initialized with an arbitrary (and meaningless) value.

property id

Get the id of the element. Ids are integer from 0 to n-1 (if n denotes the number of such elements on the grid.)

Examples

We give the example only for generators, but it works similarly for every other types of objects in a lightsim2grid.network.LSGrid.

This gives something like:

import grid2op
from lightsim2grid import LightSimBackend

env_name = ... # eg. "l2rpn_case14_test"
env = grid2op.make(env_name, backend=LightSimBackend())

grid_model = env.backend._grid

first_gen = grid_model.get_generators()[0]  # or get_loads for loads, etc.
first_gen.id  # should be 0
property name

Get the name of the element. Names are string that should be unique. But if you really want things unique, use the id

Warning

Names are optional and might not be set when reading the grid.

Examples

We give the example only for generators, but it works similarly for every other types of objects in a lightsim2grid.network.LSGrid.

This gives something like:

import grid2op
from lightsim2grid import LightSimBackend

env_name = ... # eg. "l2rpn_case14_test"
env = grid2op.make(env_name, backend=LightSimBackend())

grid_model = env.backend._grid

first_gen = grid_model.get_generators()[0]  # or get_loads for loads, etc.
first_gen.name
property pos_topo_vect

Get the position of this storage unit in the grid2op “topo_vect” vector (-1 if never set).

Read-only here; this is set once, by the grid loaders, via lightsim2grid.network.LSGrid.set_storage_pos_topo_vect().

property res_p_mw

Get the active production (or consumption) in MW for element of the grid supporting this feature.

For generators (and static generators) it is given following the “generator convention” (positive = power is injected to the grid)

For loads (and storage units) it is given following the “load convention” (positive = power is absorbed from the grid)

Read-only powerflow result, no LSGrid setter – also available in bulk, for every element of this container at once, via the corresponding LSGrid.get_*_res() method.

Warning

This feature is only relevant if the results have been computed (for example if a powerflow has successfully run)

property res_q_mvar

Get the reactive production (or consumption) in MVAr for element of the grid supporting this feature.

For generators (and static generators) it is given following the “generator convention” (positive = power is injected to the grid)

For loads (and storage units) it is given following the “load convention” (positive = power is absorbed from the grid)

Read-only powerflow result, no LSGrid setter – also available in bulk, for every element of this container at once, via the corresponding LSGrid.get_*_res() method.

Warning

This feature is only relevant if the results have been computed (for example if a powerflow has successfully run)

property res_theta_deg

Get the angle of the complex voltage (in degree, not in radian) of the bus at which this object is connected.

Note

All elements (load, generators, side of powerline etc.) connected at the same bus have the same “res_theta_deg”

Read-only powerflow result, no LSGrid setter – also available in bulk, for every element of this container at once, via the corresponding LSGrid.get_*_theta() method.

Warning

This feature is only relevant if the results have been computed (for example if a powerflow has successfully run)

property res_v_kv

Get the magnitude of the complex voltage (in kV) of the bus at which this object is connected.

Note

All elements (load, generators, side of powerline etc.) connected at the same bus have the same “res_v_kv”

Read-only powerflow result, no LSGrid setter – also available in bulk, for every element of this container at once, via the corresponding LSGrid.get_*_res() method.

Warning

This feature is only relevant if the results have been computed (for example if a powerflow has successfully run)

property sub_id

Get the substation id of this storage unit (-1 if never set; called “voltage level” in pypowsybl).

Read-only here; this is set once, by the grid loaders, via lightsim2grid.network.LSGrid.set_storage_to_subid().

property target_p_mw

Get the active power setpoint (MW, load convention) of this storage unit.

Read-only here. To change it, call lightsim2grid.network.LSGrid.change_p_storage().

property target_q_mvar

Get the reactive power setpoint (MVAr, load convention) of this storage unit.

Read-only here. To change it, call lightsim2grid.network.LSGrid.change_q_storage().

property voltage_level_id

Get the substation id of this storage unit (-1 if never set; called “voltage level” in pypowsybl).

Read-only here; this is set once, by the grid loaders, via lightsim2grid.network.LSGrid.set_storage_to_subid().

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 maintains target_vm_pu at its regulated bus, possibly with a non-zero slope_pu (droop);

  • 2 (REACTIVE_POWER): it injects target_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.

class lightsim2grid.elements.SvcContainer

This class allows to iterate through the Static Var Compensators (SVC) of the lightsim2grid.network.LSGrid easily, as if they were in a python list.

An SVC injects reactive power only (its active power is always 0). It follows the IIDM model of powsybl, with three regulation modes (see regulation_mode):

  • VOLTAGE: regulates the voltage of a bus (local or remote), optionally with a voltage/reactive slope (“droop”). Stamps nothing directly in Sbus: it is never a PV bus, and is always a controller of a VoltageControl group (the bordered formulation), even for the local, non-sloped case.

  • REACTIVE_POWER: a fixed reactive injection (behaves like a non-regulating generator, or a load): stamps Q (and P = 0) into Sbus directly.

  • OFF: behaves as if disconnected.

b_min / b_max are stored for introspection only: they are never enforced by the powerflow (no outer loop, no limit check), mirroring how a generator’s min_q_mvar / max_q_mvar is handled.

Voltage regulation equations (VOLTAGE mode)

A VOLTAGE-mode SVC never becomes a PV bus. Instead it is solved as a “controller” of a bordered Newton-Raphson block, exactly like a remote-regulating generator (see regulated_bus_id): its reactive injection \(Q_c\) (generator sign convention, per unit) becomes an extra unknown of the powerflow, solved for jointly with the bus voltages and angles.

All controllers (generators and/or SVCs) that regulate the same bus form one “group”. For a group regulating bus reg at setpoint \(v_{set}\), with controllers \(c = 1..N\):

  • voltage constraint (one equation for the whole group):

    \[V_m(reg) + \sum_{c=1}^{N} s_c \, Q_c = v_{set}\]

    where \(s_c\) is the slope (slope_pu) of controller \(c\), 0 for a generator or a non-sloped (slope_pu = 0) SVC. With a single non-sloped controller in the group this reduces to the usual PV-like \(V_m(reg) = v_{set}\), only enforced through this bordered \(Q_c\) unknown rather than by reclassifying the bus.

  • reactive sharing (\(N-1\) equations, only when the group has more than one controller):

    \[\frac{Q_1}{w_1} = \frac{Q_2}{w_2} = \dots = \frac{Q_N}{w_N}\]

    i.e. controllers share the group’s total reactive effort in proportion to their weight \(w_c\), with \(w_c\) = b_max \(-\) b_min for an SVC (qmax - qmin for a generator).

slope_pu is expressed directly in per-unit (a pu voltage deviation per pu of \(Q_c\)). When importing from a pypowsybl grid, the slope is read from the voltagePerReactivePowerControl extension in kV/MVar and converted as

\[s_{pu} = slope_{kV/MVar} \cdot \frac{s_{n,mva}}{v_{n,kv}(reg)}\]

with \(v_{n,kv}(reg)\) the nominal voltage of the regulated bus.

Examples

import grid2op
from lightsim2grid import LightSimBackend

env_name = ... # eg. "l2rpn_case14_test"
env = grid2op.make(env_name, backend=LightSimBackend())
grid_model = env.backend._grid

for svc in grid_model.get_svcs():
    # svc is a `SvcInfo`
    svc.bus_id

Classes:

RegulationMode

The regulation mode of a Static Var Compensator (values follow the IIDM model of powsybl):

Methods:

load_binary(path)

Load an object previously saved with save_binary().

save_binary(self, path[, atomic])

Save this object's state to a fast custom binary file (additive alternative to pickle).

class RegulationMode

The regulation mode of a Static Var Compensator (values follow the IIDM model of powsybl): OFF (0), VOLTAGE (1), or REACTIVE_POWER (2) – see lightsim2grid.elements.SvcContainer for what each means.

Members:

OFF

VOLTAGE

REACTIVE_POWER

Attributes:

name

property name
staticmethod load_binary(path: str) lightsim2grid.lightsim2grid_cpp.SvcContainer

Load an object previously saved with save_binary(). Raises RuntimeError on an incompatible binary format, a wrong object type, or a corrupted / truncated file (including corrupted internal sizes: no attempt is made to allocate more data than the file actually contains). Loading a whole grid additionally validates its consistency (see check_grid): a byte-wise well-formed but inconsistent grid raises IndexError (out-of-range index) or RuntimeError (structural inconsistency).

save_binary(self: lightsim2grid.lightsim2grid_cpp.SvcContainer, path: str, atomic: bool = True) None

Save this object’s state to a fast custom binary file (additive alternative to pickle). By default (atomic=True) the write is atomic: an existing file at that path is only replaced once the new content has been written completely (an interrupted save never destroys a previous file). Pass atomic=False to write the destination directly instead – marginally faster (skips one temporary file + rename), without that protection. The file stays readable by any lightsim2grid version sharing the same binary format number.

class lightsim2grid.elements.SvcInfo

This class represents what you get from retrieving some elements from lightsim2grid.elements.SvcContainer.

It allows to read information from each Static Var Compensator (SVC) of the powergrid.

Warning

Data can only be accessed from this element. You cannot modify (yet) the grid using this class.

Examples

import grid2op
from lightsim2grid import LightSimBackend

env_name = ... # eg. "l2rpn_case14_test"
env = grid2op.make(env_name, backend=LightSimBackend())
grid_model = env.backend._grid

first_svc = grid_model.get_svcs()[0]  # first SVC is a `SvcInfo`

for svc in grid_model.get_svcs():
    # svc is a `SvcInfo`
    svc.bus_id

Attributes:

b_max

Maximum susceptance (pu) -- stored for introspection only, it is never enforced by the powerflow (no outer loop, no limit check).

b_min

Minimum susceptance (pu) -- stored for introspection only, it is never enforced by the powerflow (no outer loop, no limit check).

bus_id

Get the bus id (as an integer) at which this SVC is connected.

connected

Get the status (True = connected, False = disconnected) of this SVC.

has_res

This property specify whether or not a given element contains some "result" information.

id

Get the id of the element.

name

Get the name of the element.

pos_topo_vect

Get the position of this SVC in the grid2op "topo_vect" vector (-1 if never set).

regulated_bus_id

The grid bus id whose voltage this SVC regulates, when regulation_mode is VOLTAGE.

regulation_mode

This SVC's regulation mode, as a RegulationMode (0 = OFF, 1 = VOLTAGE, 2 = REACTIVE_POWER) -- see lightsim2grid.elements.SvcContainer for what each means.

res_p_mw

Get the active production (or consumption) in MW for element of the grid supporting this feature.

res_q_mvar

Get the reactive production (or consumption) in MVAr for element of the grid supporting this feature.

res_theta_deg

Get the angle of the complex voltage (in degree, not in radian) of the bus at which this object is connected.

res_v_kv

Get the magnitude of the complex voltage (in kV) of the bus at which this object is connected.

slope_pu

Voltage/reactive slope ("droop", pu) -- in VOLTAGE mode, 0. means the SVC holds target_vm_pu exactly; a non-zero slope lets the regulated voltage deviate from the setpoint in proportion to the reactive power delivered.

sub_id

Get the substation id of this SVC (-1 if never set; called "voltage level" in pypowsybl).

target_q_mvar

Reactive power setpoint (MVAr, generator sign convention -- positive injects into the grid).

target_vm_pu

Voltage setpoint (pu of the regulated bus).

voltage_level_id

Get the substation id of this SVC (-1 if never set; called "voltage level" in pypowsybl).

property b_max

Maximum susceptance (pu) – stored for introspection only, it is never enforced by the powerflow (no outer loop, no limit check).

property b_min

Minimum susceptance (pu) – stored for introspection only, it is never enforced by the powerflow (no outer loop, no limit check).

property bus_id

Get the bus id (as an integer) at which this SVC is connected. If -1 is returned it means the SVC is disconnected.

(This is the gridmodel / global bus id, not the solver bus id – see lightsim2grid.network.LSGrid.id_me_to_ac_solver() to convert.)

Read-only here; equivalent to lightsim2grid.network.LSGrid.get_bus_svc(). To move this SVC to another bus, call lightsim2grid.network.LSGrid.change_bus_svc().

property connected

Get the status (True = connected, False = disconnected) of this SVC.

Read-only here. To disconnect / reconnect it, call lightsim2grid.network.LSGrid.deactivate_svc() / lightsim2grid.network.LSGrid.reactivate_svc().

property has_res

This property specify whether or not a given element contains some “result” information. If set to True then the fields starting with res_ (eg res_p_mw) are filled otherwise they are initialized with an arbitrary (and meaningless) value.

property id

Get the id of the element. Ids are integer from 0 to n-1 (if n denotes the number of such elements on the grid.)

Examples

We give the example only for generators, but it works similarly for every other types of objects in a lightsim2grid.network.LSGrid.

This gives something like:

import grid2op
from lightsim2grid import LightSimBackend

env_name = ... # eg. "l2rpn_case14_test"
env = grid2op.make(env_name, backend=LightSimBackend())

grid_model = env.backend._grid

first_gen = grid_model.get_generators()[0]  # or get_loads for loads, etc.
first_gen.id  # should be 0
property name

Get the name of the element. Names are string that should be unique. But if you really want things unique, use the id

Warning

Names are optional and might not be set when reading the grid.

Examples

We give the example only for generators, but it works similarly for every other types of objects in a lightsim2grid.network.LSGrid.

This gives something like:

import grid2op
from lightsim2grid import LightSimBackend

env_name = ... # eg. "l2rpn_case14_test"
env = grid2op.make(env_name, backend=LightSimBackend())

grid_model = env.backend._grid

first_gen = grid_model.get_generators()[0]  # or get_loads for loads, etc.
first_gen.name
property pos_topo_vect

Get the position of this SVC in the grid2op “topo_vect” vector (-1 if never set).

SVCs have no dedicated LSGrid position setter – unlike other elements, they are not part of grid2op’s topology vector.

property regulated_bus_id

The grid bus id whose voltage this SVC regulates, when regulation_mode is VOLTAGE.

Defaults to this element’s own bus_id (“local” voltage control). When it differs from bus_id, the SVC performs “remote voltage control”: instead of behaving as an ordinary PV bus itself, it acts as a controller contributing (jointly with any other element regulating the same bus, eg a remote-regulating generator) to holding that bus’s voltage magnitude at target_vm_pu. Same mechanism as lightsim2grid.elements.GenInfo.regulated_bus_id.

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 if you need to follow such a topology change.

Read-only from python: unlike lightsim2grid.elements.GenInfo.regulated_bus_id, there is no LSGrid method to change an SVC’s regulated bus after construction (only set once, via lightsim2grid.network.LSGrid.init_svcs()).

property regulation_mode

This SVC’s regulation mode, as a RegulationMode (0 = OFF, 1 = VOLTAGE, 2 = REACTIVE_POWER) – see lightsim2grid.elements.SvcContainer for what each means.

property res_p_mw

Get the active production (or consumption) in MW for element of the grid supporting this feature.

For generators (and static generators) it is given following the “generator convention” (positive = power is injected to the grid)

For loads (and storage units) it is given following the “load convention” (positive = power is absorbed from the grid)

Read-only powerflow result, no LSGrid setter – also available in bulk, for every element of this container at once, via the corresponding LSGrid.get_*_res() method.

Warning

This feature is only relevant if the results have been computed (for example if a powerflow has successfully run)

property res_q_mvar

Get the reactive production (or consumption) in MVAr for element of the grid supporting this feature.

For generators (and static generators) it is given following the “generator convention” (positive = power is injected to the grid)

For loads (and storage units) it is given following the “load convention” (positive = power is absorbed from the grid)

Read-only powerflow result, no LSGrid setter – also available in bulk, for every element of this container at once, via the corresponding LSGrid.get_*_res() method.

Warning

This feature is only relevant if the results have been computed (for example if a powerflow has successfully run)

property res_theta_deg

Get the angle of the complex voltage (in degree, not in radian) of the bus at which this object is connected.

Note

All elements (load, generators, side of powerline etc.) connected at the same bus have the same “res_theta_deg”

Read-only powerflow result, no LSGrid setter – also available in bulk, for every element of this container at once, via the corresponding LSGrid.get_*_theta() method.

Warning

This feature is only relevant if the results have been computed (for example if a powerflow has successfully run)

property res_v_kv

Get the magnitude of the complex voltage (in kV) of the bus at which this object is connected.

Note

All elements (load, generators, side of powerline etc.) connected at the same bus have the same “res_v_kv”

Read-only powerflow result, no LSGrid setter – also available in bulk, for every element of this container at once, via the corresponding LSGrid.get_*_res() method.

Warning

This feature is only relevant if the results have been computed (for example if a powerflow has successfully run)

property slope_pu

Voltage/reactive slope (“droop”, pu) – in VOLTAGE mode, 0. means the SVC holds target_vm_pu exactly; a non-zero slope lets the regulated voltage deviate from the setpoint in proportion to the reactive power delivered. Unused (but still stored) outside VOLTAGE mode. See SvcContainer for the exact voltage regulation equations.

property sub_id

Get the substation id of this SVC (-1 if never set; called “voltage level” in pypowsybl).

SVCs have no dedicated LSGrid substation-id setter.

property target_q_mvar

Reactive power setpoint (MVAr, generator sign convention – positive injects into the grid). Only meaningful in REACTIVE_POWER mode (see regulation_mode).

property target_vm_pu

Voltage setpoint (pu of the regulated bus). Only meaningful in VOLTAGE mode (see regulation_mode).

property voltage_level_id

Get the substation id of this SVC (-1 if never set; called “voltage level” in pypowsybl).

SVCs have no dedicated LSGrid substation-id setter.

Shunts

class lightsim2grid.elements.ShuntContainer

This class allows to iterate through the load of the lightsim2grid.network.LSGrid easily, as if they were in a python list.

Shunts are modeled as in pandapower and can be represented a the pandapower shunts .

Examples

import grid2op
from lightsim2grid import LightSimBackend

# create a lightsim2grid "gridmodel"
env_name = ... # eg. "l2rpn_case14_test"
env = grid2op.make(env_name, backend=LightSimBackend())
grid_model = env.backend._grid

# manipulate the load
for shunt in grid_model.get_shunts():
    # do something with shunt !
    shunt.bus_id

print(f"There are {len(grid_model.get_shunts())} shunts on the grid.")

first_shunt = grid_model.get_shunts()[0]

You can have a look at lightsim2grid.elements.ShuntInfo for properties of these elements.

Methods:

get_bus_id(self)

bus_id (see the field of the same name on this container's element type, eg lightsim2grid.elements.GenInfo) for every element of this container, as a single array: element i of the result is that element's bus id, -1 if disconnected.

load_binary(path)

Load an object previously saved with save_binary().

save_binary(self, path[, atomic])

Save this object's state to a fast custom binary file (additive alternative to pickle).

get_bus_id(self: lightsim2grid.lightsim2grid_cpp.ShuntContainer) Annotated[numpy.typing.NDArray[numpy.int32], '[m, 1]']

bus_id (see the field of the same name on this container’s element type, eg lightsim2grid.elements.GenInfo) for every element of this container, as a single array: element i of the result is that element’s bus id, -1 if disconnected.

staticmethod load_binary(path: str) lightsim2grid.lightsim2grid_cpp.ShuntContainer

Load an object previously saved with save_binary(). Raises RuntimeError on an incompatible binary format, a wrong object type, or a corrupted / truncated file (including corrupted internal sizes: no attempt is made to allocate more data than the file actually contains). Loading a whole grid additionally validates its consistency (see check_grid): a byte-wise well-formed but inconsistent grid raises IndexError (out-of-range index) or RuntimeError (structural inconsistency).

save_binary(self: lightsim2grid.lightsim2grid_cpp.ShuntContainer, path: str, atomic: bool = True) None

Save this object’s state to a fast custom binary file (additive alternative to pickle). By default (atomic=True) the write is atomic: an existing file at that path is only replaced once the new content has been written completely (an interrupted save never destroys a previous file). Pass atomic=False to write the destination directly instead – marginally faster (skips one temporary file + rename), without that protection. The file stays readable by any lightsim2grid version sharing the same binary format number.

class lightsim2grid.elements.ShuntInfo

This class represents what you get from retrieving the shunts from lightsim2grid.elements.ShuntContainer.

It allows to read information from each shunt of the powergrid.

Warning

Data ca only be accessed from this element. You cannot modify (yet) the grid using this class.

Examples

import grid2op
from lightsim2grid import LightSimBackend

# create a lightsim2grid "gridmodel"
env_name = ... # eg. "l2rpn_case14_test"
env = grid2op.make(env_name, backend=LightSimBackend())
grid_model = env.backend._grid

# for shunts
first_shunt = grid_model.get_shunts()[0]  # first shunt, this is a `ShuntInfo`
for shunt in grid_model.get_shunts():
    # shunt is a `ShuntInfo`
    shunt.bus_id

Attributes:

bus_id

Get the bus id (as an integer) at which this shunt is connected.

connected

Get the status (True = connected, False = disconnected) of this shunt.

has_res

This property specify whether or not a given element contains some "result" information.

id

Get the id of the element.

name

Get the name of the element.

pos_topo_vect

Get the position of this shunt in the grid2op "topo_vect" vector (-1 if never set).

res_p_mw

Get the active production (or consumption) in MW for element of the grid supporting this feature.

res_q_mvar

Get the reactive production (or consumption) in MVAr for element of the grid supporting this feature.

res_theta_deg

Get the angle of the complex voltage (in degree, not in radian) of the bus at which this object is connected.

res_v_kv

Get the magnitude of the complex voltage (in kV) of the bus at which this object is connected.

sub_id

Get the substation id of this shunt (-1 if never set; called "voltage level" in pypowsybl).

target_p_mw

Get the active power (MW, load convention) of this shunt.

target_q_mvar

Get the reactive power (MVAr, load convention) of this shunt.

voltage_level_id

Get the substation id of this shunt (-1 if never set; called "voltage level" in pypowsybl).

property bus_id

Get the bus id (as an integer) at which this shunt is connected. If -1 is returned it means the shunt is disconnected.

(This is the gridmodel / global bus id, not the solver bus id – see lightsim2grid.network.LSGrid.id_me_to_ac_solver() to convert.)

Read-only here; equivalent to lightsim2grid.network.LSGrid.get_bus_shunt(). To move this shunt to another bus, call lightsim2grid.network.LSGrid.change_bus_shunt().

property connected

Get the status (True = connected, False = disconnected) of this shunt.

Read-only here. To disconnect / reconnect it, call lightsim2grid.network.LSGrid.deactivate_shunt() / lightsim2grid.network.LSGrid.reactivate_shunt().

property has_res

This property specify whether or not a given element contains some “result” information. If set to True then the fields starting with res_ (eg res_p_mw) are filled otherwise they are initialized with an arbitrary (and meaningless) value.

property id

Get the id of the element. Ids are integer from 0 to n-1 (if n denotes the number of such elements on the grid.)

Examples

We give the example only for generators, but it works similarly for every other types of objects in a lightsim2grid.network.LSGrid.

This gives something like:

import grid2op
from lightsim2grid import LightSimBackend

env_name = ... # eg. "l2rpn_case14_test"
env = grid2op.make(env_name, backend=LightSimBackend())

grid_model = env.backend._grid

first_gen = grid_model.get_generators()[0]  # or get_loads for loads, etc.
first_gen.id  # should be 0
property name

Get the name of the element. Names are string that should be unique. But if you really want things unique, use the id

Warning

Names are optional and might not be set when reading the grid.

Examples

We give the example only for generators, but it works similarly for every other types of objects in a lightsim2grid.network.LSGrid.

This gives something like:

import grid2op
from lightsim2grid import LightSimBackend

env_name = ... # eg. "l2rpn_case14_test"
env = grid2op.make(env_name, backend=LightSimBackend())

grid_model = env.backend._grid

first_gen = grid_model.get_generators()[0]  # or get_loads for loads, etc.
first_gen.name
property pos_topo_vect

Get the position of this shunt in the grid2op “topo_vect” vector (-1 if never set).

Shunts have no dedicated LSGrid position setter – unlike other elements, shunts are not part of grid2op’s topology vector.

property res_p_mw

Get the active production (or consumption) in MW for element of the grid supporting this feature.

For generators (and static generators) it is given following the “generator convention” (positive = power is injected to the grid)

For loads (and storage units) it is given following the “load convention” (positive = power is absorbed from the grid)

Read-only powerflow result, no LSGrid setter – also available in bulk, for every element of this container at once, via the corresponding LSGrid.get_*_res() method.

Warning

This feature is only relevant if the results have been computed (for example if a powerflow has successfully run)

property res_q_mvar

Get the reactive production (or consumption) in MVAr for element of the grid supporting this feature.

For generators (and static generators) it is given following the “generator convention” (positive = power is injected to the grid)

For loads (and storage units) it is given following the “load convention” (positive = power is absorbed from the grid)

Read-only powerflow result, no LSGrid setter – also available in bulk, for every element of this container at once, via the corresponding LSGrid.get_*_res() method.

Warning

This feature is only relevant if the results have been computed (for example if a powerflow has successfully run)

property res_theta_deg

Get the angle of the complex voltage (in degree, not in radian) of the bus at which this object is connected.

Note

All elements (load, generators, side of powerline etc.) connected at the same bus have the same “res_theta_deg”

Read-only powerflow result, no LSGrid setter – also available in bulk, for every element of this container at once, via the corresponding LSGrid.get_*_theta() method.

Warning

This feature is only relevant if the results have been computed (for example if a powerflow has successfully run)

property res_v_kv

Get the magnitude of the complex voltage (in kV) of the bus at which this object is connected.

Note

All elements (load, generators, side of powerline etc.) connected at the same bus have the same “res_v_kv”

Read-only powerflow result, no LSGrid setter – also available in bulk, for every element of this container at once, via the corresponding LSGrid.get_*_res() method.

Warning

This feature is only relevant if the results have been computed (for example if a powerflow has successfully run)

property sub_id

Get the substation id of this shunt (-1 if never set; called “voltage level” in pypowsybl).

Read-only here; this is set once, by the grid loaders, via lightsim2grid.network.LSGrid.set_shunt_to_subid().

property target_p_mw

Get the active power (MW, load convention) of this shunt.

Read-only here. To change it, call lightsim2grid.network.LSGrid.change_p_shunt().

property target_q_mvar

Get the reactive power (MVAr, load convention) of this shunt.

Read-only here. To change it, call lightsim2grid.network.LSGrid.change_q_shunt().

property voltage_level_id

Get the substation id of this shunt (-1 if never set; called “voltage level” in pypowsybl).

Read-only here; this is set once, by the grid loaders, via lightsim2grid.network.LSGrid.set_shunt_to_subid().

Lines

class lightsim2grid.elements.LineContainer

This class allows to iterate through the powerlines of the lightsim2grid.network.LSGrid easily, as if they were in a python list.

Powerlines are modeled as in pandapower and can be represented a the pandapower lines .

Examples

import grid2op
from lightsim2grid import LightSimBackend

# create a lightsim2grid "gridmodel"
env_name = ... # eg. "l2rpn_case14_test"
env = grid2op.make(env_name, backend=LightSimBackend())
grid_model = env.backend._grid

# manipulate the powerlines
for line in grid_model.get_lines():
    # do something with line !
    line.bus1_id

print(f"There are {len(grid_model.get_lines())} lines on the grid.")

first_line = grid_model.get_lines()[0]

You can have a look at lightsim2grid.elements.LineInfo for properties of these elements.

Methods:

get_bus_id_side_1(self)

bus_1_id for every element of this container, as a single array: element i of the result is that element's side-1 bus id, -1 if disconnected on that side.

get_bus_id_side_2(self)

bus_2_id for every element of this container, as a single array: element i of the result is that element's side-2 bus id, -1 if disconnected on that side.

get_yac_eff_11(self)

yac_eff_11 (etc, see lightsim2grid.elements.LineInfo / lightsim2grid.elements.TrafoInfo) for every element of this container, as a single array.

get_yac_eff_12(self)

yac_eff_11 (etc, see lightsim2grid.elements.LineInfo / lightsim2grid.elements.TrafoInfo) for every element of this container, as a single array.

get_yac_eff_21(self)

yac_eff_11 (etc, see lightsim2grid.elements.LineInfo / lightsim2grid.elements.TrafoInfo) for every element of this container, as a single array.

get_yac_eff_22(self)

yac_eff_11 (etc, see lightsim2grid.elements.LineInfo / lightsim2grid.elements.TrafoInfo) for every element of this container, as a single array.

load_binary(path)

Load an object previously saved with save_binary().

save_binary(self, path[, atomic])

Save this object's state to a fast custom binary file (additive alternative to pickle).

get_bus_id_side_1(self: lightsim2grid.lightsim2grid_cpp.LineContainer) Annotated[numpy.typing.NDArray[numpy.int32], '[m, 1]']

bus_1_id for every element of this container, as a single array: element i of the result is that element’s side-1 bus id, -1 if disconnected on that side.

get_bus_id_side_2(self: lightsim2grid.lightsim2grid_cpp.LineContainer) Annotated[numpy.typing.NDArray[numpy.int32], '[m, 1]']

bus_2_id for every element of this container, as a single array: element i of the result is that element’s side-2 bus id, -1 if disconnected on that side.

get_yac_eff_11(self: lightsim2grid.lightsim2grid_cpp.LineContainer) Annotated[numpy.typing.NDArray[numpy.complex128], '[m, 1]']

yac_eff_11 (etc, see lightsim2grid.elements.LineInfo / lightsim2grid.elements.TrafoInfo) for every element of this container, as a single array.

The “line model” (also valid for transformers) is:

             i1                       ________             i2
 `bus 1` o------>   -----------------|r + j.x|---------<-------o `bus 2`
         |       ) (            |                  |           |
         |       ) (         |     |            |     |        |
         | v1    ) ( n:1      | h1  |            | h2  |        | v2
         |       ) (         |     |            |     |        |
         \/      ) (            |                  |           \/
ground---o-------   -------------------------------------------o---- ground

(fyi: i1, i2, n, h1 and h2 are all complex numbers. r and x are real numbers. j is a complex number such that j^2 = -1)

Note

h1 and h2 are independent per-side shunt admittances, NOT necessarily one half of a single total value each (they can differ, eg for an asymmetric line/transformer coming from pypowsybl): the admittance matrix contribution of one branch is [[ys + h1, -ys], [-ys, ys + h2]] with ys = 1 / (r + j.x) (see lightsim2grid.elements.LineContainer.get_yac_eff_11() and friends for the coefficients actually used, including any tap-side / phase-shift correction for transformers).

Note

For a powerline, side 1 / side 2 used to be called or (origin) / ex (extremity) in older lightsim2grid versions; for a transformer they are hv (high voltage) / lv (low voltage) instead, since which physical side is tap-side matters there (see is_tap_side_1).

get_yac_eff_12(self: lightsim2grid.lightsim2grid_cpp.LineContainer) Annotated[numpy.typing.NDArray[numpy.complex128], '[m, 1]']

yac_eff_11 (etc, see lightsim2grid.elements.LineInfo / lightsim2grid.elements.TrafoInfo) for every element of this container, as a single array.

The “line model” (also valid for transformers) is:

             i1                       ________             i2
 `bus 1` o------>   -----------------|r + j.x|---------<-------o `bus 2`
         |       ) (            |                  |           |
         |       ) (         |     |            |     |        |
         | v1    ) ( n:1      | h1  |            | h2  |        | v2
         |       ) (         |     |            |     |        |
         \/      ) (            |                  |           \/
ground---o-------   -------------------------------------------o---- ground

(fyi: i1, i2, n, h1 and h2 are all complex numbers. r and x are real numbers. j is a complex number such that j^2 = -1)

Note

h1 and h2 are independent per-side shunt admittances, NOT necessarily one half of a single total value each (they can differ, eg for an asymmetric line/transformer coming from pypowsybl): the admittance matrix contribution of one branch is [[ys + h1, -ys], [-ys, ys + h2]] with ys = 1 / (r + j.x) (see lightsim2grid.elements.LineContainer.get_yac_eff_11() and friends for the coefficients actually used, including any tap-side / phase-shift correction for transformers).

Note

For a powerline, side 1 / side 2 used to be called or (origin) / ex (extremity) in older lightsim2grid versions; for a transformer they are hv (high voltage) / lv (low voltage) instead, since which physical side is tap-side matters there (see is_tap_side_1).

get_yac_eff_21(self: lightsim2grid.lightsim2grid_cpp.LineContainer) Annotated[numpy.typing.NDArray[numpy.complex128], '[m, 1]']

yac_eff_11 (etc, see lightsim2grid.elements.LineInfo / lightsim2grid.elements.TrafoInfo) for every element of this container, as a single array.

The “line model” (also valid for transformers) is:

             i1                       ________             i2
 `bus 1` o------>   -----------------|r + j.x|---------<-------o `bus 2`
         |       ) (            |                  |           |
         |       ) (         |     |            |     |        |
         | v1    ) ( n:1      | h1  |            | h2  |        | v2
         |       ) (         |     |            |     |        |
         \/      ) (            |                  |           \/
ground---o-------   -------------------------------------------o---- ground

(fyi: i1, i2, n, h1 and h2 are all complex numbers. r and x are real numbers. j is a complex number such that j^2 = -1)

Note

h1 and h2 are independent per-side shunt admittances, NOT necessarily one half of a single total value each (they can differ, eg for an asymmetric line/transformer coming from pypowsybl): the admittance matrix contribution of one branch is [[ys + h1, -ys], [-ys, ys + h2]] with ys = 1 / (r + j.x) (see lightsim2grid.elements.LineContainer.get_yac_eff_11() and friends for the coefficients actually used, including any tap-side / phase-shift correction for transformers).

Note

For a powerline, side 1 / side 2 used to be called or (origin) / ex (extremity) in older lightsim2grid versions; for a transformer they are hv (high voltage) / lv (low voltage) instead, since which physical side is tap-side matters there (see is_tap_side_1).

get_yac_eff_22(self: lightsim2grid.lightsim2grid_cpp.LineContainer) Annotated[numpy.typing.NDArray[numpy.complex128], '[m, 1]']

yac_eff_11 (etc, see lightsim2grid.elements.LineInfo / lightsim2grid.elements.TrafoInfo) for every element of this container, as a single array.

The “line model” (also valid for transformers) is:

             i1                       ________             i2
 `bus 1` o------>   -----------------|r + j.x|---------<-------o `bus 2`
         |       ) (            |                  |           |
         |       ) (         |     |            |     |        |
         | v1    ) ( n:1      | h1  |            | h2  |        | v2
         |       ) (         |     |            |     |        |
         \/      ) (            |                  |           \/
ground---o-------   -------------------------------------------o---- ground

(fyi: i1, i2, n, h1 and h2 are all complex numbers. r and x are real numbers. j is a complex number such that j^2 = -1)

Note

h1 and h2 are independent per-side shunt admittances, NOT necessarily one half of a single total value each (they can differ, eg for an asymmetric line/transformer coming from pypowsybl): the admittance matrix contribution of one branch is [[ys + h1, -ys], [-ys, ys + h2]] with ys = 1 / (r + j.x) (see lightsim2grid.elements.LineContainer.get_yac_eff_11() and friends for the coefficients actually used, including any tap-side / phase-shift correction for transformers).

Note

For a powerline, side 1 / side 2 used to be called or (origin) / ex (extremity) in older lightsim2grid versions; for a transformer they are hv (high voltage) / lv (low voltage) instead, since which physical side is tap-side matters there (see is_tap_side_1).

staticmethod load_binary(path: str) lightsim2grid.lightsim2grid_cpp.LineContainer

Load an object previously saved with save_binary(). Raises RuntimeError on an incompatible binary format, a wrong object type, or a corrupted / truncated file (including corrupted internal sizes: no attempt is made to allocate more data than the file actually contains). Loading a whole grid additionally validates its consistency (see check_grid): a byte-wise well-formed but inconsistent grid raises IndexError (out-of-range index) or RuntimeError (structural inconsistency).

save_binary(self: lightsim2grid.lightsim2grid_cpp.LineContainer, path: str, atomic: bool = True) None

Save this object’s state to a fast custom binary file (additive alternative to pickle). By default (atomic=True) the write is atomic: an existing file at that path is only replaced once the new content has been written completely (an interrupted save never destroys a previous file). Pass atomic=False to write the destination directly instead – marginally faster (skips one temporary file + rename), without that protection. The file stays readable by any lightsim2grid version sharing the same binary format number.

class lightsim2grid.elements.LineInfo

This class represents what you get from retrieving the powerlines from lightsim2grid.elements.LineContainer.

It allows to read information from each powerline of the powergrid.

Powerlines have two sides, “1” and “2” (called “or” for “origin” and “ex” for “extremity” in older lightsim2grid versions), that are connected and linked to each other by some equations.

For accessing the results, it’s basically the same as having two “elements” (so you get two “voltage_magnitude” res_v_kv, two “injected power” res_p_mw etc.)

Warning

Data ca only be accessed from this element. You cannot modify (yet) the grid using this class.

Examples

import grid2op
from lightsim2grid import LightSimBackend

# create a lightsim2grid "gridmodel"
env_name = ... # eg. "l2rpn_case14_test"
env = grid2op.make(env_name, backend=LightSimBackend())
grid_model = env.backend._grid

# for powerlines
first_line = grid_model.get_lines()[0]  # first line, this is a `LineInfo`
for line in grid_model.get_lines():
    # line is a `LineInfo`
    line.bus1_id

Notes

Line are modeled using the “line model” as shown in the schema at the end of the paragraph.

The tap ratio n on this schema will be 1.0 for all powerline. If you want to model phase shifters, please model them as Trafo (see lightsim2grid.elements.TrafoInfo)

For more information about the model and the equations linking all the quantities, please visit matpower manual , especially the “3. Modeling” and the “3.2 Branches” subsection, as well as the equation 3.1, 3.2 and 3.3 therein.

The “line model” (also valid for transformers) is:

             i1                       ________             i2
 `bus 1` o------>   -----------------|r + j.x|---------<-------o `bus 2`
         |       ) (            |                  |           |
         |       ) (         |     |            |     |        |
         | v1    ) ( n:1      | h1  |            | h2  |        | v2
         |       ) (         |     |            |     |        |
         \/      ) (            |                  |           \/
ground---o-------   -------------------------------------------o---- ground

(fyi: i1, i2, n, h1 and h2 are all complex numbers. r and x are real numbers. j is a complex number such that j^2 = -1)

Note

h1 and h2 are independent per-side shunt admittances, NOT necessarily one half of a single total value each (they can differ, eg for an asymmetric line/transformer coming from pypowsybl): the admittance matrix contribution of one branch is [[ys + h1, -ys], [-ys, ys + h2]] with ys = 1 / (r + j.x) (see lightsim2grid.elements.LineContainer.get_yac_eff_11() and friends for the coefficients actually used, including any tap-side / phase-shift correction for transformers).

Note

For a powerline, side 1 / side 2 used to be called or (origin) / ex (extremity) in older lightsim2grid versions; for a transformer they are hv (high voltage) / lv (low voltage) instead, since which physical side is tap-side matters there (see is_tap_side_1).

Attributes:

bus1_id

Get the bus id (as an integer) at which side 1 of the line is connected.

bus2_id

Get the bus id (as an integer) at which side 2 of the line is connected.

connected1

Get the status of side 1 of this powerline alone (relevant for a "half-open" line, see connected_global for the combined status).

connected2

Get the status of side 2 of this powerline alone, see connected1.

connected_global

Get the global status (True as soon as either side is connected) of this powerline.

h1_pu

Retrieve the shunt admittance (in pair unit system) of one side of the powerline / transformer: conductance g as the real part, susceptance b (related to the line charging capacitance) as the imaginary part, ie h = g + 1j * b.

h2_pu

Retrieve the shunt admittance (in pair unit system) of one side of the powerline / transformer: conductance g as the real part, susceptance b (related to the line charging capacitance) as the imaginary part, ie h = g + 1j * b.

has_res

This property specify whether or not a given element contains some "result" information.

id

Get the id of the element.

limit_a1_ka

Current limit, origin side, in kA (NaN if not set, see LSGrid.set_line_current_limit_side1).

limit_a2_ka

Current limit, extremity side, in kA (NaN if not set, see LSGrid.set_line_current_limit_side2).

name

Get the name of the element.

pos1_topo_vect

Get the position of side 1 of this powerline in the grid2op "topo_vect" vector (-1 if never set).

pos2_topo_vect

Get the position of side 2 of this powerline in the grid2op "topo_vect" vector (-1 if never set).

r_pu

Retrieve the resistance (given in pair unit system, and not in Ohm) of the powerlines or the transformers.

res_a1_ka

Get the current flows (in kA) at side 1 of the line.

res_a2_ka

Get the current flows (in kA) at side 2 of the line.

res_p1_mw

Get the active power in MW at side 1 of the line.

res_p2_mw

Get the active power in MW at side 2 of the line.

res_q1_mvar

Get the reactive power in MVAr at side 1 of the line.

res_q2_mvar

Get the reactive power in MVAr at side 2 of the line.

res_theta1_deg

Get the angle of the complex voltage (in degree, not in radian) of the bus at which side 1 of the line is connected.

res_theta2_deg

Get the angle of the complex voltage (in degree, not in radian) of the bus at which side 2 of the line is connected.

res_v1_kv

Get the magnitude of the complex voltage (in kV) of the bus at which side 1 of the line is connected.

res_v2_kv

Get the magnitude of the complex voltage (in kV) of the bus at which side 2 of the line is connected.

sub1_id

Get the substation id of side 1 of this powerline (-1 if never set; called "voltage level" in pypowsybl).

sub2_id

Get the substation id of side 2 of this powerline (-1 if never set; called "voltage level" in pypowsybl).

voltage_level1_id

Get the substation id of side 1 of this powerline (-1 if never set; called "voltage level" in pypowsybl).

voltage_level2_id

Get the substation id of side 2 of this powerline (-1 if never set; called "voltage level" in pypowsybl).

x_pu

Retrieve the reactance (given in pair unit system, and not in Ohm) of the powerlines or the transformers.

yac_11

One entry of this branch's raw two-port AC admittance matrix, computed as if both sides were connected (see yac_eff_11 for the version that accounts for the actual connection status).

yac_12

One entry of this branch's raw two-port AC admittance matrix, computed as if both sides were connected (see yac_eff_11 for the version that accounts for the actual connection status).

yac_21

One entry of this branch's raw two-port AC admittance matrix, computed as if both sides were connected (see yac_eff_11 for the version that accounts for the actual connection status).

yac_22

One entry of this branch's raw two-port AC admittance matrix, computed as if both sides were connected (see yac_eff_11 for the version that accounts for the actual connection status).

yac_eff_11

One entry of this branch's effective two-port AC admittance matrix -- yac_11 and friends, corrected for the actual connection status.

yac_eff_12

One entry of this branch's effective two-port AC admittance matrix -- yac_11 and friends, corrected for the actual connection status.

yac_eff_21

One entry of this branch's effective two-port AC admittance matrix -- yac_11 and friends, corrected for the actual connection status.

yac_eff_22

One entry of this branch's effective two-port AC admittance matrix -- yac_11 and friends, corrected for the actual connection status.

ydc_11

One entry of this branch's two-port DC admittance matrix -- the DC powerflow linearization only keeps the series susceptance (1 / x_pu), so ydc_11 = ydc_22 = 1 / x_pu and ydc_12 = ydc_21 = -1 / x_pu for a plain powerline (a transformer's tap ratio additionally divides it in).

ydc_12

One entry of this branch's two-port DC admittance matrix -- the DC powerflow linearization only keeps the series susceptance (1 / x_pu), so ydc_11 = ydc_22 = 1 / x_pu and ydc_12 = ydc_21 = -1 / x_pu for a plain powerline (a transformer's tap ratio additionally divides it in).

ydc_21

One entry of this branch's two-port DC admittance matrix -- the DC powerflow linearization only keeps the series susceptance (1 / x_pu), so ydc_11 = ydc_22 = 1 / x_pu and ydc_12 = ydc_21 = -1 / x_pu for a plain powerline (a transformer's tap ratio additionally divides it in).

ydc_22

One entry of this branch's two-port DC admittance matrix -- the DC powerflow linearization only keeps the series susceptance (1 / x_pu), so ydc_11 = ydc_22 = 1 / x_pu and ydc_12 = ydc_21 = -1 / x_pu for a plain powerline (a transformer's tap ratio additionally divides it in).

property bus1_id

Get the bus id (as an integer) at which side 1 of the line is connected. If -1 is returned it means that the line is disconnected.

(This is the gridmodel / global bus id, not the solver bus id – see lightsim2grid.network.LSGrid.id_me_to_ac_solver() to convert.)

Read-only here; equivalent to lightsim2grid.network.LSGrid.get_bus1_powerline(). To move this side to another bus, call lightsim2grid.network.LSGrid.change_bus1_powerline().

property bus2_id

Get the bus id (as an integer) at which side 2 of the line is connected. If -1 is returned it means that the line is disconnected.

(This is the gridmodel / global bus id, not the solver bus id – see lightsim2grid.network.LSGrid.id_me_to_ac_solver() to convert.)

Read-only here; equivalent to lightsim2grid.network.LSGrid.get_bus2_powerline(). To move this side to another bus, call lightsim2grid.network.LSGrid.change_bus2_powerline().

property connected1

Get the status of side 1 of this powerline alone (relevant for a “half-open” line, see connected_global for the combined status).

Read-only here. To disconnect / reconnect only this side, call lightsim2grid.network.LSGrid.deactivate_powerline_side1() / lightsim2grid.network.LSGrid.reactivate_powerline_side1().

property connected2

Get the status of side 2 of this powerline alone, see connected1.

Read-only here. To disconnect / reconnect only this side, call lightsim2grid.network.LSGrid.deactivate_powerline_side2() / lightsim2grid.network.LSGrid.reactivate_powerline_side2().

property connected_global

Get the global status (True as soon as either side is connected) of this powerline.

Read-only here. To disconnect / reconnect both sides at once, call lightsim2grid.network.LSGrid.deactivate_powerline() / lightsim2grid.network.LSGrid.reactivate_powerline(); see connected1 / connected2 and their own setters to act on a single side (“half-open”).

property h1_pu

Retrieve the shunt admittance (in pair unit system) of one side of the powerline / transformer: conductance g as the real part, susceptance b (related to the line charging capacitance) as the imaginary part, ie h = g + 1j * b.

This is a complex number, represented by h1 (side 1) or h2 (side 2) in the line model – they are independent values, not half of a single shared h each (see the note in the line model below).

The “line model” (also valid for transformers) is:

             i1                       ________             i2
 `bus 1` o------>   -----------------|r + j.x|---------<-------o `bus 2`
         |       ) (            |                  |           |
         |       ) (         |     |            |     |        |
         | v1    ) ( n:1      | h1  |            | h2  |        | v2
         |       ) (         |     |            |     |        |
         \/      ) (            |                  |           \/
ground---o-------   -------------------------------------------o---- ground

(fyi: i1, i2, n, h1 and h2 are all complex numbers. r and x are real numbers. j is a complex number such that j^2 = -1)

Note

h1 and h2 are independent per-side shunt admittances, NOT necessarily one half of a single total value each (they can differ, eg for an asymmetric line/transformer coming from pypowsybl): the admittance matrix contribution of one branch is [[ys + h1, -ys], [-ys, ys + h2]] with ys = 1 / (r + j.x) (see lightsim2grid.elements.LineContainer.get_yac_eff_11() and friends for the coefficients actually used, including any tap-side / phase-shift correction for transformers).

Note

For a powerline, side 1 / side 2 used to be called or (origin) / ex (extremity) in older lightsim2grid versions; for a transformer they are hv (high voltage) / lv (low voltage) instead, since which physical side is tap-side matters there (see is_tap_side_1).

property h2_pu

Retrieve the shunt admittance (in pair unit system) of one side of the powerline / transformer: conductance g as the real part, susceptance b (related to the line charging capacitance) as the imaginary part, ie h = g + 1j * b.

This is a complex number, represented by h1 (side 1) or h2 (side 2) in the line model – they are independent values, not half of a single shared h each (see the note in the line model below).

The “line model” (also valid for transformers) is:

             i1                       ________             i2
 `bus 1` o------>   -----------------|r + j.x|---------<-------o `bus 2`
         |       ) (            |                  |           |
         |       ) (         |     |            |     |        |
         | v1    ) ( n:1      | h1  |            | h2  |        | v2
         |       ) (         |     |            |     |        |
         \/      ) (            |                  |           \/
ground---o-------   -------------------------------------------o---- ground

(fyi: i1, i2, n, h1 and h2 are all complex numbers. r and x are real numbers. j is a complex number such that j^2 = -1)

Note

h1 and h2 are independent per-side shunt admittances, NOT necessarily one half of a single total value each (they can differ, eg for an asymmetric line/transformer coming from pypowsybl): the admittance matrix contribution of one branch is [[ys + h1, -ys], [-ys, ys + h2]] with ys = 1 / (r + j.x) (see lightsim2grid.elements.LineContainer.get_yac_eff_11() and friends for the coefficients actually used, including any tap-side / phase-shift correction for transformers).

Note

For a powerline, side 1 / side 2 used to be called or (origin) / ex (extremity) in older lightsim2grid versions; for a transformer they are hv (high voltage) / lv (low voltage) instead, since which physical side is tap-side matters there (see is_tap_side_1).

property has_res

This property specify whether or not a given element contains some “result” information. If set to True then the fields starting with res_ (eg res_p_mw) are filled otherwise they are initialized with an arbitrary (and meaningless) value.

property id

Get the id of the element. Ids are integer from 0 to n-1 (if n denotes the number of such elements on the grid.)

Examples

We give the example only for generators, but it works similarly for every other types of objects in a lightsim2grid.network.LSGrid.

This gives something like:

import grid2op
from lightsim2grid import LightSimBackend

env_name = ... # eg. "l2rpn_case14_test"
env = grid2op.make(env_name, backend=LightSimBackend())

grid_model = env.backend._grid

first_gen = grid_model.get_generators()[0]  # or get_loads for loads, etc.
first_gen.id  # should be 0
property limit_a1_ka

Current limit, origin side, in kA (NaN if not set, see LSGrid.set_line_current_limit_side1).

property limit_a2_ka

Current limit, extremity side, in kA (NaN if not set, see LSGrid.set_line_current_limit_side2).

property name

Get the name of the element. Names are string that should be unique. But if you really want things unique, use the id

Warning

Names are optional and might not be set when reading the grid.

Examples

We give the example only for generators, but it works similarly for every other types of objects in a lightsim2grid.network.LSGrid.

This gives something like:

import grid2op
from lightsim2grid import LightSimBackend

env_name = ... # eg. "l2rpn_case14_test"
env = grid2op.make(env_name, backend=LightSimBackend())

grid_model = env.backend._grid

first_gen = grid_model.get_generators()[0]  # or get_loads for loads, etc.
first_gen.name
property pos1_topo_vect

Get the position of side 1 of this powerline in the grid2op “topo_vect” vector (-1 if never set).

Read-only here; this is set once, by the grid loaders, via lightsim2grid.network.LSGrid.set_line_pos1_topo_vect().

property pos2_topo_vect

Get the position of side 2 of this powerline in the grid2op “topo_vect” vector (-1 if never set).

Read-only here; this is set once, by the grid loaders, via lightsim2grid.network.LSGrid.set_line_pos2_topo_vect().

property r_pu

Retrieve the resistance (given in pair unit system, and not in Ohm) of the powerlines or the transformers. This is a real number and is represented by the number r in the line model.

The “line model” (also valid for transformers) is:

             i1                       ________             i2
 `bus 1` o------>   -----------------|r + j.x|---------<-------o `bus 2`
         |       ) (            |                  |           |
         |       ) (         |     |            |     |        |
         | v1    ) ( n:1      | h1  |            | h2  |        | v2
         |       ) (         |     |            |     |        |
         \/      ) (            |                  |           \/
ground---o-------   -------------------------------------------o---- ground

(fyi: i1, i2, n, h1 and h2 are all complex numbers. r and x are real numbers. j is a complex number such that j^2 = -1)

Note

h1 and h2 are independent per-side shunt admittances, NOT necessarily one half of a single total value each (they can differ, eg for an asymmetric line/transformer coming from pypowsybl): the admittance matrix contribution of one branch is [[ys + h1, -ys], [-ys, ys + h2]] with ys = 1 / (r + j.x) (see lightsim2grid.elements.LineContainer.get_yac_eff_11() and friends for the coefficients actually used, including any tap-side / phase-shift correction for transformers).

Note

For a powerline, side 1 / side 2 used to be called or (origin) / ex (extremity) in older lightsim2grid versions; for a transformer they are hv (high voltage) / lv (low voltage) instead, since which physical side is tap-side matters there (see is_tap_side_1).

property res_a1_ka

Get the current flows (in kA) at side 1 of the line.

Warning

This feature is only relevant if the results have been computed (for example if a powerflow has successfully run)

property res_a2_ka

Get the current flows (in kA) at side 2 of the line.

Warning

This feature is only relevant if the results have been computed (for example if a powerflow has successfully run)

property res_p1_mw

Get the active power in MW at side 1 of the line. If it is positive it means power is absorbed by the line.

Warning

This feature is only relevant if the results have been computed (for example if a powerflow has successfully run)

property res_p2_mw

Get the active power in MW at side 2 of the line. If it is positive it means power is absorbed by the line.

Warning

This feature is only relevant if the results have been computed (for example if a powerflow has successfully run)

property res_q1_mvar

Get the reactive power in MVAr at side 1 of the line. If it is positive it means power is absorbed by the line.

Warning

This feature is only relevant if the results have been computed (for example if a powerflow has successfully run)

property res_q2_mvar

Get the reactive power in MVAr at side 2 of the line. If it is positive it means power is absorbed by the line.

Warning

This feature is only relevant if the results have been computed (for example if a powerflow has successfully run)

property res_theta1_deg

Get the angle of the complex voltage (in degree, not in radian) of the bus at which side 1 of the line is connected.

Note

All elements (load, generators, side of powerline etc.) connected at the same bus have the same “res_theta_deg”

Warning

This feature is only relevant if the results have been computed (for example if a powerflow has successfully run)

property res_theta2_deg

Get the angle of the complex voltage (in degree, not in radian) of the bus at which side 2 of the line is connected.

Note

All elements (load, generators, side of powerline etc.) connected at the same bus have the same “res_theta_deg”

Warning

This feature is only relevant if the results have been computed (for example if a powerflow has successfully run)

property res_v1_kv

Get the magnitude of the complex voltage (in kV) of the bus at which side 1 of the line is connected.

Note

All elements (load, generators, side of powerline etc.) connected at the same bus have the same “res_v_kv”

Warning

This feature is only relevant if the results have been computed (for example if a powerflow has successfully run)

property res_v2_kv

Get the magnitude of the complex voltage (in kV) of the bus at which side 2 of the line is connected.

Note

All elements (load, generators, side of powerline etc.) connected at the same bus have the same “res_v_kv”

Warning

This feature is only relevant if the results have been computed (for example if a powerflow has successfully run)

property sub1_id

Get the substation id of side 1 of this powerline (-1 if never set; called “voltage level” in pypowsybl).

Read-only here; this is set once, by the grid loaders, via lightsim2grid.network.LSGrid.set_line_to_sub1_id().

property sub2_id

Get the substation id of side 2 of this powerline (-1 if never set; called “voltage level” in pypowsybl).

Read-only here; this is set once, by the grid loaders, via lightsim2grid.network.LSGrid.set_line_to_sub2_id().

property voltage_level1_id

Get the substation id of side 1 of this powerline (-1 if never set; called “voltage level” in pypowsybl).

Read-only here; this is set once, by the grid loaders, via lightsim2grid.network.LSGrid.set_line_to_sub1_id().

property voltage_level2_id

Get the substation id of side 2 of this powerline (-1 if never set; called “voltage level” in pypowsybl).

Read-only here; this is set once, by the grid loaders, via lightsim2grid.network.LSGrid.set_line_to_sub2_id().

property x_pu

Retrieve the reactance (given in pair unit system, and not in Ohm) of the powerlines or the transformers. This is a real number and is represented by the number x in the line model.

The “line model” (also valid for transformers) is:

             i1                       ________             i2
 `bus 1` o------>   -----------------|r + j.x|---------<-------o `bus 2`
         |       ) (            |                  |           |
         |       ) (         |     |            |     |        |
         | v1    ) ( n:1      | h1  |            | h2  |        | v2
         |       ) (         |     |            |     |        |
         \/      ) (            |                  |           \/
ground---o-------   -------------------------------------------o---- ground

(fyi: i1, i2, n, h1 and h2 are all complex numbers. r and x are real numbers. j is a complex number such that j^2 = -1)

Note

h1 and h2 are independent per-side shunt admittances, NOT necessarily one half of a single total value each (they can differ, eg for an asymmetric line/transformer coming from pypowsybl): the admittance matrix contribution of one branch is [[ys + h1, -ys], [-ys, ys + h2]] with ys = 1 / (r + j.x) (see lightsim2grid.elements.LineContainer.get_yac_eff_11() and friends for the coefficients actually used, including any tap-side / phase-shift correction for transformers).

Note

For a powerline, side 1 / side 2 used to be called or (origin) / ex (extremity) in older lightsim2grid versions; for a transformer they are hv (high voltage) / lv (low voltage) instead, since which physical side is tap-side matters there (see is_tap_side_1).

property yac_11

One entry of this branch’s raw two-port AC admittance matrix, computed as if both sides were connected (see yac_eff_11 for the version that accounts for the actual connection status).

With ys = 1 / (r_pu + 1j * x_pu), for a plain powerline (ratio == 1, shift_rad == 0): yac_11 = ys + h1, yac_22 = ys + h2, yac_12 = yac_21 = -ys – see the note in r_pu’s line model. For a transformer, the tap ratio and shift_rad additionally fold into all four entries.

The “line model” (also valid for transformers) is:

             i1                       ________             i2
 `bus 1` o------>   -----------------|r + j.x|---------<-------o `bus 2`
         |       ) (            |                  |           |
         |       ) (         |     |            |     |        |
         | v1    ) ( n:1      | h1  |            | h2  |        | v2
         |       ) (         |     |            |     |        |
         \/      ) (            |                  |           \/
ground---o-------   -------------------------------------------o---- ground

(fyi: i1, i2, n, h1 and h2 are all complex numbers. r and x are real numbers. j is a complex number such that j^2 = -1)

Note

h1 and h2 are independent per-side shunt admittances, NOT necessarily one half of a single total value each (they can differ, eg for an asymmetric line/transformer coming from pypowsybl): the admittance matrix contribution of one branch is [[ys + h1, -ys], [-ys, ys + h2]] with ys = 1 / (r + j.x) (see lightsim2grid.elements.LineContainer.get_yac_eff_11() and friends for the coefficients actually used, including any tap-side / phase-shift correction for transformers).

Note

For a powerline, side 1 / side 2 used to be called or (origin) / ex (extremity) in older lightsim2grid versions; for a transformer they are hv (high voltage) / lv (low voltage) instead, since which physical side is tap-side matters there (see is_tap_side_1).

property yac_12

One entry of this branch’s raw two-port AC admittance matrix, computed as if both sides were connected (see yac_eff_11 for the version that accounts for the actual connection status).

With ys = 1 / (r_pu + 1j * x_pu), for a plain powerline (ratio == 1, shift_rad == 0): yac_11 = ys + h1, yac_22 = ys + h2, yac_12 = yac_21 = -ys – see the note in r_pu’s line model. For a transformer, the tap ratio and shift_rad additionally fold into all four entries.

The “line model” (also valid for transformers) is:

             i1                       ________             i2
 `bus 1` o------>   -----------------|r + j.x|---------<-------o `bus 2`
         |       ) (            |                  |           |
         |       ) (         |     |            |     |        |
         | v1    ) ( n:1      | h1  |            | h2  |        | v2
         |       ) (         |     |            |     |        |
         \/      ) (            |                  |           \/
ground---o-------   -------------------------------------------o---- ground

(fyi: i1, i2, n, h1 and h2 are all complex numbers. r and x are real numbers. j is a complex number such that j^2 = -1)

Note

h1 and h2 are independent per-side shunt admittances, NOT necessarily one half of a single total value each (they can differ, eg for an asymmetric line/transformer coming from pypowsybl): the admittance matrix contribution of one branch is [[ys + h1, -ys], [-ys, ys + h2]] with ys = 1 / (r + j.x) (see lightsim2grid.elements.LineContainer.get_yac_eff_11() and friends for the coefficients actually used, including any tap-side / phase-shift correction for transformers).

Note

For a powerline, side 1 / side 2 used to be called or (origin) / ex (extremity) in older lightsim2grid versions; for a transformer they are hv (high voltage) / lv (low voltage) instead, since which physical side is tap-side matters there (see is_tap_side_1).

property yac_21

One entry of this branch’s raw two-port AC admittance matrix, computed as if both sides were connected (see yac_eff_11 for the version that accounts for the actual connection status).

With ys = 1 / (r_pu + 1j * x_pu), for a plain powerline (ratio == 1, shift_rad == 0): yac_11 = ys + h1, yac_22 = ys + h2, yac_12 = yac_21 = -ys – see the note in r_pu’s line model. For a transformer, the tap ratio and shift_rad additionally fold into all four entries.

The “line model” (also valid for transformers) is:

             i1                       ________             i2
 `bus 1` o------>   -----------------|r + j.x|---------<-------o `bus 2`
         |       ) (            |                  |           |
         |       ) (         |     |            |     |        |
         | v1    ) ( n:1      | h1  |            | h2  |        | v2
         |       ) (         |     |            |     |        |
         \/      ) (            |                  |           \/
ground---o-------   -------------------------------------------o---- ground

(fyi: i1, i2, n, h1 and h2 are all complex numbers. r and x are real numbers. j is a complex number such that j^2 = -1)

Note

h1 and h2 are independent per-side shunt admittances, NOT necessarily one half of a single total value each (they can differ, eg for an asymmetric line/transformer coming from pypowsybl): the admittance matrix contribution of one branch is [[ys + h1, -ys], [-ys, ys + h2]] with ys = 1 / (r + j.x) (see lightsim2grid.elements.LineContainer.get_yac_eff_11() and friends for the coefficients actually used, including any tap-side / phase-shift correction for transformers).

Note

For a powerline, side 1 / side 2 used to be called or (origin) / ex (extremity) in older lightsim2grid versions; for a transformer they are hv (high voltage) / lv (low voltage) instead, since which physical side is tap-side matters there (see is_tap_side_1).

property yac_22

One entry of this branch’s raw two-port AC admittance matrix, computed as if both sides were connected (see yac_eff_11 for the version that accounts for the actual connection status).

With ys = 1 / (r_pu + 1j * x_pu), for a plain powerline (ratio == 1, shift_rad == 0): yac_11 = ys + h1, yac_22 = ys + h2, yac_12 = yac_21 = -ys – see the note in r_pu’s line model. For a transformer, the tap ratio and shift_rad additionally fold into all four entries.

The “line model” (also valid for transformers) is:

             i1                       ________             i2
 `bus 1` o------>   -----------------|r + j.x|---------<-------o `bus 2`
         |       ) (            |                  |           |
         |       ) (         |     |            |     |        |
         | v1    ) ( n:1      | h1  |            | h2  |        | v2
         |       ) (         |     |            |     |        |
         \/      ) (            |                  |           \/
ground---o-------   -------------------------------------------o---- ground

(fyi: i1, i2, n, h1 and h2 are all complex numbers. r and x are real numbers. j is a complex number such that j^2 = -1)

Note

h1 and h2 are independent per-side shunt admittances, NOT necessarily one half of a single total value each (they can differ, eg for an asymmetric line/transformer coming from pypowsybl): the admittance matrix contribution of one branch is [[ys + h1, -ys], [-ys, ys + h2]] with ys = 1 / (r + j.x) (see lightsim2grid.elements.LineContainer.get_yac_eff_11() and friends for the coefficients actually used, including any tap-side / phase-shift correction for transformers).

Note

For a powerline, side 1 / side 2 used to be called or (origin) / ex (extremity) in older lightsim2grid versions; for a transformer they are hv (high voltage) / lv (low voltage) instead, since which physical side is tap-side matters there (see is_tap_side_1).

property yac_eff_11

One entry of this branch’s effective two-port AC admittance matrix – yac_11 and friends, corrected for the actual connection status. This is exactly what is stamped into the grid’s Ybus.

  • Both sides connected: equal to yac_11 (etc) unchanged.

  • Exactly one side connected (a “half-open” branch): Kron-reduced to a single self-admittance at the connected end (the open end is eliminated); the three other entries are 0.

  • Neither side connected (or the branch itself disconnected): all four entries are 0.

The “line model” (also valid for transformers) is:

             i1                       ________             i2
 `bus 1` o------>   -----------------|r + j.x|---------<-------o `bus 2`
         |       ) (            |                  |           |
         |       ) (         |     |            |     |        |
         | v1    ) ( n:1      | h1  |            | h2  |        | v2
         |       ) (         |     |            |     |        |
         \/      ) (            |                  |           \/
ground---o-------   -------------------------------------------o---- ground

(fyi: i1, i2, n, h1 and h2 are all complex numbers. r and x are real numbers. j is a complex number such that j^2 = -1)

Note

h1 and h2 are independent per-side shunt admittances, NOT necessarily one half of a single total value each (they can differ, eg for an asymmetric line/transformer coming from pypowsybl): the admittance matrix contribution of one branch is [[ys + h1, -ys], [-ys, ys + h2]] with ys = 1 / (r + j.x) (see lightsim2grid.elements.LineContainer.get_yac_eff_11() and friends for the coefficients actually used, including any tap-side / phase-shift correction for transformers).

Note

For a powerline, side 1 / side 2 used to be called or (origin) / ex (extremity) in older lightsim2grid versions; for a transformer they are hv (high voltage) / lv (low voltage) instead, since which physical side is tap-side matters there (see is_tap_side_1).

property yac_eff_12

One entry of this branch’s effective two-port AC admittance matrix – yac_11 and friends, corrected for the actual connection status. This is exactly what is stamped into the grid’s Ybus.

  • Both sides connected: equal to yac_11 (etc) unchanged.

  • Exactly one side connected (a “half-open” branch): Kron-reduced to a single self-admittance at the connected end (the open end is eliminated); the three other entries are 0.

  • Neither side connected (or the branch itself disconnected): all four entries are 0.

The “line model” (also valid for transformers) is:

             i1                       ________             i2
 `bus 1` o------>   -----------------|r + j.x|---------<-------o `bus 2`
         |       ) (            |                  |           |
         |       ) (         |     |            |     |        |
         | v1    ) ( n:1      | h1  |            | h2  |        | v2
         |       ) (         |     |            |     |        |
         \/      ) (            |                  |           \/
ground---o-------   -------------------------------------------o---- ground

(fyi: i1, i2, n, h1 and h2 are all complex numbers. r and x are real numbers. j is a complex number such that j^2 = -1)

Note

h1 and h2 are independent per-side shunt admittances, NOT necessarily one half of a single total value each (they can differ, eg for an asymmetric line/transformer coming from pypowsybl): the admittance matrix contribution of one branch is [[ys + h1, -ys], [-ys, ys + h2]] with ys = 1 / (r + j.x) (see lightsim2grid.elements.LineContainer.get_yac_eff_11() and friends for the coefficients actually used, including any tap-side / phase-shift correction for transformers).

Note

For a powerline, side 1 / side 2 used to be called or (origin) / ex (extremity) in older lightsim2grid versions; for a transformer they are hv (high voltage) / lv (low voltage) instead, since which physical side is tap-side matters there (see is_tap_side_1).

property yac_eff_21

One entry of this branch’s effective two-port AC admittance matrix – yac_11 and friends, corrected for the actual connection status. This is exactly what is stamped into the grid’s Ybus.

  • Both sides connected: equal to yac_11 (etc) unchanged.

  • Exactly one side connected (a “half-open” branch): Kron-reduced to a single self-admittance at the connected end (the open end is eliminated); the three other entries are 0.

  • Neither side connected (or the branch itself disconnected): all four entries are 0.

The “line model” (also valid for transformers) is:

             i1                       ________             i2
 `bus 1` o------>   -----------------|r + j.x|---------<-------o `bus 2`
         |       ) (            |                  |           |
         |       ) (         |     |            |     |        |
         | v1    ) ( n:1      | h1  |            | h2  |        | v2
         |       ) (         |     |            |     |        |
         \/      ) (            |                  |           \/
ground---o-------   -------------------------------------------o---- ground

(fyi: i1, i2, n, h1 and h2 are all complex numbers. r and x are real numbers. j is a complex number such that j^2 = -1)

Note

h1 and h2 are independent per-side shunt admittances, NOT necessarily one half of a single total value each (they can differ, eg for an asymmetric line/transformer coming from pypowsybl): the admittance matrix contribution of one branch is [[ys + h1, -ys], [-ys, ys + h2]] with ys = 1 / (r + j.x) (see lightsim2grid.elements.LineContainer.get_yac_eff_11() and friends for the coefficients actually used, including any tap-side / phase-shift correction for transformers).

Note

For a powerline, side 1 / side 2 used to be called or (origin) / ex (extremity) in older lightsim2grid versions; for a transformer they are hv (high voltage) / lv (low voltage) instead, since which physical side is tap-side matters there (see is_tap_side_1).

property yac_eff_22

One entry of this branch’s effective two-port AC admittance matrix – yac_11 and friends, corrected for the actual connection status. This is exactly what is stamped into the grid’s Ybus.

  • Both sides connected: equal to yac_11 (etc) unchanged.

  • Exactly one side connected (a “half-open” branch): Kron-reduced to a single self-admittance at the connected end (the open end is eliminated); the three other entries are 0.

  • Neither side connected (or the branch itself disconnected): all four entries are 0.

The “line model” (also valid for transformers) is:

             i1                       ________             i2
 `bus 1` o------>   -----------------|r + j.x|---------<-------o `bus 2`
         |       ) (            |                  |           |
         |       ) (         |     |            |     |        |
         | v1    ) ( n:1      | h1  |            | h2  |        | v2
         |       ) (         |     |            |     |        |
         \/      ) (            |                  |           \/
ground---o-------   -------------------------------------------o---- ground

(fyi: i1, i2, n, h1 and h2 are all complex numbers. r and x are real numbers. j is a complex number such that j^2 = -1)

Note

h1 and h2 are independent per-side shunt admittances, NOT necessarily one half of a single total value each (they can differ, eg for an asymmetric line/transformer coming from pypowsybl): the admittance matrix contribution of one branch is [[ys + h1, -ys], [-ys, ys + h2]] with ys = 1 / (r + j.x) (see lightsim2grid.elements.LineContainer.get_yac_eff_11() and friends for the coefficients actually used, including any tap-side / phase-shift correction for transformers).

Note

For a powerline, side 1 / side 2 used to be called or (origin) / ex (extremity) in older lightsim2grid versions; for a transformer they are hv (high voltage) / lv (low voltage) instead, since which physical side is tap-side matters there (see is_tap_side_1).

property ydc_11

One entry of this branch’s two-port DC admittance matrix – the DC powerflow linearization only keeps the series susceptance (1 / x_pu), so ydc_11 = ydc_22 = 1 / x_pu and ydc_12 = ydc_21 = -1 / x_pu for a plain powerline (a transformer’s tap ratio additionally divides it in). Real numbers, unlike the AC yac_11 family.

Note

Unlike yac_eff_11, there is no status-aware “effective” counterpart exposed for the DC admittance: a disconnected side is instead handled directly by the DC solver / Ybus construction.

The “line model” (also valid for transformers) is:

             i1                       ________             i2
 `bus 1` o------>   -----------------|r + j.x|---------<-------o `bus 2`
         |       ) (            |                  |           |
         |       ) (         |     |            |     |        |
         | v1    ) ( n:1      | h1  |            | h2  |        | v2
         |       ) (         |     |            |     |        |
         \/      ) (            |                  |           \/
ground---o-------   -------------------------------------------o---- ground

(fyi: i1, i2, n, h1 and h2 are all complex numbers. r and x are real numbers. j is a complex number such that j^2 = -1)

Note

h1 and h2 are independent per-side shunt admittances, NOT necessarily one half of a single total value each (they can differ, eg for an asymmetric line/transformer coming from pypowsybl): the admittance matrix contribution of one branch is [[ys + h1, -ys], [-ys, ys + h2]] with ys = 1 / (r + j.x) (see lightsim2grid.elements.LineContainer.get_yac_eff_11() and friends for the coefficients actually used, including any tap-side / phase-shift correction for transformers).

Note

For a powerline, side 1 / side 2 used to be called or (origin) / ex (extremity) in older lightsim2grid versions; for a transformer they are hv (high voltage) / lv (low voltage) instead, since which physical side is tap-side matters there (see is_tap_side_1).

property ydc_12

One entry of this branch’s two-port DC admittance matrix – the DC powerflow linearization only keeps the series susceptance (1 / x_pu), so ydc_11 = ydc_22 = 1 / x_pu and ydc_12 = ydc_21 = -1 / x_pu for a plain powerline (a transformer’s tap ratio additionally divides it in). Real numbers, unlike the AC yac_11 family.

Note

Unlike yac_eff_11, there is no status-aware “effective” counterpart exposed for the DC admittance: a disconnected side is instead handled directly by the DC solver / Ybus construction.

The “line model” (also valid for transformers) is:

             i1                       ________             i2
 `bus 1` o------>   -----------------|r + j.x|---------<-------o `bus 2`
         |       ) (            |                  |           |
         |       ) (         |     |            |     |        |
         | v1    ) ( n:1      | h1  |            | h2  |        | v2
         |       ) (         |     |            |     |        |
         \/      ) (            |                  |           \/
ground---o-------   -------------------------------------------o---- ground

(fyi: i1, i2, n, h1 and h2 are all complex numbers. r and x are real numbers. j is a complex number such that j^2 = -1)

Note

h1 and h2 are independent per-side shunt admittances, NOT necessarily one half of a single total value each (they can differ, eg for an asymmetric line/transformer coming from pypowsybl): the admittance matrix contribution of one branch is [[ys + h1, -ys], [-ys, ys + h2]] with ys = 1 / (r + j.x) (see lightsim2grid.elements.LineContainer.get_yac_eff_11() and friends for the coefficients actually used, including any tap-side / phase-shift correction for transformers).

Note

For a powerline, side 1 / side 2 used to be called or (origin) / ex (extremity) in older lightsim2grid versions; for a transformer they are hv (high voltage) / lv (low voltage) instead, since which physical side is tap-side matters there (see is_tap_side_1).

property ydc_21

One entry of this branch’s two-port DC admittance matrix – the DC powerflow linearization only keeps the series susceptance (1 / x_pu), so ydc_11 = ydc_22 = 1 / x_pu and ydc_12 = ydc_21 = -1 / x_pu for a plain powerline (a transformer’s tap ratio additionally divides it in). Real numbers, unlike the AC yac_11 family.

Note

Unlike yac_eff_11, there is no status-aware “effective” counterpart exposed for the DC admittance: a disconnected side is instead handled directly by the DC solver / Ybus construction.

The “line model” (also valid for transformers) is:

             i1                       ________             i2
 `bus 1` o------>   -----------------|r + j.x|---------<-------o `bus 2`
         |       ) (            |                  |           |
         |       ) (         |     |            |     |        |
         | v1    ) ( n:1      | h1  |            | h2  |        | v2
         |       ) (         |     |            |     |        |
         \/      ) (            |                  |           \/
ground---o-------   -------------------------------------------o---- ground

(fyi: i1, i2, n, h1 and h2 are all complex numbers. r and x are real numbers. j is a complex number such that j^2 = -1)

Note

h1 and h2 are independent per-side shunt admittances, NOT necessarily one half of a single total value each (they can differ, eg for an asymmetric line/transformer coming from pypowsybl): the admittance matrix contribution of one branch is [[ys + h1, -ys], [-ys, ys + h2]] with ys = 1 / (r + j.x) (see lightsim2grid.elements.LineContainer.get_yac_eff_11() and friends for the coefficients actually used, including any tap-side / phase-shift correction for transformers).

Note

For a powerline, side 1 / side 2 used to be called or (origin) / ex (extremity) in older lightsim2grid versions; for a transformer they are hv (high voltage) / lv (low voltage) instead, since which physical side is tap-side matters there (see is_tap_side_1).

property ydc_22

One entry of this branch’s two-port DC admittance matrix – the DC powerflow linearization only keeps the series susceptance (1 / x_pu), so ydc_11 = ydc_22 = 1 / x_pu and ydc_12 = ydc_21 = -1 / x_pu for a plain powerline (a transformer’s tap ratio additionally divides it in). Real numbers, unlike the AC yac_11 family.

Note

Unlike yac_eff_11, there is no status-aware “effective” counterpart exposed for the DC admittance: a disconnected side is instead handled directly by the DC solver / Ybus construction.

The “line model” (also valid for transformers) is:

             i1                       ________             i2
 `bus 1` o------>   -----------------|r + j.x|---------<-------o `bus 2`
         |       ) (            |                  |           |
         |       ) (         |     |            |     |        |
         | v1    ) ( n:1      | h1  |            | h2  |        | v2
         |       ) (         |     |            |     |        |
         \/      ) (            |                  |           \/
ground---o-------   -------------------------------------------o---- ground

(fyi: i1, i2, n, h1 and h2 are all complex numbers. r and x are real numbers. j is a complex number such that j^2 = -1)

Note

h1 and h2 are independent per-side shunt admittances, NOT necessarily one half of a single total value each (they can differ, eg for an asymmetric line/transformer coming from pypowsybl): the admittance matrix contribution of one branch is [[ys + h1, -ys], [-ys, ys + h2]] with ys = 1 / (r + j.x) (see lightsim2grid.elements.LineContainer.get_yac_eff_11() and friends for the coefficients actually used, including any tap-side / phase-shift correction for transformers).

Note

For a powerline, side 1 / side 2 used to be called or (origin) / ex (extremity) in older lightsim2grid versions; for a transformer they are hv (high voltage) / lv (low voltage) instead, since which physical side is tap-side matters there (see is_tap_side_1).

Transformers

class lightsim2grid.elements.TrafoContainer

This class allows to iterate through the transformers of the lightsim2grid.network.LSGrid easily, as if they were in a python list.

Transformers are modeled as in pandapower and can be represented a the pandapower transformers .

Examples

import grid2op
from lightsim2grid import LightSimBackend

# create a lightsim2grid "gridmodel"
env_name = ... # eg. "l2rpn_case14_test"
env = grid2op.make(env_name, backend=LightSimBackend())
grid_model = env.backend._grid

# manipulate the tranformers
for trafo in grid_model.get_trafos():
    # do something with trafo !
    trafo.bus_hv_id

print(f"There are {len(grid_model.get_trafos())} transformers on the grid.")

first_transformer = grid_model.get_trafos()[0]

You can have a look at lightsim2grid.elements.TrafoInfo for properties of these elements.

Methods:

get_bus_id_side_1(self)

bus_1_id for every element of this container, as a single array: element i of the result is that element's side-1 bus id, -1 if disconnected on that side.

get_bus_id_side_2(self)

bus_2_id for every element of this container, as a single array: element i of the result is that element's side-2 bus id, -1 if disconnected on that side.

get_yac_eff_11(self)

yac_eff_11 (etc, see lightsim2grid.elements.LineInfo / lightsim2grid.elements.TrafoInfo) for every element of this container, as a single array.

get_yac_eff_12(self)

yac_eff_11 (etc, see lightsim2grid.elements.LineInfo / lightsim2grid.elements.TrafoInfo) for every element of this container, as a single array.

get_yac_eff_21(self)

yac_eff_11 (etc, see lightsim2grid.elements.LineInfo / lightsim2grid.elements.TrafoInfo) for every element of this container, as a single array.

get_yac_eff_22(self)

yac_eff_11 (etc, see lightsim2grid.elements.LineInfo / lightsim2grid.elements.TrafoInfo) for every element of this container, as a single array.

load_binary(path)

Load an object previously saved with save_binary().

save_binary(self, path[, atomic])

Save this object's state to a fast custom binary file (additive alternative to pickle).

Attributes:

ignore_tap_side_for_shift

Whether ignore the tap side is ignored when using the 'shift' attribute (should be True for pandapower, where it is ignored and False otherwise).

get_bus_id_side_1(self: lightsim2grid.lightsim2grid_cpp.TrafoContainer) Annotated[numpy.typing.NDArray[numpy.int32], '[m, 1]']

bus_1_id for every element of this container, as a single array: element i of the result is that element’s side-1 bus id, -1 if disconnected on that side.

get_bus_id_side_2(self: lightsim2grid.lightsim2grid_cpp.TrafoContainer) Annotated[numpy.typing.NDArray[numpy.int32], '[m, 1]']

bus_2_id for every element of this container, as a single array: element i of the result is that element’s side-2 bus id, -1 if disconnected on that side.

get_yac_eff_11(self: lightsim2grid.lightsim2grid_cpp.TrafoContainer) Annotated[numpy.typing.NDArray[numpy.complex128], '[m, 1]']

yac_eff_11 (etc, see lightsim2grid.elements.LineInfo / lightsim2grid.elements.TrafoInfo) for every element of this container, as a single array.

The “line model” (also valid for transformers) is:

             i1                       ________             i2
 `bus 1` o------>   -----------------|r + j.x|---------<-------o `bus 2`
         |       ) (            |                  |           |
         |       ) (         |     |            |     |        |
         | v1    ) ( n:1      | h1  |            | h2  |        | v2
         |       ) (         |     |            |     |        |
         \/      ) (            |                  |           \/
ground---o-------   -------------------------------------------o---- ground

(fyi: i1, i2, n, h1 and h2 are all complex numbers. r and x are real numbers. j is a complex number such that j^2 = -1)

Note

h1 and h2 are independent per-side shunt admittances, NOT necessarily one half of a single total value each (they can differ, eg for an asymmetric line/transformer coming from pypowsybl): the admittance matrix contribution of one branch is [[ys + h1, -ys], [-ys, ys + h2]] with ys = 1 / (r + j.x) (see lightsim2grid.elements.LineContainer.get_yac_eff_11() and friends for the coefficients actually used, including any tap-side / phase-shift correction for transformers).

Note

For a powerline, side 1 / side 2 used to be called or (origin) / ex (extremity) in older lightsim2grid versions; for a transformer they are hv (high voltage) / lv (low voltage) instead, since which physical side is tap-side matters there (see is_tap_side_1).

get_yac_eff_12(self: lightsim2grid.lightsim2grid_cpp.TrafoContainer) Annotated[numpy.typing.NDArray[numpy.complex128], '[m, 1]']

yac_eff_11 (etc, see lightsim2grid.elements.LineInfo / lightsim2grid.elements.TrafoInfo) for every element of this container, as a single array.

The “line model” (also valid for transformers) is:

             i1                       ________             i2
 `bus 1` o------>   -----------------|r + j.x|---------<-------o `bus 2`
         |       ) (            |                  |           |
         |       ) (         |     |            |     |        |
         | v1    ) ( n:1      | h1  |            | h2  |        | v2
         |       ) (         |     |            |     |        |
         \/      ) (            |                  |           \/
ground---o-------   -------------------------------------------o---- ground

(fyi: i1, i2, n, h1 and h2 are all complex numbers. r and x are real numbers. j is a complex number such that j^2 = -1)

Note

h1 and h2 are independent per-side shunt admittances, NOT necessarily one half of a single total value each (they can differ, eg for an asymmetric line/transformer coming from pypowsybl): the admittance matrix contribution of one branch is [[ys + h1, -ys], [-ys, ys + h2]] with ys = 1 / (r + j.x) (see lightsim2grid.elements.LineContainer.get_yac_eff_11() and friends for the coefficients actually used, including any tap-side / phase-shift correction for transformers).

Note

For a powerline, side 1 / side 2 used to be called or (origin) / ex (extremity) in older lightsim2grid versions; for a transformer they are hv (high voltage) / lv (low voltage) instead, since which physical side is tap-side matters there (see is_tap_side_1).

get_yac_eff_21(self: lightsim2grid.lightsim2grid_cpp.TrafoContainer) Annotated[numpy.typing.NDArray[numpy.complex128], '[m, 1]']

yac_eff_11 (etc, see lightsim2grid.elements.LineInfo / lightsim2grid.elements.TrafoInfo) for every element of this container, as a single array.

The “line model” (also valid for transformers) is:

             i1                       ________             i2
 `bus 1` o------>   -----------------|r + j.x|---------<-------o `bus 2`
         |       ) (            |                  |           |
         |       ) (         |     |            |     |        |
         | v1    ) ( n:1      | h1  |            | h2  |        | v2
         |       ) (         |     |            |     |        |
         \/      ) (            |                  |           \/
ground---o-------   -------------------------------------------o---- ground

(fyi: i1, i2, n, h1 and h2 are all complex numbers. r and x are real numbers. j is a complex number such that j^2 = -1)

Note

h1 and h2 are independent per-side shunt admittances, NOT necessarily one half of a single total value each (they can differ, eg for an asymmetric line/transformer coming from pypowsybl): the admittance matrix contribution of one branch is [[ys + h1, -ys], [-ys, ys + h2]] with ys = 1 / (r + j.x) (see lightsim2grid.elements.LineContainer.get_yac_eff_11() and friends for the coefficients actually used, including any tap-side / phase-shift correction for transformers).

Note

For a powerline, side 1 / side 2 used to be called or (origin) / ex (extremity) in older lightsim2grid versions; for a transformer they are hv (high voltage) / lv (low voltage) instead, since which physical side is tap-side matters there (see is_tap_side_1).

get_yac_eff_22(self: lightsim2grid.lightsim2grid_cpp.TrafoContainer) Annotated[numpy.typing.NDArray[numpy.complex128], '[m, 1]']

yac_eff_11 (etc, see lightsim2grid.elements.LineInfo / lightsim2grid.elements.TrafoInfo) for every element of this container, as a single array.

The “line model” (also valid for transformers) is:

             i1                       ________             i2
 `bus 1` o------>   -----------------|r + j.x|---------<-------o `bus 2`
         |       ) (            |                  |           |
         |       ) (         |     |            |     |        |
         | v1    ) ( n:1      | h1  |            | h2  |        | v2
         |       ) (         |     |            |     |        |
         \/      ) (            |                  |           \/
ground---o-------   -------------------------------------------o---- ground

(fyi: i1, i2, n, h1 and h2 are all complex numbers. r and x are real numbers. j is a complex number such that j^2 = -1)

Note

h1 and h2 are independent per-side shunt admittances, NOT necessarily one half of a single total value each (they can differ, eg for an asymmetric line/transformer coming from pypowsybl): the admittance matrix contribution of one branch is [[ys + h1, -ys], [-ys, ys + h2]] with ys = 1 / (r + j.x) (see lightsim2grid.elements.LineContainer.get_yac_eff_11() and friends for the coefficients actually used, including any tap-side / phase-shift correction for transformers).

Note

For a powerline, side 1 / side 2 used to be called or (origin) / ex (extremity) in older lightsim2grid versions; for a transformer they are hv (high voltage) / lv (low voltage) instead, since which physical side is tap-side matters there (see is_tap_side_1).

property ignore_tap_side_for_shift

Whether ignore the tap side is ignored when using the ‘shift’ attribute (should be True for pandapower, where it is ignored and False otherwise).

staticmethod load_binary(path: str) lightsim2grid.lightsim2grid_cpp.TrafoContainer

Load an object previously saved with save_binary(). Raises RuntimeError on an incompatible binary format, a wrong object type, or a corrupted / truncated file (including corrupted internal sizes: no attempt is made to allocate more data than the file actually contains). Loading a whole grid additionally validates its consistency (see check_grid): a byte-wise well-formed but inconsistent grid raises IndexError (out-of-range index) or RuntimeError (structural inconsistency).

save_binary(self: lightsim2grid.lightsim2grid_cpp.TrafoContainer, path: str, atomic: bool = True) None

Save this object’s state to a fast custom binary file (additive alternative to pickle). By default (atomic=True) the write is atomic: an existing file at that path is only replaced once the new content has been written completely (an interrupted save never destroys a previous file). Pass atomic=False to write the destination directly instead – marginally faster (skips one temporary file + rename), without that protection. The file stays readable by any lightsim2grid version sharing the same binary format number.

class lightsim2grid.elements.TrafoInfo

This class represents what you get from retrieving the transformers from lightsim2grid.elements.TrafoContainer.

It allows to read information from each transformer of the powergrid.

Transformers have two sides, one is “hv” for “high voltage” and one is “lv” for “low voltage” that are connected and linked to each other by some equations.

For accessing the results, it’s basically the same as having two “elements” (so you get two “voltage_magnitude” res_v_kv, two “injected power” res_p_mw etc.)

Warning

Data ca only be accessed from this element. You cannot modify (yet) the grid using this class.

Examples

import grid2op
from lightsim2grid import LightSimBackend

# create a lightsim2grid "gridmodel"
env_name = ... # eg. "l2rpn_case14_test"
env = grid2op.make(env_name, backend=LightSimBackend())
grid_model = env.backend._grid

# for transformers
first_transformer = grid_model.get_trafos()[0]  # first transformer, this is a `TrafoInfo`
for trafo in grid_model.get_trafos():
    # trafo is a `TrafoInfo`
    trafo.bus_hv_id

Notes

Transformer are modeled using the “line model”.

Usually, the “or” side is the “hv” side and the “ex” side is the “lv” side.

The tap ratio n bellow is a complex number with its magnitude corresponding to the tap ratio and its angle to the phase shifter.

For more information about the model and the equations linking all the quantities, please visit matpower manual , especially the “3. Modeling” and the “3.2 Branches” subsection, as well as the equation 3.1, 3.2 and 3.3 therein.

The “line model” (also valid for transformers) is:

             i1                       ________             i2
 `bus 1` o------>   -----------------|r + j.x|---------<-------o `bus 2`
         |       ) (            |                  |           |
         |       ) (         |     |            |     |        |
         | v1    ) ( n:1      | h1  |            | h2  |        | v2
         |       ) (         |     |            |     |        |
         \/      ) (            |                  |           \/
ground---o-------   -------------------------------------------o---- ground

(fyi: i1, i2, n, h1 and h2 are all complex numbers. r and x are real numbers. j is a complex number such that j^2 = -1)

Note

h1 and h2 are independent per-side shunt admittances, NOT necessarily one half of a single total value each (they can differ, eg for an asymmetric line/transformer coming from pypowsybl): the admittance matrix contribution of one branch is [[ys + h1, -ys], [-ys, ys + h2]] with ys = 1 / (r + j.x) (see lightsim2grid.elements.LineContainer.get_yac_eff_11() and friends for the coefficients actually used, including any tap-side / phase-shift correction for transformers).

Note

For a powerline, side 1 / side 2 used to be called or (origin) / ex (extremity) in older lightsim2grid versions; for a transformer they are hv (high voltage) / lv (low voltage) instead, since which physical side is tap-side matters there (see is_tap_side_1).

Attributes:

bus1_id

Get the bus id (as an integer) at which the "hv" side of the transformer is connected.

bus2_id

Get the bus id (as an integer) at which the "lv" side of the transformer is connected.

connected1

Get the status of side 1 (hv) of this transformer alone, see connected_global.

connected2

Get the status of side 2 (lv) of this transformer alone, see connected_global.

connected_global

Get the global status (True as soon as either side is connected) of this transformer.

h1_pu

Retrieve the shunt admittance (in pair unit system) of one side of the powerline / transformer: conductance g as the real part, susceptance b (related to the line charging capacitance) as the imaginary part, ie h = g + 1j * b.

h2_pu

Retrieve the shunt admittance (in pair unit system) of one side of the powerline / transformer: conductance g as the real part, susceptance b (related to the line charging capacitance) as the imaginary part, ie h = g + 1j * b.

has_res

This property specify whether or not a given element contains some "result" information.

id

Get the id of the element.

is_tap_side_1

Gives whether the tap (both for the ratio and the phase shifter) is located "hv" side (default, when True) or "lv" side (when False).

limit_a1_ka

Current limit, hv side, in kA (NaN if not set, see LSGrid.set_trafo_current_limit_side1).

limit_a2_ka

Current limit, lv side, in kA (NaN if not set, see LSGrid.set_trafo_current_limit_side2).

name

Get the name of the element.

pos1_topo_vect

Get the position of side 1 (hv) of this transformer in the grid2op "topo_vect" vector (-1 if never set).

pos2_topo_vect

Get the position of side 2 (lv) of this transformer in the grid2op "topo_vect" vector (-1 if never set).

r_pu

Retrieve the resistance (given in pair unit system, and not in Ohm) of the powerlines or the transformers.

ratio

Retrieve the ratio (absolute value of the complex coefficient n in the powerline model).

res_a1_ka

Get the current flows (in kA) at the "hv" side of the transformer.

res_a2_ka

Get the current flows (in kA) at the "lv" side of the transformer.

res_p1_mw

Get the active power in MW for at the "hv" side of the transformer.

res_p2_mw

Get the active power in MW for at the "lv" side of the transformer.

res_q1_mvar

Get the reactive power in MVAr for at the "hv" side of the transformer.

res_q2_mvar

Get the reactive power in MVAr for at the "lv" side of the transformer.

res_theta1_deg

Get the angle of the complex voltage (in degree, not in radian) of the bus at which this "hv" side of the transformer is connected.

res_theta2_deg

Get the angle of the complex voltage (in degree, not in radian) of the bus at which this "lv" side of the transformer is connected.

res_v1_kv

Get the magnitude of the complex voltage (in kV) of the bus at which this "hv" side of the transformer is connected.

res_v2_kv

Get the magnitude of the complex voltage (in kV) of the bus at which this "lv" side of the transformer is connected.

shift_rad

Retrieve the shift angle (angle of the complex coefficient n in the powerline model).

sub1_id

Get the substation id of side 1 (hv) of this transformer (-1 if never set; called "voltage level" in pypowsybl).

sub2_id

Get the substation id of side 2 (lv) of this transformer (-1 if never set; called "voltage level" in pypowsybl).

voltage_level1_id

Get the substation id of side 1 (hv) of this transformer (-1 if never set; called "voltage level" in pypowsybl).

voltage_level2_id

Get the substation id of side 2 (lv) of this transformer (-1 if never set; called "voltage level" in pypowsybl).

x_pu

Retrieve the reactance (given in pair unit system, and not in Ohm) of the powerlines or the transformers.

yac_11

One entry of this branch's raw two-port AC admittance matrix, computed as if both sides were connected (see yac_eff_11 for the version that accounts for the actual connection status).

yac_12

One entry of this branch's raw two-port AC admittance matrix, computed as if both sides were connected (see yac_eff_11 for the version that accounts for the actual connection status).

yac_21

One entry of this branch's raw two-port AC admittance matrix, computed as if both sides were connected (see yac_eff_11 for the version that accounts for the actual connection status).

yac_22

One entry of this branch's raw two-port AC admittance matrix, computed as if both sides were connected (see yac_eff_11 for the version that accounts for the actual connection status).

yac_eff_11

One entry of this branch's effective two-port AC admittance matrix -- yac_11 and friends, corrected for the actual connection status.

yac_eff_12

One entry of this branch's effective two-port AC admittance matrix -- yac_11 and friends, corrected for the actual connection status.

yac_eff_21

One entry of this branch's effective two-port AC admittance matrix -- yac_11 and friends, corrected for the actual connection status.

yac_eff_22

One entry of this branch's effective two-port AC admittance matrix -- yac_11 and friends, corrected for the actual connection status.

ydc_11

One entry of this branch's two-port DC admittance matrix -- the DC powerflow linearization only keeps the series susceptance (1 / x_pu), so ydc_11 = ydc_22 = 1 / x_pu and ydc_12 = ydc_21 = -1 / x_pu for a plain powerline (a transformer's tap ratio additionally divides it in).

ydc_12

One entry of this branch's two-port DC admittance matrix -- the DC powerflow linearization only keeps the series susceptance (1 / x_pu), so ydc_11 = ydc_22 = 1 / x_pu and ydc_12 = ydc_21 = -1 / x_pu for a plain powerline (a transformer's tap ratio additionally divides it in).

ydc_21

One entry of this branch's two-port DC admittance matrix -- the DC powerflow linearization only keeps the series susceptance (1 / x_pu), so ydc_11 = ydc_22 = 1 / x_pu and ydc_12 = ydc_21 = -1 / x_pu for a plain powerline (a transformer's tap ratio additionally divides it in).

ydc_22

One entry of this branch's two-port DC admittance matrix -- the DC powerflow linearization only keeps the series susceptance (1 / x_pu), so ydc_11 = ydc_22 = 1 / x_pu and ydc_12 = ydc_21 = -1 / x_pu for a plain powerline (a transformer's tap ratio additionally divides it in).

property bus1_id

Get the bus id (as an integer) at which the “hv” side of the transformer is connected. If -1 is returned it means that the transformer is disconnected.

(This is the gridmodel / global bus id, not the solver bus id – see lightsim2grid.network.LSGrid.id_me_to_ac_solver() to convert.)

Read-only here; equivalent to lightsim2grid.network.LSGrid.get_bus1_trafo(). To move this side to another bus, call lightsim2grid.network.LSGrid.change_bus1_trafo().

property bus2_id

Get the bus id (as an integer) at which the “lv” side of the transformer is connected. If -1 is returned it means that the transformer is disconnected.

(This is the gridmodel / global bus id, not the solver bus id – see lightsim2grid.network.LSGrid.id_me_to_ac_solver() to convert.)

Read-only here; equivalent to lightsim2grid.network.LSGrid.get_bus2_trafo(). To move this side to another bus, call lightsim2grid.network.LSGrid.change_bus2_trafo().

property connected1

Get the status of side 1 (hv) of this transformer alone, see connected_global.

Read-only here. To disconnect / reconnect only this side, call lightsim2grid.network.LSGrid.deactivate_trafo_side1() / lightsim2grid.network.LSGrid.reactivate_trafo_side1().

property connected2

Get the status of side 2 (lv) of this transformer alone, see connected_global.

Read-only here. To disconnect / reconnect only this side, call lightsim2grid.network.LSGrid.deactivate_trafo_side2() / lightsim2grid.network.LSGrid.reactivate_trafo_side2().

property connected_global

Get the global status (True as soon as either side is connected) of this transformer.

Read-only here. To disconnect / reconnect both sides at once, call lightsim2grid.network.LSGrid.deactivate_trafo() / lightsim2grid.network.LSGrid.reactivate_trafo(); see connected1 / connected2 and their own setters to act on a single side (“half-open”).

property h1_pu

Retrieve the shunt admittance (in pair unit system) of one side of the powerline / transformer: conductance g as the real part, susceptance b (related to the line charging capacitance) as the imaginary part, ie h = g + 1j * b.

This is a complex number, represented by h1 (side 1) or h2 (side 2) in the line model – they are independent values, not half of a single shared h each (see the note in the line model below).

The “line model” (also valid for transformers) is:

             i1                       ________             i2
 `bus 1` o------>   -----------------|r + j.x|---------<-------o `bus 2`
         |       ) (            |                  |           |
         |       ) (         |     |            |     |        |
         | v1    ) ( n:1      | h1  |            | h2  |        | v2
         |       ) (         |     |            |     |        |
         \/      ) (            |                  |           \/
ground---o-------   -------------------------------------------o---- ground

(fyi: i1, i2, n, h1 and h2 are all complex numbers. r and x are real numbers. j is a complex number such that j^2 = -1)

Note

h1 and h2 are independent per-side shunt admittances, NOT necessarily one half of a single total value each (they can differ, eg for an asymmetric line/transformer coming from pypowsybl): the admittance matrix contribution of one branch is [[ys + h1, -ys], [-ys, ys + h2]] with ys = 1 / (r + j.x) (see lightsim2grid.elements.LineContainer.get_yac_eff_11() and friends for the coefficients actually used, including any tap-side / phase-shift correction for transformers).

Note

For a powerline, side 1 / side 2 used to be called or (origin) / ex (extremity) in older lightsim2grid versions; for a transformer they are hv (high voltage) / lv (low voltage) instead, since which physical side is tap-side matters there (see is_tap_side_1).

property h2_pu

Retrieve the shunt admittance (in pair unit system) of one side of the powerline / transformer: conductance g as the real part, susceptance b (related to the line charging capacitance) as the imaginary part, ie h = g + 1j * b.

This is a complex number, represented by h1 (side 1) or h2 (side 2) in the line model – they are independent values, not half of a single shared h each (see the note in the line model below).

The “line model” (also valid for transformers) is:

             i1                       ________             i2
 `bus 1` o------>   -----------------|r + j.x|---------<-------o `bus 2`
         |       ) (            |                  |           |
         |       ) (         |     |            |     |        |
         | v1    ) ( n:1      | h1  |            | h2  |        | v2
         |       ) (         |     |            |     |        |
         \/      ) (            |                  |           \/
ground---o-------   -------------------------------------------o---- ground

(fyi: i1, i2, n, h1 and h2 are all complex numbers. r and x are real numbers. j is a complex number such that j^2 = -1)

Note

h1 and h2 are independent per-side shunt admittances, NOT necessarily one half of a single total value each (they can differ, eg for an asymmetric line/transformer coming from pypowsybl): the admittance matrix contribution of one branch is [[ys + h1, -ys], [-ys, ys + h2]] with ys = 1 / (r + j.x) (see lightsim2grid.elements.LineContainer.get_yac_eff_11() and friends for the coefficients actually used, including any tap-side / phase-shift correction for transformers).

Note

For a powerline, side 1 / side 2 used to be called or (origin) / ex (extremity) in older lightsim2grid versions; for a transformer they are hv (high voltage) / lv (low voltage) instead, since which physical side is tap-side matters there (see is_tap_side_1).

property has_res

This property specify whether or not a given element contains some “result” information. If set to True then the fields starting with res_ (eg res_p_mw) are filled otherwise they are initialized with an arbitrary (and meaningless) value.

property id

Get the id of the element. Ids are integer from 0 to n-1 (if n denotes the number of such elements on the grid.)

Examples

We give the example only for generators, but it works similarly for every other types of objects in a lightsim2grid.network.LSGrid.

This gives something like:

import grid2op
from lightsim2grid import LightSimBackend

env_name = ... # eg. "l2rpn_case14_test"
env = grid2op.make(env_name, backend=LightSimBackend())

grid_model = env.backend._grid

first_gen = grid_model.get_generators()[0]  # or get_loads for loads, etc.
first_gen.id  # should be 0
property is_tap_side_1

Gives whether the tap (both for the ratio and the phase shifter) is located “hv” side (default, when True) or “lv” side (when False).

property limit_a1_ka

Current limit, hv side, in kA (NaN if not set, see LSGrid.set_trafo_current_limit_side1).

property limit_a2_ka

Current limit, lv side, in kA (NaN if not set, see LSGrid.set_trafo_current_limit_side2).

property name

Get the name of the element. Names are string that should be unique. But if you really want things unique, use the id

Warning

Names are optional and might not be set when reading the grid.

Examples

We give the example only for generators, but it works similarly for every other types of objects in a lightsim2grid.network.LSGrid.

This gives something like:

import grid2op
from lightsim2grid import LightSimBackend

env_name = ... # eg. "l2rpn_case14_test"
env = grid2op.make(env_name, backend=LightSimBackend())

grid_model = env.backend._grid

first_gen = grid_model.get_generators()[0]  # or get_loads for loads, etc.
first_gen.name
property pos1_topo_vect

Get the position of side 1 (hv) of this transformer in the grid2op “topo_vect” vector (-1 if never set).

Read-only here; this is set once, by the grid loaders, via lightsim2grid.network.LSGrid.set_trafo_pos1_topo_vect().

property pos2_topo_vect

Get the position of side 2 (lv) of this transformer in the grid2op “topo_vect” vector (-1 if never set).

Read-only here; this is set once, by the grid loaders, via lightsim2grid.network.LSGrid.set_trafo_pos2_topo_vect().

property r_pu

Retrieve the resistance (given in pair unit system, and not in Ohm) of the powerlines or the transformers. This is a real number and is represented by the number r in the line model.

The “line model” (also valid for transformers) is:

             i1                       ________             i2
 `bus 1` o------>   -----------------|r + j.x|---------<-------o `bus 2`
         |       ) (            |                  |           |
         |       ) (         |     |            |     |        |
         | v1    ) ( n:1      | h1  |            | h2  |        | v2
         |       ) (         |     |            |     |        |
         \/      ) (            |                  |           \/
ground---o-------   -------------------------------------------o---- ground

(fyi: i1, i2, n, h1 and h2 are all complex numbers. r and x are real numbers. j is a complex number such that j^2 = -1)

Note

h1 and h2 are independent per-side shunt admittances, NOT necessarily one half of a single total value each (they can differ, eg for an asymmetric line/transformer coming from pypowsybl): the admittance matrix contribution of one branch is [[ys + h1, -ys], [-ys, ys + h2]] with ys = 1 / (r + j.x) (see lightsim2grid.elements.LineContainer.get_yac_eff_11() and friends for the coefficients actually used, including any tap-side / phase-shift correction for transformers).

Note

For a powerline, side 1 / side 2 used to be called or (origin) / ex (extremity) in older lightsim2grid versions; for a transformer they are hv (high voltage) / lv (low voltage) instead, since which physical side is tap-side matters there (see is_tap_side_1).

property ratio

Retrieve the ratio (absolute value of the complex coefficient n in the powerline model). It has no units

The “line model” (also valid for transformers) is:

             i1                       ________             i2
 `bus 1` o------>   -----------------|r + j.x|---------<-------o `bus 2`
         |       ) (            |                  |           |
         |       ) (         |     |            |     |        |
         | v1    ) ( n:1      | h1  |            | h2  |        | v2
         |       ) (         |     |            |     |        |
         \/      ) (            |                  |           \/
ground---o-------   -------------------------------------------o---- ground

(fyi: i1, i2, n, h1 and h2 are all complex numbers. r and x are real numbers. j is a complex number such that j^2 = -1)

Note

h1 and h2 are independent per-side shunt admittances, NOT necessarily one half of a single total value each (they can differ, eg for an asymmetric line/transformer coming from pypowsybl): the admittance matrix contribution of one branch is [[ys + h1, -ys], [-ys, ys + h2]] with ys = 1 / (r + j.x) (see lightsim2grid.elements.LineContainer.get_yac_eff_11() and friends for the coefficients actually used, including any tap-side / phase-shift correction for transformers).

Note

For a powerline, side 1 / side 2 used to be called or (origin) / ex (extremity) in older lightsim2grid versions; for a transformer they are hv (high voltage) / lv (low voltage) instead, since which physical side is tap-side matters there (see is_tap_side_1).

property res_a1_ka

Get the current flows (in kA) at the “hv” side of the transformer.

Warning

This feature is only relevant if the results have been computed (for example if a powerflow has successfully run)

property res_a2_ka

Get the current flows (in kA) at the “lv” side of the transformer.

Warning

This feature is only relevant if the results have been computed (for example if a powerflow has successfully run)

property res_p1_mw

Get the active power in MW for at the “hv” side of the transformer. If it is positive it means power is absorbed by the transformer.

Warning

This feature is only relevant if the results have been computed (for example if a powerflow has successfully run)

property res_p2_mw

Get the active power in MW for at the “lv” side of the transformer. If it is positive it means power is absorbed by the transformer.

Warning

This feature is only relevant if the results have been computed (for example if a powerflow has successfully run)

property res_q1_mvar

Get the reactive power in MVAr for at the “hv” side of the transformer. If it is positive it means power is absorbed by the transformer.

Warning

This feature is only relevant if the results have been computed (for example if a powerflow has successfully run)

property res_q2_mvar

Get the reactive power in MVAr for at the “lv” side of the transformer. If it is positive it means power is absorbed by the transformer.

Warning

This feature is only relevant if the results have been computed (for example if a powerflow has successfully run)

property res_theta1_deg

Get the angle of the complex voltage (in degree, not in radian) of the bus at which this “hv” side of the transformer is connected.

Note

All elements (load, generators, side of powerline etc.) connected at the same bus have the same “res_theta_deg”

Warning

This feature is only relevant if the results have been computed (for example if a powerflow has successfully run)

property res_theta2_deg

Get the angle of the complex voltage (in degree, not in radian) of the bus at which this “lv” side of the transformer is connected.

Note

All elements (load, generators, side of powerline etc.) connected at the same bus have the same “res_theta_deg”

Warning

This feature is only relevant if the results have been computed (for example if a powerflow has successfully run)

property res_v1_kv

Get the magnitude of the complex voltage (in kV) of the bus at which this “hv” side of the transformer is connected.

Note

All elements (load, generators, side of powerline etc.) connected at the same bus have the same “res_v_kv”

Warning

This feature is only relevant if the results have been computed (for example if a powerflow has successfully run)

property res_v2_kv

Get the magnitude of the complex voltage (in kV) of the bus at which this “lv” side of the transformer is connected.

Note

All elements (load, generators, side of powerline etc.) connected at the same bus have the same “res_v_kv”

Warning

This feature is only relevant if the results have been computed (for example if a powerflow has successfully run)

property shift_rad

Retrieve the shift angle (angle of the complex coefficient n in the powerline model). It is given in radian (and not in degree)

The “line model” (also valid for transformers) is:

             i1                       ________             i2
 `bus 1` o------>   -----------------|r + j.x|---------<-------o `bus 2`
         |       ) (            |                  |           |
         |       ) (         |     |            |     |        |
         | v1    ) ( n:1      | h1  |            | h2  |        | v2
         |       ) (         |     |            |     |        |
         \/      ) (            |                  |           \/
ground---o-------   -------------------------------------------o---- ground

(fyi: i1, i2, n, h1 and h2 are all complex numbers. r and x are real numbers. j is a complex number such that j^2 = -1)

Note

h1 and h2 are independent per-side shunt admittances, NOT necessarily one half of a single total value each (they can differ, eg for an asymmetric line/transformer coming from pypowsybl): the admittance matrix contribution of one branch is [[ys + h1, -ys], [-ys, ys + h2]] with ys = 1 / (r + j.x) (see lightsim2grid.elements.LineContainer.get_yac_eff_11() and friends for the coefficients actually used, including any tap-side / phase-shift correction for transformers).

Note

For a powerline, side 1 / side 2 used to be called or (origin) / ex (extremity) in older lightsim2grid versions; for a transformer they are hv (high voltage) / lv (low voltage) instead, since which physical side is tap-side matters there (see is_tap_side_1).

property sub1_id

Get the substation id of side 1 (hv) of this transformer (-1 if never set; called “voltage level” in pypowsybl).

Read-only here; this is set once, by the grid loaders, via lightsim2grid.network.LSGrid.set_trafo_to_sub1_id().

property sub2_id

Get the substation id of side 2 (lv) of this transformer (-1 if never set; called “voltage level” in pypowsybl).

Read-only here; this is set once, by the grid loaders, via lightsim2grid.network.LSGrid.set_trafo_to_sub2_id().

property voltage_level1_id

Get the substation id of side 1 (hv) of this transformer (-1 if never set; called “voltage level” in pypowsybl).

Read-only here; this is set once, by the grid loaders, via lightsim2grid.network.LSGrid.set_trafo_to_sub1_id().

property voltage_level2_id

Get the substation id of side 2 (lv) of this transformer (-1 if never set; called “voltage level” in pypowsybl).

Read-only here; this is set once, by the grid loaders, via lightsim2grid.network.LSGrid.set_trafo_to_sub2_id().

property x_pu

Retrieve the reactance (given in pair unit system, and not in Ohm) of the powerlines or the transformers. This is a real number and is represented by the number x in the line model.

The “line model” (also valid for transformers) is:

             i1                       ________             i2
 `bus 1` o------>   -----------------|r + j.x|---------<-------o `bus 2`
         |       ) (            |                  |           |
         |       ) (         |     |            |     |        |
         | v1    ) ( n:1      | h1  |            | h2  |        | v2
         |       ) (         |     |            |     |        |
         \/      ) (            |                  |           \/
ground---o-------   -------------------------------------------o---- ground

(fyi: i1, i2, n, h1 and h2 are all complex numbers. r and x are real numbers. j is a complex number such that j^2 = -1)

Note

h1 and h2 are independent per-side shunt admittances, NOT necessarily one half of a single total value each (they can differ, eg for an asymmetric line/transformer coming from pypowsybl): the admittance matrix contribution of one branch is [[ys + h1, -ys], [-ys, ys + h2]] with ys = 1 / (r + j.x) (see lightsim2grid.elements.LineContainer.get_yac_eff_11() and friends for the coefficients actually used, including any tap-side / phase-shift correction for transformers).

Note

For a powerline, side 1 / side 2 used to be called or (origin) / ex (extremity) in older lightsim2grid versions; for a transformer they are hv (high voltage) / lv (low voltage) instead, since which physical side is tap-side matters there (see is_tap_side_1).

property yac_11

One entry of this branch’s raw two-port AC admittance matrix, computed as if both sides were connected (see yac_eff_11 for the version that accounts for the actual connection status).

With ys = 1 / (r_pu + 1j * x_pu), for a plain powerline (ratio == 1, shift_rad == 0): yac_11 = ys + h1, yac_22 = ys + h2, yac_12 = yac_21 = -ys – see the note in r_pu’s line model. For a transformer, the tap ratio and shift_rad additionally fold into all four entries.

The “line model” (also valid for transformers) is:

             i1                       ________             i2
 `bus 1` o------>   -----------------|r + j.x|---------<-------o `bus 2`
         |       ) (            |                  |           |
         |       ) (         |     |            |     |        |
         | v1    ) ( n:1      | h1  |            | h2  |        | v2
         |       ) (         |     |            |     |        |
         \/      ) (            |                  |           \/
ground---o-------   -------------------------------------------o---- ground

(fyi: i1, i2, n, h1 and h2 are all complex numbers. r and x are real numbers. j is a complex number such that j^2 = -1)

Note

h1 and h2 are independent per-side shunt admittances, NOT necessarily one half of a single total value each (they can differ, eg for an asymmetric line/transformer coming from pypowsybl): the admittance matrix contribution of one branch is [[ys + h1, -ys], [-ys, ys + h2]] with ys = 1 / (r + j.x) (see lightsim2grid.elements.LineContainer.get_yac_eff_11() and friends for the coefficients actually used, including any tap-side / phase-shift correction for transformers).

Note

For a powerline, side 1 / side 2 used to be called or (origin) / ex (extremity) in older lightsim2grid versions; for a transformer they are hv (high voltage) / lv (low voltage) instead, since which physical side is tap-side matters there (see is_tap_side_1).

property yac_12

One entry of this branch’s raw two-port AC admittance matrix, computed as if both sides were connected (see yac_eff_11 for the version that accounts for the actual connection status).

With ys = 1 / (r_pu + 1j * x_pu), for a plain powerline (ratio == 1, shift_rad == 0): yac_11 = ys + h1, yac_22 = ys + h2, yac_12 = yac_21 = -ys – see the note in r_pu’s line model. For a transformer, the tap ratio and shift_rad additionally fold into all four entries.

The “line model” (also valid for transformers) is:

             i1                       ________             i2
 `bus 1` o------>   -----------------|r + j.x|---------<-------o `bus 2`
         |       ) (            |                  |           |
         |       ) (         |     |            |     |        |
         | v1    ) ( n:1      | h1  |            | h2  |        | v2
         |       ) (         |     |            |     |        |
         \/      ) (            |                  |           \/
ground---o-------   -------------------------------------------o---- ground

(fyi: i1, i2, n, h1 and h2 are all complex numbers. r and x are real numbers. j is a complex number such that j^2 = -1)

Note

h1 and h2 are independent per-side shunt admittances, NOT necessarily one half of a single total value each (they can differ, eg for an asymmetric line/transformer coming from pypowsybl): the admittance matrix contribution of one branch is [[ys + h1, -ys], [-ys, ys + h2]] with ys = 1 / (r + j.x) (see lightsim2grid.elements.LineContainer.get_yac_eff_11() and friends for the coefficients actually used, including any tap-side / phase-shift correction for transformers).

Note

For a powerline, side 1 / side 2 used to be called or (origin) / ex (extremity) in older lightsim2grid versions; for a transformer they are hv (high voltage) / lv (low voltage) instead, since which physical side is tap-side matters there (see is_tap_side_1).

property yac_21

One entry of this branch’s raw two-port AC admittance matrix, computed as if both sides were connected (see yac_eff_11 for the version that accounts for the actual connection status).

With ys = 1 / (r_pu + 1j * x_pu), for a plain powerline (ratio == 1, shift_rad == 0): yac_11 = ys + h1, yac_22 = ys + h2, yac_12 = yac_21 = -ys – see the note in r_pu’s line model. For a transformer, the tap ratio and shift_rad additionally fold into all four entries.

The “line model” (also valid for transformers) is:

             i1                       ________             i2
 `bus 1` o------>   -----------------|r + j.x|---------<-------o `bus 2`
         |       ) (            |                  |           |
         |       ) (         |     |            |     |        |
         | v1    ) ( n:1      | h1  |            | h2  |        | v2
         |       ) (         |     |            |     |        |
         \/      ) (            |                  |           \/
ground---o-------   -------------------------------------------o---- ground

(fyi: i1, i2, n, h1 and h2 are all complex numbers. r and x are real numbers. j is a complex number such that j^2 = -1)

Note

h1 and h2 are independent per-side shunt admittances, NOT necessarily one half of a single total value each (they can differ, eg for an asymmetric line/transformer coming from pypowsybl): the admittance matrix contribution of one branch is [[ys + h1, -ys], [-ys, ys + h2]] with ys = 1 / (r + j.x) (see lightsim2grid.elements.LineContainer.get_yac_eff_11() and friends for the coefficients actually used, including any tap-side / phase-shift correction for transformers).

Note

For a powerline, side 1 / side 2 used to be called or (origin) / ex (extremity) in older lightsim2grid versions; for a transformer they are hv (high voltage) / lv (low voltage) instead, since which physical side is tap-side matters there (see is_tap_side_1).

property yac_22

One entry of this branch’s raw two-port AC admittance matrix, computed as if both sides were connected (see yac_eff_11 for the version that accounts for the actual connection status).

With ys = 1 / (r_pu + 1j * x_pu), for a plain powerline (ratio == 1, shift_rad == 0): yac_11 = ys + h1, yac_22 = ys + h2, yac_12 = yac_21 = -ys – see the note in r_pu’s line model. For a transformer, the tap ratio and shift_rad additionally fold into all four entries.

The “line model” (also valid for transformers) is:

             i1                       ________             i2
 `bus 1` o------>   -----------------|r + j.x|---------<-------o `bus 2`
         |       ) (            |                  |           |
         |       ) (         |     |            |     |        |
         | v1    ) ( n:1      | h1  |            | h2  |        | v2
         |       ) (         |     |            |     |        |
         \/      ) (            |                  |           \/
ground---o-------   -------------------------------------------o---- ground

(fyi: i1, i2, n, h1 and h2 are all complex numbers. r and x are real numbers. j is a complex number such that j^2 = -1)

Note

h1 and h2 are independent per-side shunt admittances, NOT necessarily one half of a single total value each (they can differ, eg for an asymmetric line/transformer coming from pypowsybl): the admittance matrix contribution of one branch is [[ys + h1, -ys], [-ys, ys + h2]] with ys = 1 / (r + j.x) (see lightsim2grid.elements.LineContainer.get_yac_eff_11() and friends for the coefficients actually used, including any tap-side / phase-shift correction for transformers).

Note

For a powerline, side 1 / side 2 used to be called or (origin) / ex (extremity) in older lightsim2grid versions; for a transformer they are hv (high voltage) / lv (low voltage) instead, since which physical side is tap-side matters there (see is_tap_side_1).

property yac_eff_11

One entry of this branch’s effective two-port AC admittance matrix – yac_11 and friends, corrected for the actual connection status. This is exactly what is stamped into the grid’s Ybus.

  • Both sides connected: equal to yac_11 (etc) unchanged.

  • Exactly one side connected (a “half-open” branch): Kron-reduced to a single self-admittance at the connected end (the open end is eliminated); the three other entries are 0.

  • Neither side connected (or the branch itself disconnected): all four entries are 0.

The “line model” (also valid for transformers) is:

             i1                       ________             i2
 `bus 1` o------>   -----------------|r + j.x|---------<-------o `bus 2`
         |       ) (            |                  |           |
         |       ) (         |     |            |     |        |
         | v1    ) ( n:1      | h1  |            | h2  |        | v2
         |       ) (         |     |            |     |        |
         \/      ) (            |                  |           \/
ground---o-------   -------------------------------------------o---- ground

(fyi: i1, i2, n, h1 and h2 are all complex numbers. r and x are real numbers. j is a complex number such that j^2 = -1)

Note

h1 and h2 are independent per-side shunt admittances, NOT necessarily one half of a single total value each (they can differ, eg for an asymmetric line/transformer coming from pypowsybl): the admittance matrix contribution of one branch is [[ys + h1, -ys], [-ys, ys + h2]] with ys = 1 / (r + j.x) (see lightsim2grid.elements.LineContainer.get_yac_eff_11() and friends for the coefficients actually used, including any tap-side / phase-shift correction for transformers).

Note

For a powerline, side 1 / side 2 used to be called or (origin) / ex (extremity) in older lightsim2grid versions; for a transformer they are hv (high voltage) / lv (low voltage) instead, since which physical side is tap-side matters there (see is_tap_side_1).

property yac_eff_12

One entry of this branch’s effective two-port AC admittance matrix – yac_11 and friends, corrected for the actual connection status. This is exactly what is stamped into the grid’s Ybus.

  • Both sides connected: equal to yac_11 (etc) unchanged.

  • Exactly one side connected (a “half-open” branch): Kron-reduced to a single self-admittance at the connected end (the open end is eliminated); the three other entries are 0.

  • Neither side connected (or the branch itself disconnected): all four entries are 0.

The “line model” (also valid for transformers) is:

             i1                       ________             i2
 `bus 1` o------>   -----------------|r + j.x|---------<-------o `bus 2`
         |       ) (            |                  |           |
         |       ) (         |     |            |     |        |
         | v1    ) ( n:1      | h1  |            | h2  |        | v2
         |       ) (         |     |            |     |        |
         \/      ) (            |                  |           \/
ground---o-------   -------------------------------------------o---- ground

(fyi: i1, i2, n, h1 and h2 are all complex numbers. r and x are real numbers. j is a complex number such that j^2 = -1)

Note

h1 and h2 are independent per-side shunt admittances, NOT necessarily one half of a single total value each (they can differ, eg for an asymmetric line/transformer coming from pypowsybl): the admittance matrix contribution of one branch is [[ys + h1, -ys], [-ys, ys + h2]] with ys = 1 / (r + j.x) (see lightsim2grid.elements.LineContainer.get_yac_eff_11() and friends for the coefficients actually used, including any tap-side / phase-shift correction for transformers).

Note

For a powerline, side 1 / side 2 used to be called or (origin) / ex (extremity) in older lightsim2grid versions; for a transformer they are hv (high voltage) / lv (low voltage) instead, since which physical side is tap-side matters there (see is_tap_side_1).

property yac_eff_21

One entry of this branch’s effective two-port AC admittance matrix – yac_11 and friends, corrected for the actual connection status. This is exactly what is stamped into the grid’s Ybus.

  • Both sides connected: equal to yac_11 (etc) unchanged.

  • Exactly one side connected (a “half-open” branch): Kron-reduced to a single self-admittance at the connected end (the open end is eliminated); the three other entries are 0.

  • Neither side connected (or the branch itself disconnected): all four entries are 0.

The “line model” (also valid for transformers) is:

             i1                       ________             i2
 `bus 1` o------>   -----------------|r + j.x|---------<-------o `bus 2`
         |       ) (            |                  |           |
         |       ) (         |     |            |     |        |
         | v1    ) ( n:1      | h1  |            | h2  |        | v2
         |       ) (         |     |            |     |        |
         \/      ) (            |                  |           \/
ground---o-------   -------------------------------------------o---- ground

(fyi: i1, i2, n, h1 and h2 are all complex numbers. r and x are real numbers. j is a complex number such that j^2 = -1)

Note

h1 and h2 are independent per-side shunt admittances, NOT necessarily one half of a single total value each (they can differ, eg for an asymmetric line/transformer coming from pypowsybl): the admittance matrix contribution of one branch is [[ys + h1, -ys], [-ys, ys + h2]] with ys = 1 / (r + j.x) (see lightsim2grid.elements.LineContainer.get_yac_eff_11() and friends for the coefficients actually used, including any tap-side / phase-shift correction for transformers).

Note

For a powerline, side 1 / side 2 used to be called or (origin) / ex (extremity) in older lightsim2grid versions; for a transformer they are hv (high voltage) / lv (low voltage) instead, since which physical side is tap-side matters there (see is_tap_side_1).

property yac_eff_22

One entry of this branch’s effective two-port AC admittance matrix – yac_11 and friends, corrected for the actual connection status. This is exactly what is stamped into the grid’s Ybus.

  • Both sides connected: equal to yac_11 (etc) unchanged.

  • Exactly one side connected (a “half-open” branch): Kron-reduced to a single self-admittance at the connected end (the open end is eliminated); the three other entries are 0.

  • Neither side connected (or the branch itself disconnected): all four entries are 0.

The “line model” (also valid for transformers) is:

             i1                       ________             i2
 `bus 1` o------>   -----------------|r + j.x|---------<-------o `bus 2`
         |       ) (            |                  |           |
         |       ) (         |     |            |     |        |
         | v1    ) ( n:1      | h1  |            | h2  |        | v2
         |       ) (         |     |            |     |        |
         \/      ) (            |                  |           \/
ground---o-------   -------------------------------------------o---- ground

(fyi: i1, i2, n, h1 and h2 are all complex numbers. r and x are real numbers. j is a complex number such that j^2 = -1)

Note

h1 and h2 are independent per-side shunt admittances, NOT necessarily one half of a single total value each (they can differ, eg for an asymmetric line/transformer coming from pypowsybl): the admittance matrix contribution of one branch is [[ys + h1, -ys], [-ys, ys + h2]] with ys = 1 / (r + j.x) (see lightsim2grid.elements.LineContainer.get_yac_eff_11() and friends for the coefficients actually used, including any tap-side / phase-shift correction for transformers).

Note

For a powerline, side 1 / side 2 used to be called or (origin) / ex (extremity) in older lightsim2grid versions; for a transformer they are hv (high voltage) / lv (low voltage) instead, since which physical side is tap-side matters there (see is_tap_side_1).

property ydc_11

One entry of this branch’s two-port DC admittance matrix – the DC powerflow linearization only keeps the series susceptance (1 / x_pu), so ydc_11 = ydc_22 = 1 / x_pu and ydc_12 = ydc_21 = -1 / x_pu for a plain powerline (a transformer’s tap ratio additionally divides it in). Real numbers, unlike the AC yac_11 family.

Note

Unlike yac_eff_11, there is no status-aware “effective” counterpart exposed for the DC admittance: a disconnected side is instead handled directly by the DC solver / Ybus construction.

The “line model” (also valid for transformers) is:

             i1                       ________             i2
 `bus 1` o------>   -----------------|r + j.x|---------<-------o `bus 2`
         |       ) (            |                  |           |
         |       ) (         |     |            |     |        |
         | v1    ) ( n:1      | h1  |            | h2  |        | v2
         |       ) (         |     |            |     |        |
         \/      ) (            |                  |           \/
ground---o-------   -------------------------------------------o---- ground

(fyi: i1, i2, n, h1 and h2 are all complex numbers. r and x are real numbers. j is a complex number such that j^2 = -1)

Note

h1 and h2 are independent per-side shunt admittances, NOT necessarily one half of a single total value each (they can differ, eg for an asymmetric line/transformer coming from pypowsybl): the admittance matrix contribution of one branch is [[ys + h1, -ys], [-ys, ys + h2]] with ys = 1 / (r + j.x) (see lightsim2grid.elements.LineContainer.get_yac_eff_11() and friends for the coefficients actually used, including any tap-side / phase-shift correction for transformers).

Note

For a powerline, side 1 / side 2 used to be called or (origin) / ex (extremity) in older lightsim2grid versions; for a transformer they are hv (high voltage) / lv (low voltage) instead, since which physical side is tap-side matters there (see is_tap_side_1).

property ydc_12

One entry of this branch’s two-port DC admittance matrix – the DC powerflow linearization only keeps the series susceptance (1 / x_pu), so ydc_11 = ydc_22 = 1 / x_pu and ydc_12 = ydc_21 = -1 / x_pu for a plain powerline (a transformer’s tap ratio additionally divides it in). Real numbers, unlike the AC yac_11 family.

Note

Unlike yac_eff_11, there is no status-aware “effective” counterpart exposed for the DC admittance: a disconnected side is instead handled directly by the DC solver / Ybus construction.

The “line model” (also valid for transformers) is:

             i1                       ________             i2
 `bus 1` o------>   -----------------|r + j.x|---------<-------o `bus 2`
         |       ) (            |                  |           |
         |       ) (         |     |            |     |        |
         | v1    ) ( n:1      | h1  |            | h2  |        | v2
         |       ) (         |     |            |     |        |
         \/      ) (            |                  |           \/
ground---o-------   -------------------------------------------o---- ground

(fyi: i1, i2, n, h1 and h2 are all complex numbers. r and x are real numbers. j is a complex number such that j^2 = -1)

Note

h1 and h2 are independent per-side shunt admittances, NOT necessarily one half of a single total value each (they can differ, eg for an asymmetric line/transformer coming from pypowsybl): the admittance matrix contribution of one branch is [[ys + h1, -ys], [-ys, ys + h2]] with ys = 1 / (r + j.x) (see lightsim2grid.elements.LineContainer.get_yac_eff_11() and friends for the coefficients actually used, including any tap-side / phase-shift correction for transformers).

Note

For a powerline, side 1 / side 2 used to be called or (origin) / ex (extremity) in older lightsim2grid versions; for a transformer they are hv (high voltage) / lv (low voltage) instead, since which physical side is tap-side matters there (see is_tap_side_1).

property ydc_21

One entry of this branch’s two-port DC admittance matrix – the DC powerflow linearization only keeps the series susceptance (1 / x_pu), so ydc_11 = ydc_22 = 1 / x_pu and ydc_12 = ydc_21 = -1 / x_pu for a plain powerline (a transformer’s tap ratio additionally divides it in). Real numbers, unlike the AC yac_11 family.

Note

Unlike yac_eff_11, there is no status-aware “effective” counterpart exposed for the DC admittance: a disconnected side is instead handled directly by the DC solver / Ybus construction.

The “line model” (also valid for transformers) is:

             i1                       ________             i2
 `bus 1` o------>   -----------------|r + j.x|---------<-------o `bus 2`
         |       ) (            |                  |           |
         |       ) (         |     |            |     |        |
         | v1    ) ( n:1      | h1  |            | h2  |        | v2
         |       ) (         |     |            |     |        |
         \/      ) (            |                  |           \/
ground---o-------   -------------------------------------------o---- ground

(fyi: i1, i2, n, h1 and h2 are all complex numbers. r and x are real numbers. j is a complex number such that j^2 = -1)

Note

h1 and h2 are independent per-side shunt admittances, NOT necessarily one half of a single total value each (they can differ, eg for an asymmetric line/transformer coming from pypowsybl): the admittance matrix contribution of one branch is [[ys + h1, -ys], [-ys, ys + h2]] with ys = 1 / (r + j.x) (see lightsim2grid.elements.LineContainer.get_yac_eff_11() and friends for the coefficients actually used, including any tap-side / phase-shift correction for transformers).

Note

For a powerline, side 1 / side 2 used to be called or (origin) / ex (extremity) in older lightsim2grid versions; for a transformer they are hv (high voltage) / lv (low voltage) instead, since which physical side is tap-side matters there (see is_tap_side_1).

property ydc_22

One entry of this branch’s two-port DC admittance matrix – the DC powerflow linearization only keeps the series susceptance (1 / x_pu), so ydc_11 = ydc_22 = 1 / x_pu and ydc_12 = ydc_21 = -1 / x_pu for a plain powerline (a transformer’s tap ratio additionally divides it in). Real numbers, unlike the AC yac_11 family.

Note

Unlike yac_eff_11, there is no status-aware “effective” counterpart exposed for the DC admittance: a disconnected side is instead handled directly by the DC solver / Ybus construction.

The “line model” (also valid for transformers) is:

             i1                       ________             i2
 `bus 1` o------>   -----------------|r + j.x|---------<-------o `bus 2`
         |       ) (            |                  |           |
         |       ) (         |     |            |     |        |
         | v1    ) ( n:1      | h1  |            | h2  |        | v2
         |       ) (         |     |            |     |        |
         \/      ) (            |                  |           \/
ground---o-------   -------------------------------------------o---- ground

(fyi: i1, i2, n, h1 and h2 are all complex numbers. r and x are real numbers. j is a complex number such that j^2 = -1)

Note

h1 and h2 are independent per-side shunt admittances, NOT necessarily one half of a single total value each (they can differ, eg for an asymmetric line/transformer coming from pypowsybl): the admittance matrix contribution of one branch is [[ys + h1, -ys], [-ys, ys + h2]] with ys = 1 / (r + j.x) (see lightsim2grid.elements.LineContainer.get_yac_eff_11() and friends for the coefficients actually used, including any tap-side / phase-shift correction for transformers).

Note

For a powerline, side 1 / side 2 used to be called or (origin) / ex (extremity) in older lightsim2grid versions; for a transformer they are hv (high voltage) / lv (low voltage) instead, since which physical side is tap-side matters there (see is_tap_side_1).

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.

class lightsim2grid.elements.HvdcLineContainer

This class allows to iterate through the hvdc lines of the lightsim2grid.network.LSGrid easily, as if they were in a python list. (Kept under the historical name DCLineContainer / get_dclines() for backward compatibility; the legacy pandapower dc line is now just a special case of the model below.)

The model follows powsybl IIDM / open-loadflow: the hvdc line itself owns the active power (p_setpoint_mw, drawn at the rectifier, and converters_mode, saying which side rectifies), while its two embedded converter stations (station1 / station2, one on each side of the line, see lightsim2grid.elements.ConverterStationInfo) own the reactive power / voltage behaviour and can be controlled independently for their voltage setpoint. See lightsim2grid.elements.HvdcLineInfo for the loss model turning the setpoint at the rectifier side into the active power actually injected at the other side, and for the angle-droop (“AC emulation”) alternative to a fixed setpoint.

Examples

import grid2op
from lightsim2grid import LightSimBackend

# create a lightsim2grid "gridmodel"
env_name = ... # eg. "l2rpn_case14_test"
env = grid2op.make(env_name, backend=LightSimBackend())
grid_model = env.backend._grid

# manipulate the hvdc lines (usually there are none...)
for hvdc_line in grid_model.get_dclines():
    # do something with the line !
    hvdc_line.bus1_id

print(f"There are {len(grid_model.get_dclines())} hvdc lines on the grid.")

You can have a look at lightsim2grid.elements.HvdcLineInfo for properties of these elements.

Classes:

ConvertersMode

Which side of an hvdc line is the rectifier (the other being the inverter)

Methods:

get_bus_id_side_1(self)

bus_1_id for every element of this container, as a single array: element i of the result is that element's side-1 bus id, -1 if disconnected on that side.

get_bus_id_side_2(self)

bus_2_id for every element of this container, as a single array: element i of the result is that element's side-2 bus id, -1 if disconnected on that side.

load_binary(path)

Load an object previously saved with save_binary().

save_binary(self, path[, atomic])

Save this object's state to a fast custom binary file (additive alternative to pickle).

class ConvertersMode

Which side of an hvdc line is the rectifier (the other being the inverter)

Members:

SIDE_1_RECTIFIER

SIDE_2_RECTIFIER

Attributes:

name

property name
get_bus_id_side_1(self: lightsim2grid.lightsim2grid_cpp.HvdcLineContainer) Annotated[numpy.typing.NDArray[numpy.int32], '[m, 1]']

bus_1_id for every element of this container, as a single array: element i of the result is that element’s side-1 bus id, -1 if disconnected on that side.

get_bus_id_side_2(self: lightsim2grid.lightsim2grid_cpp.HvdcLineContainer) Annotated[numpy.typing.NDArray[numpy.int32], '[m, 1]']

bus_2_id for every element of this container, as a single array: element i of the result is that element’s side-2 bus id, -1 if disconnected on that side.

staticmethod load_binary(path: str) lightsim2grid.lightsim2grid_cpp.HvdcLineContainer

Load an object previously saved with save_binary(). Raises RuntimeError on an incompatible binary format, a wrong object type, or a corrupted / truncated file (including corrupted internal sizes: no attempt is made to allocate more data than the file actually contains). Loading a whole grid additionally validates its consistency (see check_grid): a byte-wise well-formed but inconsistent grid raises IndexError (out-of-range index) or RuntimeError (structural inconsistency).

save_binary(self: lightsim2grid.lightsim2grid_cpp.HvdcLineContainer, path: str, atomic: bool = True) None

Save this object’s state to a fast custom binary file (additive alternative to pickle). By default (atomic=True) the write is atomic: an existing file at that path is only replaced once the new content has been written completely (an interrupted save never destroys a previous file). Pass atomic=False to write the destination directly instead – marginally faster (skips one temporary file + rename), without that protection. The file stays readable by any lightsim2grid version sharing the same binary format number.

class lightsim2grid.elements.HvdcLineInfo

This class represents what you get from retrieving the hvdc lines from lightsim2grid.elements.HvdcLineContainer.

It allows to read information from each hvdc line of the powergrid.

Hvdc lines have two sides, “1” and “2”, each with its own converter station (station1 / station2, see lightsim2grid.elements.ConverterStationInfo) – the equivalent of the “origin” / “extremity” naming used in older lightsim2grid versions for AC powerlines and transformers.

For accessing the results, it’s basically the same as having two “elements” (so you get two “voltage magnitude” res_v1_kv / res_v2_kv, two “injected power” res_p1_mw / res_p2_mw, etc.)

Warning

Data can only be read from this element. You cannot modify (yet) the grid using this class.

Examples

import grid2op
from lightsim2grid import LightSimBackend

# create a lightsim2grid "gridmodel"
env_name = ... # eg. "l2rpn_case14_test"
env = grid2op.make(env_name, backend=LightSimBackend())
grid_model = env.backend._grid

# for hvdc lines
first_hvdc_line = grid_model.get_dclines()[0]  # first hvdc line, this is an `HvdcLineInfo`
for hvdc_line in grid_model.get_dclines():
    # hvdc_line is an `HvdcLineInfo`
    hvdc_line.bus1_id

Notes

See lightsim2grid.elements.HvdcLineInfo.target_p1_mw() for the active-power loss model turning the setpoint given at the rectifier side into the active power actually injected at the other side, and droop_enabled / droop_p0_mw / droop_k_mw_per_rad for the angle-droop (“AC emulation”) alternative, where the active power follows the angle difference between the two sides instead of a fixed setpoint.

Attributes:

bus1_id

Get the bus id (as an integer) at which converter station 1 of the HVDC line is connected.

bus2_id

Get the bus id (as an integer) at which converter station 2 of the HVDC line is connected.

connected1

Get the status of converter station 1 of this HVDC line alone, see connected_global.

connected2

Get the status of converter station 2 of this HVDC line alone, see connected_global.

connected_global

Get the global status (True as soon as either converter station is connected) of this HVDC line.

converters_mode

Which side of the HVDC line rectifies -- 0 means side 1 is the rectifier (side 2 the inverter), 1 means side 2 is the rectifier (side 1 the inverter).

droop_enabled

Whether angle-droop control ("AC emulation", IIDM HvdcAngleDroopActivePowerControl) is enabled for this HVDC line.

droop_k_mw_per_rad

Angle-droop slope k (MW per radian of angle difference between the two sides).

droop_p0_mw

the active power flow (side 1 to side 2) when the two sides' voltage angles are equal.

has_res

This property specify whether or not a given element contains some "result" information.

id

Get the id of the element.

loss_mw

The loss_mw (flat loss, in MW) parameter of the hvdc line, used in the active-power loss model below.

loss_pct

The loss_pct (relative loss, in percent) parameter of the hvdc line, used in the active-power loss model below.

name

Get the name of the element.

nominal_v_kv

DC nominal voltage (kV) of the line, used together with r_ohm in the resistive loss term described in lightsim2grid.elements.HvdcLineInfo.

p2_mw

The active power target (in MW) of the converter station on side 2 of the hvdc line, generator sign convention (positive = power injected into the AC grid at side 2).

p_setpoint_mw

which physical side that is depends on converters_mode.

pmax_1to2_mw

Maximum active power (MW) the angle-droop equation is allowed to deliver from side 1 to side 2 before saturating -- see droop_enabled and status_droop.

pmax_2to1_mw

Maximum active power (MW) the angle-droop equation is allowed to deliver from side 2 to side 1 before saturating -- see droop_enabled and status_droop.

pos1_topo_vect

Get the position of converter station 1 of this HVDC line in the grid2op "topo_vect" vector (-1 if never set).

pos2_topo_vect

Get the position of converter station 2 of this HVDC line in the grid2op "topo_vect" vector (-1 if never set), see pos1_topo_vect.

r_ohm

DC line resistance (Ohm), used in the resistive loss term of the loss model described in lightsim2grid.elements.HvdcLineInfo.

res_p1_mw

The active power actually injected at side 1 of the hvdc line (in MW, generator convention).

res_p2_mw

The active power actually injected at side 2 of the hvdc line (in MW, generator convention).

res_q1_mvar

The reactive power actually injected at side 1 of the hvdc line (in MVAr, generator convention).

res_q2_mvar

The reactive power actually injected at side 2 of the hvdc line (in MVAr, generator convention).

res_theta1_deg

Get the angle of the complex voltage (in degree, not in radian) of the bus at which side 1 of the hvdc line is connected.

res_theta2_deg

Get the angle of the complex voltage (in degree, not in radian) of the bus at which side 2 of the hvdc line is connected.

res_v1_kv

Get the magnitude of the complex voltage (in kV) of the bus at which side 1 of the hvdc line is connected.

res_v2_kv

Get the magnitude of the complex voltage (in kV) of the bus at which side 2 of the hvdc line is connected.

station1

The converter station on side 1 of this HVDC line, as a lightsim2grid.elements.ConverterStationInfo.

station2

The converter station on side 2 of this HVDC line, as a lightsim2grid.elements.ConverterStationInfo.

status_droop

The angle-droop regime currently in effect -- 0 means the raw droop equation applies unsaturated (linear), +1 means it is saturated at pmax_1to2_mw (flow forced from side 1 to side 2), -1 means it is saturated at pmax_2to1_mw (flow forced from side 2 to side 1).

sub1_id

Get the substation id of converter station 1 of this HVDC line (-1 if never set; called "voltage level" in pypowsybl).

sub2_id

Get the substation id of converter station 2 of this HVDC line (-1 if never set; called "voltage level" in pypowsybl), see sub1_id.

target_p1_mw

The active power target (in MW) of the converter station on side 1 of the hvdc line, generator sign convention (positive = power injected into the AC grid at side 1).

target_vm1_pu

The target voltage setpoint (in pu, NOT in kV) of the converter station on side 1 of the hvdc line.

target_vm2_pu

The target voltage setpoint (in pu, NOT in kV) of the converter station on side 2 of the hvdc line.

voltage_level1_id

Get the substation id of converter station 1 of this HVDC line (-1 if never set; called "voltage level" in pypowsybl).

voltage_level2_id

Get the substation id of converter station 2 of this HVDC line (-1 if never set; called "voltage level" in pypowsybl), see sub1_id.

property bus1_id

Get the bus id (as an integer) at which converter station 1 of the HVDC line is connected. If -1 is returned it means that side is disconnected.

(This is the gridmodel / global bus id, not the solver bus id – see lightsim2grid.network.LSGrid.id_me_to_ac_solver() to convert.)

Read-only here; equivalent to lightsim2grid.network.LSGrid.get_bus1_dcline(). To move this converter station to another bus, call lightsim2grid.network.LSGrid.change_bus1_dcline().

property bus2_id

Get the bus id (as an integer) at which converter station 2 of the HVDC line is connected. If -1 is returned it means that side is disconnected.

(This is the gridmodel / global bus id, not the solver bus id – see lightsim2grid.network.LSGrid.id_me_to_ac_solver() to convert.)

Read-only here; equivalent to lightsim2grid.network.LSGrid.get_bus2_dcline(). To move this converter station to another bus, call lightsim2grid.network.LSGrid.change_bus2_dcline().

property connected1

Get the status of converter station 1 of this HVDC line alone, see connected_global.

Read-only here. To disconnect only this station, call lightsim2grid.network.LSGrid.deactivate_dcline_side1() (there is no per-station reconnect: lightsim2grid.network.LSGrid.reactivate_dcline() reconnects both stations at once).

property connected2

Get the status of converter station 2 of this HVDC line alone, see connected_global.

Read-only here. To disconnect only this station, call lightsim2grid.network.LSGrid.deactivate_dcline_side2() (there is no per-station reconnect: lightsim2grid.network.LSGrid.reactivate_dcline() reconnects both stations at once).

property connected_global

Get the global status (True as soon as either converter station is connected) of this HVDC line.

Read-only here. To disconnect / reconnect both stations at once, call lightsim2grid.network.LSGrid.deactivate_dcline() / lightsim2grid.network.LSGrid.reactivate_dcline(); see connected1 / connected2 and their own setters to act on a single station (“half-open”).

property converters_mode

Which side of the HVDC line rectifies – 0 means side 1 is the rectifier (side 2 the inverter), 1 means side 2 is the rectifier (side 1 the inverter).

Active power flows from the rectifier side to the inverter side, minus losses – see p_setpoint_mw and the loss model described in lightsim2grid.elements.HvdcLineInfo.

property droop_enabled

Whether angle-droop control (“AC emulation”, IIDM HvdcAngleDroopActivePowerControl) is enabled for this HVDC line.

When True, the active power is not fixed at p_setpoint_mw but instead follows the angle difference between the two sides:

raw_mw = droop_p0_mw + droop_k_mw_per_rad * (theta_1 - theta_2)

saturated at pmax_1to2_mw / pmax_2to1_mw – see status_droop for the regime currently in effect.

Note

Angle-droop cannot run once either converter station is individually disconnected while the line stays otherwise connected (the remote angle is no longer available): it then falls back to the fixed p_setpoint_mw for that line, regardless of this flag.

property droop_k_mw_per_rad

Angle-droop slope k (MW per radian of angle difference between the two sides).

Only meaningful when droop_enabled is True – see droop_enabled for the full equation.

property droop_p0_mw

the active power flow (side 1 to side 2) when the two sides’ voltage angles are equal.

Only meaningful when droop_enabled is True – see droop_enabled for the full equation.

Type:

Angle-droop set point p0 (MW)

property has_res

This property specify whether or not a given element contains some “result” information. If set to True then the fields starting with res_ (eg res_p_mw) are filled otherwise they are initialized with an arbitrary (and meaningless) value.

property id

Get the id of the element. Ids are integer from 0 to n-1 (if n denotes the number of such elements on the grid.)

Examples

We give the example only for generators, but it works similarly for every other types of objects in a lightsim2grid.network.LSGrid.

This gives something like:

import grid2op
from lightsim2grid import LightSimBackend

env_name = ... # eg. "l2rpn_case14_test"
env = grid2op.make(env_name, backend=LightSimBackend())

grid_model = env.backend._grid

first_gen = grid_model.get_generators()[0]  # or get_loads for loads, etc.
first_gen.id  # should be 0
property loss_mw

The loss_mw (flat loss, in MW) parameter of the hvdc line, used in the active-power loss model below.

Note

The active power actually injected at one side of an hvdc line is derived from the active power setpoint at the rectifier side through a loss model (mirrors open-loadflow’s HvdcUtils.getConverterStationTargetP, extended with the legacy pandapower fixed-loss term):

line_in   = (1 - lf_rect) * (1 - loss_pct / 100) * p_setpoint_mw
line_loss = r_ohm * line_in^2 / nominal_v_kv^2        (0 when nominal_v_kv == 0)
received  = (1 - lf_inv) * (line_in - line_loss) - loss_mw

where p_setpoint_mw (>= 0) is drawn at the rectifier side (converters_mode says which side that is), lf_rect / lf_inv are the rectifier / inverter converter stations’ own loss factors, and received is the target active power (generator convention) at the non-rectifier side. The legacy pandapower dc line maps onto this exactly with station loss factors = 0 and r_ohm = 0.

Note

Both target_p1_mw and target_p2_mw use the generator sign convention: a positive value means power is injected into the AC grid at that side (so a positive target_p1_mw means power flows from side 2 to side 1 through the line).

Note

In angle-droop mode (droop_enabled is True), none of the above applies: the active power instead follows p0 + k * (theta1 - theta2); see droop_p0_mw / droop_k_mw_per_rad / status_droop.

property loss_pct

The loss_pct (relative loss, in percent) parameter of the hvdc line, used in the active-power loss model below.

Note

The active power actually injected at one side of an hvdc line is derived from the active power setpoint at the rectifier side through a loss model (mirrors open-loadflow’s HvdcUtils.getConverterStationTargetP, extended with the legacy pandapower fixed-loss term):

line_in   = (1 - lf_rect) * (1 - loss_pct / 100) * p_setpoint_mw
line_loss = r_ohm * line_in^2 / nominal_v_kv^2        (0 when nominal_v_kv == 0)
received  = (1 - lf_inv) * (line_in - line_loss) - loss_mw

where p_setpoint_mw (>= 0) is drawn at the rectifier side (converters_mode says which side that is), lf_rect / lf_inv are the rectifier / inverter converter stations’ own loss factors, and received is the target active power (generator convention) at the non-rectifier side. The legacy pandapower dc line maps onto this exactly with station loss factors = 0 and r_ohm = 0.

Note

Both target_p1_mw and target_p2_mw use the generator sign convention: a positive value means power is injected into the AC grid at that side (so a positive target_p1_mw means power flows from side 2 to side 1 through the line).

Note

In angle-droop mode (droop_enabled is True), none of the above applies: the active power instead follows p0 + k * (theta1 - theta2); see droop_p0_mw / droop_k_mw_per_rad / status_droop.

property name

Get the name of the element. Names are string that should be unique. But if you really want things unique, use the id

Warning

Names are optional and might not be set when reading the grid.

Examples

We give the example only for generators, but it works similarly for every other types of objects in a lightsim2grid.network.LSGrid.

This gives something like:

import grid2op
from lightsim2grid import LightSimBackend

env_name = ... # eg. "l2rpn_case14_test"
env = grid2op.make(env_name, backend=LightSimBackend())

grid_model = env.backend._grid

first_gen = grid_model.get_generators()[0]  # or get_loads for loads, etc.
first_gen.name
property nominal_v_kv

DC nominal voltage (kV) of the line, used together with r_ohm in the resistive loss term described in lightsim2grid.elements.HvdcLineInfo.

The resistive loss term is 0. when this is 0. (e.g. the legacy pandapower-shaped hvdc lines, which do not model DC resistive losses).

property p2_mw

The active power target (in MW) of the converter station on side 2 of the hvdc line, generator sign convention (positive = power injected into the AC grid at side 2). See target_p1_mw for the side-1 counterpart and the loss model turning one into the other.

property p_setpoint_mw

which physical side that is depends on converters_mode.

The power actually delivered at the other (inverter) side is this value minus the resistive (r_ohm) and converter (loss_factor) losses – see the loss model described in lightsim2grid.elements.HvdcLineInfo.

Note

When droop_enabled is True, this setpoint is not used: the active power instead follows the angle-droop equation, see droop_enabled.

Read-only here. To change it, call lightsim2grid.network.LSGrid.change_p_dcline() (target_p1_mw / p2_mw are then derived from it, not settable directly).

Type:

Active power drawn at the rectifier side of the HVDC line (MW, always >= 0)

property pmax_1to2_mw

Maximum active power (MW) the angle-droop equation is allowed to deliver from side 1 to side 2 before saturating – see droop_enabled and status_droop.

Only meaningful when droop_enabled is True.

property pmax_2to1_mw

Maximum active power (MW) the angle-droop equation is allowed to deliver from side 2 to side 1 before saturating – see droop_enabled and status_droop.

Only meaningful when droop_enabled is True.

property pos1_topo_vect

Get the position of converter station 1 of this HVDC line in the grid2op “topo_vect” vector (-1 if never set).

HVDC lines have no dedicated LSGrid position setter – unlike AC lines and transformers, they are not part of grid2op’s topology vector.

property pos2_topo_vect

Get the position of converter station 2 of this HVDC line in the grid2op “topo_vect” vector (-1 if never set), see pos1_topo_vect.

property r_ohm

DC line resistance (Ohm), used in the resistive loss term of the loss model described in lightsim2grid.elements.HvdcLineInfo.

0. for lines that do not model a resistive loss (e.g. the legacy pandapower-shaped hvdc lines).

property res_p1_mw

The active power actually injected at side 1 of the hvdc line (in MW, generator convention).

Warning

This feature is only relevant if the results have been computed (for example if a powerflow has successfully run)

Note

The active power actually injected at one side of an hvdc line is derived from the active power setpoint at the rectifier side through a loss model (mirrors open-loadflow’s HvdcUtils.getConverterStationTargetP, extended with the legacy pandapower fixed-loss term):

line_in   = (1 - lf_rect) * (1 - loss_pct / 100) * p_setpoint_mw
line_loss = r_ohm * line_in^2 / nominal_v_kv^2        (0 when nominal_v_kv == 0)
received  = (1 - lf_inv) * (line_in - line_loss) - loss_mw

where p_setpoint_mw (>= 0) is drawn at the rectifier side (converters_mode says which side that is), lf_rect / lf_inv are the rectifier / inverter converter stations’ own loss factors, and received is the target active power (generator convention) at the non-rectifier side. The legacy pandapower dc line maps onto this exactly with station loss factors = 0 and r_ohm = 0.

Note

Both target_p1_mw and target_p2_mw use the generator sign convention: a positive value means power is injected into the AC grid at that side (so a positive target_p1_mw means power flows from side 2 to side 1 through the line).

Note

In angle-droop mode (droop_enabled is True), none of the above applies: the active power instead follows p0 + k * (theta1 - theta2); see droop_p0_mw / droop_k_mw_per_rad / status_droop.

property res_p2_mw

The active power actually injected at side 2 of the hvdc line (in MW, generator convention).

Warning

This feature is only relevant if the results have been computed (for example if a powerflow has successfully run)

Note

The active power actually injected at one side of an hvdc line is derived from the active power setpoint at the rectifier side through a loss model (mirrors open-loadflow’s HvdcUtils.getConverterStationTargetP, extended with the legacy pandapower fixed-loss term):

line_in   = (1 - lf_rect) * (1 - loss_pct / 100) * p_setpoint_mw
line_loss = r_ohm * line_in^2 / nominal_v_kv^2        (0 when nominal_v_kv == 0)
received  = (1 - lf_inv) * (line_in - line_loss) - loss_mw

where p_setpoint_mw (>= 0) is drawn at the rectifier side (converters_mode says which side that is), lf_rect / lf_inv are the rectifier / inverter converter stations’ own loss factors, and received is the target active power (generator convention) at the non-rectifier side. The legacy pandapower dc line maps onto this exactly with station loss factors = 0 and r_ohm = 0.

Note

Both target_p1_mw and target_p2_mw use the generator sign convention: a positive value means power is injected into the AC grid at that side (so a positive target_p1_mw means power flows from side 2 to side 1 through the line).

Note

In angle-droop mode (droop_enabled is True), none of the above applies: the active power instead follows p0 + k * (theta1 - theta2); see droop_p0_mw / droop_k_mw_per_rad / status_droop.

property res_q1_mvar

The reactive power actually injected at side 1 of the hvdc line (in MVAr, generator convention).

Warning

This feature is only relevant if the results have been computed (for example if a powerflow has successfully run)

property res_q2_mvar

The reactive power actually injected at side 2 of the hvdc line (in MVAr, generator convention).

Warning

This feature is only relevant if the results have been computed (for example if a powerflow has successfully run)

property res_theta1_deg

Get the angle of the complex voltage (in degree, not in radian) of the bus at which side 1 of the hvdc line is connected.

Note

All elements (load, generators, side of powerline etc.) connected at the same bus have the same “res_theta_deg”

Warning

This feature is only relevant if the results have been computed (for example if a powerflow has successfully run)

property res_theta2_deg

Get the angle of the complex voltage (in degree, not in radian) of the bus at which side 2 of the hvdc line is connected.

Note

All elements (load, generators, side of powerline etc.) connected at the same bus have the same “res_theta_deg”

Warning

This feature is only relevant if the results have been computed (for example if a powerflow has successfully run)

property res_v1_kv

Get the magnitude of the complex voltage (in kV) of the bus at which side 1 of the hvdc line is connected.

Note

All elements (load, generators, side of powerline etc.) connected at the same bus have the same “res_v_kv”

Warning

This feature is only relevant if the results have been computed (for example if a powerflow has successfully run)

property res_v2_kv

Get the magnitude of the complex voltage (in kV) of the bus at which side 2 of the hvdc line is connected.

Note

All elements (load, generators, side of powerline etc.) connected at the same bus have the same “res_v_kv”

Warning

This feature is only relevant if the results have been computed (for example if a powerflow has successfully run)

property station1

The converter station on side 1 of this HVDC line, as a lightsim2grid.elements.ConverterStationInfo.

property station2

The converter station on side 2 of this HVDC line, as a lightsim2grid.elements.ConverterStationInfo.

property status_droop

The angle-droop regime currently in effect – 0 means the raw droop equation applies unsaturated (linear), +1 means it is saturated at pmax_1to2_mw (flow forced from side 1 to side 2), -1 means it is saturated at pmax_2to1_mw (flow forced from side 2 to side 1).

Note

This is an INPUT to the powerflow, not something it decides on its own: switching regime changes which equation is stamped in the jacobian, so which regime applies is decided by an outer loop (typically in Python, between two solves), not by this solve itself. Use lightsim2grid.network.LSGrid.set_status_droop_hvdc() / lightsim2grid.network.LSGrid.get_status_droop_hvdc() to set / read it at the grid level.

Only meaningful when droop_enabled is True.

property sub1_id

Get the substation id of converter station 1 of this HVDC line (-1 if never set; called “voltage level” in pypowsybl).

HVDC lines have no dedicated LSGrid substation-id setter.

property sub2_id

Get the substation id of converter station 2 of this HVDC line (-1 if never set; called “voltage level” in pypowsybl), see sub1_id.

property target_p1_mw

The active power target (in MW) of the converter station on side 1 of the hvdc line, generator sign convention (positive = power injected into the AC grid at side 1).

For a line NOT in angle-droop mode, this is derived from p_setpoint_mw / converters_mode through the loss model described in lightsim2grid.elements.HvdcLineInfo – it is the target for the AC powerflow, not necessarily equal to p_setpoint_mw itself (which is always >= 0 and lives at the rectifier side, whichever side that is). See target_p2_mw for the side-2 counterpart.

Note

In angle-droop mode (droop_enabled is True), the active power actually used by the solver instead follows p0 + k * (theta1 - theta2) and is NOT read from this field; see droop_p0_mw / droop_k_mw_per_rad.

property target_vm1_pu

The target voltage setpoint (in pu, NOT in kV) of the converter station on side 1 of the hvdc line.

Read-only here. To change it, call lightsim2grid.network.LSGrid.change_v1_dcline().

property target_vm2_pu

The target voltage setpoint (in pu, NOT in kV) of the converter station on side 2 of the hvdc line.

Read-only here. To change it, call lightsim2grid.network.LSGrid.change_v2_dcline().

property voltage_level1_id

Get the substation id of converter station 1 of this HVDC line (-1 if never set; called “voltage level” in pypowsybl).

HVDC lines have no dedicated LSGrid substation-id setter.

property voltage_level2_id

Get the substation id of converter station 2 of this HVDC line (-1 if never set; called “voltage level” in pypowsybl), see sub1_id.

class lightsim2grid.elements.ConverterStationInfo

This class represents what you get from retrieving one side’s converter station of an lightsim2grid.elements.HvdcLineInfo (station1 / station2).

It follows the IIDM model of powsybl: a station is either a VSC (voltage source converter – behaves like a generator, either regulating voltage or with a fixed reactive setpoint, see voltage_regulator_on) or a LCC (line commutated converter – behaves like a load, always consuming Q = abs(P) * tan(acos(power_factor))), see converter_type.

The active power of a station (target_p_mw, generator sign convention) is not an independent input: it is derived from the owning HVDC line’s active power setpoint (or its angle-droop behaviour) and the loss model – see lightsim2grid.elements.HvdcLineInfo.

Warning

Data can only be read from this element. You cannot modify (yet) the grid using this class directly (see lightsim2grid.elements.HvdcLineInfo for how to act on the owning HVDC line).

Classes:

ConverterType

Type of an hvdc converter station

Attributes:

bus_id

Get the bus id (as an integer) at which each element of a lightsim2grid.network.LSGrid is connected.

connected

Get the status (True = connected, False = disconnected) of each element of a lightsim2grid.network.LSGrid

converter_type

Whether this converter station is a VSC (0, voltage source converter) or a LCC (1, line commutated converter).

has_res

This property specify whether or not a given element contains some "result" information.

id

Get the id of the element.

loss_factor

Converter loss factor (fraction, between 0. and 1.) applied when deriving this station's active power from the owning HVDC line's power flow -- see the loss model described in lightsim2grid.elements.HvdcLineInfo.

max_q_mvar

Maximum reactive value that can be produced / absorbed by this generator, in MVAr.

min_q_mvar

Minimum reactive value that can be produced / absorbed by this generator, in MVAr.

name

Get the name of the element.

pos_topo_vect

Get the position of the element in the grid2op "topo_vect" vector.

power_factor

LCC power factor -- the reactive power consumed by the station is Q = abs(P) * tan(acos(power_factor)).

res_p_mw

Get the active production (or consumption) in MW for element of the grid supporting this feature.

res_q_mvar

Get the reactive production (or consumption) in MVAr for element of the grid supporting this feature.

res_theta_deg

Get the angle of the complex voltage (in degree, not in radian) of the bus at which this object is connected.

res_v_kv

Get the magnitude of the complex voltage (in kV) of the bus at which this object is connected.

sub_id

Get the substation id of the element.

target_p_mw

Get the active production (or consumption) setpoint in MW for element of the grid supporting this feature.

target_q_mvar

Get the reactive production (or consumption) setpoint in MVAr for element of the grid supporting this feature.

target_vm_pu

Get the voltage magnitude setpoint (in pair unit and NOT in kV) for each element of the grid supporting this feature.

voltage_level_id

Get the substation id of the element.

voltage_regulator_on

Whether this element tries to regulate a bus voltage (PV-like behaviour, following target_vm_pu) or applies a fixed reactive setpoint instead (PQ-like behaviour, following target_q_mvar).

class ConverterType

Type of an hvdc converter station

Members:

VSC

LCC

Attributes:

name

property name
property bus_id

Get the bus id (as an integer) at which each element of a lightsim2grid.network.LSGrid is connected. If -1 is returned it means that the object is disconnected.

Note

This is the “gridmodel” (aka “global”) bus id, not the “solver” bus id used internally by the powerflow (which only numbers connected buses, and renumbers them whenever the topology changes) – see lightsim2grid.network.LSGrid.id_me_to_ac_solver() / lightsim2grid.network.LSGrid.id_ac_solver_to_me() to convert between the two.

On ConverterStationInfo (the only remaining user of this generic docstring): read-only, no dedicated LSGrid setter – a converter station’s bus follows its parent HvdcLineInfo.

property connected

Get the status (True = connected, False = disconnected) of each element of a lightsim2grid.network.LSGrid

On ConverterStationInfo (the only remaining user of this generic docstring): read-only, there is no LSGrid method to (de)activate a converter station independently of its parent HvdcLineInfo – see lightsim2grid.network.LSGrid.deactivate_dcline_side1() / lightsim2grid.network.LSGrid.deactivate_dcline_side2().

property converter_type

Whether this converter station is a VSC (0, voltage source converter) or a LCC (1, line commutated converter).

See lightsim2grid.elements.ConverterStationInfo for the behaviour of each.

property has_res

This property specify whether or not a given element contains some “result” information. If set to True then the fields starting with res_ (eg res_p_mw) are filled otherwise they are initialized with an arbitrary (and meaningless) value.

property id

Get the id of the element. Ids are integer from 0 to n-1 (if n denotes the number of such elements on the grid.)

Examples

We give the example only for generators, but it works similarly for every other types of objects in a lightsim2grid.network.LSGrid.

This gives something like:

import grid2op
from lightsim2grid import LightSimBackend

env_name = ... # eg. "l2rpn_case14_test"
env = grid2op.make(env_name, backend=LightSimBackend())

grid_model = env.backend._grid

first_gen = grid_model.get_generators()[0]  # or get_loads for loads, etc.
first_gen.id  # should be 0
property loss_factor

Converter loss factor (fraction, between 0. and 1.) applied when deriving this station’s active power from the owning HVDC line’s power flow – see the loss model described in lightsim2grid.elements.HvdcLineInfo.

property max_q_mvar

Maximum reactive value that can be produced / absorbed by this generator, in MVAr. See min_q_mvar for when (and how) this is actually used.

property min_q_mvar

Minimum reactive value that can be produced / absorbed by this generator, in MVAr.

Note

On a lightsim2grid.elements.GenInfo or lightsim2grid.elements.ConverterStationInfo that is locally voltage-regulating (voltage_regulator_on is True and it does not regulate a remote bus), this is genuinely used at every solve: when several such units share the same bus, their reactive-power mismatch is split between them proportionally to max_q_mvar - min_q_mvar. It is also used, in the same case, by lightsim2grid.network.LSGrid.check_solution() when check_q_limits is True, to report any part of the mismatch that falls outside [min_q_mvar, max_q_mvar] instead of masking it.

On a “PQ” generator (voltage_regulator_on is False), a remotely-regulating one, or a lightsim2grid.elements.SGenInfo (static generators never regulate voltage), this value is NOT used anywhere by lightsim2grid: it is pure metadata carried over from the source model.

property name

Get the name of the element. Names are string that should be unique. But if you really want things unique, use the id

Warning

Names are optional and might not be set when reading the grid.

Examples

We give the example only for generators, but it works similarly for every other types of objects in a lightsim2grid.network.LSGrid.

This gives something like:

import grid2op
from lightsim2grid import LightSimBackend

env_name = ... # eg. "l2rpn_case14_test"
env = grid2op.make(env_name, backend=LightSimBackend())

grid_model = env.backend._grid

first_gen = grid_model.get_generators()[0]  # or get_loads for loads, etc.
first_gen.name
property pos_topo_vect

Get the position of the element in the grid2op “topo_vect” vector.

Warning

Position in the “topo vector” are optional and might not be set when reading the grid. In that case -1 is set for this attribute.

On ConverterStationInfo (the only remaining user of this generic docstring): read-only, no dedicated LSGrid position setter – HVDC lines are not part of grid2op’s topology vector.

property power_factor

LCC power factor – the reactive power consumed by the station is Q = abs(P) * tan(acos(power_factor)).

Only meaningful when converter_type is 1 (LCC); always 1. (unused) for VSC stations.

property res_p_mw

Get the active production (or consumption) in MW for element of the grid supporting this feature.

For generators (and static generators) it is given following the “generator convention” (positive = power is injected to the grid)

For loads (and storage units) it is given following the “load convention” (positive = power is absorbed from the grid)

Read-only powerflow result, no LSGrid setter – also available in bulk, for every element of this container at once, via the corresponding LSGrid.get_*_res() method.

Warning

This feature is only relevant if the results have been computed (for example if a powerflow has successfully run)

property res_q_mvar

Get the reactive production (or consumption) in MVAr for element of the grid supporting this feature.

For generators (and static generators) it is given following the “generator convention” (positive = power is injected to the grid)

For loads (and storage units) it is given following the “load convention” (positive = power is absorbed from the grid)

Read-only powerflow result, no LSGrid setter – also available in bulk, for every element of this container at once, via the corresponding LSGrid.get_*_res() method.

Warning

This feature is only relevant if the results have been computed (for example if a powerflow has successfully run)

property res_theta_deg

Get the angle of the complex voltage (in degree, not in radian) of the bus at which this object is connected.

Note

All elements (load, generators, side of powerline etc.) connected at the same bus have the same “res_theta_deg”

Read-only powerflow result, no LSGrid setter – also available in bulk, for every element of this container at once, via the corresponding LSGrid.get_*_theta() method.

Warning

This feature is only relevant if the results have been computed (for example if a powerflow has successfully run)

property res_v_kv

Get the magnitude of the complex voltage (in kV) of the bus at which this object is connected.

Note

All elements (load, generators, side of powerline etc.) connected at the same bus have the same “res_v_kv”

Read-only powerflow result, no LSGrid setter – also available in bulk, for every element of this container at once, via the corresponding LSGrid.get_*_res() method.

Warning

This feature is only relevant if the results have been computed (for example if a powerflow has successfully run)

property sub_id

Get the substation id of the element.

Note

In pypowsybl, this is called “voltage levels”.

Warning

Substation ids are optional and might not be set when reading the grid. In that case -1 is set for this attribute.

On ConverterStationInfo (the only remaining user of this generic docstring): read-only, no dedicated LSGrid substation-id setter – a converter station’s substation follows its parent HvdcLineInfo.

property target_p_mw

Get the active production (or consumption) setpoint in MW for element of the grid supporting this feature.

For generators (and static generators) it is given following the “generator convention” (positive = power is injected to the grid)

For loads (and storage units) it is given following the “load convention” (positive = power is absorbed from the grid)

On ConverterStationInfo (the only remaining user of this generic docstring): read-only, no dedicated LSGrid setter – it follows its parent HvdcLineInfo’s lightsim2grid.network.LSGrid.change_p_dcline().

property target_q_mvar

Get the reactive production (or consumption) setpoint in MVAr for element of the grid supporting this feature.

For generators (and static generators) it is given following the “generator convention” (positive = power is injected to the grid)

For loads (and storage units) it is given following the “load convention” (positive = power is absorbed from the grid)

Note

For elements that can regulate a voltage instead of applying a fixed reactive setpoint (see lightsim2grid.elements.GenInfo.voltage_regulator_on / lightsim2grid.elements.ConverterStationInfo.voltage_regulator_on), this value is only actually used when voltage regulation is OFF. When it is ON, the reactive power is computed by the powerflow instead and this setpoint is ignored.

On GenInfo and ConverterStationInfo (the remaining users of this generic docstring): read-only, there is no LSGrid method exposed to change this value directly.

property target_vm_pu

Get the voltage magnitude setpoint (in pair unit and NOT in kV) for each element of the grid supporting this feature.

Warning

This is given in “pair unit” (pu) system and not in kilo Volt (kV) !

On ConverterStationInfo (the only remaining user of this generic docstring): read-only, no dedicated LSGrid setter – it follows its parent HvdcLineInfo’s lightsim2grid.network.LSGrid.change_v1_dcline() / lightsim2grid.network.LSGrid.change_v2_dcline().

property voltage_level_id

Get the substation id of the element.

Note

In pypowsybl, this is called “voltage levels”.

Warning

Substation ids are optional and might not be set when reading the grid. In that case -1 is set for this attribute.

On ConverterStationInfo (the only remaining user of this generic docstring): read-only, no dedicated LSGrid substation-id setter – a converter station’s substation follows its parent HvdcLineInfo.

property voltage_regulator_on

Whether this element tries to regulate a bus voltage (PV-like behaviour, following target_vm_pu) or applies a fixed reactive setpoint instead (PQ-like behaviour, following target_q_mvar).

When True, the reactive power is not an independent input: it is computed by the powerflow so that the regulated bus’s voltage magnitude matches target_vm_pu (within min_q_mvar / max_q_mvar). When False, target_q_mvar is used directly and target_vm_pu / min_q_mvar / max_q_mvar are ignored.

Note

On a lightsim2grid.elements.GenInfo, the regulated bus is not necessarily this generator’s own bus – see lightsim2grid.elements.GenInfo.regulated_bus_id (“remote voltage control”).

On a lightsim2grid.elements.ConverterStationInfo, this is only meaningful for VSC stations (lightsim2grid.elements.ConverterStationInfo.converter_type == 0): LCC stations (converter_type == 1) always have it False and instead consume reactive power following lightsim2grid.elements.ConverterStationInfo.power_factor.

PTDF / LODF

As long as the topology of the grid is not modified, a DC powerflow is a linear function of the bus injections, so it can be replaced by a matrix multiplication – much faster than solving the linear system again for every new injection or contingency (see Benchmarks (dc solvers) for numbers).

  • get_ptdf() (or get_ptdf_solver() for the solver bus labelling) returns the Power Transfer Distribution Factor matrix: how much the flow on each powerline / transformer changes for a 1 MW injection change at each bus.

  • get_lodf() returns the Line Outage Distribution Factor matrix: how much the flow on each powerline / transformer changes when another one is disconnected – the tool of choice for an n-1 contingency analysis restricted to DC (see also lightsim2grid.contingencyAnalysis.ContingencyAnalysis for the general AC/DC case).

  • get_Bf() returns the sparse “bus to branch” susceptance matrix these are built from.

Both get_ptdf and get_lodf require a DC powerflow (dc_pf) to have been run first, and are only valid for the topology that was in place when that powerflow was solved – any topology change invalidates them. See each function’s own documentation below for a full worked example.

Solver cache reuse

Solving a powerflow is not only the linear algebra: the grid must first be turned into what the solver consumes – a compact bus labelling, the admittance matrix Ybus, the injection vector Sbus, the PV / PQ split, the slack weights. On a small grid that assembly is worth a good fifth of the total time, and it is almost entirely redundant between two consecutive powerflows: changing one load’s setpoint does not move a single admittance coefficient.

So LSGrid keeps what it built and re-stamps only the parts that changed. Every method that modifies the grid (change_*, deactivate_*, reactivate_*, …) records what it invalidated, and each powerflow rebuilds exactly that much.

This is on by default and needs nothing from you. Every powerflow marks its own solver family “in sync” on the way out.

Changed in version 1.0.0: Before 1.0.0 you had to call lsgrid.unset_changes() yourself after each powerflow, or silently pay for a full rebuild every time. That call is now unnecessary (it does nothing when cache reuse is enabled, which is the default) and it is kept only for backward compatibility.

The AC and the DC solver cache independently: each has its own bus labelling, its own matrix (Ybus / Bbus), its own injections, its own PV / PQ split and slack weights. An AC powerflow never marks, invalidates or overwrites anything belonging to the DC family, and the reverse. Hence the per-family accessors get_ac_pv_solver(), get_dc_pv_solver(), and their pq / slack_weights counterparts.

Controlling it

Method

Meaning

lsgrid.allow_cache_reuse(bool)

turn reuse on (default) or off, for both families

lsgrid.allow_ac_cache_reuse(bool)

… for the AC family only

lsgrid.allow_dc_cache_reuse(bool)

… for the DC family only

lsgrid.get_allow_cache_reuse()

True iff both families may reuse

lsgrid.get_allow_ac_cache_reuse()

is the AC family allowed to reuse?

lsgrid.get_allow_dc_cache_reuse()

is the DC family allowed to reuse?

lsgrid.prevent_cache_reuse()

drop what both families cached, once

lsgrid.prevent_ac_cache_reuse()

… for the AC family only

lsgrid.prevent_dc_cache_reuse()

… for the DC family only

Note the difference: allow_* is a mode (it stays until you change it back), while prevent_* is a one-shot invalidation – the family throws away what it had and caches again from the next powerflow on. prevent_cache_reuse() is the function historically called tell_solver_need_reset(), which still works.

You should not normally need either. The two cases that call for them are:

  • You suspect a caching bug. allow_cache_reuse(False) makes every powerflow rebuild everything from the containers; the two runs must agree to the last bit.

    v_cached = lsgrid.ac_pf(v_init, 10, 1e-8)
    lsgrid.allow_cache_reuse(False)
    v_rebuilt = lsgrid.ac_pf(v_init, 10, 1e-8)
    assert (abs(v_cached - v_rebuilt) < 1e-12).all()
    
  • You modified the grid behind ``LSGrid``’s back, through something other than its own change_* / deactivate_* / reactivate_* methods – then nothing recorded the invalidation, and prevent_cache_reuse() (or the narrower tell_recompute_ybus / tell_recompute_sbus) is how you say so.

Note

A wrong “nothing changed” claim can cost you a rebuild you were trying to avoid; it can never make lightsim2grid read memory it does not own. Every powerflow checks that the data the flags describe is actually there before reusing it, and rebuilds from scratch otherwise.

What is never cached across

Serialization. Nothing the solvers cache is written to a pickle or a binary file, and nothing is read back: a grid restored through load_binary() or pickle.loads always starts cold and rebuilds on its first powerflow. This is a security property rather than a performance one. A cache is a second copy of state the elements already determine; read back from a file it becomes a copy that cannot be checked against the elements it claims to describe. check_grid() can validate that an index is in range – it cannot validate that a matrix really is the admittance matrix of the grid stored next to it, and one that merely looked well-formed would be solved without complaint. Files are not trusted input, so the cache is rebuilt, once, from data that is.

Copying. copy() does not carry the cache either: the copy starts cold and rebuilds on its first powerflow. Unlike the serialization case this is not a safety requirement – a copy is the same grid, in the same process, so its cache would be perfectly valid – and it may change in a future version. The allow_*_cache_reuse settings are copied.

Detailed documentation

Classes:

ComparisonResult(max_dvm_pu, max_dva_deg, ...)

Outcome of compare_baked(): how far lightsim2grid and OLF disagree.

LSGrid

This class represent a lightsim2grid power network.

LightsimResultNetwork(ls_grid, net)

pypowsybl-Network-shaped view of a solved lightsim2grid LSGrid.

Functions:

bake_outer_loops(network[, bake_taps, ...])

Rewrite network input setpoints to the converged outer-loop state.

compare_baked(network_factory, slack_gen_id)

Bake, optionally apply outages, solve in both engines, and compare.

get_pypowsybl_loopfree_distributed_slack_parameters([...])

Loop-free OLF parameters EXCEPT the active-power slack distribution.

get_pypowsybl_loopfree_parameters([...])

Build a fresh pypowsybl.loadflow.Parameters with every OLF outer loop removed (see remove_outer_loops()).

init_from_matpower(source[, n_busbar_per_sub])

Convert a MATPOWER case into a LSGrid.

init_from_pandapower(pp_net[, n_sub, ...])

Convert a pandapower network as input into a LSGrid.

init_from_pf_delta(row[, n_busbar_per_sub])

Convert a PFΔ dataset row into a LSGrid.

init_from_powermodels(network[, ...])

Convert a PowerModels.jl network data dictionary into a LSGrid.

init_from_pypowsybl(net[, gen_slack_id, ...])

This function is available under the init_from_pypowsybl in lightsim2grid

remove_outer_loops(parameters[, keep, ...])

Return a copy of parameters with OLF's outer loops removed.

class lightsim2grid.network.ComparisonResult(max_dvm_pu: float, max_dva_deg: float, max_dva_deg_offset_removed: float, table: DataFrame)[source]

Outcome of compare_baked(): how far lightsim2grid and OLF disagree.

max_dvm_pu

Largest absolute voltage-magnitude difference, in per unit, over every bus common to both engines.

Type:

float

max_dva_deg

Largest absolute voltage-angle difference, in degrees (raw).

Type:

float

max_dva_deg_offset_removed

Same as max_dva_deg but with a uniform angle offset removed first. A constant offset on all buses is just a difference of reference-datum convention between the two engines, not a physical disagreement, so this is usually the meaningful angle metric.

Type:

float

table

Per-bus detail, indexed by IIDM bus id, with the OLF and lightsim2grid magnitudes / angles and their differences (columns olf_vm, ls_vm, olf_va, ls_va, dvm, dva).

Type:

pandas.DataFrame

class lightsim2grid.network.LSGrid

This class represent a lightsim2grid power network. All the elements that can be manipulated by lightsim2grid are represented here.

We do not recommend to use this class directly, but rather to use a lightsim2grid.lightSimBackend.LightSimBackend.

Examples

We DO NOT recommend to do:

import lightsim2grid
from lightsim2grid.network import init_from_pandapower
pp_net = ...  # any pandapower network for example pp_net = pn.case118()

grid_model = init_from_pandapower(pp_net)

It’s better to do:

import grid2op
from lightsim2grid import LightSimBackend
env_name = ...  # any grid2op environment
grid2op_env = grid2op.make(env_name, backend=LightSimBackend())

grid_model = grid2op_env.backend._grid

The best way to use this class is through the LightSimBackend and not to use it directly !

Methods:

ac_pf(self, arg0, arg1, arg2)

Allows to perform an AC (alternating current) powerflow.

add_gen_slackbus(self, arg0, arg1)

Make generator gen_id participate in the distributed slack, with the given (strictly positive) weight -- see is_slack / slack_weight.

allow_ac_cache_reuse(self, allowed)

Enable (default) or disable cache reuse for the AC solver family.

allow_cache_reuse(self, allowed)

Convenience: set lightsim2grid.network.LSGrid.allow_ac_cache_reuse() and lightsim2grid.network.LSGrid.allow_dc_cache_reuse() at once.

allow_dc_cache_reuse(self, allowed)

Enable (default) or disable cache reuse for the DC solver family.

assign_slack_to_most_connected(self)

Pick a single new slack generator automatically: among the buses with at least one generator producing (target_p_mw > 0), the one with the most powerline / transformer ends connected to it: then, at that bus, the generator with the highest abs(target_p_mw).

available_algorithm_names(self)

Returns the names of all registered algorithms, including any loaded plugins, as a list of string.

available_default_algorithms(self)

Return the list of the names of the algorithm available on the current lightsim2grid installation.

available_solver_names(self)

DEPRECATED: use 'available_algorithm_names' instead

available_solvers(self)

DEPRECATED: use 'available_default_algorithms' instead

change_algorithm(*args, **kwargs)

Overloaded function.

change_bus1_dcline(self, arg0, arg1)

Move converter station 1 of HVDC line dcline_id to bus new_gridmodel_bus_id (sets bus1_id), see change_bus_load() for the bus id convention.

change_bus1_powerline(self, arg0, arg1)

Move side 1 of powerline powerline_id to bus new_gridmodel_bus_id (sets bus1_id), see change_bus_load() for the bus id convention.

change_bus1_trafo(self, arg0, arg1)

Move side 1 (hv) of transformer trafo_id to bus new_gridmodel_bus_id (sets bus1_id), see change_bus_load() for the bus id convention.

change_bus2_dcline(self, arg0, arg1)

Move converter station 2 of HVDC line dcline_id to bus new_gridmodel_bus_id (sets bus2_id), see change_bus_load() for the bus id convention.

change_bus2_powerline(self, arg0, arg1)

Move side 2 of powerline powerline_id to bus new_gridmodel_bus_id (sets bus2_id), see change_bus_load() for the bus id convention.

change_bus2_trafo(self, arg0, arg1)

Move side 2 (lv) of transformer trafo_id to bus new_gridmodel_bus_id (sets bus2_id), see change_bus_load() for the bus id convention.

change_bus_gen(self, arg0, arg1)

Move generator gen_id to bus new_gridmodel_bus_id (sets bus_id), see change_bus_load() for the bus id convention.

change_bus_load(self, arg0, arg1)

Move load load_id to bus new_gridmodel_bus_id (sets bus_id).

change_bus_sgen(self, arg0, arg1)

Move static generator sgen_id to bus new_gridmodel_bus_id (sets bus_id), see change_bus_load() for the bus id convention.

change_bus_shunt(self, arg0, arg1)

Move shunt shunt_id to bus new_gridmodel_bus_id (sets bus_id), see change_bus_load() for the bus id convention.

change_bus_storage(self, arg0, arg1)

Move storage unit storage_id to bus new_gridmodel_bus_id (sets bus_id), see change_bus_load() for the bus id convention.

change_bus_svc(self, arg0, arg1)

Move SVC svc_id to bus new_gridmodel_bus_id (sets bus_id), see change_bus_load() for the bus id convention.

change_p_dcline(self, arg0, arg1)

Change HVDC line dcline_id's active power setpoint (sets p_setpoint_mw, the power drawn at the rectifier; target_p1_mw / p2_mw are then derived from it and converters_mode).

change_p_gen(self, arg0, arg1)

Change generator gen_id's active power setpoint (sets target_p_mw), see change_p_load() for the "never throws" note.

change_p_load(self, arg0, arg1)

Change load load_id's active power setpoint (sets target_p_mw).

change_p_sgen(self, arg0, arg1)

Change static generator sgen_id's active power setpoint (sets target_p_mw), see change_p_load() for the "never throws" note.

change_p_shunt(self, arg0, arg1)

Change shunt shunt_id's active power (sets target_p_mw), see change_p_load() for the "never throws" note.

change_p_storage(self, arg0, arg1)

Change storage unit storage_id's active power setpoint (sets target_p_mw), see change_p_load() for the "never throws" note.

change_q_load(self, arg0, arg1)

Change load load_id's reactive power setpoint (sets target_q_mvar), see change_p_load() for the "never throws" note.

change_q_sgen(self, arg0, arg1)

Change static generator sgen_id's reactive power setpoint (sets target_q_mvar), see change_p_load() for the "never throws" note.

change_q_shunt(self, arg0, arg1)

Change shunt shunt_id's reactive power (sets target_q_mvar), see change_p_load() for the "never throws" note.

change_q_storage(self, arg0, arg1)

Change storage unit storage_id's reactive power setpoint (sets target_q_mvar), see change_p_load() for the "never throws" note.

change_ratio_trafo(self, arg0, arg1)

Change the tap ratio of a given transformer (see lightsim2grid.elements.TrafoInfo.ratio).

change_shift_trafo(self, arg0, arg1)

Change the phase-shift angle for a given transformer.

change_shift_trafo_deg(self, arg0, arg1)

Same as change_shift_trafo() but the phase-shift angle is expressed in degree, not in radian.

change_solver(*args, **kwargs)

Overloaded function.

change_v1_dcline(self, arg0, arg1)

Change the voltage setpoint of converter station 1 of HVDC line dcline_id (sets target_vm1_pu).

change_v2_dcline(self, arg0, arg1)

Change the voltage setpoint of converter station 2 of HVDC line dcline_id (sets target_vm2_pu).

change_v_gen(self, arg0, arg1)

Change generator gen_id's voltage setpoint (sets target_vm_pu), see change_p_load() for the "never throws" note.

check_grid(self)

Check that the grid is internally consistent and safe to run a powerflow on.

check_solution(self, arg0, arg1)

This function allows to check that a given complex voltage vector satisfies the KCL or not, given the state of the sytem.

compute_newton(self, arg0, arg1, arg2)

Allows to perform an AC (alternating current) powerflow.

consider_only_main_component(self)

Restrict the grid to its main synchronous component: starting a breadth-first search from the slack bus(es) over the branch graph (powerlines, transformers, and any other connecting element), find every bus reachable from them, then disconnect every element with no bus in that component.

copy(self)

Return a full, independent deep copy of this grid.

dc_pf(self, arg0, arg1, arg2)

This function has the same interface, inputs, outputs, behaviour, etc.

deactivate_bus(self, arg0)

Low-level / internal primitive, not part of the stable public API: called directly by lightsim2grid's own machinery (eg LightSimBackend, the grid loaders, or another part of the C++ core) rather than meant for everyday use.

deactivate_dcline(self, arg0)

Disconnect HVDC line dcline_id entirely (both converter stations) -- sets connected_global (and both connected1 / connected2) to False.

deactivate_dcline_side1(self, arg0)

Disconnect only converter station 1 of an HVDC line; station 2 stays active (injecting / regulating).

deactivate_dcline_side2(self, arg0)

Disconnect only converter station 2 of an HVDC line; station 1 stays active (injecting / regulating).

deactivate_gen(self, arg0)

Disconnect generator gen_id -- sets connected to False.

deactivate_load(self, arg0)

Disconnect load load_id -- sets connected to False.

deactivate_powerline(self, arg0)

Disconnect powerline powerline_id entirely (both sides) -- sets connected_global (and both connected1 / connected2) to False.

deactivate_powerline_side1(self, arg0)

Disconnect only side 1 of a powerline (half-open).

deactivate_powerline_side2(self, arg0)

Disconnect only side 2 of a powerline (half-open).

deactivate_result_computation(self)

Allows to deactivate the computation of the flows, reactive power absorbed by generators etc.

deactivate_sgen(self, arg0)

Disconnect static generator sgen_id -- sets connected to False.

deactivate_shunt(self, arg0)

Disconnect shunt shunt_id -- sets connected to False.

deactivate_storage(self, arg0)

Disconnect storage unit storage_id -- sets connected to False.

deactivate_svc(self, arg0)

Disconnect SVC svc_id -- sets connected to False (equivalent to setting its regulation_mode to OFF for powerflow purposes, but does not change the stored regulation_mode value).

deactivate_trafo(self, arg0)

Disconnect transformer trafo_id entirely (both sides) -- sets connected_global (and both connected1 / connected2) to False.

deactivate_trafo_side1(self, arg0)

Disconnect only side 1 of a transformer (half-open).

deactivate_trafo_side2(self, arg0)

Disconnect only side 2 of a transformer (half-open).

debug_get_Bp_python(self, arg0)

Low-level / internal primitive, not part of the stable public API: called directly by lightsim2grid's own machinery (eg LightSimBackend, the grid loaders, or another part of the C++ core) rather than meant for everyday use.

debug_get_Bpp_python(self, arg0)

Low-level / internal primitive, not part of the stable public API: called directly by lightsim2grid's own machinery (eg LightSimBackend, the grid loaders, or another part of the C++ core) rather than meant for everyday use.

get_2_windings_transformers(self)

This function allows to retrieve the transformers (as a lightsim2grid.elements.LineContainer object, see Elements modeled for more information)

get_Bf(self)

Returns the "Bus from" matrix, with the bus having the gridmodel id (sparse matrix).

get_Bf_solver(self)

Returns the "Bus from" matrix, with the bus having the solver id (sparse matrix).

get_J_solver(self)

Returns the Jacobian matrix used for solving the powerflow as a scipy sparse CSC matrix matrix of real number.

get_Sbus(self)

This function returns the (complex) Sbus vector of the gridmodel.

get_Sbus_solver(self)

This function returns the (complex) Sbus vector used by the AC solver.

get_V(self)

Returns the complex voltage for each buses as a numpy vector of complex number.

get_V_solver(self)

Returns the complex voltage for each buses as a numpy vector of complex number.

get_Va(self)

Returns the voltage angles for each buses as a numpy vector of real number.

get_Va_solver(self)

Returns the voltage angles for each buses as a numpy vector of real number.

get_Vm(self)

Returns the voltage magnitude for each buses as a numpy vector of real number.

get_Vm_solver(self)

Returns the voltage magnitude for each buses as a numpy vector of real number.

get_Ybus(self)

This function returns the (complex) Ybus matrix (for the AC powerflow) with the gridmodel convention.

get_Ybus_solver(self)

This function returns the (complex) Ybus matrix used to compute the AC powerflow.

get_ac_algo_config(self)

Return the AC solver's lightsim2grid.algorithm.AlgoConfig (scaling/refactor policy type and parameters).

get_ac_algo_controler(self)

Return the AC solver family's change-tracking flags, as a lightsim2grid.algorithm.AlgoControl instance.

get_ac_pq_solver(self)

Same as lightsim2grid.network.LSGrid.get_pq_solver(), but always for the AC solver family.

get_ac_pv_solver(self)

Same as lightsim2grid.network.LSGrid.get_pv_solver(), but always for the AC solver family, whatever powerflow ran last.

get_ac_slack_weights_solver(self)

Same as lightsim2grid.network.LSGrid.get_slack_weights_solver(), but always for the AC solver family.

get_algo(self)

Return the solver currently in use as a lightsim2grid.algorithm.AlgorithmSelector() instance.

get_algo_type(self)

Return the type of the solver currently used.

get_all_shunt_buses(self)

Get the grid bus id of every shunt at once -- the bulk equivalent of bus_id.

get_allow_ac_cache_reuse(self)

Whether the AC solver family may reuse its cache (True by default).

get_allow_cache_reuse(self)

True only when both families may reuse their cache (the default).

get_allow_dc_cache_reuse(self)

Whether the DC solver family may reuse its cache (True by default).

get_bus1_dcline(self, arg0)

Get the grid bus id converter station 1 of HVDC line dcline_id is connected to -- see bus1_id.

get_bus1_powerline(self, arg0)

Get the grid bus id side 1 of powerline powerline_id is connected to -- see bus1_id.

get_bus1_trafo(self, arg0)

Get the grid bus id side 1 (hv) of transformer trafo_id is connected to -- see bus1_id.

get_bus2_dcline(self, arg0)

Get the grid bus id converter station 2 of HVDC line dcline_id is connected to -- see bus2_id.

get_bus2_powerline(self, arg0)

Get the grid bus id side 2 of powerline powerline_id is connected to -- see bus2_id.

get_bus2_trafo(self, arg0)

Get the grid bus id side 2 (lv) of transformer trafo_id is connected to -- see bus2_id.

get_bus_gen(self, arg0)

Get the grid bus id generator gen_id is connected to -- see bus_id.

get_bus_load(self, arg0)

Get the grid bus id load load_id is connected to -- see bus_id.

get_bus_sgen(self, arg0)

Get the grid bus id static generator sgen_id is connected to -- see bus_id.

get_bus_shunt(self, arg0)

Get the grid bus id shunt shunt_id is connected to -- see bus_id.

get_bus_status(self)

Whether each bus ("gridmodel" numbering) is currently connected -- part of at least one active element or busbar coupling, so contributing an unknown to the powerflow.

get_bus_storage(self, arg0)

Get the grid bus id storage unit storage_id is connected to -- see bus_id.

get_bus_svc(self, arg0)

Get the grid bus id SVC svc_id is connected to -- see bus_id.

get_bus_vmax_kv(self)

Per-bus max operating voltage, in kV (NaN if not provided for a given bus, empty array if never set).

get_bus_vmin_kv(self)

Per-bus min operating voltage, in kV (NaN if not provided for a given bus, empty array if never set).

get_bus_vn_kv(self)

Nominal voltage (kV) of every bus, in "gridmodel" bus numbering -- one entry per bus (not per substation): every busbar of a given substation shares the same value, the one given to init_bus() for that substation.

get_computation_time(self)

Return the total computation time (in second) spend in the solver when performing a powerflow.

get_controller_elem_id_solver(self)

Element id of each VoltageControl controller (generator id if a generator, SVC id if an SVC), same order as get_controller_q_solver().

get_controller_kind_solver(self)

Kind of each VoltageControl controller (0 = generator, 1 = SVC), same order as get_controller_q_solver().

get_controller_q_col_solver(self)

Jacobian column of each VoltageControl controller's own Q unknown, same order as get_controller_q_solver().

get_controller_q_solver(self)

Converged reactive injection (pu) per VoltageControl controller (a remote-regulating generator or a voltage-mode SVC), in controller registration order.

get_dcSbus(self)

This function returns the (complex) Sbus vector of the gridmodel for the DC solver (imaginary part should be 0.).

get_dcSbus_solver(self)

This function returns the (complex) Sbus vector used by the DC sovler.

get_dcYbus(self)

This function returns the (complex) Ybus matrix (for the DC powerflow) (its imaginary part should be 0.) with the gridmodel convention.

get_dcYbus_solver(self)

This function returns the (complex) Ybus matrix used to compute the DC powerflow (its imaginary part should be 0.).

get_dc_algo(self)

Return the solver currently in use as a lightsim2grid.algorithm.AlgorithmSelector() instance for the dc powerflow.

get_dc_algo_config(self)

Return the DC solver's lightsim2grid.algorithm.AlgoConfig (no-op for non-NR solvers, returns an empty config).

get_dc_algo_controler(self)

Return the DC solver family's change-tracking flags, as a lightsim2grid.algorithm.AlgoControl instance.

get_dc_algo_type(self)

Return the type of the solver currently used to compute DC powerflow.

get_dc_computation_time(self)

Return the total computation time (in second) spend in the solver (used to perform DC approximation) when performing a DC powerflow.

get_dc_pq_solver(self)

Same as lightsim2grid.network.LSGrid.get_pq_solver(), but always for the DC solver family.

get_dc_pv_solver(self)

Same as lightsim2grid.network.LSGrid.get_pv_solver(), but always for the DC solver family.

get_dc_slack_weights_solver(self)

Same as lightsim2grid.network.LSGrid.get_slack_weights_solver(), but always for the DC solver family.

get_dc_solver(self)

DEPRECATED: use 'get_dc_algo' instead

get_dc_solver_type(self)

DEPRECATED: use 'get_dc_algo_type' instead

get_dcline_res1_full(self)

Get, for every HVDC line at once, the converter-station-1 (p1_mw, q1_mvar, v1_kv, theta1_deg) result quadruplet -- see res_p1_mw / res_q1_mvar / res_v1_kv / res_theta1_deg.

get_dcline_res2_full(self)

Get, for every HVDC line at once, the converter-station-2 result quadruplet, see get_dcline_res1_full().

get_dclines(self)

This function allows to retrieve the dc powerlines (as a lightsim2grid.elements.DCLineContainer object, see Elements modeled for more information)

get_gen_res(self)

Get, for every generator at once, the (p_mw, q_mvar, v_kv) result triplet, see get_loads_res() and GenInfo.

get_gen_res_full(self)

Get, for every generator at once, the (p_mw, q_mvar, v_kv, theta_deg) result quadruplet, see get_loads_res_full() and GenInfo.

get_gen_status(self)

Get the connection status of every generator at once, see get_loads_status() and GenInfo.

get_gen_target_p(self)

Get the active power setpoint of every generator at once, see get_shunt_target_p() and GenInfo.

get_gen_theta(self)

Get the voltage angle (degree) of every generator's bus at once -- see res_theta_deg.

get_generators(self)

This function allows to retrieve the (standard) generators (as a lightsim2grid.elements.GeneratorContainer object, see Elements modeled for more information)

get_hvdc_droop_data_solver(self)

(bus1, bus2, status, p0, k, lf1, lf2, r, pmax12, pmax21), one entry per CONNECTED droop-enabled HVDC line (solver bus numbering, pu).

get_ignore_status_global(self)

Current value of the ignore_status_global flag, see set_ignore_status_global().

get_init_vm_pu(self)

Get the value set by set_init_vm_pu().

get_line_names(self)

Names of the powerlines, as set by set_line_names; empty if never set.

get_line_res1(self)

Get, for every powerline at once, the side-1 (p1_mw, q1_mvar, v1_kv, a1_ka) result quadruplet -- see res_p1_mw / res_q1_mvar / res_v1_kv / res_a1_ka.

get_line_res1_full(self)

Get, for every powerline at once, the side-1 (p1_mw, q1_mvar, v1_kv, a1_ka, theta1_deg) result quintuplet -- same as get_line_res1() with res_theta1_deg appended.

get_line_res2(self)

Get, for every powerline at once, the side-2 result quadruplet, see get_line_res1().

get_line_res2_full(self)

Get, for every powerline at once, the side-2 result quintuplet, see get_line_res1_full().

get_line_theta1(self)

Get the voltage angle (degree) of every powerline's side-1 bus at once -- see res_theta1_deg.

get_line_theta2(self)

Get the voltage angle (degree) of every powerline's side-2 bus at once, see get_line_theta1().

get_lines(self)

This function allows to retrieve the powerlines (as a lightsim2grid.elements.LineContainer object, see Elements modeled for more information)

get_lines_status(self)

Get the global connection status of every powerline at once -- see connected_global (True as soon as either side is connected; see get_lines_status_side1() / get_lines_status_side2() for the per-side status).

get_lines_status_side1(self)

Per-side status of each powerline's side 1 (relevant for half-open lines: get_lines_status() is True as soon as either side is connected).

get_lines_status_side2(self)

Per-side status of each powerline's side 2, see get_lines_status_side1().

get_load_target_p(self)

Get the active power setpoint of every load at once, see get_shunt_target_p() and LoadInfo.

get_load_theta(self)

Get the voltage angle (degree) of every load's bus at once, see get_gen_theta() and LoadInfo.

get_loads(self)

This function allows to retrieve the loads (as a lightsim2grid.elements.LoadContainer object, see Elements modeled for more information)

get_loads_res(self)

Get, for every load at once, the (p_mw, q_mvar, v_kv) result triplet -- see res_p_mw / res_q_mvar / res_v_kv.

get_loads_res_full(self)

Get, for every load at once, the (p_mw, q_mvar, v_kv, theta_deg) result quadruplet -- same as get_loads_res() with res_theta_deg appended.

get_loads_status(self)

Get the connection status of every load at once -- see connected.

get_lodf(self)

This function returns the LODF (Line Outage Distribution Factor) which tells you how much the flows on each powerline / tranformer will vary if some given powerline / transformer is disconnected.

get_n_sub(self)

Get the value set by set_n_sub().

get_p_buses_solver(self)

Compact (bus, row) pair list for the P equations -- the row/col counterpart of get_p_to_J_row_solver(), preserving EVERY registration (a bus may appear more than once; see NRLedger's "Multiplicity rules").

get_p_rows_solver(self)

Jacobian row of each entry in get_p_buses_solver(), same order.

get_pq(self)

Returns the ids of the buses that are labelled as "PQ".

get_pq_solver(self)

Returns the ids of the buses that are labelled as "PQ".

get_ptdf(self)

This function returns the PTDF (Power Transfer Distribution Factor) which tells you how much the flows on each powerline / tranformer will vary if some given power is injected on each bus of the grid.

get_ptdf_solver(self)

This function returns the PTDF (Power Transfer Distribution Factor) which tells you how much the flows on each powerline / tranformer will vary if some given power is injected on each bus of the grid.

get_pv(self)

Returns the ids of the buses that are labelled as "PV" (ie the buses on which at least a generator is connected.).

get_pv_solver(self)

Returns the ids of the buses that are labelled as "PV" (ie the buses on which at least a generator is connected.).

get_q_buses_solver(self)

Compact (bus, row) pair list for the Q equations, see get_p_buses_solver().

get_q_rows_solver(self)

Jacobian row of each entry in get_q_buses_solver(), same order.

get_reference_slack_bus(self)

Forced angle-reference slack bus (gridmodel id), or -1 if none.

get_sgen_target_p(self)

Get the active power setpoint of every static generator at once, see get_shunt_target_p() and SGenInfo.

get_sgens_res(self)

Get, for every static generator at once, the (p_mw, q_mvar, v_kv) result triplet, see get_loads_res() and SGenInfo.

get_sgens_res_full(self)

Get, for every static generator at once, the (p_mw, q_mvar, v_kv, theta_deg) result quadruplet, see get_loads_res_full() and SGenInfo.

get_sgens_status(self)

Get the connection status of every static generator at once, see get_loads_status() and SGenInfo.

get_shunt_compensators(self)

This function allows to retrieve the shunts (as a lightsim2grid.elements.ShuntContainer object, see Elements modeled for more information)

get_shunt_target_p(self)

Get the active power setpoint of every shunt at once -- see target_p_mw.

get_shunt_theta(self)

Get the voltage angle (degree) of every shunt's bus at once, see get_gen_theta() and ShuntInfo.

get_shunts(self)

This function allows to retrieve the shunts (as a lightsim2grid.elements.ShuntContainer object, see Elements modeled for more information)

get_shunts_res(self)

Get, for every shunt at once, the (p_mw, q_mvar, v_kv) result triplet, see get_loads_res() and ShuntInfo.

get_shunts_res_full(self)

Get, for every shunt at once, the (p_mw, q_mvar, v_kv, theta_deg) result quadruplet, see get_loads_res_full() and ShuntInfo.

get_shunts_status(self)

Get the connection status of every shunt at once, see get_loads_status() and ShuntInfo.

get_slack_absorbed_solver(self)

Converged value (pu) of the MultiSlack slack_absorbed unknown (0 when distributed slack is inactive).

get_slack_col_solver(self)

Jacobian column of the MultiSlack slack_absorbed unknown (-1 when distributed slack is inactive).

get_slack_ids(self)

Returns the ids of the buses that are part of the distributed slack.

get_slack_ids_dc(self)

Returns the ids of the buses that are part of the distributed slack.

get_slack_ids_dc_solver(self)

Returns the ids of the buses that are part of the distributed slack.

get_slack_ids_solver(self)

Returns the ids of the buses that are part of the distributed slack.

get_slack_weights(self)

For each bus in the gridmodel solver, it outputs its participation to the distributed slack.

get_slack_weights_solver(self)

For each bus used by the solver, it outputs its participation to the distributed slack.

get_sn_mva(self)

Get the value set by set_sn_mva().

get_solver(self)

DEPRECATED: use 'get_algo' instead

get_solver_type(self)

DEPRECATED: use 'get_algo_type' instead

get_static_generators(self)

This function allows to retrieve the (more exotic) static generators (as a lightsim2grid.elements.SGenContainer object, see Elements modeled for more information)

get_status_droop_hvdc(self, arg0)

Angle-droop regime of one HVDC line, see set_status_droop_hvdc().

get_status_droop_hvdc_vect(self)

Angle-droop regimes of every HVDC line, see set_status_droop_hvdc().

get_storage_target_p(self)

Get the active power setpoint of every storage unit at once, see get_shunt_target_p() and StorageInfo.

get_storage_theta(self)

Get the voltage angle (degree) of every storage unit's bus at once, see get_gen_theta() and StorageInfo.

get_storages(self)

This function allows to retrieve the storage units (as a lightsim2grid.elements.LoadContainer object, see Elements modeled for more information)

get_storages_res(self)

Get, for every storage unit at once, the (p_mw, q_mvar, v_kv) result triplet, see get_loads_res() and StorageInfo.

get_storages_res_full(self)

Get, for every storage unit at once, the (p_mw, q_mvar, v_kv, theta_deg) result quadruplet, see get_loads_res_full() and StorageInfo.

get_storages_status(self)

Get the connection status of every storage unit at once, see get_loads_status() and StorageInfo.

get_substation_names(self)

Get the name of every substation at once, see set_substation_names() / name.

get_substations(self)

This function allows to retrieve the substations (as a lightsim2grid.elements.SubstationContainer object, see Elements modeled for more information).

get_svcs(self)

Get the container of all the Static Var Compensators (SVC), as a lightsim2grid.elements.SvcContainer.

get_synch_status_both_side(self)

Current value of the synch_status_both_side flag, see set_synch_status_both_side().

get_theta_buses_solver(self)

Compact (bus, col) pair list for the theta unknowns, see get_p_buses_solver().

get_theta_cols_solver(self)

Jacobian column of each entry in get_theta_buses_solver(), same order.

get_trafo_names(self)

Names of the transformers, as set by set_trafo_names; empty if never set.

get_trafo_res1(self)

Get, for every transformer at once, the side-1 (hv) result quadruplet, see get_line_res1() and TrafoInfo.

get_trafo_res1_full(self)

Get, for every transformer at once, the side-1 (hv) result quintuplet, see get_line_res1_full() and TrafoInfo.

get_trafo_res2(self)

Get, for every transformer at once, the side-2 (lv) result quadruplet, see get_line_res1() and TrafoInfo.

get_trafo_res2_full(self)

Get, for every transformer at once, the side-2 (lv) result quintuplet, see get_line_res1_full() and TrafoInfo.

get_trafo_status(self)

Get the global connection status of every transformer at once, see get_lines_status() and TrafoInfo.

get_trafo_status_side1(self)

Per-side status of each transformer's side 1, see get_lines_status_side1().

get_trafo_status_side2(self)

Per-side status of each transformer's side 2, see get_lines_status_side1().

get_trafo_theta1(self)

Get the voltage angle (degree) of every transformer's side-1 (hv) bus at once, see get_line_theta1() and TrafoInfo.

get_trafo_theta2(self)

Get the voltage angle (degree) of every transformer's side-2 (lv) bus at once, see get_line_theta1() and TrafoInfo.

get_trafos(self)

This function allows to retrieve the transformers (as a lightsim2grid.elements.LineContainer object, see Elements modeled for more information)

get_turnedoff_gen_pv(self)

Whether a turned-off generator (or one with target_p_mw == 0) counts as a PV bus, as set by turnedoff_pv() / turnedoff_no_pv() (default: True, ie turnedoff_pv()).

get_vm_buses_solver(self)

Compact (bus, col) pair list for the Vm unknowns, see get_p_buses_solver().

get_vm_cols_solver(self)

Jacobian column of each entry in get_vm_buses_solver(), same order.

get_voltage_levels(self)

This function allows to retrieve the substations (as a lightsim2grid.elements.SubstationContainer object, see Elements modeled for more information).

id_ac_solver_to_me(self)

In lightsim2grid, buses are labelled from 0 to n-1 (if n denotes the total number of buses on the grid) [this is called "grid model bus id"]

id_dc_solver_to_me(self)

Same as lightsim2grid.network.LSGrid.id_ac_solver_to_me but only used for the DC approximation.

id_me_to_ac_solver(self)

In lightsim2grid, buses are labelled from 0 to n-1 (if n denotes the total number of buses on the grid) [this is called "grid model bus id"]

id_me_to_dc_solver(self)

Same as lightsim2grid.network.LSGrid.id_me_to_ac_solver but only used for the DC approximation.

init_bus(self, arg0, arg1, arg2, arg3, arg4)

Low-level / internal primitive, not part of the stable public API: called directly by lightsim2grid's own machinery (eg LightSimBackend, the grid loaders, or another part of the C++ core) rather than meant for everyday use.

init_bus_status(self)

Low-level / internal primitive, not part of the stable public API: called directly by lightsim2grid's own machinery (eg LightSimBackend, the grid loaders, or another part of the C++ core) rather than meant for everyday use.

init_dclines(self, arg0, arg1, arg2, arg3, ...)

Construct every HVDC line of the grid at once from these per-line arrays (both ends' buses, active power setpoint, loss percentage and voltage setpoints) -- see HvdcLineContainer / HvdcLineInfo.

init_generators(self, arg0, arg1, arg2, ...)

Construct every generator of the grid at once from these per-generator arrays (active power, voltage setpoint, reactive limits and bus) -- see GeneratorContainer / GenInfo.

init_generators_full(self, arg0, arg1, arg2, ...)

Same as init_generators(), but also taking a reactive power value and an explicit voltage_regulator_on flag per generator (used when the source format, eg pypowsybl, distinguishes a PV generator from a fixed-Q one explicitly).

init_hvdc_lines(self, arg0, arg1, arg2, ...)

Construct every HVDC line of the grid at once, like init_dclines() but also taking each converter station's type (VSC / LCC) -- see ConverterStationInfo.

init_loads(self, arg0, arg1, arg2)

Construct every load of the grid at once from these per-load arrays (active / reactive power and bus) -- see LoadContainer / LoadInfo.

init_powerlines(self, arg0, arg1, arg2, ...)

Construct every powerline of the grid at once from these per-line arrays (r/x/h in per-unit, plus each end's bus) -- see LineContainer / LineInfo for what each resulting attribute means.

init_powerlines_full(self, arg0, arg1, arg2, ...)

Same as init_powerlines(), but with independent shunt admittances h1 / h2 on each side instead of a single shared h -- see h1_pu / h2_pu.

init_sgens(self, arg0, arg1, arg2, arg3, ...)

Construct every static generator of the grid at once from these per-element arrays (active / reactive power, active power range and bus) -- see SGenContainer / SGenInfo.

init_shunt(self, arg0, arg1, arg2)

Construct every shunt of the grid at once from these per-shunt arrays (active / reactive power and bus) -- see ShuntContainer / ShuntInfo.

init_storages(self, arg0, arg1, arg2)

Construct every storage unit of the grid at once from these per-storage arrays (active / reactive power and bus) -- see StorageContainer / StorageInfo.

init_svcs(self, arg0, arg1, arg2, arg3, ...)

Construct every SVC of the grid at once from these per-element arrays (regulation mode, voltage / reactive setpoints, slope and susceptance limits) -- see SvcContainer / SvcInfo.

init_trafo(self, arg0, arg1, arg2, arg3, ...)

Construct every transformer of the grid at once, like init_trafo_pandapower() but taking an already-computed complex ratio directly instead of a pandapower tap step.

init_trafo_pandapower(self, arg0, arg1, ...)

Construct every transformer of the grid at once from pandapower-style parameters (tap step in percent rather than a ready-made ratio) -- see TrafoContainer / TrafoInfo, and lightsim2grid.network.init_from_pandapower() which uses this.

load_binary(path)

Load an object previously saved with save_binary().

load_binary_without_algorithm(path)

Load a grid saved with save_binary(), WITHOUT restoring the AC / DC solver it was saved with (nor that solver's configuration): the grid keeps the default solvers and you select one yourself with change_algorithm().

nb_connected_bus(self)

Returns (>0 integer) the number of connected buses on the powergrid (ignores the disconnected bus).

prevent_ac_cache_reuse(self)

Throw away what the AC family cached: its next powerflow starts from scratch (bus labelling, Ybus, Sbus, PV / PQ split, slack weights, the algorithm's own factorization, and the bus-connectivity snapshot used to detect topology changes).

prevent_cache_reuse(self)

Throw away what both families cached -- see lightsim2grid.network.LSGrid.prevent_ac_cache_reuse().

prevent_dc_cache_reuse(self)

Same as lightsim2grid.network.LSGrid.prevent_ac_cache_reuse(), for the DC family.

reactivate_bus(self, arg0)

Low-level / internal primitive, not part of the stable public API: called directly by lightsim2grid's own machinery (eg LightSimBackend, the grid loaders, or another part of the C++ core) rather than meant for everyday use.

reactivate_dcline(self, arg0)

Reconnect HVDC line dcline_id (both converter stations), the opposite of deactivate_dcline().

reactivate_gen(self, arg0)

Reconnect generator gen_id, the opposite of deactivate_gen().

reactivate_load(self, arg0)

Reconnect load load_id, the opposite of deactivate_load().

reactivate_powerline(self, arg0)

Reconnect powerline powerline_id (both sides), the opposite of deactivate_powerline().

reactivate_powerline_side1(self, arg0)

Reconnect only side 1 of a powerline.

reactivate_powerline_side2(self, arg0)

Reconnect only side 2 of a powerline.

reactivate_result_computation(self)

Allows to reactivate the computation of the flows, reactive power absorbed by generators etc.

reactivate_sgen(self, arg0)

Reconnect static generator sgen_id, the opposite of deactivate_sgen().

reactivate_shunt(self, arg0)

Reconnect shunt shunt_id, the opposite of deactivate_shunt().

reactivate_storage(self, arg0)

Reconnect storage unit storage_id, the opposite of deactivate_storage().

reactivate_svc(self, arg0)

Reconnect SVC svc_id, the opposite of deactivate_svc().

reactivate_trafo(self, arg0)

Reconnect transformer trafo_id (both sides), the opposite of deactivate_trafo().

reactivate_trafo_side1(self, arg0)

Reconnect only side 1 of a transformer.

reactivate_trafo_side2(self, arg0)

Reconnect only side 2 of a transformer.

remove_gen_slackbus(self, arg0)

Remove generator gen_id from the distributed slack (the opposite of add_gen_slackbus()) -- see is_slack.

save_binary(self, path[, atomic])

Save this object's state to a fast custom binary file (additive alternative to pickle).

set_ac_algo_config(self, config)

Apply a lightsim2grid.algorithm.AlgoConfig to the AC solver (restores scaling/refactor policy and parameters).

set_bus_voltage_limits(self, arg0, arg1)

Set the per-bus min/max operating voltage (in kV), one value per bus (see get_bus_vn_kv()).

set_dc_algo_config(self, config)

Apply a lightsim2grid.algorithm.AlgoConfig to the DC solver.

set_dcline_names(self, arg0)

Set the HVDC lines' names, one per HVDC line (raises if the length does not match the number of HVDC lines).

set_gen_names(self, arg0)

Set the generators' names, one per generator (raises if the length does not match the number of generators).

set_gen_pos_topo_vect(self, arg0)

Set, for every generator at once, its position in the topology vector, see set_load_pos_topo_vect() and GenInfo.

set_gen_regulated_bus(self, arg0, arg1)

Set the grid bus whose voltage a generator regulates ("remote voltage control", see lightsim2grid.elements.GenInfo.regulated_bus_id; bus == own bus for local control).

set_gen_to_subid(self, arg0)

Set, for every generator at once, the substation it belongs to, see set_load_to_subid() and GenInfo.

set_ignore_status_global(self, arg0)

Ignore the global_status flags for powerlines and transformers (set to True if you want to control each side of a powerline / transformer independently).

set_init_vm_pu(self, arg0)

Set the flat-start voltage magnitude (pu), used to initialize every bus's Vm before an AC powerflow when no better guess is available (see ac_pf()'s Vinit), and directly as every bus's Vm for a DC powerflow (see dc_pf()).

set_line_current_limit_side1(self, arg0)

Set the side-1 current limit of each powerline, in kA (see lightsim2grid.elements.LineInfo.limit_a1_ka).

set_line_current_limit_side2(self, arg0)

Set the side-2 current limit of each powerline, in kA (see lightsim2grid.elements.LineInfo.limit_a2_ka).

set_line_names(self, arg0)

Set the powerlines' names, one per powerline (raises if the length does not match the number of powerlines).

set_line_pos1_topo_vect(self, arg0)

Set, for every powerline at once, its side-1 position in the topology vector -- see pos1_topo_vect, see also set_load_pos_topo_vect().

set_line_pos2_topo_vect(self, arg0)

Set, for every powerline at once, its side-2 position in the topology vector, see set_line_pos1_topo_vect().

set_line_to_sub1_id(self, arg0)

Set, for every powerline at once, the substation its side 1 belongs to -- see sub1_id, see also set_load_to_subid().

set_line_to_sub2_id(self, arg0)

Set, for every powerline at once, the substation its side 2 belongs to, see set_line_to_sub1_id().

set_load_names(self, arg0)

Set the loads' names, one per load (raises if the length does not match the number of loads).

set_load_pos_topo_vect(self, arg0)

Set, for every load at once, its position in the topology vector -- see pos_topo_vect.

set_load_to_subid(self, arg0)

Set, for every load at once, the substation it belongs to -- see sub_id.

set_max_nb_bus_per_sub(self, arg0)

Set the (constant, grid-wide) maximum number of busbars per substation.

set_n_sub(self, arg0)

Set the number of substations of the grid (unchecked against anything else -- see set_max_nb_bus_per_sub(), which does cross-check it against the bus count from init_bus()).

set_reference_slack_bus(self, arg0)

Force a (gridmodel) bus to be the angle reference among the slack buses (reordered to slack_ids[0]) without changing the slack set / weights; -1 clears it.

set_sgen_names(self, arg0)

Set the static generators' names, one per static generator (raises if the length does not match the number of static generators).

set_shunt_names(self, arg0)

Set the shunts' names, one per shunt (raises if the length does not match the number of shunts).

set_shunt_to_subid(self, arg0)

Set, for every shunt at once, the substation it belongs to, see set_load_to_subid() and ShuntInfo.

set_sn_mva(self, arg0)

Set the base power (MVA) of the grid's per-unit system: Sbus is expressed in this unit internally, every MW / MVAr result is the per-unit value multiplied back by it, and the solver's convergence tolerance is scaled by it (see ac_pf()).

set_status_droop_hvdc(self, arg0, arg1)

Set the angle-droop regime of an HVDC line (see lightsim2grid.elements.HvdcLineInfo.status_droop): 0 = linear, +1 = saturated side 1 to side 2, -1 = saturated side 2 to side 1.

set_storage_names(self, arg0)

Set the storage units' names, one per storage unit (raises if the length does not match the number of storage units).

set_storage_pos_topo_vect(self, arg0)

Set, for every storage unit at once, its position in the topology vector, see set_load_pos_topo_vect() and StorageInfo.

set_storage_to_subid(self, arg0)

Set, for every storage unit at once, the substation it belongs to, see set_load_to_subid() and StorageInfo.

set_substation_names(self, arg0)

Set the name of every substation at once -- see name.

set_svc_names(self, arg0)

Set the Static Var Compensators' names, one per SVC (raises if the length does not match the number of SVCs).

set_synch_status_both_side(self, arg0)

Synchronize the status of each side of a powerline / transformer: if you disconnect one side, the other side is also disconnected.

set_trafo_current_limit_side1(self, arg0)

Set the side-1 current limit of each transformer, in kA (see lightsim2grid.elements.TrafoInfo.limit_a1_ka).

set_trafo_current_limit_side2(self, arg0)

Set the side-2 current limit of each transformer, in kA (see lightsim2grid.elements.TrafoInfo.limit_a2_ka).

set_trafo_names(self, arg0)

Set the transformers' names, one per transformer (raises if the length does not match the number of transformers).

set_trafo_pos1_topo_vect(self, arg0)

Set, for every transformer at once, its side-1 (hv) position in the topology vector, see set_line_pos1_topo_vect() and TrafoInfo.

set_trafo_pos2_topo_vect(self, arg0)

Set, for every transformer at once, its side-2 (lv) position in the topology vector, see set_line_pos1_topo_vect() and TrafoInfo.

set_trafo_shift_dependent_rx(self, enable, ...)

Declare that (some) transformers have a series impedance (r, x) that depends on their phase-shift angle alpha, supplied as a per-transformer table of sample points alpha (rad) -> r/x correction (%) (the per-step r/x deltas of a pypowsybl phase-tap-changer; r% == x%).

set_trafo_to_sub1_id(self, arg0)

Set, for every transformer at once, the substation its side 1 (hv) belongs to, see set_line_to_sub1_id() and TrafoInfo.

set_trafo_to_sub2_id(self, arg0)

Set, for every transformer at once, the substation its side 2 (lv) belongs to, see set_line_to_sub1_id() and TrafoInfo.

tell_recompute_sbus(self)

Low-level / internal primitive, not part of the stable public API: called directly by lightsim2grid's own machinery (eg LightSimBackend, the grid loaders, or another part of the C++ core) rather than meant for everyday use.

tell_recompute_ybus(self)

Low-level / internal primitive, not part of the stable public API: called directly by lightsim2grid's own machinery (eg LightSimBackend, the grid loaders, or another part of the C++ core) rather than meant for everyday use.

tell_solver_need_reset(self)

Backward-compatible name of lightsim2grid.network.LSGrid.prevent_cache_reuse(): throw away what both solver families cached, so their next powerflow starts from scratch.

tell_ybus_change_sparsity_pattern(self)

Low-level / internal primitive, not part of the stable public API: called directly by lightsim2grid's own machinery (eg LightSimBackend, the grid loaders, or another part of the C++ core) rather than meant for everyday use.

total_bus(self)

Returns (>0 integer) the total number of buses in the powergrid (both connected and disconnected)

turnedoff_no_pv(self)

Turned-off generators (or generators with target_p_mw == 0) will not be PV buses: they will not maintain voltage.

turnedoff_pv(self)

Turned-off generators (or generators with target_p_mw == 0) will be PV buses: they will maintain voltage.

unset_changes(self)

Historical, manual way of telling the grid "the data cached for the solvers matches me, reuse it".

update_gens_p(self, arg0, arg1)

Masked, vectorized equivalent of change_p_gen(): for every generator i with has_changed[i], set its active power setpoint to new_values[i].

update_gens_v(self, arg0, arg1)

Masked, vectorized equivalent of change_v_gen(), see update_gens_p().

update_loads_p(self, arg0, arg1)

Masked, vectorized equivalent of change_p_load(), see update_gens_p().

update_loads_q(self, arg0, arg1)

Masked, vectorized equivalent of change_q_load(), see update_gens_p().

update_sgens_p(self, arg0, arg1)

Masked, vectorized equivalent of change_p_sgen(), see update_gens_p().

update_slack_weights(self, arg0)

Recompute the distributed-slack weight of every generator, restricted to the ones for which could_be_slack is True (a boolean array, one entry per generator): each such generator's weight becomes proportional to its abs(target_p_mw) (or, if every candidate's target_p_mw is 0., an equal split among them).

update_slack_weights_by_id(self, arg0)

Same as update_slack_weights(), but slack_ids is a list of candidate generator ids instead of a per-generator boolean mask.

update_storages_p(self, arg0, arg1)

Masked, vectorized equivalent of change_p_storage(), see update_gens_p().

update_topo(self, arg0, arg1)

Masked, vectorized bus-change equivalent of change_bus_load() / change_bus_gen() / change_bus_storage() / change_bus1_powerline() / change_bus2_powerline() / change_bus1_trafo() / change_bus2_trafo(), all at once.

Attributes:

timer_last_ac_pf

Wall-clock time (seconds) of the last ac_pf() call, from pre-processing through result storage -- the whole call, not just the solver's own internal timers (see lightsim2grid.algorithm.NR_SparseLU.get_timers() / get_timers_jacobian() for those).

timer_last_dc_pf

Same as timer_last_ac_pf, but for the last dc_pf() call.

ac_pf(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: Annotated[numpy.typing.NDArray[numpy.complex128], '[m, 1]'], arg1: SupportsInt | SupportsIndex, arg2: SupportsFloat | SupportsIndex) Annotated[numpy.typing.NDArray[numpy.complex128], '[m, 1]']

Allows to perform an AC (alternating current) powerflow.

Note

It is expected that you provide a complex number even for the buses that are disconnected in the grid model. They will not be affected (if the powerflow converges) and you can put anything you want there. We keep the public interface this way to avoid headaches with the bus order between the grid model and the solver (you can refer to lightsim2grid.network.LSGrid.id_me_to_ac_solver() and lightsim2grid.network.LSGrid.id_ac_solver_to_me() if you still want to have a look)

See also

lightsim2grid.network.LSGrid.dc_pf() if you want to perform DC powerflow (same interface, same results, same behaviour)

Warning

The input vector V is modified (and is equal to the resulting vector V)

Parameters:
  • V – It expects a complex voltage vector (having as many components as the total number of buses in the grid.) representing the initial guess of the resulting flows. This vector will be modified !

  • max_iter (int) – Maximum number of iterations allowed (this might be ignored) and should be a >= 0 integer

  • tol (float) – Tolerance criteria to stop the computation. This should be > 0 real number.

Returns:

A complex vector given the complex voltage at each buses of the grid model. Will be empty when the powerflow diverged.

Return type:

V

Examples

# create a grid model
import grid2op
from lightsim2grid import LightSimBackend
env_name = ...  # eg "l2rpn_case14_sandbox"
env = grid2op.make(env_name, backend=LightSimBackend())
grid_model = env.backend._grid

# have an initial guess for the complex voltage at each bus
Vinit = np.ones(grid_model.total_bus(), dtype=complex)

# maximum number of iteration
nb_iter = 10  # a good default

# tolerance
tol = 1e-8

V = grid_model.ac_pf(Vinit, nb_iter, tol)
# if the powerflow has converged, V.shape > 0 otherwise V is empty (size 0)
# the original V is modified in the process !
add_gen_slackbus(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsInt | SupportsIndex, arg1: SupportsFloat | SupportsIndex) None

Make generator gen_id participate in the distributed slack, with the given (strictly positive) weight – see is_slack / slack_weight. Calling it again on the same generator updates its weight. Raises for an invalid gen_id or a non-positive weight.

allow_ac_cache_reuse(self: lightsim2grid.lightsim2grid_cpp.LSGrid, allowed: bool) None

Enable (default) or disable cache reuse for the AC solver family.

When enabled, an AC powerflow reuses what the previous AC powerflow built – the solver bus labelling, the admittance matrix Ybus, the injection vector Sbus, the PV / PQ split, the slack weights – and only re-stamps the parts the grid reports as modified since. Every AC powerflow marks the AC family “in sync” on its way out, so this needs nothing from you.

When disabled, every AC powerflow rebuilds all of it from the grid, every time.

The result is identical either way. This switch exists to answer “is this wrong number a caching bug?” in one line, and as a safety net for code that mutates the C++ containers behind lightsim2grid.network.LSGrid’s back instead of going through its change_* / deactivate_* / reactivate_* methods (which set the invalidation flags themselves). Expect the rebuild to cost roughly 20-25% of the time of a small powerflow.

Parameters:
allow_cache_reuse(self: lightsim2grid.lightsim2grid_cpp.LSGrid, allowed: bool) None

Convenience: set lightsim2grid.network.LSGrid.allow_ac_cache_reuse() and lightsim2grid.network.LSGrid.allow_dc_cache_reuse() at once.

Parameters:

allowed (bool) – Whether both families may reuse their cache.

Examples

# is this result a caching artefact?
grid.allow_cache_reuse(False)
v_no_cache = grid.ac_pf(v_init, 10, 1e-8)
grid.allow_cache_reuse(True)
# v_no_cache and the cached result must agree bit for bit

Added in version 1.0.0.

allow_dc_cache_reuse(self: lightsim2grid.lightsim2grid_cpp.LSGrid, allowed: bool) None

Enable (default) or disable cache reuse for the DC solver family.

Exactly lightsim2grid.network.LSGrid.allow_ac_cache_reuse(), for the DC solver: its own bus labelling, its own Bbus / Pbus, its own PV / PQ split and slack weights. The two families are fully independent – switching one off says nothing about the other, and neither can invalidate or overwrite the other’s data.

Parameters:
  • allowed (bool) – Whether the DC family may reuse its cache.

  • versionadded: (..) – 1.0.0:

assign_slack_to_most_connected(self: lightsim2grid.lightsim2grid_cpp.LSGrid) tuple[int, int]

Pick a single new slack generator automatically: among the buses with at least one generator producing (target_p_mw > 0), the one with the most powerline / transformer ends connected to it: then, at that bus, the generator with the highest abs(target_p_mw).

Clears every existing slack assignment first, so the result is always a single slack generator, not a distributed one.

Returns (bus_id, gen_id) (gridmodel ids) of the bus and generator picked.

available_algorithm_names(self: lightsim2grid.lightsim2grid_cpp.LSGrid) list[str]

Returns the names of all registered algorithms, including any loaded plugins, as a list of string.

available_default_algorithms(self: lightsim2grid.lightsim2grid_cpp.LSGrid) list[lightsim2grid.lightsim2grid_cpp.AlgorithmType]

Return the list of the names of the algorithm available on the current lightsim2grid installation.

This is a list of lightsim2grid.algorithm.AlgorithmType.

available_solver_names(self: lightsim2grid.lightsim2grid_cpp.LSGrid) list[str]

DEPRECATED: use ‘available_algorithm_names’ instead

available_solvers(self: lightsim2grid.lightsim2grid_cpp.LSGrid) list[lightsim2grid.lightsim2grid_cpp.AlgorithmType]

DEPRECATED: use ‘available_default_algorithms’ instead

change_algorithm(*args, **kwargs)

Overloaded function.

  1. change_algorithm(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: lightsim2grid.lightsim2grid_cpp.AlgorithmType) -> None

    This function allows to control which solver is used during the powerflow. See the section Available powerflow algorithms for more information about them.

    See also

    lightsim2grid.algorithm.AlgorithmType for a list of the available algorithms (NB: some algorithms might not be available on all platform)

    Note

    If the algorithm type entered is a DC algorithm (eg from lightsim2grid.algorithm.AlgorithmType, DC_SparseLU, DC_KLU or DC_NICSLU), it will change the _dc_solver otherwise the regular _solver is modified.

    Examples

    from lightsim2grid.algorithm import AlgorithmType
    # init the grid model
    from lightsim2grid.network import init_from_pandapower
    pp_net = ...  # any pandapower grid
    lightsim_grid_model = init_from_pandapower(pp_net)  # some warnings might be issued as well as some warnings
    
    # change the algorithm used for the powerflow
    # to use internally a Newton Raphson algorithm with the Eigen sparse LU linear solver
    lightsim_grid_model.change_algorithm(AlgorithmType.NR_SparseLU)
    
  2. change_algorithm(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: str) -> None

    Change the AC (or DC) algorithm by registry name. Accepts built-in names and plugin names registered via load_solver_plugin().

    See also

    change_algorithm() to change it by lightsim2grid.algorithm.AlgorithmType instead.

change_bus1_dcline(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: typing.SupportsInt | typing.SupportsIndex, arg1: ls2g::IntClass<1>) None

Move converter station 1 of HVDC line dcline_id to bus new_gridmodel_bus_id (sets bus1_id), see change_bus_load() for the bus id convention.

change_bus1_powerline(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsInt | SupportsIndex, arg1: SupportsInt | SupportsIndex) None

Move side 1 of powerline powerline_id to bus new_gridmodel_bus_id (sets bus1_id), see change_bus_load() for the bus id convention.

change_bus1_trafo(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsInt | SupportsIndex, arg1: SupportsInt | SupportsIndex) None

Move side 1 (hv) of transformer trafo_id to bus new_gridmodel_bus_id (sets bus1_id), see change_bus_load() for the bus id convention.

change_bus2_dcline(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: typing.SupportsInt | typing.SupportsIndex, arg1: ls2g::IntClass<1>) None

Move converter station 2 of HVDC line dcline_id to bus new_gridmodel_bus_id (sets bus2_id), see change_bus_load() for the bus id convention.

change_bus2_powerline(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsInt | SupportsIndex, arg1: SupportsInt | SupportsIndex) None

Move side 2 of powerline powerline_id to bus new_gridmodel_bus_id (sets bus2_id), see change_bus_load() for the bus id convention.

change_bus2_trafo(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsInt | SupportsIndex, arg1: SupportsInt | SupportsIndex) None

Move side 2 (lv) of transformer trafo_id to bus new_gridmodel_bus_id (sets bus2_id), see change_bus_load() for the bus id convention.

change_bus_gen(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsInt | SupportsIndex, arg1: SupportsInt | SupportsIndex) None

Move generator gen_id to bus new_gridmodel_bus_id (sets bus_id), see change_bus_load() for the bus id convention.

change_bus_load(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsInt | SupportsIndex, arg1: SupportsInt | SupportsIndex) None

Move load load_id to bus new_gridmodel_bus_id (sets bus_id). The bus id is in “gridmodel” convention, between 0 and n_busbar_per_sub * n_sub.

change_bus_sgen(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsInt | SupportsIndex, arg1: SupportsInt | SupportsIndex) None

Move static generator sgen_id to bus new_gridmodel_bus_id (sets bus_id), see change_bus_load() for the bus id convention.

change_bus_shunt(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsInt | SupportsIndex, arg1: SupportsInt | SupportsIndex) None

Move shunt shunt_id to bus new_gridmodel_bus_id (sets bus_id), see change_bus_load() for the bus id convention.

change_bus_storage(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsInt | SupportsIndex, arg1: SupportsInt | SupportsIndex) None

Move storage unit storage_id to bus new_gridmodel_bus_id (sets bus_id), see change_bus_load() for the bus id convention.

change_bus_svc(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsInt | SupportsIndex, arg1: SupportsInt | SupportsIndex) None

Move SVC svc_id to bus new_gridmodel_bus_id (sets bus_id), see change_bus_load() for the bus id convention.

change_p_dcline(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsInt | SupportsIndex, arg1: SupportsFloat | SupportsIndex) None

Change HVDC line dcline_id’s active power setpoint (sets p_setpoint_mw, the power drawn at the rectifier; target_p1_mw / p2_mw are then derived from it and converters_mode). Raises if the line is disconnected (unlike the AC setpoint setters above, which never throw).

change_p_gen(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsInt | SupportsIndex, arg1: SupportsFloat | SupportsIndex) None

Change generator gen_id’s active power setpoint (sets target_p_mw), see change_p_load() for the “never throws” note.

change_p_load(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsInt | SupportsIndex, arg1: SupportsFloat | SupportsIndex) None

Change load load_id’s active power setpoint (sets target_p_mw). Never throws, even on a disconnected load (the grid2op action pipeline may apply changes to disconnected elements).

change_p_sgen(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsInt | SupportsIndex, arg1: SupportsFloat | SupportsIndex) None

Change static generator sgen_id’s active power setpoint (sets target_p_mw), see change_p_load() for the “never throws” note.

change_p_shunt(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsInt | SupportsIndex, arg1: SupportsFloat | SupportsIndex) None

Change shunt shunt_id’s active power (sets target_p_mw), see change_p_load() for the “never throws” note.

change_p_storage(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsInt | SupportsIndex, arg1: SupportsFloat | SupportsIndex) None

Change storage unit storage_id’s active power setpoint (sets target_p_mw), see change_p_load() for the “never throws” note.

change_q_load(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsInt | SupportsIndex, arg1: SupportsFloat | SupportsIndex) None

Change load load_id’s reactive power setpoint (sets target_q_mvar), see change_p_load() for the “never throws” note.

change_q_sgen(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsInt | SupportsIndex, arg1: SupportsFloat | SupportsIndex) None

Change static generator sgen_id’s reactive power setpoint (sets target_q_mvar), see change_p_load() for the “never throws” note.

change_q_shunt(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsInt | SupportsIndex, arg1: SupportsFloat | SupportsIndex) None

Change shunt shunt_id’s reactive power (sets target_q_mvar), see change_p_load() for the “never throws” note.

change_q_storage(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsInt | SupportsIndex, arg1: SupportsFloat | SupportsIndex) None

Change storage unit storage_id’s reactive power setpoint (sets target_q_mvar), see change_p_load() for the “never throws” note.

change_ratio_trafo(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsInt | SupportsIndex, arg1: SupportsFloat | SupportsIndex) None

Change the tap ratio of a given transformer (see lightsim2grid.elements.TrafoInfo.ratio).

See also

change_shift_trafo() / change_shift_trafo_deg() to change its phase-shift angle instead.

change_shift_trafo(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsInt | SupportsIndex, arg1: SupportsFloat | SupportsIndex) None

Change the phase-shift angle for a given transformer.

Warning

It should be expressed in radian (not in degree) – see change_shift_trafo_deg() for the degree variant.

If the flag ignore_tap_side_for_shift (eg lightsim_grid_model.get_trafos().ignore_tap_side_for_shift) is False (the default), the angle is given at the tap side (side 1 or side 2). If this flag is True (eg the grid comes from pandapower) the phase-shift angle should instead be given at side 1 (the hv side in pandapower).

change_shift_trafo_deg(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsInt | SupportsIndex, arg1: SupportsFloat | SupportsIndex) None

Same as change_shift_trafo() but the phase-shift angle is expressed in degree, not in radian.

change_solver(*args, **kwargs)

Overloaded function.

  1. change_solver(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: lightsim2grid.lightsim2grid_cpp.AlgorithmType) -> None

DEPRECATED: use ‘change_algorithm’ instead

  1. change_solver(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: str) -> None

DEPRECATED: use ‘change_algorithm’ instead

change_v1_dcline(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsInt | SupportsIndex, arg1: SupportsFloat | SupportsIndex) None

Change the voltage setpoint of converter station 1 of HVDC line dcline_id (sets target_vm1_pu).

change_v2_dcline(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsInt | SupportsIndex, arg1: SupportsFloat | SupportsIndex) None

Change the voltage setpoint of converter station 2 of HVDC line dcline_id (sets target_vm2_pu).

change_v_gen(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsInt | SupportsIndex, arg1: SupportsFloat | SupportsIndex) None

Change generator gen_id’s voltage setpoint (sets target_vm_pu), see change_p_load() for the “never throws” note.

The voltage setpoint is expressed in pu, NOT kV.

check_grid(self: lightsim2grid.lightsim2grid_cpp.LSGrid) None

Check that the grid is internally consistent and safe to run a powerflow on.

It verifies that every index the grid carries is in range: the bus id of each element (load, generator, static generator, storage, shunt, line, transformer, hvdc line, static var compensator), the substation id and the position in the topology vector (both optional), and the generator slack / remote-regulated bus references.

This is called automatically when a grid is loaded (from a pickle or from the fast binary format), and by the grid loaders (from pandapower, pypowsybl, matpower or powermodels). You normally do not need to call it yourself; it is exposed so you can validate a grid you built or modified by hand.

Raises:
  • IndexError – (C++ std::out_of_range) if an index is out of range.

  • RuntimeError – (C++ std::runtime_error) on a structural inconsistency.

Returns:

If the grid is consistent.

Return type:

None

Notes

Runs in time proportional to the number of elements in the grid, so it is cheap compared to a powerflow.

check_solution(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: Annotated[numpy.typing.NDArray[numpy.complex128], '[m, 1]'], arg1: bool) Annotated[numpy.typing.NDArray[numpy.complex128], '[m, 1]']

This function allows to check that a given complex voltage vector satisfies the KCL or not, given the state of the sytem.

Note

It is expected that you provide a complex number even for the buses that are disconnected in the grid model. They will not be ignored so you can put anything you want. We keep the public interface this way to avoid headaches with the bus order between the grid model and the solver (you can refer to lightsim2grid.network.LSGrid.id_me_to_ac_solver() and lightsim2grid.network.LSGrid.id_ac_solver_to_me() if you still want to have a look)

See also

lightsim2grid.physical_law_checker.PhysicalLawChecker for an easier to use, more pythonic function !

Parameters:
  • V – It expects a complex voltage vector (having as many components as the total number of buses in the grid.) representing the vector you want to test.

  • check_q_limits (bool) – whether you want to take into account the reactive limit of generators when performing the check

Returns:

A complex vector having the size of the number of total buses on the grid, given, for each of them, the active / reactive power mismatch at each bus (ie the power you would need to take from the grid and have the input vector V checking the KCL given the current state of the grid)

Return type:

mismatch

compute_newton(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: Annotated[numpy.typing.NDArray[numpy.complex128], '[m, 1]'], arg1: SupportsInt | SupportsIndex, arg2: SupportsFloat | SupportsIndex) Annotated[numpy.typing.NDArray[numpy.complex128], '[m, 1]']

Allows to perform an AC (alternating current) powerflow.

Note

It is expected that you provide a complex number even for the buses that are disconnected in the grid model. They will not be affected (if the powerflow converges) and you can put anything you want there. We keep the public interface this way to avoid headaches with the bus order between the grid model and the solver (you can refer to lightsim2grid.network.LSGrid.id_me_to_ac_solver() and lightsim2grid.network.LSGrid.id_ac_solver_to_me() if you still want to have a look)

See also

lightsim2grid.network.LSGrid.dc_pf() if you want to perform DC powerflow (same interface, same results, same behaviour)

Warning

The input vector V is modified (and is equal to the resulting vector V)

Parameters:
  • V – It expects a complex voltage vector (having as many components as the total number of buses in the grid.) representing the initial guess of the resulting flows. This vector will be modified !

  • max_iter (int) – Maximum number of iterations allowed (this might be ignored) and should be a >= 0 integer

  • tol (float) – Tolerance criteria to stop the computation. This should be > 0 real number.

Returns:

A complex vector given the complex voltage at each buses of the grid model. Will be empty when the powerflow diverged.

Return type:

V

Examples

# create a grid model
import grid2op
from lightsim2grid import LightSimBackend
env_name = ...  # eg "l2rpn_case14_sandbox"
env = grid2op.make(env_name, backend=LightSimBackend())
grid_model = env.backend._grid

# have an initial guess for the complex voltage at each bus
Vinit = np.ones(grid_model.total_bus(), dtype=complex)

# maximum number of iteration
nb_iter = 10  # a good default

# tolerance
tol = 1e-8

V = grid_model.ac_pf(Vinit, nb_iter, tol)
# if the powerflow has converged, V.shape > 0 otherwise V is empty (size 0)
# the original V is modified in the process !
consider_only_main_component(self: lightsim2grid.lightsim2grid_cpp.LSGrid) None

Restrict the grid to its main synchronous component: starting a breadth-first search from the slack bus(es) over the branch graph (powerlines, transformers, and any other connecting element), find every bus reachable from them, then disconnect every element with no bus in that component.

An HVDC line with only one converter station in the main component is not fully disconnected: the in-main-component converter stays active (still injecting / regulating its scheduled power), and only the out-of-component one is opened – see lightsim2grid.elements.HvdcLineContainer.

Requires at least one slack bus to already be defined (see assign_slack_to_most_connected()); raises otherwise.

copy(self: lightsim2grid.lightsim2grid_cpp.LSGrid) lightsim2grid.lightsim2grid_cpp.LSGrid

Return a full, independent deep copy of this grid.

dc_pf(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: Annotated[numpy.typing.NDArray[numpy.complex128], '[m, 1]'], arg1: SupportsInt | SupportsIndex, arg2: SupportsFloat | SupportsIndex) Annotated[numpy.typing.NDArray[numpy.complex128], '[m, 1]']

This function has the same interface, inputs, outputs, behaviour, etc. as the lightsim2grid.network.LSGrid.ac_pf().

deactivate_bus(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsInt | SupportsIndex) None

Low-level / internal primitive, not part of the stable public API: called directly by lightsim2grid’s own machinery (eg LightSimBackend, the grid loaders, or another part of the C++ core) rather than meant for everyday use.

Warning

Argument validation here is deliberately minimal or absent, and its exact behavior / signature may change between releases without notice. Prefer the higher-level methods documented elsewhere on this class (or grid2op’s own API) unless you specifically need this one and understand what it does internally.

deactivate_dcline(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsInt | SupportsIndex) None

Disconnect HVDC line dcline_id entirely (both converter stations) – sets connected_global (and both connected1 / connected2) to False. See deactivate_dcline_side1() / deactivate_dcline_side2() to disconnect only one converter station (“half-open”).

deactivate_dcline_side1(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsInt | SupportsIndex) None

Disconnect only converter station 1 of an HVDC line; station 2 stays active (injecting / regulating).

deactivate_dcline_side2(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsInt | SupportsIndex) None

Disconnect only converter station 2 of an HVDC line; station 1 stays active (injecting / regulating).

deactivate_gen(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsInt | SupportsIndex) None

Disconnect generator gen_id – sets connected to False.

deactivate_load(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsInt | SupportsIndex) None

Disconnect load load_id – sets connected to False.

deactivate_powerline(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsInt | SupportsIndex) None

Disconnect powerline powerline_id entirely (both sides) – sets connected_global (and both connected1 / connected2) to False. See deactivate_powerline_side1() / deactivate_powerline_side2() to disconnect only one side (“half-open”).

deactivate_powerline_side1(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsInt | SupportsIndex) None

Disconnect only side 1 of a powerline (half-open). Needs set_synch_status_both_side(False) to keep side 2 connected.

deactivate_powerline_side2(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsInt | SupportsIndex) None

Disconnect only side 2 of a powerline (half-open). Needs set_synch_status_both_side(False) to keep side 1 connected.

deactivate_result_computation(self: lightsim2grid.lightsim2grid_cpp.LSGrid) None

Allows to deactivate the computation of the flows, reactive power absorbed by generators etc. to gain a bit of time when it is not needed.

deactivate_sgen(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsInt | SupportsIndex) None

Disconnect static generator sgen_id – sets connected to False.

deactivate_shunt(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsInt | SupportsIndex) None

Disconnect shunt shunt_id – sets connected to False.

deactivate_storage(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsInt | SupportsIndex) None

Disconnect storage unit storage_id – sets connected to False.

deactivate_svc(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsInt | SupportsIndex) None

Disconnect SVC svc_id – sets connected to False (equivalent to setting its regulation_mode to OFF for powerflow purposes, but does not change the stored regulation_mode value).

deactivate_trafo(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsInt | SupportsIndex) None

Disconnect transformer trafo_id entirely (both sides) – sets connected_global (and both connected1 / connected2) to False. See deactivate_trafo_side1() / deactivate_trafo_side2() to disconnect only one side (“half-open”).

deactivate_trafo_side1(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsInt | SupportsIndex) None

Disconnect only side 1 of a transformer (half-open). Needs set_synch_status_both_side(False) to keep side 2 connected.

deactivate_trafo_side2(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsInt | SupportsIndex) None

Disconnect only side 2 of a transformer (half-open). Needs set_synch_status_both_side(False) to keep side 1 connected.

debug_get_Bp_python(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: lightsim2grid.lightsim2grid_cpp.FDPFMethod) scipy.sparse.csc_matrix[numpy.float64]

Low-level / internal primitive, not part of the stable public API: called directly by lightsim2grid’s own machinery (eg LightSimBackend, the grid loaders, or another part of the C++ core) rather than meant for everyday use.

Warning

Argument validation here is deliberately minimal or absent, and its exact behavior / signature may change between releases without notice. Prefer the higher-level methods documented elsewhere on this class (or grid2op’s own API) unless you specifically need this one and understand what it does internally.

debug_get_Bpp_python(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: lightsim2grid.lightsim2grid_cpp.FDPFMethod) scipy.sparse.csc_matrix[numpy.float64]

Low-level / internal primitive, not part of the stable public API: called directly by lightsim2grid’s own machinery (eg LightSimBackend, the grid loaders, or another part of the C++ core) rather than meant for everyday use.

Warning

Argument validation here is deliberately minimal or absent, and its exact behavior / signature may change between releases without notice. Prefer the higher-level methods documented elsewhere on this class (or grid2op’s own API) unless you specifically need this one and understand what it does internally.

get_2_windings_transformers(self: lightsim2grid.lightsim2grid_cpp.LSGrid) lightsim2grid.lightsim2grid_cpp.TrafoContainer

This function allows to retrieve the transformers (as a lightsim2grid.elements.LineContainer object, see Elements modeled for more information)

Examples

# init the grid model
from lightsim2grid.network import init_from_pandapower
pp_net = ...  # any pandapower grid
lightsim_grid_model = init_from_pandapower(pp_net)  # some warnings might be issued as well as some warnings

# usage example: print some information about the trafos
print([el.x_pu for el in lightsim_grid_model.get_trafos()]) # to print the "x" for each transformer
get_Bf(self: lightsim2grid.lightsim2grid_cpp.LSGrid) scipy.sparse.csc_matrix[numpy.float64]

Returns the “Bus from” matrix, with the bus having the gridmodel id (sparse matrix).

More specifically, it is a matrix with (nb line + nb trafo) rows and (nb total bus) columns.

For each powerline / transformer (row i), there is a +1 for the “origin side” bus and a -1 for the “extremity side” bus if the line / trafo is connected. If it is disconnected then the associated row will be full of 0.

Note

First len(gridmodel.get_lines()) rows represent the powerlines, the remaining len(gridmodel.get_trafos()) represent transformers.

See also

lightsim2grid.network.LSGrid.get_Bf_solver() which will give the same matrix but with buses with the “solver” labelling (thus having no columns of 0)

get_Bf_solver(self: lightsim2grid.lightsim2grid_cpp.LSGrid) scipy.sparse.csc_matrix[numpy.float64]

Returns the “Bus from” matrix, with the bus having the solver id (sparse matrix).

More specifically, it is a matrix with (nb line + nb trafo) rows and (nb connected bus) columns.

For each powerline / transformer (row i), there is a +1 for the “origin side” bus and a -1 for the “extremity side” bus if the line / trafo is connected. If it is disconnected then the associated row will be full of 0.

Note

First len(gridmodel.get_lines()) rows represent the powerlines, the remaining len(gridmodel.get_trafos()) represent transformers.

See also

lightsim2grid.network.LSGrid.get_Bf() which will give the same matrix but with the buses having the “gridmodel” labelling

get_J_solver(self: lightsim2grid.lightsim2grid_cpp.LSGrid) scipy.sparse.csc_matrix[numpy.float64]

Returns the Jacobian matrix used for solving the powerflow as a scipy sparse CSC matrix matrix of real number.

The “jacobian” matrix is only available for some powerflow algorithms (the one based on the Newton Raphson algorithm) and we provide it only for the last computed iteration.

Danger

They are labelled with the solver labelling, which corresponds to the previous (before version 0.9.0) behaviour of this function, which used to be called get_J.

Added in version 0.9.0: This function is the renamed get_J of earlier lightsim2grid versions. Unlike lightsim2grid.network.LSGrid.get_Va()/lightsim2grid.network.LSGrid.get_Vm(), no gridmodel-labelled get_J was added: the Jacobian is only ever exposed with the solver labelling, through this function.

Note

Some powerflows (eg DC or Gauss Seidel) do not rely on jacobian matrix, in this case, calling this function will return an exception.

J is NOT a fixed-shape 2x2 block anymore: it is assembled by composing a common “Base” block with independent extensions, and which extensions are active depends on the solver (lightsim2grid.algorithm.NRSing_SparseLU and friends use only Base + VoltageControl + Hvdc; lightsim2grid.algorithm.NR_SparseLU and friends additionally use MultiSlack). Each part below claims its own rows (equations) / columns (unknowns); nothing below is claimed twice.

Base (always present) is the usual decoupled-looking core:

| J11 | J12 | = dimensions: | (pvpq, pvpq) | (pvpq, pq) |
| --------- |               | ------------------------ |
| J21 | J22 |               |  (pq, pvpq)  |  (pq, pq)  |

with:

  • J11 = dS_dVa[array([pvpq]).T, pvpq].real (= real part of dS / dVa for all pv and pq buses)

  • J12 = dS_dVm[array([pvpq]).T, pq].real

  • J21 = dS_dVa[array([pq]).T, pvpq].imag

  • J22 = dS_dVm[array([pq]).T, pq].imag (= imaginary part of dS / dVm for all pq buses)

Note

A slack bus that is NOT locally pinned by its own directly-connected voltage-regulating generator (a PQ distributed-slack participant, or a slack bus regulated only remotely / by an SVC – see the VoltageControl extension below) also gets a free vm unknown and a Q equation added by Base, exactly like an ordinary pq bus. This is NOT restricted to “all but the first ref bus”: it depends on how each individual slack bus is actually voltage-pinned.

MultiSlack (distributed-slack solvers only, ie NR_*, not NRSing_*): for every slack bus it adds one P-equation row (including the reference bus’); for every slack bus OTHER than the reference, it additionally adds a theta unknown column. On top of that, it adds exactly ONE extra column, shared by the whole system, for the “slack_absorbed” unknown (the distributed slack’s total absorbed mismatch) – not one extra row/column pair per slack bus.

VoltageControl (always present; covers both a generator remotely regulating another bus’ voltage and an SVC in voltage-control mode): controllers sharing the same regulated bus are grouped; each group of N controllers adds N reactive-power (Q) unknown columns (one per controller – a plain, non-regulating “PQ” generator gets none), 1 voltage-setpoint row, and N-1 reactive-power-sharing rows.

Hvdc (always present, angle-droop / “AC emulation” hvdc lines only): claims no row or column of its own; it only adds extra dP/dtheta terms into the P-mismatch rows / theta columns that Base/MultiSlack already registered for the two buses of each droop-controlled hvdc line.

Note

the notation pvpq above means “the concatenation of the pv vector and the pq vector”. Slack buses (participating in the distributed slack or not) are NOT part of pvpq: they are registered by Base/MultiSlack as described above, independently of it.

Note

All notation here are notation for the solver. You should use gridmodel.get_pq_solver() and gridmodel.get_pv_solver() to retrieve their value.

get_Sbus(self: lightsim2grid.lightsim2grid_cpp.LSGrid) Annotated[numpy.typing.NDArray[numpy.complex128], '[m, 1]']

This function returns the (complex) Sbus vector of the gridmodel. It is build using the “Sbus” passed to the AC solver for which the buses have been properly relabelled in the gridmodel convention.

The resulting vector is a vector of complex number having the size of the number of total buses on the grid.

See also

If you want to retrieve the Sbus with the “solver” convention, you can use lightsim2grid.network.LSGrid.get_Sbus_solver()

Danger

Major change in version 0.9.0 of lightsim2grid (see versionchanged below)

Changed in version 0.9.0: It has not the same definition as the “old” behaviour. In the old behaviour, the get_Sbus used the solver convention. To get the “old” behaviour, you need to use lightsim2grid.network.LSGrid.get_Sbus_solver()

Warning

This is given in the pair unit system and in load convention (so generation will be negative)

See also

lightsim2grid.network.LSGrid.id_me_to_ac_solver() and lightsim2grid.network.LSGrid.id_ac_solver_to_me() for ways to link the “grid model” bus id to the “solver” bus id.

Notes

Suppose that the grid model bus of id k is connected. Then the row / column id_me_to_ac_solver[k] (will be >= 0) and will represent this bus: Sbus[id_me_to_ac_solver[k]] is the total power injected at the grid model bus solver k.

Warning

The above only holds when the bus of id k is connected which is when id_me_to_ac_solver[k] >= 0 !

get_Sbus_solver(self: lightsim2grid.lightsim2grid_cpp.LSGrid) Annotated[numpy.typing.NDArray[numpy.complex128], '[m, 1]']

This function returns the (complex) Sbus vector used by the AC solver. It is the vector of active / reactive power injected at each active bus

The resulting vector is a vector of complex number having the size of the number of connected buses on the grid.

See also

If you want to retrieve the Sbus with the “gridmodel” convention, you can use lightsim2grid.network.LSGrid.get_Sbus()

Added in version 0.9.0: It was named get_Sbus before this version, but the name has been changed to avoid confusing AND a new function (this one) has been made with the proper gridmodel labelling.

Warning

Each row / columns of this matrix represents a “solver bus” (and not a “grid model bus”). In other word, the first row / column of this matrix is not necessarily the first bus of the grid model.

Warning

This is given in the pair unit system and in load convention (so generation will be negative)

See also

lightsim2grid.network.LSGrid.id_me_to_ac_solver() and lightsim2grid.network.LSGrid.id_ac_solver_to_me() for ways to link the “grid model” bus id to the “solver” bus id.

Notes

Suppose that the grid model bus of id k is connected. Then the row / column id_me_to_ac_solver[k] (will be >= 0) and will represent this bus: Sbus[id_me_to_ac_solver[k]] is the total power injected at the grid model bus solver k.

Warning

The above only holds when the bus of id k is connected which is when id_me_to_ac_solver[k] >= 0 !

get_V(self: lightsim2grid.lightsim2grid_cpp.LSGrid) Annotated[numpy.typing.NDArray[numpy.complex128], '[m, 1]']

Returns the complex voltage for each buses as a numpy vector of complex number. This vector have the size of the total number buses on the system, including the disconnected bus. It adopts the “gridmodel” labelling.

Changed in version 0.9.0: They are labelled with the grimodel labelling. To retrieve the previous behaviour (solver labelling) you can use the current lightsim2grid.network.LSGrid.get_V_solver() (before version 0.9.0)

Danger

Some breaking change have been introduced in lighsim2grid 0.9.0. You can lightsim2grid.network.LSGrid.get_V_solver() to get the previous (before 0.9.0) behaviour.

Note

You can use the lightsim2grid.network.LSGrid.id_ac_solver_to_me (or lightsim2grid.network.LSGrid.id_dc_solver_to_me) to know at which bus (on the grid) they corresponds.

get_V_solver(self: lightsim2grid.lightsim2grid_cpp.LSGrid) Annotated[numpy.typing.NDArray[numpy.complex128], '[m, 1]']

Returns the complex voltage for each buses as a numpy vector of complex number. This vector have the size of the number of active buses on the system and adopts the “solver” labelling.

Danger

They are labelled with the solver labelling, which corresponds to the previous behaviour in lightsim2grid.network.LSGrid.get_V() (before version 0.9.0)

Added in version 0.9.0: This function replace the lightsim2grid.network.LSGrid.get_V() of earlier lightsim2grid version. The new version of lightsim2grid.network.LSGrid.get_V() now returns the id labelled with the gridmodel convention (for consistency).

Note

You can use the lightsim2grid.network.LSGrid.id_ac_solver_to_me (or lightsim2grid.network.LSGrid.id_dc_solver_to_me) to know at which bus (on the grid) they corresponds.

get_Va(self: lightsim2grid.lightsim2grid_cpp.LSGrid) Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]']

Returns the voltage angles for each buses as a numpy vector of real number. This vector have the size of the total number buses on the system, including the disconnected bus. It adopts the “gridmodel” labelling.

Changed in version 0.9.0: They are labelled with the grimodel labelling. To retrieve the previous behaviour (solver labelling) you can use the current lightsim2grid.network.LSGrid.get_Va_solver() (before version 0.9.0)

Danger

Some breaking change have been introduced in lighsim2grid 0.9.0. You can lightsim2grid.network.LSGrid.get_Va_solver() to get the previous (before 0.9.0) behaviour.

Note

You can use the lightsim2grid.network.LSGrid.id_ac_solver_to_me (or lightsim2grid.network.LSGrid.id_dc_solver_to_me) to know at which bus (on the grid) they corresponds.

get_Va_solver(self: lightsim2grid.lightsim2grid_cpp.LSGrid) Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]']

Returns the voltage angles for each buses as a numpy vector of real number. This vector have the size of the number of active buses on the system and adopts the “solver” labelling.

Danger

They are labelled with the solver labelling, which corresponds to the previous behaviour in lightsim2grid.network.LSGrid.get_Va() (before version 0.9.0)

Added in version 0.9.0: This function replace the lightsim2grid.network.LSGrid.get_Va() of earlier lightsim2grid version. The new version of lightsim2grid.network.LSGrid.get_Va() now returns the id labelled with the gridmodel convention (for consistency).

Note

You can use the lightsim2grid.network.LSGrid.id_ac_solver_to_me (or lightsim2grid.network.LSGrid.id_dc_solver_to_me) to know at which bus (on the grid) they corresponds.

get_Vm(self: lightsim2grid.lightsim2grid_cpp.LSGrid) Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]']

Returns the voltage magnitude for each buses as a numpy vector of real number. This vector have the size of the total number buses on the system, including the disconnected bus. It adopts the “gridmodel” labelling.

Changed in version 0.9.0: They are labelled with the grimodel labelling. To retrieve the previous behaviour (solver labelling) you can use the current lightsim2grid.network.LSGrid.get_Vm_solver() (before version 0.9.0)

Danger

Some breaking change have been introduced in lighsim2grid 0.9.0. You can lightsim2grid.network.LSGrid.get_Vm_solver() to get the previous (before 0.9.0) behaviour.

Note

You can use the lightsim2grid.network.LSGrid.id_ac_solver_to_me (or lightsim2grid.network.LSGrid.id_dc_solver_to_me) to know at which bus (on the grid) they corresponds.

get_Vm_solver(self: lightsim2grid.lightsim2grid_cpp.LSGrid) Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]']

Returns the voltage magnitude for each buses as a numpy vector of real number. This vector have the size of the number of active buses on the system and adopts the “solver” labelling.

Danger

They are labelled with the solver labelling, which corresponds to the previous behaviour in lightsim2grid.network.LSGrid.get_Vm() (before version 0.9.0)

Added in version 0.9.0: This function replace the lightsim2grid.network.LSGrid.get_Vm() of earlier lightsim2grid version. The new version of lightsim2grid.network.LSGrid.get_Vm() now returns the id labelled with the gridmodel convention (for consistency).

Note

You can use the lightsim2grid.network.LSGrid.id_ac_solver_to_me (or lightsim2grid.network.LSGrid.id_dc_solver_to_me) to know at which bus (on the grid) they corresponds.

get_Ybus(self: lightsim2grid.lightsim2grid_cpp.LSGrid) scipy.sparse.csc_matrix[numpy.complex128]

This function returns the (complex) Ybus matrix (for the AC powerflow) with the gridmodel convention.

The resulting matrix is a CSC scipy sparse matrix of complex number.

It is a square matrix, as many rows (columns) as there are total buses on the grid.

See also

If you want to retrieve the Ybus adopting the “solver” bus labelling (old behaviour), you can use lightsim2grid.network.LSGrid.get_Ybus_solver()

Danger

Major change in version 0.9.0 of lightsim2grid (see versionchanged below)

Changed in version 0.9.0: It has not the same definition as the “old” behaviour. In the old behaviour, the get_Ybus used the solver convention. To get the “old” behaviour, you need to use lightsim2grid.network.LSGrid.get_Ybus_solver()

Warning

Each row / columns of this matrix represents a “solver bus” (and not a “grid model bus”). In other word, the first row / column of this matrix is not necessarily the first bus of the grid model.

Warning

This is given in the pair unit system !

See also

lightsim2grid.network.LSGrid.id_me_to_ac_solver() and lightsim2grid.network.LSGrid.id_ac_solver_to_me() for ways to link the “grid model” bus id to the “solver” bus id.

Notes

Suppose that the grid model bus of id k is connected. Then the row / column id_me_to_ac_solver[k] (will be >= 0) and will represent this bus: Ybus[id_me_to_ac_solver[k],:] (rows of this bus), Ybus[:, id_me_to_ac_solver[k]] (column for this bus)

Warning

The above only holds when the bus of id k is connected which is when id_me_to_ac_solver[k] >= 0 !

get_Ybus_solver(self: lightsim2grid.lightsim2grid_cpp.LSGrid) scipy.sparse.csc_matrix[numpy.complex128]

This function returns the (complex) Ybus matrix used to compute the AC powerflow.

The resulting matrix is a CSC scipy sparse matrix of complex number.

It is a square matrix, as many rows (columns) as there are connected buses on the grid.

See also

If you want to retrieve the Ybus adopting the “gridmodel” bus labelling, you can use lightsim2grid.network.LSGrid.get_Ybus()

Added in version 0.9.0: It was named get_Ybus before this version, but the name has been changed to avoid confusing AND a new function (this one) has been made with the proper gridmodel labelling.

Warning

Each row / columns of this matrix represents a “solver bus” (and not a “grid model bus”). In other word, the first row / column of this matrix is not necessarily the first bus of the grid model.

Warning

This is given in the pair unit system !

See also

lightsim2grid.network.LSGrid.id_me_to_ac_solver() and lightsim2grid.network.LSGrid.id_ac_solver_to_me() for ways to link the “grid model” bus id to the “solver” bus id.

Notes

Suppose that the grid model bus of id k is connected. Then the row / column id_me_to_ac_solver[k] (will be >= 0) and will represent this bus: Ybus[id_me_to_ac_solver[k],:] (rows of this bus), Ybus[:, id_me_to_ac_solver[k]] (column for this bus)

Warning

The above only holds when the bus of id k is connected which is when id_me_to_ac_solver[k] >= 0 !

get_ac_algo_config(self: lightsim2grid.lightsim2grid_cpp.LSGrid) lightsim2grid.lightsim2grid_cpp.AlgoConfig

Return the AC solver’s lightsim2grid.algorithm.AlgoConfig (scaling/refactor policy type and parameters).

get_ac_algo_controler(self: lightsim2grid.lightsim2grid_cpp.LSGrid) lightsim2grid.lightsim2grid_cpp.AlgoControl

Return the AC solver family’s change-tracking flags, as a lightsim2grid.algorithm.AlgoControl instance.

A grid modification (eg. disconnecting a line, changing a setpoint) sets one or more of these flags; the AC solver reads and resets them the next time it runs an AC powerflow, so it only recomputes what actually changed since the last one. Mostly useful for debugging / introspecting exactly what a given modification invalidated.

See also

get_dc_algo_controler() for the independent set of flags tracked for the DC solver family.

get_ac_pq_solver(self: lightsim2grid.lightsim2grid_cpp.LSGrid) Annotated[numpy.typing.NDArray[numpy.int32], '[m, 1]']

Same as lightsim2grid.network.LSGrid.get_pq_solver(), but always for the AC solver family. See lightsim2grid.network.LSGrid.get_ac_pv_solver().

Added in version 1.0.0.

get_ac_pv_solver(self: lightsim2grid.lightsim2grid_cpp.LSGrid) Annotated[numpy.typing.NDArray[numpy.int32], '[m, 1]']

Same as lightsim2grid.network.LSGrid.get_pv_solver(), but always for the AC solver family, whatever powerflow ran last. Empty until an AC powerflow (or lightsim2grid.network.LSGrid.check_solution()) has built the AC data.

Added in version 1.0.0.

get_ac_slack_weights_solver(self: lightsim2grid.lightsim2grid_cpp.LSGrid) Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]']

Same as lightsim2grid.network.LSGrid.get_slack_weights_solver(), but always for the AC solver family. See lightsim2grid.network.LSGrid.get_ac_pv_solver().

Added in version 1.0.0.

get_algo(self: lightsim2grid.lightsim2grid_cpp.LSGrid) lightsim2grid.lightsim2grid_cpp.AlgorithmSelector

Return the solver currently in use as a lightsim2grid.algorithm.AlgorithmSelector() instance.

get_algo_type(self: lightsim2grid.lightsim2grid_cpp.LSGrid) lightsim2grid.lightsim2grid_cpp.AlgorithmType

Return the type of the solver currently used.

This is equivalent to the get_type of the lightsim2grid.algorithm.AlgorithmSelector.get_type() of the solver used.

get_all_shunt_buses(self: lightsim2grid.lightsim2grid_cpp.LSGrid) Annotated[numpy.typing.NDArray[numpy.int32], '[m, 1]']

Get the grid bus id of every shunt at once – the bulk equivalent of bus_id.

get_allow_ac_cache_reuse(self: lightsim2grid.lightsim2grid_cpp.LSGrid) bool

Whether the AC solver family may reuse its cache (True by default).

Added in version 1.0.0.

get_allow_cache_reuse(self: lightsim2grid.lightsim2grid_cpp.LSGrid) bool

True only when both families may reuse their cache (the default). Use lightsim2grid.network.LSGrid.get_allow_ac_cache_reuse() / lightsim2grid.network.LSGrid.get_allow_dc_cache_reuse() to tell them apart.

Added in version 1.0.0.

get_allow_dc_cache_reuse(self: lightsim2grid.lightsim2grid_cpp.LSGrid) bool

Whether the DC solver family may reuse its cache (True by default).

Added in version 1.0.0.

get_bus1_dcline(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsInt | SupportsIndex) int

Get the grid bus id converter station 1 of HVDC line dcline_id is connected to – see bus1_id.

get_bus1_powerline(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsInt | SupportsIndex) int

Get the grid bus id side 1 of powerline powerline_id is connected to – see bus1_id.

get_bus1_trafo(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsInt | SupportsIndex) int

Get the grid bus id side 1 (hv) of transformer trafo_id is connected to – see bus1_id.

get_bus2_dcline(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsInt | SupportsIndex) int

Get the grid bus id converter station 2 of HVDC line dcline_id is connected to – see bus2_id.

get_bus2_powerline(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsInt | SupportsIndex) int

Get the grid bus id side 2 of powerline powerline_id is connected to – see bus2_id.

get_bus2_trafo(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsInt | SupportsIndex) int

Get the grid bus id side 2 (lv) of transformer trafo_id is connected to – see bus2_id.

get_bus_gen(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsInt | SupportsIndex) int

Get the grid bus id generator gen_id is connected to – see bus_id.

get_bus_load(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsInt | SupportsIndex) int

Get the grid bus id load load_id is connected to – see bus_id.

get_bus_sgen(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsInt | SupportsIndex) int

Get the grid bus id static generator sgen_id is connected to – see bus_id.

get_bus_shunt(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsInt | SupportsIndex) int

Get the grid bus id shunt shunt_id is connected to – see bus_id.

get_bus_status(self: lightsim2grid.lightsim2grid_cpp.LSGrid) list[bool]

Whether each bus (“gridmodel” numbering) is currently connected – part of at least one active element or busbar coupling, so contributing an unknown to the powerflow.

There is no dedicated python class for a single bus (unlike loads, generators, etc.): this raw per-bus vector, together with get_bus_vn_kv(), is the only way to inspect bus-level state directly.

get_bus_storage(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsInt | SupportsIndex) int

Get the grid bus id storage unit storage_id is connected to – see bus_id.

get_bus_svc(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsInt | SupportsIndex) int

Get the grid bus id SVC svc_id is connected to – see bus_id.

get_bus_vmax_kv(self: lightsim2grid.lightsim2grid_cpp.LSGrid) Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]']

Per-bus max operating voltage, in kV (NaN if not provided for a given bus, empty array if never set).

get_bus_vmin_kv(self: lightsim2grid.lightsim2grid_cpp.LSGrid) Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]']

Per-bus min operating voltage, in kV (NaN if not provided for a given bus, empty array if never set).

get_bus_vn_kv(self: lightsim2grid.lightsim2grid_cpp.LSGrid) Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]']

Nominal voltage (kV) of every bus, in “gridmodel” bus numbering – one entry per bus (not per substation): every busbar of a given substation shares the same value, the one given to init_bus() for that substation.

See also

vn_kv, the same information read per substation through get_substations().

get_computation_time(self: lightsim2grid.lightsim2grid_cpp.LSGrid) float

Return the total computation time (in second) spend in the solver when performing a powerflow.

This is equivalent to the get_computation_time of the lightsim2grid.algorithm.AlgorithmSelector.get_computation_time() of the solver used (lightsim2grid.network.LSGrid.get_solver())

get_controller_elem_id_solver(self: lightsim2grid.lightsim2grid_cpp.LSGrid) Annotated[numpy.typing.NDArray[numpy.int32], '[m, 1]']

Element id of each VoltageControl controller (generator id if a generator, SVC id if an SVC), same order as get_controller_q_solver().

get_controller_kind_solver(self: lightsim2grid.lightsim2grid_cpp.LSGrid) Annotated[numpy.typing.NDArray[numpy.int32], '[m, 1]']

Kind of each VoltageControl controller (0 = generator, 1 = SVC), same order as get_controller_q_solver().

get_controller_q_col_solver(self: lightsim2grid.lightsim2grid_cpp.LSGrid) Annotated[numpy.typing.NDArray[numpy.int32], '[m, 1]']

Jacobian column of each VoltageControl controller’s own Q unknown, same order as get_controller_q_solver().

NOT the same as the bus-keyed get_q_to_J_col_solver: that map only keeps the LAST controller registered at a given bus, so it silently collides whenever two controllers regulate reactive power from the same bus. External solvers rebuilding this bordered block must use this instead.

get_controller_q_solver(self: lightsim2grid.lightsim2grid_cpp.LSGrid) Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]']

Converged reactive injection (pu) per VoltageControl controller (a remote-regulating generator or a voltage-mode SVC), in controller registration order. Empty when the extension is inactive.

get_dcSbus(self: lightsim2grid.lightsim2grid_cpp.LSGrid) Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]']

This function returns the (complex) Sbus vector of the gridmodel for the DC solver (imaginary part should be 0.). It is build using the “dcSbus” passed to the DC solver for which the buses have been properly relabelled in the gridmodel convention.

The resulting vector is a vector of complex number having the size of the number of total buses on the grid.

See also

If you want to retrieve the Sbus with the “sovler” convention, you can use lightsim2grid.network.LSGrid.get_dcSbus_solver()

Added in version 0.9.0.

Warning

This is given in the pair unit system and in load convention (so generation will be negative)

See also

lightsim2grid.network.LSGrid.id_me_to_ac_solver() and lightsim2grid.network.LSGrid.id_ac_solver_to_me() for ways to link the “grid model” bus id to the “solver” bus id.

Notes

Suppose that the grid model bus of id k is connected. Then the row / column id_me_to_ac_solver[k] (will be >= 0) and will represent this bus: Sbus[id_me_to_ac_solver[k]] is the total power injected at the grid model bus solver k.

Warning

The above only holds when the bus of id k is connected which is when id_me_to_ac_solver[k] >= 0 !

get_dcSbus_solver(self: lightsim2grid.lightsim2grid_cpp.LSGrid) Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]']

This function returns the (complex) Sbus vector used by the DC sovler. It is the vector of active / reactive power injected at each active bus

The resulting vector is a vector of complex number having the size of the number of connected buses on the grid.

See also

If you want to retrieve the Sbus with the “gridmodel” convention, you can use lightsim2grid.network.LSGrid.get_dcSbus()

Added in version 0.9.0.

Warning

Each row / columns of this matrix represents a “solver bus” (and not a “grid model bus”). In other word, the first row / column of this matrix is not necessarily the first bus of the grid model.

Warning

This is given in the pair unit system and in load convention (so generation will be negative)

See also

lightsim2grid.network.LSGrid.id_me_to_ac_solver() and lightsim2grid.network.LSGrid.id_ac_solver_to_me() for ways to link the “grid model” bus id to the “solver” bus id.

Notes

Suppose that the grid model bus of id k is connected. Then the row / column id_me_to_ac_solver[k] (will be >= 0) and will represent this bus: Sbus[id_me_to_ac_solver[k]] is the total power injected at the grid model bus solver k.

Warning

The above only holds when the bus of id k is connected which is when id_me_to_ac_solver[k] >= 0 !

get_dcYbus(self: lightsim2grid.lightsim2grid_cpp.LSGrid) scipy.sparse.csc_matrix[numpy.float64]

This function returns the (complex) Ybus matrix (for the DC powerflow) (its imaginary part should be 0.) with the gridmodel convention.

The resulting matrix is a CSC scipy sparse matrix of complex number.

It is a square matrix, as many rows (columns) as there are total buses on the grid.

See also

If you want to retrieve the Ybus adopting the “solver” bus labelling (old behaviour), you can use lightsim2grid.network.LSGrid.get_dcYbus_solver()

Danger

Major change in version 0.9.0 of lightsim2grid (see versionchanged below)

Changed in version 0.9.0: It has not the same definition as the “old” behaviour. In the old behaviour, the get_dcYbus used the solver convention. To get the “old” behaviour, you need to use lightsim2grid.network.LSGrid.get_dcYbus_solver()

Warning

This is given in the pair unit system !

See also

lightsim2grid.network.LSGrid.id_me_to_ac_solver() and lightsim2grid.network.LSGrid.id_ac_solver_to_me() for ways to link the “grid model” bus id to the “solver” bus id.

Notes

Suppose that the grid model bus of id k is connected. Then the row / column id_me_to_ac_solver[k] (will be >= 0) and will represent this bus: Ybus[id_me_to_ac_solver[k],:] (rows of this bus), Ybus[:, id_me_to_ac_solver[k]] (column for this bus)

Warning

The above only holds when the bus of id k is connected which is when id_me_to_ac_solver[k] >= 0 !

get_dcYbus_solver(self: lightsim2grid.lightsim2grid_cpp.LSGrid) scipy.sparse.csc_matrix[numpy.float64]

This function returns the (complex) Ybus matrix used to compute the DC powerflow (its imaginary part should be 0.).

The resulting matrix is a CSC scipy sparse matrix of complex number.

It is a square matrix, as many rows (columns) as there are connected buses on the grid.

See also

If you want to retrieve the Ybus adopting the “gridmodel” bus labelling, you can use lightsim2grid.network.LSGrid.get_dcYbus()

Added in version 0.9.0: It was named get_dcYbus before this version, but the name has been changed to avoid confusing AND a new function (this one) has been made with the proper gridmodel labelling.

Warning

Each row / columns of this matrix represents a “solver bus” (and not a “grid model bus”). In other word, the first row / column of this matrix is not necessarily the first bus of the grid model.

Warning

This is given in the pair unit system !

See also

lightsim2grid.network.LSGrid.id_me_to_ac_solver() and lightsim2grid.network.LSGrid.id_ac_solver_to_me() for ways to link the “grid model” bus id to the “solver” bus id.

Notes

Suppose that the grid model bus of id k is connected. Then the row / column id_me_to_ac_solver[k] (will be >= 0) and will represent this bus: Ybus[id_me_to_ac_solver[k],:] (rows of this bus), Ybus[:, id_me_to_ac_solver[k]] (column for this bus)

Warning

The above only holds when the bus of id k is connected which is when id_me_to_ac_solver[k] >= 0 !

get_dc_algo(self: lightsim2grid.lightsim2grid_cpp.LSGrid) lightsim2grid.lightsim2grid_cpp.AlgorithmSelector

Return the solver currently in use as a lightsim2grid.algorithm.AlgorithmSelector() instance for the dc powerflow.

get_dc_algo_config(self: lightsim2grid.lightsim2grid_cpp.LSGrid) lightsim2grid.lightsim2grid_cpp.AlgoConfig

Return the DC solver’s lightsim2grid.algorithm.AlgoConfig (no-op for non-NR solvers, returns an empty config).

get_dc_algo_controler(self: lightsim2grid.lightsim2grid_cpp.LSGrid) lightsim2grid.lightsim2grid_cpp.AlgoControl

Return the DC solver family’s change-tracking flags, as a lightsim2grid.algorithm.AlgoControl instance.

Same as get_ac_algo_controler(), but for the DC solver family: the two are tracked independently since a DC powerflow does not consume (and reset) the AC flags, and vice versa.

get_dc_algo_type(self: lightsim2grid.lightsim2grid_cpp.LSGrid) lightsim2grid.lightsim2grid_cpp.AlgorithmType

Return the type of the solver currently used to compute DC powerflow.

get_dc_computation_time(self: lightsim2grid.lightsim2grid_cpp.LSGrid) float

Return the total computation time (in second) spend in the solver (used to perform DC approximation) when performing a DC powerflow.

This is equivalent to the get_computation_time of the lightsim2grid.algorithm.AlgorithmSelector.get_computation_time() of the DC solver used (lightsim2grid.network.LSGrid.get_dc_solver())

get_dc_pq_solver(self: lightsim2grid.lightsim2grid_cpp.LSGrid) Annotated[numpy.typing.NDArray[numpy.int32], '[m, 1]']

Same as lightsim2grid.network.LSGrid.get_pq_solver(), but always for the DC solver family. See lightsim2grid.network.LSGrid.get_dc_pv_solver().

Added in version 1.0.0.

get_dc_pv_solver(self: lightsim2grid.lightsim2grid_cpp.LSGrid) Annotated[numpy.typing.NDArray[numpy.int32], '[m, 1]']

Same as lightsim2grid.network.LSGrid.get_pv_solver(), but always for the DC solver family. Empty until a DC powerflow has built the DC data. Note that the DC solver labels its buses independently of the AC one: these ids are only meaningful together with lightsim2grid.network.LSGrid.id_dc_solver_to_me().

Added in version 1.0.0.

get_dc_slack_weights_solver(self: lightsim2grid.lightsim2grid_cpp.LSGrid) Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]']

Same as lightsim2grid.network.LSGrid.get_slack_weights_solver(), but always for the DC solver family. See lightsim2grid.network.LSGrid.get_dc_pv_solver().

Added in version 1.0.0.

get_dc_solver(self: lightsim2grid.lightsim2grid_cpp.LSGrid) lightsim2grid.lightsim2grid_cpp.AlgorithmSelector

DEPRECATED: use ‘get_dc_algo’ instead

get_dc_solver_type(self: lightsim2grid.lightsim2grid_cpp.LSGrid) lightsim2grid.lightsim2grid_cpp.AlgorithmType

DEPRECATED: use ‘get_dc_algo_type’ instead

get_dcline_res1_full(self: lightsim2grid.lightsim2grid_cpp.LSGrid) tuple[Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]']]

Get, for every HVDC line at once, the converter-station-1 (p1_mw, q1_mvar, v1_kv, theta1_deg) result quadruplet – see res_p1_mw / res_q1_mvar / res_v1_kv / res_theta1_deg.

get_dcline_res2_full(self: lightsim2grid.lightsim2grid_cpp.LSGrid) tuple[Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]']]

Get, for every HVDC line at once, the converter-station-2 result quadruplet, see get_dcline_res1_full().

get_dclines(self: lightsim2grid.lightsim2grid_cpp.LSGrid) lightsim2grid.lightsim2grid_cpp.HvdcLineContainer

This function allows to retrieve the dc powerlines (as a lightsim2grid.elements.DCLineContainer object, see Elements modeled for more information)

Examples

# init the grid model
from lightsim2grid.network import init_from_pandapower
pp_net = ...  # any pandapower grid
lightsim_grid_model = init_from_pandapower(pp_net)  # some warnings might be issued as well as some warnings

# usage example: print some information about the powerlines
print([el.x_pu for el in lightsim_grid_model.get_dclines()]) # to print the "x" for each powerlines
get_gen_res(self: lightsim2grid.lightsim2grid_cpp.LSGrid) tuple[Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]']]

Get, for every generator at once, the (p_mw, q_mvar, v_kv) result triplet, see get_loads_res() and GenInfo.

get_gen_res_full(self: lightsim2grid.lightsim2grid_cpp.LSGrid) tuple[Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]']]

Get, for every generator at once, the (p_mw, q_mvar, v_kv, theta_deg) result quadruplet, see get_loads_res_full() and GenInfo.

get_gen_status(self: lightsim2grid.lightsim2grid_cpp.LSGrid) list[bool]

Get the connection status of every generator at once, see get_loads_status() and GenInfo.

get_gen_target_p(self: lightsim2grid.lightsim2grid_cpp.LSGrid) Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]']

Get the active power setpoint of every generator at once, see get_shunt_target_p() and GenInfo.

get_gen_theta(self: lightsim2grid.lightsim2grid_cpp.LSGrid) Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]']

Get the voltage angle (degree) of every generator’s bus at once – see res_theta_deg.

get_generators(self: lightsim2grid.lightsim2grid_cpp.LSGrid) lightsim2grid.lightsim2grid_cpp.GeneratorContainer

This function allows to retrieve the (standard) generators (as a lightsim2grid.elements.GeneratorContainer object, see Elements modeled for more information)

Examples

# init the grid model
from lightsim2grid.network import init_from_pandapower
pp_net = ...  # any pandapower grid
lightsim_grid_model = init_from_pandapower(pp_net)  # some warnings might be issued as well as some warnings

# usage example: print some information about the generators
print([el.target_p_mw for el in lightsim_grid_model.get_generators()]) # to print the active production setpoint for each generators
get_hvdc_droop_data_solver(self: lightsim2grid.lightsim2grid_cpp.LSGrid) tuple[Annotated[numpy.typing.NDArray[numpy.int32], '[m, 1]'], Annotated[numpy.typing.NDArray[numpy.int32], '[m, 1]'], Annotated[numpy.typing.NDArray[numpy.int32], '[m, 1]'], Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]']]

(bus1, bus2, status, p0, k, lf1, lf2, r, pmax12, pmax21), one entry per CONNECTED droop-enabled HVDC line (solver bus numbering, pu). Ground truth for external solvers re-deriving the theta-dependent droop-flow contribution to F independently – see HvdcDroopSolverData for the flow formula.

get_ignore_status_global(self: lightsim2grid.lightsim2grid_cpp.LSGrid) bool

Current value of the ignore_status_global flag, see set_ignore_status_global().

get_init_vm_pu(self: lightsim2grid.lightsim2grid_cpp.LSGrid) float

Get the value set by set_init_vm_pu().

get_line_names(self: lightsim2grid.lightsim2grid_cpp.LSGrid) list[str]

Names of the powerlines, as set by set_line_names; empty if never set.

get_line_res1(self: lightsim2grid.lightsim2grid_cpp.LSGrid) tuple[Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]']]

Get, for every powerline at once, the side-1 (p1_mw, q1_mvar, v1_kv, a1_ka) result quadruplet – see res_p1_mw / res_q1_mvar / res_v1_kv / res_a1_ka.

get_line_res1_full(self: lightsim2grid.lightsim2grid_cpp.LSGrid) tuple[Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]']]

Get, for every powerline at once, the side-1 (p1_mw, q1_mvar, v1_kv, a1_ka, theta1_deg) result quintuplet – same as get_line_res1() with res_theta1_deg appended.

get_line_res2(self: lightsim2grid.lightsim2grid_cpp.LSGrid) tuple[Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]']]

Get, for every powerline at once, the side-2 result quadruplet, see get_line_res1().

get_line_res2_full(self: lightsim2grid.lightsim2grid_cpp.LSGrid) tuple[Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]']]

Get, for every powerline at once, the side-2 result quintuplet, see get_line_res1_full().

get_line_theta1(self: lightsim2grid.lightsim2grid_cpp.LSGrid) Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]']

Get the voltage angle (degree) of every powerline’s side-1 bus at once – see res_theta1_deg.

get_line_theta2(self: lightsim2grid.lightsim2grid_cpp.LSGrid) Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]']

Get the voltage angle (degree) of every powerline’s side-2 bus at once, see get_line_theta1().

get_lines(self: lightsim2grid.lightsim2grid_cpp.LSGrid) lightsim2grid.lightsim2grid_cpp.LineContainer

This function allows to retrieve the powerlines (as a lightsim2grid.elements.LineContainer object, see Elements modeled for more information)

Examples

# init the grid model
from lightsim2grid.network import init_from_pandapower
pp_net = ...  # any pandapower grid
lightsim_grid_model = init_from_pandapower(pp_net)  # some warnings might be issued as well as some warnings

# usage example: print some information about the powerlines
print([el.x_pu for el in lightsim_grid_model.get_lines()]) # to print the "x" for each powerlines
get_lines_status(self: lightsim2grid.lightsim2grid_cpp.LSGrid) list[bool]

Get the global connection status of every powerline at once – see connected_global (True as soon as either side is connected; see get_lines_status_side1() / get_lines_status_side2() for the per-side status).

get_lines_status_side1(self: lightsim2grid.lightsim2grid_cpp.LSGrid) list[bool]

Per-side status of each powerline’s side 1 (relevant for half-open lines: get_lines_status() is True as soon as either side is connected).

get_lines_status_side2(self: lightsim2grid.lightsim2grid_cpp.LSGrid) list[bool]

Per-side status of each powerline’s side 2, see get_lines_status_side1().

get_load_target_p(self: lightsim2grid.lightsim2grid_cpp.LSGrid) Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]']

Get the active power setpoint of every load at once, see get_shunt_target_p() and LoadInfo.

get_load_theta(self: lightsim2grid.lightsim2grid_cpp.LSGrid) Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]']

Get the voltage angle (degree) of every load’s bus at once, see get_gen_theta() and LoadInfo.

get_loads(self: lightsim2grid.lightsim2grid_cpp.LSGrid) lightsim2grid.lightsim2grid_cpp.LoadContainer

This function allows to retrieve the loads (as a lightsim2grid.elements.LoadContainer object, see Elements modeled for more information)

Examples

# init the grid model
from lightsim2grid.network import init_from_pandapower
pp_net = ...  # any pandapower grid
lightsim_grid_model = init_from_pandapower(pp_net)  # some warnings might be issued as well as some warnings

# print the target consumption of each loads
print([el.target_p_mw for el in lightsim_grid_model.get_loads()]) # to print the active consumption for each load
get_loads_res(self: lightsim2grid.lightsim2grid_cpp.LSGrid) tuple[Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]']]

Get, for every load at once, the (p_mw, q_mvar, v_kv) result triplet – see res_p_mw / res_q_mvar / res_v_kv.

get_loads_res_full(self: lightsim2grid.lightsim2grid_cpp.LSGrid) tuple[Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]']]

Get, for every load at once, the (p_mw, q_mvar, v_kv, theta_deg) result quadruplet – same as get_loads_res() with res_theta_deg appended.

get_loads_status(self: lightsim2grid.lightsim2grid_cpp.LSGrid) list[bool]

Get the connection status of every load at once – see connected.

get_lodf(self: lightsim2grid.lightsim2grid_cpp.LSGrid) Annotated[numpy.typing.NDArray[numpy.float64], '[m, n]']

This function returns the LODF (Line Outage Distribution Factor) which tells you how much the flows on each powerline / tranformer will vary if some given powerline / transformer is disconnected.

It is a dense matrix, with (nb lines + nb tranformers) rows and (nb lines + nb tranformers) columns.

Each rows / columns represent a powerline / transformers. More concretely, the coefficient at row i and column j represents how much the flows on line / transformer i will vary if line / transformer j is disconnected.

Note

First len(gridmodel.get_lines()) rows / columns represent the powerlines, the remaining len(gridmodel.get_trafos()) represent transformers.

Note

You need to run a DC powerflow before calling this method (otherwise an exception is raised.)

Internally, this method will compute the PTDF

It is an alternative to compute DC powerflows when powerlines are disconnected.

import numpy as np
# create a grid model
import grid2op
from lightsim2grid import LightSimBackend
env_name = ...  # eg "l2rpn_case14_sandbox"
env = grid2op.make(env_name, backend=LightSimBackend())
grid_model = env.backend._grid

# have an initial guess for the complex voltage at each bus
Vinit = np.ones(grid_model.total_bus(), dtype=complex)

Vdc = grid_model.dc_pf(Vinit, 1, 1e-8)

LODF_mat = 1. * grid_model.get_lodf()

lor_p, *_ = grid_model.get_lineor_res()
tor_p, *_ = grid_model.get_trafohv_res()
init_powerflow = np.concatenate((lor_p, tor_p))

# if you want to see the impact of a single line disconnected
l_id = 0 # (or anything between 0 and n_line + n_trafo)
por_lodf = init_powerflow + LODF_mat[:, l_id] * init_powerflow[l_id]

# the effect when disconnecting all powerlines (one powerline disconnected each steps)
mat_flow = np.tile(init_powerflow, LODF_mat.shape[0]).reshape(LODF_mat.shape)
por_lodf = mat_flow + LODF_mat.T * mat_flow.T
get_n_sub(self: lightsim2grid.lightsim2grid_cpp.LSGrid) int

Get the value set by set_n_sub().

get_p_buses_solver(self: lightsim2grid.lightsim2grid_cpp.LSGrid) Annotated[numpy.typing.NDArray[numpy.int32], '[m, 1]']

Compact (bus, row) pair list for the P equations – the row/col counterpart of get_p_to_J_row_solver(), preserving EVERY registration (a bus may appear more than once; see NRLedger’s “Multiplicity rules”). Same length as get_p_rows_solver().

get_p_rows_solver(self: lightsim2grid.lightsim2grid_cpp.LSGrid) Annotated[numpy.typing.NDArray[numpy.int32], '[m, 1]']

Jacobian row of each entry in get_p_buses_solver(), same order.

get_pq(self: lightsim2grid.lightsim2grid_cpp.LSGrid) Annotated[numpy.typing.NDArray[numpy.int32], '[m, 1]']

Returns the ids of the buses that are labelled as “PQ”.

It returns a vector of integer.

Danger

From lightsim2grid 0.9.0 they are labelled with the gridmodel labelling.

This behaviour is now accessible with the lightsim2grid.network.LSGrid.get_pq() before version 0.9.0

Changed in version 0.9.0: The new version of this function returns the id labelled with the gridmodel convention (for consistency).

Earlier version returned the labelling in the “solver” convention. To access the earlier function, please use the lightsim2grid.network.LSGrid.get_pq() function.

Warning

The index are given in the “solver bus” convention. This means that it will might be the bus of the original grid model.

See also

lightsim2grid.network.LSGrid.id_me_to_ac_solver() and lightsim2grid.network.LSGrid.id_ac_solver_to_me() for ways to link the “grid model” bus id to the “solver” bus id.

get_pq_solver(self: lightsim2grid.lightsim2grid_cpp.LSGrid) Annotated[numpy.typing.NDArray[numpy.int32], '[m, 1]']

Returns the ids of the buses that are labelled as “PQ”.

It returns a vector of integer.

Danger

They are labelled with the solver labelling, which corresponds to the previous behaviour in lightsim2grid.network.LSGrid.get_pq() before version 0.9.0

Added in version 0.9.0: This function replace the lightsim2grid.network.LSGrid.get_pq() of earlier lightsim2grid version. The new version of lightsim2grid.network.LSGrid.get_pq() now returns the id labelled with the gridmodel convention (for consistency).

Warning

The index are given in the “solver bus” convention. This means that it will might be the bus of the original grid model.

See also

lightsim2grid.network.LSGrid.id_me_to_ac_solver() and lightsim2grid.network.LSGrid.id_ac_solver_to_me() for ways to link the “grid model” bus id to the “solver” bus id.

Added in version 1.0.0: The AC and the DC solver each keep their own copy of this. This accessor answers for the AC family as soon as an AC powerflow has run on this grid, and falls back to the DC one otherwise; the get_ac_* / get_dc_* variants name the family explicitly and never guess.

get_ptdf(self: lightsim2grid.lightsim2grid_cpp.LSGrid) Annotated[numpy.typing.NDArray[numpy.float64], '[m, n]']

This function returns the PTDF (Power Transfer Distribution Factor) which tells you how much the flows on each powerline / tranformer will vary if some given power is injected on each bus of the grid.

It adopts the gridmodel bus labelling.

It is a dense matrix, with (nb lines + nb tranformers) rows and (nb total bus) columns.

Note

You need to run a DC powerflow before calling this method (otherwise an exception is raised.)

It is an alternative to compute DC powerflows (provided that the topology of the grid is not modified). You can do it with:

import numpy as np
# create a grid model
import grid2op
from lightsim2grid import LightSimBackend
env_name = ...  # eg "l2rpn_case14_sandbox"
env = grid2op.make(env_name, backend=LightSimBackend())
grid_model = env.backend._grid

# have an initial guess for the complex voltage at each bus
Vinit = np.ones(grid_model.total_bus(), dtype=complex)

Vdc = grid_model.dc_pf(Vinit, 1, 1e-8)

PTDF = grid_model.get_ptdf()

new_Sbus = 1.7 * grid_model.get_dcSbus()

new_flows = np.dot(PTDF, new_Sbus * grid_model.get_sn_mva())
# the flows on the grid if every injection is multiplied by 1.7

Note

If a bus is disconnected, then the associated columns is full of 0.

Note

If the vector Sbus does not sum to 0. the “slack” used is the first slack of the slack vector. No distributed slack is used for DC at the moment.

If you want distributed slack in this case, please open a feature request on github.

Note

The ‘power’ “injected” at disconnected buses (buses with colums of PTDF full of 0.) is completely discarded (multiplied by 0.)

get_ptdf_solver(self: lightsim2grid.lightsim2grid_cpp.LSGrid) Annotated[numpy.typing.NDArray[numpy.float64], '[m, n]']

This function returns the PTDF (Power Transfer Distribution Factor) which tells you how much the flows on each powerline / tranformer will vary if some given power is injected on each bus of the grid.

It adopts the solver bus labelling.

It is a dense matrix, with (nb lines + nb tranformers) rows and (nb activated bus) columns.

Each rows represents a powerline (or a transformer) and each columns represent a bus.

So the coefficient at row i and column j of this matrix represents the increase of flow (in MW) of powerline i if the power on bus j is increased of 1MW.

Note

First len(gridmodel.get_lines()) rows represent the powerlines, the remaining len(gridmodel.get_trafos()) represent transformers.

Note

You need to run a DC powerflow before calling this method (otherwise an exception is raised.)

It is an alternative to compute DC powerflows (provided that the topology of the grid is not modified). You can do it with:

import numpy as np
# create a grid model
import grid2op
from lightsim2grid import LightSimBackend
env_name = ...  # eg "l2rpn_case14_sandbox"
env = grid2op.make(env_name, backend=LightSimBackend())
grid_model = env.backend._grid

# have an initial guess for the complex voltage at each bus
Vinit = np.ones(grid_model.total_bus(), dtype=complex)

Vdc = grid_model.dc_pf(Vinit, 1, 1e-8)

PTDF = grid_model.get_ptdf_solver()

new_Sbus = 1.7 * grid_model.get_dcSbus_solver()

new_flows = np.dot(PTDF, new_Sbus * grid_model.get_sn_mva())
# the flows on the grid if every injection is multiplied by 1.7
# spoiler: it will be multiplied by 1.7, but you get the idea,
# you can change Sbus in a different ways...

Note

If a bus is disconnected, then the associated columns is full of 0.

Note

If the vector Sbus does not sum to 0. the “slack” used is the first slack of the slack vector. No distributed slack is used for DC at the moment.

If you want distributed slack in this case, please open a feature request on github.

Note

With this convention, the disconnected bus are not modeled.

get_pv(self: lightsim2grid.lightsim2grid_cpp.LSGrid) Annotated[numpy.typing.NDArray[numpy.int32], '[m, 1]']

Returns the ids of the buses that are labelled as “PV” (ie the buses on which at least a generator is connected.).

It returns a vector of integer.

Danger

From lightsim2grid 0.9.0 they are labelled with the gridmodel labelling.

This behaviour is now accessible with the lightsim2grid.network.LSGrid.get_pv() before version 0.9.0

Changed in version 0.9.0: The new version of this function returns the id labelled with the gridmodel convention (for consistency).

Earlier version returned the labelling in the “solver” convention. To access the earlier function, please use the lightsim2grid.network.LSGrid.get_pv() function.

Warning

The index are given in the “solver bus” convention. This means that it might not be the bus of the original grid model.

See also

lightsim2grid.network.LSGrid.id_me_to_ac_solver() and lightsim2grid.network.LSGrid.id_ac_solver_to_me() for ways to link the “grid model” bus id to the “solver” bus id.

get_pv_solver(self: lightsim2grid.lightsim2grid_cpp.LSGrid) Annotated[numpy.typing.NDArray[numpy.int32], '[m, 1]']

Returns the ids of the buses that are labelled as “PV” (ie the buses on which at least a generator is connected.).

It returns a vector of integer.

Danger

They are labelled with the solver labelling, which corresponds to the previous behaviour in lightsim2grid.network.LSGrid.get_pv() before version 0.9.0

Added in version 0.9.0: This function replace the lightsim2grid.network.LSGrid.get_pv() of earlier lightsim2grid version. The new version of lightsim2grid.network.LSGrid.get_pv() now returns the id labelled with the gridmodel convention (for consistency).

Warning

The index are given in the “solver bus” convention. This means that it might not be the bus of the original grid model.

See also

lightsim2grid.network.LSGrid.id_me_to_ac_solver() and lightsim2grid.network.LSGrid.id_ac_solver_to_me() for ways to link the “grid model” bus id to the “solver” bus id.

Added in version 1.0.0: The AC and the DC solver each keep their own copy of this. This accessor answers for the AC family as soon as an AC powerflow has run on this grid, and falls back to the DC one otherwise; the get_ac_* / get_dc_* variants name the family explicitly and never guess.

get_q_buses_solver(self: lightsim2grid.lightsim2grid_cpp.LSGrid) Annotated[numpy.typing.NDArray[numpy.int32], '[m, 1]']

Compact (bus, row) pair list for the Q equations, see get_p_buses_solver().

get_q_rows_solver(self: lightsim2grid.lightsim2grid_cpp.LSGrid) Annotated[numpy.typing.NDArray[numpy.int32], '[m, 1]']

Jacobian row of each entry in get_q_buses_solver(), same order.

get_reference_slack_bus(self: lightsim2grid.lightsim2grid_cpp.LSGrid) int

Forced angle-reference slack bus (gridmodel id), or -1 if none.

get_sgen_target_p(self: lightsim2grid.lightsim2grid_cpp.LSGrid) Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]']

Get the active power setpoint of every static generator at once, see get_shunt_target_p() and SGenInfo.

get_sgens_res(self: lightsim2grid.lightsim2grid_cpp.LSGrid) tuple[Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]']]

Get, for every static generator at once, the (p_mw, q_mvar, v_kv) result triplet, see get_loads_res() and SGenInfo.

get_sgens_res_full(self: lightsim2grid.lightsim2grid_cpp.LSGrid) tuple[Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]']]

Get, for every static generator at once, the (p_mw, q_mvar, v_kv, theta_deg) result quadruplet, see get_loads_res_full() and SGenInfo.

get_sgens_status(self: lightsim2grid.lightsim2grid_cpp.LSGrid) list[bool]

Get the connection status of every static generator at once, see get_loads_status() and SGenInfo.

get_shunt_compensators(self: lightsim2grid.lightsim2grid_cpp.LSGrid) lightsim2grid.lightsim2grid_cpp.ShuntContainer

This function allows to retrieve the shunts (as a lightsim2grid.elements.ShuntContainer object, see Elements modeled for more information)

Examples

# init the grid model
from lightsim2grid.network import init_from_pandapower
pp_net = ...  # any pandapower grid
lightsim_grid_model = init_from_pandapower(pp_net)  # some warnings might be issued as well as some warnings

# usage example: print some information about the shunts
print([el.target_q_mvar for el in lightsim_grid_model.get_shunts()]) # to print the reactive consumption for each shunts
get_shunt_target_p(self: lightsim2grid.lightsim2grid_cpp.LSGrid) Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]']

Get the active power setpoint of every shunt at once – see target_p_mw.

get_shunt_theta(self: lightsim2grid.lightsim2grid_cpp.LSGrid) Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]']

Get the voltage angle (degree) of every shunt’s bus at once, see get_gen_theta() and ShuntInfo.

get_shunts(self: lightsim2grid.lightsim2grid_cpp.LSGrid) lightsim2grid.lightsim2grid_cpp.ShuntContainer

This function allows to retrieve the shunts (as a lightsim2grid.elements.ShuntContainer object, see Elements modeled for more information)

Examples

# init the grid model
from lightsim2grid.network import init_from_pandapower
pp_net = ...  # any pandapower grid
lightsim_grid_model = init_from_pandapower(pp_net)  # some warnings might be issued as well as some warnings

# usage example: print some information about the shunts
print([el.target_q_mvar for el in lightsim_grid_model.get_shunts()]) # to print the reactive consumption for each shunts
get_shunts_res(self: lightsim2grid.lightsim2grid_cpp.LSGrid) tuple[Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]']]

Get, for every shunt at once, the (p_mw, q_mvar, v_kv) result triplet, see get_loads_res() and ShuntInfo.

get_shunts_res_full(self: lightsim2grid.lightsim2grid_cpp.LSGrid) tuple[Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]']]

Get, for every shunt at once, the (p_mw, q_mvar, v_kv, theta_deg) result quadruplet, see get_loads_res_full() and ShuntInfo.

get_shunts_status(self: lightsim2grid.lightsim2grid_cpp.LSGrid) list[bool]

Get the connection status of every shunt at once, see get_loads_status() and ShuntInfo.

get_slack_absorbed_solver(self: lightsim2grid.lightsim2grid_cpp.LSGrid) float

Converged value (pu) of the MultiSlack slack_absorbed unknown (0 when distributed slack is inactive). This is the ground truth after convergence – not the 0 initial guess an external solver’s own linearized derivation starts from.

get_slack_col_solver(self: lightsim2grid.lightsim2grid_cpp.LSGrid) int

Jacobian column of the MultiSlack slack_absorbed unknown (-1 when distributed slack is inactive).

get_slack_ids(self: lightsim2grid.lightsim2grid_cpp.LSGrid) Annotated[numpy.typing.NDArray[numpy.int32], '[m, 1]']

Returns the ids of the buses that are part of the distributed slack.

It returns a vector of integer.

Danger

From lightsim2grid 0.9.0 they are labelled with the gridmodel labelling.

This behaviour is now accessible with the lightsim2grid.network.LSGrid.get_slack_ids_solver() before version 0.9.0

Changed in version 0.9.0: The new version of this function returns the id labelled with the gridmodel convention (for consistency).

Earlier version returned the labelling in the “solver” convention. To access the earlier function, please use the lightsim2grid.network.LSGrid.get_slack_ids_solver() function.

See also

lightsim2grid.network.LSGrid.id_me_to_ac_solver() and lightsim2grid.network.LSGrid.id_ac_solver_to_me() for ways to link the “grid model” bus id to the “solver” bus id.

get_slack_ids_dc(self: lightsim2grid.lightsim2grid_cpp.LSGrid) Annotated[numpy.typing.NDArray[numpy.int32], '[m, 1]']

Returns the ids of the buses that are part of the distributed slack. For DC, the active-power mismatch is spread across these buses proportionally to their slack_weights (see lightsim2grid.network.LSGrid.dc_pf()) – distributed slack IS taken into account for the DC powerflow itself; it is only get_ptdf / get_lodf that still assume a single slack bus.

It returns a vector of integer.

Danger

From lightsim2grid 0.9.0 they are labelled with the gridmodel labelling.

This behaviour is now accessible with the lightsim2grid.network.LSGrid.get_slack_ids_dc_solver() before version 0.9.0

Changed in version 0.9.0: The new version of this function returns the id labelled with the gridmodel convention (for consistency).

Earlier version returned the labelling in the “solver” convention. To access the earlier function, please use the lightsim2grid.network.LSGrid.get_slack_ids_dc_solver() function.

See also

lightsim2grid.network.LSGrid.id_me_to_ac_solver() and lightsim2grid.network.LSGrid.id_ac_solver_to_me() for ways to link the “grid model” bus id to the “solver” bus id.

get_slack_ids_dc_solver(self: lightsim2grid.lightsim2grid_cpp.LSGrid) Annotated[numpy.typing.NDArray[numpy.int32], '[m, 1]']

Returns the ids of the buses that are part of the distributed slack. For DC, the active-power mismatch is spread across these buses proportionally to their slack_weights (see lightsim2grid.network.LSGrid.dc_pf()) – distributed slack IS taken into account for the DC powerflow itself; it is only get_ptdf / get_lodf that still assume a single slack bus.

It returns a vector of integer.

Added in version 0.9.0: Only what is now lightsim2grid.network.LSGrid.get_slack_ids_solver() (that used to be called lightsim2grid.network.LSGrid.get_slack_ids()) was available.

There were no possibility to retrieve that for DC powerflow.

Danger

They are labelled with the solver labelling, which corresponds to the previous behaviour in lightsim2grid.network.LSGrid.get_slack_ids() before version 0.9.0

Warning

The index are given in the “solver bus” convention. This means that it might not be the bus of the original grid model.

See also

lightsim2grid.network.LSGrid.id_me_to_ac_solver() and lightsim2grid.network.LSGrid.id_ac_solver_to_me() for ways to link the “grid model” bus id to the “solver” bus id.

get_slack_ids_solver(self: lightsim2grid.lightsim2grid_cpp.LSGrid) Annotated[numpy.typing.NDArray[numpy.int32], '[m, 1]']

Returns the ids of the buses that are part of the distributed slack.

It returns a vector of integer.

Danger

They are labelled with the solver labelling, which corresponds to the previous behaviour in lightsim2grid.network.LSGrid.get_slack_ids() before version 0.9.0

Added in version 0.9.0: This function replace the lightsim2grid.network.LSGrid.get_slack_ids() of earlier lightsim2grid version. The new version of lightsim2grid.network.LSGrid.get_slack_ids() now returns the id labelled with the gridmodel convention (for consistency).

Warning

The index are given in the “solver bus” convention. This means that it might not be the bus of the original grid model.

See also

lightsim2grid.network.LSGrid.id_me_to_ac_solver() and lightsim2grid.network.LSGrid.id_ac_solver_to_me() for ways to link the “grid model” bus id to the “solver” bus id.

get_slack_weights(self: lightsim2grid.lightsim2grid_cpp.LSGrid) Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]']

For each bus in the gridmodel solver, it outputs its participation to the distributed slack.

It’s 0 if the current bus does not participate to it, otherwise it is made of > 0. real numbers.

This vector sums to 1 and has the same size as the number of active buses on the grid.

Danger

From lightsim2grid 0.9.0 they are labelled with the gridmodel labelling.

This behaviour is now accessible with the lightsim2grid.network.LSGrid.get_slack_weights_solver() before version 0.9.0

Changed in version 0.9.0: The new version of this function returns the id labelled with the gridmodel convention (for consistency).

Earlier version returned the labelling in the “solver” convention. To access the earlier function, please use the lightsim2grid.network.LSGrid.get_slack_weights_solver() function.

See also

lightsim2grid.network.LSGrid.id_me_to_ac_solver() and lightsim2grid.network.LSGrid.id_ac_solver_to_me() for ways to link the “grid model” bus id to the “solver” bus id.

get_slack_weights_solver(self: lightsim2grid.lightsim2grid_cpp.LSGrid) Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]']

For each bus used by the solver, it outputs its participation to the distributed slack.

It’s 0 if the current bus does not participate to it, otherwise it is made of > 0. real numbers.

This vector sums to 1 and has the same size as the number of active buses on the grid.

Danger

They are labelled with the solver labelling, which corresponds to the previous behaviour in lightsim2grid.network.LSGrid.get_slack_weights() before version 0.9.0

Added in version 0.9.0: This function replace the lightsim2grid.network.LSGrid.get_slack_weights_solver() of earlier lightsim2grid version. The new version of lightsim2grid.network.LSGrid.get_slack_weights_solver() now returns the id labelled with the gridmodel convention (for consistency).

Warning

This vector represents “solver buses” and not “original grid model buses”.

See also

lightsim2grid.network.LSGrid.id_me_to_ac_solver() and lightsim2grid.network.LSGrid.id_ac_solver_to_me() for ways to link the “grid model” bus id to the “solver” bus id.

Added in version 1.0.0: The AC and the DC solver each keep their own copy of this. This accessor answers for the AC family as soon as an AC powerflow has run on this grid, and falls back to the DC one otherwise; the get_ac_* / get_dc_* variants name the family explicitly and never guess.

get_sn_mva(self: lightsim2grid.lightsim2grid_cpp.LSGrid) float

Get the value set by set_sn_mva().

get_solver(self: lightsim2grid.lightsim2grid_cpp.LSGrid) lightsim2grid.lightsim2grid_cpp.AlgorithmSelector

DEPRECATED: use ‘get_algo’ instead

get_solver_type(self: lightsim2grid.lightsim2grid_cpp.LSGrid) lightsim2grid.lightsim2grid_cpp.AlgorithmType

DEPRECATED: use ‘get_algo_type’ instead

get_static_generators(self: lightsim2grid.lightsim2grid_cpp.LSGrid) lightsim2grid.lightsim2grid_cpp.SGenContainer

This function allows to retrieve the (more exotic) static generators (as a lightsim2grid.elements.SGenContainer object, see Elements modeled for more information)

Examples

# init the grid model
from lightsim2grid.network import init_from_pandapower
pp_net = ...  # any pandapower grid
lightsim_grid_model = init_from_pandapower(pp_net)  # some warnings might be issued as well as some warnings

# usage example: print some information about the static generators
print([el.target_p_mw for el in lightsim_grid_model.get_static_generators()]) # to print the active production setpoint for each static generator
get_status_droop_hvdc(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsInt | SupportsIndex) int

Angle-droop regime of one HVDC line, see set_status_droop_hvdc().

get_status_droop_hvdc_vect(self: lightsim2grid.lightsim2grid_cpp.LSGrid) Annotated[numpy.typing.NDArray[numpy.int32], '[m, 1]']

Angle-droop regimes of every HVDC line, see set_status_droop_hvdc().

get_storage_target_p(self: lightsim2grid.lightsim2grid_cpp.LSGrid) Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]']

Get the active power setpoint of every storage unit at once, see get_shunt_target_p() and StorageInfo.

get_storage_theta(self: lightsim2grid.lightsim2grid_cpp.LSGrid) Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]']

Get the voltage angle (degree) of every storage unit’s bus at once, see get_gen_theta() and StorageInfo.

get_storages(self: lightsim2grid.lightsim2grid_cpp.LSGrid) lightsim2grid.lightsim2grid_cpp.StorageContainer

This function allows to retrieve the storage units (as a lightsim2grid.elements.LoadContainer object, see Elements modeled for more information)

Note

We want to emphize that, as far as lightsim2grid is concerned, the storage units are modeled as loads. This is why this function will return a lightsim2grid.elements.LoadContainer.

Examples

# init the grid model
from lightsim2grid.network import init_from_pandapower
pp_net = ...  # any pandapower grid
lightsim_grid_model = init_from_pandapower(pp_net)  # some warnings might be issued as well as some warnings

# print the target consumption of each storage units
print([el.target_p_mw for el in lightsim_grid_model.get_storages()]) # to print the active consumption for each storage unit
get_storages_res(self: lightsim2grid.lightsim2grid_cpp.LSGrid) tuple[Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]']]

Get, for every storage unit at once, the (p_mw, q_mvar, v_kv) result triplet, see get_loads_res() and StorageInfo.

get_storages_res_full(self: lightsim2grid.lightsim2grid_cpp.LSGrid) tuple[Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]']]

Get, for every storage unit at once, the (p_mw, q_mvar, v_kv, theta_deg) result quadruplet, see get_loads_res_full() and StorageInfo.

get_storages_status(self: lightsim2grid.lightsim2grid_cpp.LSGrid) list[bool]

Get the connection status of every storage unit at once, see get_loads_status() and StorageInfo.

get_substation_names(self: lightsim2grid.lightsim2grid_cpp.LSGrid) list[str]

Get the name of every substation at once, see set_substation_names() / name.

get_substations(self: lightsim2grid.lightsim2grid_cpp.LSGrid) lightsim2grid.lightsim2grid_cpp.SubstationContainer

This function allows to retrieve the substations (as a lightsim2grid.elements.SubstationContainer object, see Elements modeled for more information). Also available as get_voltage_levels (its powsybl / IIDM name).

Examples

# init the grid model
from lightsim2grid.network import init_from_pandapower
pp_net = ...  # any pandapower grid
lightsim_grid_model = init_from_pandapower(pp_net)  # some warnings might be issued as well as some warnings

# usage example: print some information about the substations
print([el.vn_kv for el in lightsim_grid_model.get_substations()]) # to print the nominal voltage of each substation
get_svcs(self: lightsim2grid.lightsim2grid_cpp.LSGrid) lightsim2grid.lightsim2grid_cpp.SvcContainer

Get the container of all the Static Var Compensators (SVC), as a lightsim2grid.elements.SvcContainer.

get_synch_status_both_side(self: lightsim2grid.lightsim2grid_cpp.LSGrid) bool

Current value of the synch_status_both_side flag, see set_synch_status_both_side().

get_theta_buses_solver(self: lightsim2grid.lightsim2grid_cpp.LSGrid) Annotated[numpy.typing.NDArray[numpy.int32], '[m, 1]']

Compact (bus, col) pair list for the theta unknowns, see get_p_buses_solver().

get_theta_cols_solver(self: lightsim2grid.lightsim2grid_cpp.LSGrid) Annotated[numpy.typing.NDArray[numpy.int32], '[m, 1]']

Jacobian column of each entry in get_theta_buses_solver(), same order.

get_trafo_names(self: lightsim2grid.lightsim2grid_cpp.LSGrid) list[str]

Names of the transformers, as set by set_trafo_names; empty if never set.

get_trafo_res1(self: lightsim2grid.lightsim2grid_cpp.LSGrid) tuple[Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]']]

Get, for every transformer at once, the side-1 (hv) result quadruplet, see get_line_res1() and TrafoInfo.

get_trafo_res1_full(self: lightsim2grid.lightsim2grid_cpp.LSGrid) tuple[Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]']]

Get, for every transformer at once, the side-1 (hv) result quintuplet, see get_line_res1_full() and TrafoInfo.

get_trafo_res2(self: lightsim2grid.lightsim2grid_cpp.LSGrid) tuple[Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]']]

Get, for every transformer at once, the side-2 (lv) result quadruplet, see get_line_res1() and TrafoInfo.

get_trafo_res2_full(self: lightsim2grid.lightsim2grid_cpp.LSGrid) tuple[Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]']]

Get, for every transformer at once, the side-2 (lv) result quintuplet, see get_line_res1_full() and TrafoInfo.

get_trafo_status(self: lightsim2grid.lightsim2grid_cpp.LSGrid) list[bool]

Get the global connection status of every transformer at once, see get_lines_status() and TrafoInfo.

get_trafo_status_side1(self: lightsim2grid.lightsim2grid_cpp.LSGrid) list[bool]

Per-side status of each transformer’s side 1, see get_lines_status_side1().

get_trafo_status_side2(self: lightsim2grid.lightsim2grid_cpp.LSGrid) list[bool]

Per-side status of each transformer’s side 2, see get_lines_status_side1().

get_trafo_theta1(self: lightsim2grid.lightsim2grid_cpp.LSGrid) Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]']

Get the voltage angle (degree) of every transformer’s side-1 (hv) bus at once, see get_line_theta1() and TrafoInfo.

get_trafo_theta2(self: lightsim2grid.lightsim2grid_cpp.LSGrid) Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]']

Get the voltage angle (degree) of every transformer’s side-2 (lv) bus at once, see get_line_theta1() and TrafoInfo.

get_trafos(self: lightsim2grid.lightsim2grid_cpp.LSGrid) lightsim2grid.lightsim2grid_cpp.TrafoContainer

This function allows to retrieve the transformers (as a lightsim2grid.elements.LineContainer object, see Elements modeled for more information)

Examples

# init the grid model
from lightsim2grid.network import init_from_pandapower
pp_net = ...  # any pandapower grid
lightsim_grid_model = init_from_pandapower(pp_net)  # some warnings might be issued as well as some warnings

# usage example: print some information about the trafos
print([el.x_pu for el in lightsim_grid_model.get_trafos()]) # to print the "x" for each transformer
get_turnedoff_gen_pv(self: lightsim2grid.lightsim2grid_cpp.LSGrid) bool

Whether a turned-off generator (or one with target_p_mw == 0) counts as a PV bus, as set by turnedoff_pv() / turnedoff_no_pv() (default: True, ie turnedoff_pv()).

get_vm_buses_solver(self: lightsim2grid.lightsim2grid_cpp.LSGrid) Annotated[numpy.typing.NDArray[numpy.int32], '[m, 1]']

Compact (bus, col) pair list for the Vm unknowns, see get_p_buses_solver().

get_vm_cols_solver(self: lightsim2grid.lightsim2grid_cpp.LSGrid) Annotated[numpy.typing.NDArray[numpy.int32], '[m, 1]']

Jacobian column of each entry in get_vm_buses_solver(), same order.

get_voltage_levels(self: lightsim2grid.lightsim2grid_cpp.LSGrid) lightsim2grid.lightsim2grid_cpp.SubstationContainer

This function allows to retrieve the substations (as a lightsim2grid.elements.SubstationContainer object, see Elements modeled for more information). Also available as get_voltage_levels (its powsybl / IIDM name).

Examples

# init the grid model
from lightsim2grid.network import init_from_pandapower
pp_net = ...  # any pandapower grid
lightsim_grid_model = init_from_pandapower(pp_net)  # some warnings might be issued as well as some warnings

# usage example: print some information about the substations
print([el.vn_kv for el in lightsim_grid_model.get_substations()]) # to print the nominal voltage of each substation
id_ac_solver_to_me(self: lightsim2grid.lightsim2grid_cpp.LSGrid) list[int]

In lightsim2grid, buses are labelled from 0 to n-1 (if n denotes the total number of buses on the grid) [this is called “grid model bus id”]

At any given point in time, some buses might be deactivated (for example because nothing is connected to them).

On the other end, the solvers need a contiguous list of only active buses (otherwise they might run into divergence issue) [this will be called “solver bus id” later on]

This function allows, for all buses exported in the solver, to retrieve which was the initial bus in the lightsim2grid.network.LSGrid. It has the same size as the number of active buses on the grid.

Examples

# create a grid model
import grid2op
from lightsim2grid import LightSimBackend
env_name = ...  # eg "l2rpn_case14_sandbox"
env = grid2op.make(env_name, backend=LightSimbackend())
grid_model = env.backend._grid

id_ac_solver_to_me = grid.id_ac_solver_to_me()
# is [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]

# put everything to bus 2 on substation O
_ = env.step(env.action_space({"set_bus": {"substations_id": [(0, (2, 2, 2))]}}))

id_ac_solver_to_me2 = grid.id_ac_solver_to_me()
# is [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]

See also

lightsim2grid.network.LSGrid.id_dc_solver_to_me for its counterpart when a dc powerflow is used

See also

lightsim2grid.network.LSGrid.id_me_to_ac_solver for the “reverse” operation (given a “solver bus” id, returns the “gridmodel bus id”)

Notes

For all steps, you have the propertie that, if id_ac_solver_to_me = gridmodel.id_ac_solver_to_me() and id_me_to_ac_solver = gridmodel.id_me_to_ac_solver() and by denoting gridmodel_bus_id = np.arange(gridmodel.total_bus()) and solver_bus_id = np.arange(gridmodel.nb_connected_bus()):

  • solver_bus_id and id_ac_solver_to_me have the same shape

  • gridmodel_bus_id and id_me_to_ac_solver have the same shape

  • solver_bus_id is shorter (or of the same length) than gridmodel_bus_id

  • the connected bus (in the grid model) are given by gridmodel_bus_id[id_ac_solver_to_me], and it gives their order

id_dc_solver_to_me(self: lightsim2grid.lightsim2grid_cpp.LSGrid) list[int]

Same as lightsim2grid.network.LSGrid.id_ac_solver_to_me but only used for the DC approximation.

id_me_to_ac_solver(self: lightsim2grid.lightsim2grid_cpp.LSGrid) list[int]

In lightsim2grid, buses are labelled from 0 to n-1 (if n denotes the total number of buses on the grid) [this is called “grid model bus id”]

At any given point in time, some buses might be deactivated (for example because nothing is connected to them).

On the other end, the solvers need a contiguous list of only active buses (otherwise they might run into divergence issue) [this will be called “solver bus id” later on]

This function allows, for all buses of the lightsim2grid.network.LSGrid to know on which “solver bus” they are affected. It has the same size as the total number of buses on the grid. And for each of them it tells to which “solver bus” it is connected (unless there is a -1, meaning the associated bus is deactivated).

Examples

# create a grid model
import grid2op
from lightsim2grid import LightSimBackend
env_name = ...  # eg "l2rpn_case14_sandbox"
env = grid2op.make(env_name, backend=LightSimbackend())
grid_model = env.backend._grid

id_me_to_ac_solver = grid.id_me_to_ac_solver()
# is [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1]

# put everything to bus 2 on substation O
_ = env.step(env.action_space({"set_bus": {"substations_id": [(0, (2, 2, 2))]}}))

id_me_to_ac_solver2 = grid.id_me_to_ac_solver()
# is [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1]

See also

lightsim2grid.network.LSGrid.id_me_to_dc_solver for its counterpart when a dc powerflow is used

See also

lightsim2grid.network.LSGrid.id_ac_solver_to_me for the “reverse” operation (given a “solver bus” id, returns the “gridmodel bus id”)

Notes

For all steps, you have the propertie that, if id_ac_solver_to_me = gridmodel.id_ac_solver_to_me() and id_me_to_ac_solver = gridmodel.id_me_to_ac_solver() and by denoting gridmodel_bus_id = np.arange(gridmodel.total_bus()) and solver_bus_id = np.arange(gridmodel.nb_connected_bus()):

  • solver_bus_id and id_ac_solver_to_me have the same shape

  • gridmodel_bus_id and id_me_to_ac_solver have the same shape

  • solver_bus_id is shorter (or of the same length) than gridmodel_bus_id

  • the connected bus (in the grid model) are given by gridmodel_bus_id[id_ac_solver_to_me], and it gives their order

id_me_to_dc_solver(self: lightsim2grid.lightsim2grid_cpp.LSGrid) list[int]

Same as lightsim2grid.network.LSGrid.id_me_to_ac_solver but only used for the DC approximation.

init_bus(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsInt | SupportsIndex, arg1: SupportsInt | SupportsIndex, arg2: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], arg3: SupportsInt | SupportsIndex, arg4: SupportsInt | SupportsIndex) None

Low-level / internal primitive, not part of the stable public API: called directly by lightsim2grid’s own machinery (eg LightSimBackend, the grid loaders, or another part of the C++ core) rather than meant for everyday use.

Warning

Argument validation here is deliberately minimal or absent, and its exact behavior / signature may change between releases without notice. Prefer the higher-level methods documented elsewhere on this class (or grid2op’s own API) unless you specifically need this one and understand what it does internally.

init_bus_status(self: lightsim2grid.lightsim2grid_cpp.LSGrid) None

Low-level / internal primitive, not part of the stable public API: called directly by lightsim2grid’s own machinery (eg LightSimBackend, the grid loaders, or another part of the C++ core) rather than meant for everyday use.

Warning

Argument validation here is deliberately minimal or absent, and its exact behavior / signature may change between releases without notice. Prefer the higher-level methods documented elsewhere on this class (or grid2op’s own API) unless you specifically need this one and understand what it does internally.

init_dclines(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: Annotated[numpy.typing.NDArray[numpy.int32], '[m, 1]'], arg1: Annotated[numpy.typing.NDArray[numpy.int32], '[m, 1]'], arg2: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], arg3: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], arg4: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], arg5: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], arg6: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], arg7: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], arg8: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], arg9: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], arg10: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]']) None

Construct every HVDC line of the grid at once from these per-line arrays (both ends’ buses, active power setpoint, loss percentage and voltage setpoints) – see HvdcLineContainer / HvdcLineInfo. Called once by the grid loaders.

init_generators(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], arg1: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], arg2: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], arg3: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], arg4: Annotated[numpy.typing.NDArray[numpy.int32], '[m, 1]']) None

Construct every generator of the grid at once from these per-generator arrays (active power, voltage setpoint, reactive limits and bus) – see GeneratorContainer / GenInfo. Called once by the grid loaders.

init_generators_full(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], arg1: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], arg2: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], arg3: collections.abc.Sequence[bool], arg4: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], arg5: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], arg6: Annotated[numpy.typing.NDArray[numpy.int32], '[m, 1]']) None

Same as init_generators(), but also taking a reactive power value and an explicit voltage_regulator_on flag per generator (used when the source format, eg pypowsybl, distinguishes a PV generator from a fixed-Q one explicitly).

init_hvdc_lines(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: Annotated[numpy.typing.NDArray[numpy.int32], '[m, 1]'], arg1: Annotated[numpy.typing.NDArray[numpy.int32], '[m, 1]'], arg2: collections.abc.Sequence[SupportsInt | SupportsIndex], arg3: collections.abc.Sequence[SupportsInt | SupportsIndex], arg4: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], arg5: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], arg6: collections.abc.Sequence[bool], arg7: collections.abc.Sequence[bool], arg8: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], arg9: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], arg10: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], arg11: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], arg12: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], arg13: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], arg14: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], arg15: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], arg16: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], arg17: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], arg18: collections.abc.Sequence[SupportsInt | SupportsIndex], arg19: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], arg20: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], arg21: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], arg22: collections.abc.Sequence[bool], arg23: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], arg24: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], arg25: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], arg26: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]']) None

Construct every HVDC line of the grid at once, like init_dclines() but also taking each converter station’s type (VSC / LCC) – see ConverterStationInfo.

init_loads(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], arg1: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], arg2: Annotated[numpy.typing.NDArray[numpy.int32], '[m, 1]']) None

Construct every load of the grid at once from these per-load arrays (active / reactive power and bus) – see LoadContainer / LoadInfo. Called once by the grid loaders.

init_powerlines(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], arg1: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], arg2: Annotated[numpy.typing.NDArray[numpy.complex128], '[m, 1]'], arg3: Annotated[numpy.typing.NDArray[numpy.int32], '[m, 1]'], arg4: Annotated[numpy.typing.NDArray[numpy.int32], '[m, 1]']) None

Construct every powerline of the grid at once from these per-line arrays (r/x/h in per-unit, plus each end’s bus) – see LineContainer / LineInfo for what each resulting attribute means. Called once by the grid loaders.

init_powerlines_full(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], arg1: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], arg2: Annotated[numpy.typing.NDArray[numpy.complex128], '[m, 1]'], arg3: Annotated[numpy.typing.NDArray[numpy.complex128], '[m, 1]'], arg4: Annotated[numpy.typing.NDArray[numpy.int32], '[m, 1]'], arg5: Annotated[numpy.typing.NDArray[numpy.int32], '[m, 1]']) None

Same as init_powerlines(), but with independent shunt admittances h1 / h2 on each side instead of a single shared h – see h1_pu / h2_pu.

init_sgens(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], arg1: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], arg2: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], arg3: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], arg4: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], arg5: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], arg6: Annotated[numpy.typing.NDArray[numpy.int32], '[m, 1]']) None

Construct every static generator of the grid at once from these per-element arrays (active / reactive power, active power range and bus) – see SGenContainer / SGenInfo. Called once by the grid loaders.

init_shunt(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], arg1: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], arg2: Annotated[numpy.typing.NDArray[numpy.int32], '[m, 1]']) None

Construct every shunt of the grid at once from these per-shunt arrays (active / reactive power and bus) – see ShuntContainer / ShuntInfo. Called once by the grid loaders.

init_storages(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], arg1: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], arg2: Annotated[numpy.typing.NDArray[numpy.int32], '[m, 1]']) None

Construct every storage unit of the grid at once from these per-storage arrays (active / reactive power and bus) – see StorageContainer / StorageInfo. Called once by the grid loaders.

init_svcs(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: collections.abc.Sequence[SupportsInt | SupportsIndex], arg1: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], arg2: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], arg3: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], arg4: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], arg5: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], arg6: Annotated[numpy.typing.NDArray[numpy.int32], '[m, 1]'], arg7: Annotated[numpy.typing.NDArray[numpy.int32], '[m, 1]']) None

Construct every SVC of the grid at once from these per-element arrays (regulation mode, voltage / reactive setpoints, slope and susceptance limits) – see SvcContainer / SvcInfo. Called once by the grid loaders.

init_trafo(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], arg1: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], arg2: Annotated[numpy.typing.NDArray[numpy.complex128], '[m, 1]'], arg3: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], arg4: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], arg5: collections.abc.Sequence[bool], arg6: Annotated[numpy.typing.NDArray[numpy.int32], '[m, 1]'], arg7: Annotated[numpy.typing.NDArray[numpy.int32], '[m, 1]'], arg8: bool) None

Construct every transformer of the grid at once, like init_trafo_pandapower() but taking an already-computed complex ratio directly instead of a pandapower tap step.

init_trafo_pandapower(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], arg1: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], arg2: Annotated[numpy.typing.NDArray[numpy.complex128], '[m, 1]'], arg3: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], arg4: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], arg5: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], arg6: collections.abc.Sequence[bool], arg7: Annotated[numpy.typing.NDArray[numpy.int32], '[m, 1]'], arg8: Annotated[numpy.typing.NDArray[numpy.int32], '[m, 1]'], arg9: bool) None

Construct every transformer of the grid at once from pandapower-style parameters (tap step in percent rather than a ready-made ratio) – see TrafoContainer / TrafoInfo, and lightsim2grid.network.init_from_pandapower() which uses this. Called once by the grid loaders.

staticmethod load_binary(path: str) lightsim2grid.lightsim2grid_cpp.LSGrid

Load an object previously saved with save_binary(). Raises RuntimeError on an incompatible binary format, a wrong object type, or a corrupted / truncated file (including corrupted internal sizes: no attempt is made to allocate more data than the file actually contains). Loading a whole grid additionally validates its consistency (see check_grid): a byte-wise well-formed but inconsistent grid raises IndexError (out-of-range index) or RuntimeError (structural inconsistency).

staticmethod load_binary_without_algorithm(path: str) lightsim2grid.lightsim2grid_cpp.LSGrid

Load a grid saved with save_binary(), WITHOUT restoring the AC / DC solver it was saved with (nor that solver’s configuration): the grid keeps the default solvers and you select one yourself with change_algorithm(). Use this when load_binary() reports that the saved solver is unavailable here – typically a solver plugin that has not been loaded in this process. Every other check (binary format, corruption, grid consistency) is applied exactly as in load_binary().

nb_connected_bus(self: lightsim2grid.lightsim2grid_cpp.LSGrid) int

Returns (>0 integer) the number of connected buses on the powergrid (ignores the disconnected bus).

prevent_ac_cache_reuse(self: lightsim2grid.lightsim2grid_cpp.LSGrid) None

Throw away what the AC family cached: its next powerflow starts from scratch (bus labelling, Ybus, Sbus, PV / PQ split, slack weights, the algorithm’s own factorization, and the bus-connectivity snapshot used to detect topology changes).

This is a one-shot invalidation, not a mode: the AC family goes on caching normally afterwards. To turn caching off durably, use lightsim2grid.network.LSGrid.allow_ac_cache_reuse() instead.

You need it only after modifying the grid through a path that bypasses lightsim2grid.network.LSGrid’s own change_* / deactivate_* / reactivate_* methods – those already invalidate exactly what they touch – or when in doubt after a change of unclear scope. It is always correct, just more expensive than letting the narrower flags do their job.

Added in version 1.0.0.

prevent_cache_reuse(self: lightsim2grid.lightsim2grid_cpp.LSGrid) None

Throw away what both families cached – see lightsim2grid.network.LSGrid.prevent_ac_cache_reuse().

This is the function previously named tell_solver_need_reset, which still works and does exactly the same thing.

Added in version 1.0.0.

prevent_dc_cache_reuse(self: lightsim2grid.lightsim2grid_cpp.LSGrid) None

Same as lightsim2grid.network.LSGrid.prevent_ac_cache_reuse(), for the DC family.

Added in version 1.0.0.

reactivate_bus(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsInt | SupportsIndex) None

Low-level / internal primitive, not part of the stable public API: called directly by lightsim2grid’s own machinery (eg LightSimBackend, the grid loaders, or another part of the C++ core) rather than meant for everyday use.

Warning

Argument validation here is deliberately minimal or absent, and its exact behavior / signature may change between releases without notice. Prefer the higher-level methods documented elsewhere on this class (or grid2op’s own API) unless you specifically need this one and understand what it does internally.

reactivate_dcline(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsInt | SupportsIndex) None

Reconnect HVDC line dcline_id (both converter stations), the opposite of deactivate_dcline().

reactivate_gen(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsInt | SupportsIndex) None

Reconnect generator gen_id, the opposite of deactivate_gen().

reactivate_load(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsInt | SupportsIndex) None

Reconnect load load_id, the opposite of deactivate_load().

reactivate_powerline(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsInt | SupportsIndex) None

Reconnect powerline powerline_id (both sides), the opposite of deactivate_powerline().

reactivate_powerline_side1(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsInt | SupportsIndex) None

Reconnect only side 1 of a powerline.

reactivate_powerline_side2(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsInt | SupportsIndex) None

Reconnect only side 2 of a powerline.

reactivate_result_computation(self: lightsim2grid.lightsim2grid_cpp.LSGrid) None

Allows to reactivate the computation of the flows, reactive power absorbed by generators etc. when they are needed again after having been deactivated.

reactivate_sgen(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsInt | SupportsIndex) None

Reconnect static generator sgen_id, the opposite of deactivate_sgen().

reactivate_shunt(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsInt | SupportsIndex) None

Reconnect shunt shunt_id, the opposite of deactivate_shunt().

reactivate_storage(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsInt | SupportsIndex) None

Reconnect storage unit storage_id, the opposite of deactivate_storage().

reactivate_svc(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsInt | SupportsIndex) None

Reconnect SVC svc_id, the opposite of deactivate_svc().

reactivate_trafo(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsInt | SupportsIndex) None

Reconnect transformer trafo_id (both sides), the opposite of deactivate_trafo().

reactivate_trafo_side1(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsInt | SupportsIndex) None

Reconnect only side 1 of a transformer.

reactivate_trafo_side2(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsInt | SupportsIndex) None

Reconnect only side 2 of a transformer.

remove_gen_slackbus(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsInt | SupportsIndex) None

Remove generator gen_id from the distributed slack (the opposite of add_gen_slackbus()) – see is_slack.

save_binary(self: lightsim2grid.lightsim2grid_cpp.LSGrid, path: str, atomic: bool = True) None

Save this object’s state to a fast custom binary file (additive alternative to pickle). By default (atomic=True) the write is atomic: an existing file at that path is only replaced once the new content has been written completely (an interrupted save never destroys a previous file). Pass atomic=False to write the destination directly instead – marginally faster (skips one temporary file + rename), without that protection. The file stays readable by any lightsim2grid version sharing the same binary format number.

set_ac_algo_config(self: lightsim2grid.lightsim2grid_cpp.LSGrid, config: lightsim2grid.lightsim2grid_cpp.AlgoConfig) None

Apply a lightsim2grid.algorithm.AlgoConfig to the AC solver (restores scaling/refactor policy and parameters).

set_bus_voltage_limits(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], arg1: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]']) None

Set the per-bus min/max operating voltage (in kV), one value per bus (see get_bus_vn_kv()).

set_dc_algo_config(self: lightsim2grid.lightsim2grid_cpp.LSGrid, config: lightsim2grid.lightsim2grid_cpp.AlgoConfig) None

Apply a lightsim2grid.algorithm.AlgoConfig to the DC solver.

set_dcline_names(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: collections.abc.Sequence[str]) None

Set the HVDC lines’ names, one per HVDC line (raises if the length does not match the number of HVDC lines).

set_gen_names(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: collections.abc.Sequence[str]) None

Set the generators’ names, one per generator (raises if the length does not match the number of generators).

set_gen_pos_topo_vect(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: Annotated[numpy.typing.NDArray[numpy.int32], '[m, 1]']) None

Set, for every generator at once, its position in the topology vector, see set_load_pos_topo_vect() and GenInfo.

set_gen_regulated_bus(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsInt | SupportsIndex, arg1: SupportsInt | SupportsIndex) None

Set the grid bus whose voltage a generator regulates (“remote voltage control”, see lightsim2grid.elements.GenInfo.regulated_bus_id; bus == own bus for local control).

set_gen_to_subid(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: Annotated[numpy.typing.NDArray[numpy.int32], '[m, 1]']) None

Set, for every generator at once, the substation it belongs to, see set_load_to_subid() and GenInfo.

set_ignore_status_global(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: bool) None

Ignore the global_status flags for powerlines and transformers (set to True if you want to control each side of a powerline / transformer independently). Default: False.

set_init_vm_pu(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsFloat | SupportsIndex) None

Set the flat-start voltage magnitude (pu), used to initialize every bus’s Vm before an AC powerflow when no better guess is available (see ac_pf()’s Vinit), and directly as every bus’s Vm for a DC powerflow (see dc_pf()). Must be finite and strictly positive: a degenerate value does not fail loudly, it silently produces a confidently wrong powerflow.

set_line_current_limit_side1(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]']) None

Set the side-1 current limit of each powerline, in kA (see lightsim2grid.elements.LineInfo.limit_a1_ka).

set_line_current_limit_side2(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]']) None

Set the side-2 current limit of each powerline, in kA (see lightsim2grid.elements.LineInfo.limit_a2_ka).

set_line_names(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: collections.abc.Sequence[str]) None

Set the powerlines’ names, one per powerline (raises if the length does not match the number of powerlines).

See also

get_line_names() to read them back.

set_line_pos1_topo_vect(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: Annotated[numpy.typing.NDArray[numpy.int32], '[m, 1]']) None

Set, for every powerline at once, its side-1 position in the topology vector – see pos1_topo_vect, see also set_load_pos_topo_vect().

set_line_pos2_topo_vect(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: Annotated[numpy.typing.NDArray[numpy.int32], '[m, 1]']) None

Set, for every powerline at once, its side-2 position in the topology vector, see set_line_pos1_topo_vect().

set_line_to_sub1_id(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: Annotated[numpy.typing.NDArray[numpy.int32], '[m, 1]']) None

Set, for every powerline at once, the substation its side 1 belongs to – see sub1_id, see also set_load_to_subid().

set_line_to_sub2_id(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: Annotated[numpy.typing.NDArray[numpy.int32], '[m, 1]']) None

Set, for every powerline at once, the substation its side 2 belongs to, see set_line_to_sub1_id().

set_load_names(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: collections.abc.Sequence[str]) None

Set the loads’ names, one per load (raises if the length does not match the number of loads).

set_load_pos_topo_vect(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: Annotated[numpy.typing.NDArray[numpy.int32], '[m, 1]']) None

Set, for every load at once, its position in the topology vector – see pos_topo_vect. Called once by the grid loaders; not meant to be called again afterwards.

set_load_to_subid(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: Annotated[numpy.typing.NDArray[numpy.int32], '[m, 1]']) None

Set, for every load at once, the substation it belongs to – see sub_id. Called once by the grid loaders; not meant to be called again afterwards.

set_max_nb_bus_per_sub(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsInt | SupportsIndex) None

Set the (constant, grid-wide) maximum number of busbars per substation. Raises if n_sub * max_nb_bus_per_sub does not match the number of buses the grid was built with (see init_bus()): reinitialize the grid with init_bus(), or fix set_n_sub() first, instead of forcing a mismatched value here.

set_n_sub(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsInt | SupportsIndex) None

Set the number of substations of the grid (unchecked against anything else – see set_max_nb_bus_per_sub(), which does cross-check it against the bus count from init_bus()).

set_reference_slack_bus(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsInt | SupportsIndex) None

Force a (gridmodel) bus to be the angle reference among the slack buses (reordered to slack_ids[0]) without changing the slack set / weights; -1 clears it.

set_sgen_names(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: collections.abc.Sequence[str]) None

Set the static generators’ names, one per static generator (raises if the length does not match the number of static generators).

set_shunt_names(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: collections.abc.Sequence[str]) None

Set the shunts’ names, one per shunt (raises if the length does not match the number of shunts).

set_shunt_to_subid(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: Annotated[numpy.typing.NDArray[numpy.int32], '[m, 1]']) None

Set, for every shunt at once, the substation it belongs to, see set_load_to_subid() and ShuntInfo.

set_sn_mva(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsFloat | SupportsIndex) None

Set the base power (MVA) of the grid’s per-unit system: Sbus is expressed in this unit internally, every MW / MVAr result is the per-unit value multiplied back by it, and the solver’s convergence tolerance is scaled by it (see ac_pf()). Must be finite and strictly positive: a degenerate value does not fail loudly, it silently produces a confidently wrong powerflow.

set_status_droop_hvdc(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: SupportsInt | SupportsIndex, arg1: SupportsInt | SupportsIndex) None

Set the angle-droop regime of an HVDC line (see lightsim2grid.elements.HvdcLineInfo.status_droop): 0 = linear, +1 = saturated side 1 to side 2, -1 = saturated side 2 to side 1.

This is an INPUT of the solver, constant across one solve: the saturation logic is meant to be run between two solves (a Python outer loop).

set_storage_names(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: collections.abc.Sequence[str]) None

Set the storage units’ names, one per storage unit (raises if the length does not match the number of storage units).

set_storage_pos_topo_vect(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: Annotated[numpy.typing.NDArray[numpy.int32], '[m, 1]']) None

Set, for every storage unit at once, its position in the topology vector, see set_load_pos_topo_vect() and StorageInfo.

set_storage_to_subid(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: Annotated[numpy.typing.NDArray[numpy.int32], '[m, 1]']) None

Set, for every storage unit at once, the substation it belongs to, see set_load_to_subid() and StorageInfo.

set_substation_names(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: collections.abc.Sequence[str]) None

Set the name of every substation at once – see name. Raises if the list’s length does not match the number of substations.

set_svc_names(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: collections.abc.Sequence[str]) None

Set the Static Var Compensators’ names, one per SVC (raises if the length does not match the number of SVCs).

set_synch_status_both_side(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: bool) None

Synchronize the status of each side of a powerline / transformer: if you disconnect one side, the other side is also disconnected. Default: True.

set_trafo_current_limit_side1(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]']) None

Set the side-1 current limit of each transformer, in kA (see lightsim2grid.elements.TrafoInfo.limit_a1_ka).

set_trafo_current_limit_side2(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]']) None

Set the side-2 current limit of each transformer, in kA (see lightsim2grid.elements.TrafoInfo.limit_a2_ka).

set_trafo_names(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: collections.abc.Sequence[str]) None

Set the transformers’ names, one per transformer (raises if the length does not match the number of transformers).

See also

get_trafo_names() to read them back.

set_trafo_pos1_topo_vect(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: Annotated[numpy.typing.NDArray[numpy.int32], '[m, 1]']) None

Set, for every transformer at once, its side-1 (hv) position in the topology vector, see set_line_pos1_topo_vect() and TrafoInfo.

set_trafo_pos2_topo_vect(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: Annotated[numpy.typing.NDArray[numpy.int32], '[m, 1]']) None

Set, for every transformer at once, its side-2 (lv) position in the topology vector, see set_line_pos1_topo_vect() and TrafoInfo.

set_trafo_shift_dependent_rx(self: lightsim2grid.lightsim2grid_cpp.LSGrid, enable: bool, alpha_rad: collections.abc.Sequence[collections.abc.Sequence[SupportsFloat | SupportsIndex]], rx_corr_pct: collections.abc.Sequence[collections.abc.Sequence[SupportsFloat | SupportsIndex]]) None

Declare that (some) transformers have a series impedance (r, x) that depends on their phase-shift angle alpha, supplied as a per-transformer table of sample points alpha (rad) -> r/x correction (%) (the per-step r/x deltas of a pypowsybl phase-tap-changer; r% == x%).

The effective r / x is then base * (1 + corr(shift) / 100), interpolated on the current shift and refreshed whenever change_shift_trafo() / change_ratio_trafo is called. There is NO “tap” concept here: the dependency is purely on the (continuous) shift.

Pass an empty list for a transformer without such a dependency; enable should be kept False for pandapower grids, which have no such data.

set_trafo_to_sub1_id(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: Annotated[numpy.typing.NDArray[numpy.int32], '[m, 1]']) None

Set, for every transformer at once, the substation its side 1 (hv) belongs to, see set_line_to_sub1_id() and TrafoInfo.

set_trafo_to_sub2_id(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: Annotated[numpy.typing.NDArray[numpy.int32], '[m, 1]']) None

Set, for every transformer at once, the substation its side 2 (lv) belongs to, see set_line_to_sub1_id() and TrafoInfo.

tell_recompute_sbus(self: lightsim2grid.lightsim2grid_cpp.LSGrid) None

Low-level / internal primitive, not part of the stable public API: called directly by lightsim2grid’s own machinery (eg LightSimBackend, the grid loaders, or another part of the C++ core) rather than meant for everyday use.

Warning

Argument validation here is deliberately minimal or absent, and its exact behavior / signature may change between releases without notice. Prefer the higher-level methods documented elsewhere on this class (or grid2op’s own API) unless you specifically need this one and understand what it does internally.

tell_recompute_ybus(self: lightsim2grid.lightsim2grid_cpp.LSGrid) None

Low-level / internal primitive, not part of the stable public API: called directly by lightsim2grid’s own machinery (eg LightSimBackend, the grid loaders, or another part of the C++ core) rather than meant for everyday use.

Warning

Argument validation here is deliberately minimal or absent, and its exact behavior / signature may change between releases without notice. Prefer the higher-level methods documented elsewhere on this class (or grid2op’s own API) unless you specifically need this one and understand what it does internally.

tell_solver_need_reset(self: lightsim2grid.lightsim2grid_cpp.LSGrid) None

Backward-compatible name of lightsim2grid.network.LSGrid.prevent_cache_reuse(): throw away what both solver families cached, so their next powerflow starts from scratch.

Changed in version 1.0.0: Renamed to lightsim2grid.network.LSGrid.prevent_cache_reuse(). This name is kept and behaves identically; there is no plan to remove it.

tell_ybus_change_sparsity_pattern(self: lightsim2grid.lightsim2grid_cpp.LSGrid) None

Low-level / internal primitive, not part of the stable public API: called directly by lightsim2grid’s own machinery (eg LightSimBackend, the grid loaders, or another part of the C++ core) rather than meant for everyday use.

Warning

Argument validation here is deliberately minimal or absent, and its exact behavior / signature may change between releases without notice. Prefer the higher-level methods documented elsewhere on this class (or grid2op’s own API) unless you specifically need this one and understand what it does internally.

property timer_last_ac_pf

Wall-clock time (seconds) of the last ac_pf() call, from pre-processing through result storage – the whole call, not just the solver’s own internal timers (see lightsim2grid.algorithm.NR_SparseLU.get_timers() / get_timers_jacobian() for those). 0. if ac_pf() was never called.

property timer_last_dc_pf

Same as timer_last_ac_pf, but for the last dc_pf() call.

total_bus(self: lightsim2grid.lightsim2grid_cpp.LSGrid) int

Returns (>0 integer) the total number of buses in the powergrid (both connected and disconnected)

turnedoff_no_pv(self: lightsim2grid.lightsim2grid_cpp.LSGrid) None

Turned-off generators (or generators with target_p_mw == 0) will not be PV buses: they will not maintain voltage.

turnedoff_pv(self: lightsim2grid.lightsim2grid_cpp.LSGrid) None

Turned-off generators (or generators with target_p_mw == 0) will be PV buses: they will maintain voltage. This is the default.

unset_changes(self: lightsim2grid.lightsim2grid_cpp.LSGrid) None

Historical, manual way of telling the grid “the data cached for the solvers matches me, reuse it”. Since version 1.0.0 every powerflow does this for its own family on the way out, so there is nothing left for this function to do and it returns immediately whenever cache reuse is enabled for both families (the default).

It still has an effect on a grid where lightsim2grid.network.LSGrid.allow_cache_reuse() (or one of its per-family variants) turned the automatic marking off – and even there the family’s own setting wins: a family told not to reuse its cache rebuilds on its next powerflow regardless.

Calling it is never unsafe, and never necessary. New code should simply not call it.

Changed in version 1.0.0: No longer needed: cache reuse is automatic and on by default. Before 1.0.0, forgetting this call silently cost performance – and making it at the wrong moment (on a grid that never solved, or before a powerflow of the other family) could segfault.

update_gens_p(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: Annotated[numpy.typing.NDArray[numpy.bool], '[m, 1]'], arg1: Annotated[numpy.typing.NDArray[numpy.float32], '[m, 1]']) None

Masked, vectorized equivalent of change_p_gen(): for every generator i with has_changed[i], set its active power setpoint to new_values[i]. Used by LightSimBackend to apply a whole timestep’s injections in one call instead of looping over change_p_gen().

update_gens_v(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: Annotated[numpy.typing.NDArray[numpy.bool], '[m, 1]'], arg1: Annotated[numpy.typing.NDArray[numpy.float32], '[m, 1]']) None

Masked, vectorized equivalent of change_v_gen(), see update_gens_p().

Voltage setpoints are expressed in pu, NOT kV.

update_loads_p(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: Annotated[numpy.typing.NDArray[numpy.bool], '[m, 1]'], arg1: Annotated[numpy.typing.NDArray[numpy.float32], '[m, 1]']) None

Masked, vectorized equivalent of change_p_load(), see update_gens_p().

update_loads_q(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: Annotated[numpy.typing.NDArray[numpy.bool], '[m, 1]'], arg1: Annotated[numpy.typing.NDArray[numpy.float32], '[m, 1]']) None

Masked, vectorized equivalent of change_q_load(), see update_gens_p().

update_sgens_p(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: Annotated[numpy.typing.NDArray[numpy.bool], '[m, 1]'], arg1: Annotated[numpy.typing.NDArray[numpy.float32], '[m, 1]']) None

Masked, vectorized equivalent of change_p_sgen(), see update_gens_p().

update_slack_weights(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: Annotated[numpy.typing.NDArray[numpy.bool], '[m, 1]']) None

Recompute the distributed-slack weight of every generator, restricted to the ones for which could_be_slack is True (a boolean array, one entry per generator): each such generator’s weight becomes proportional to its abs(target_p_mw) (or, if every candidate’s target_p_mw is 0., an equal split among them). Every other generator stops participating in the slack.

See also

update_slack_weights_by_id(), the same but taking a list of generator ids instead of a boolean mask.

update_slack_weights_by_id(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: Annotated[numpy.typing.NDArray[numpy.int32], '[m, 1]']) None

Same as update_slack_weights(), but slack_ids is a list of candidate generator ids instead of a per-generator boolean mask.

update_storages_p(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: Annotated[numpy.typing.NDArray[numpy.bool], '[m, 1]'], arg1: Annotated[numpy.typing.NDArray[numpy.float32], '[m, 1]']) None

Masked, vectorized equivalent of change_p_storage(), see update_gens_p().

update_topo(self: lightsim2grid.lightsim2grid_cpp.LSGrid, arg0: Annotated[numpy.typing.NDArray[numpy.bool], '[m, 1]'], arg1: Annotated[numpy.typing.NDArray[numpy.int32], '[m, 1]']) None

Masked, vectorized bus-change equivalent of change_bus_load() / change_bus_gen() / change_bus_storage() / change_bus1_powerline() / change_bus2_powerline() / change_bus1_trafo() / change_bus2_trafo(), all at once.

Both arrays are indexed by position in the topology vector (loads, then generators, then storage units, then each powerline’s two sides, then each transformer’s two sides – exactly pos_topo_vect / pos_topo_vect / etc. for that element), not by element id: for every position k with has_changed[k], the corresponding side is moved to bus new_values[k] (in “local” – 1-based busbar-within-substation – convention; 0 disconnects that side). Both arrays must have exactly the size of the topology vector, or this raises.

class lightsim2grid.network.LightsimResultNetwork(ls_grid: LSGrid, net: Network)[source]

pypowsybl-Network-shaped view of a solved lightsim2grid LSGrid.

Parameters:
  • ls_grid – a grid built by init_from_pypowsybl(net, ...) and already solved (ac_pf/dc_pf converged).

  • net – the same pypowsybl network passed to that init() call.

Every get_* method mirrors its pypo.network.Network namesake: it accepts an optional attributes list and returns a DataFrame indexed by the pypowsybl element id, built lazily on first call and cached afterwards.

Supported element types (one get_* method each): buses, lines, 2-winding transformers, generators, loads, shunt compensators, static var compensators, batteries/storage units, HVDC lines, and VSC / LCC converter stations.

Not exposed here, even when present on net (or, for dangling lines, on the LSGrid itself): dangling lines – no get_dangling_lines method, including when the grid was built with init_from_pypowsybl(..., convert_dangling_lines=True) – and three-winding transformers, which initLSGrid.init does not model at all (not just unexposed here).

Column provenance, for every get_* method’s DataFrame:

  • power-flow results (p/q/i/i1/i2/p1/p2/ q1/q2/v_mag/v_angle) are read off the solved LSGrid – this specific powerflow’s outcome, not the original net’s.

  • topology / metadata columns (bus_id/bus1_id/bus2_id, connected/connected1/connected2, voltage_level_id/voltage_level1_id/voltage_level2_id, is_lcc) reflect LSGrid’s current state, which mirrors net only as long as nothing changed the grid (topology, connectivity, …) after init_from_pypowsybl built it – they are not re-read from net on every call.

  • a handful of columns are read verbatim from the original net and frozen at construction time, never from LSGrid: currently only converter_station1_id / converter_station2_id on get_hvdc_lines().

  • every DataFrame’s index (id) mirrors the element’s pypowsybl id by construction (initLSGrid.init sets every non-bus element’s lightsim2grid name verbatim to it, see the module docstring), even though it is technically sourced from LSGrid, not read from net.

Methods:

get_2_windings_transformers([attributes])

Same columns as get_lines() (this class does not expose tap position / ratio / phase-shift columns).

get_batteries([attributes])

See the one-sided column list above get_generators().

get_buses([attributes])

Columns: v_mag (kV, solved result), v_angle (degree, solved result, offset-aligned to net's own angle datum -- see _build_buses()), voltage_level_id (topology, from net).

get_generators([attributes])

See the one-sided column list above get_generators.

get_hvdc_lines([attributes])

Columns: p1/q1/p2/q2 (solved results, MW/MVAr, generation sign convention, negated from lightsim2grid's internal convention), connected1/connected2 (topology, from the current LSGrid state), converter_station1_id / converter_station2_id (the only columns in this whole class read verbatim from the original net and frozen at construction time -- see the class docstring).

get_lcc_converter_stations([attributes])

Same columns as get_vsc_converter_stations() (this class does not expose power_factor).

get_lines([attributes])

Columns: p1/q1/i1/p2/q2/i2 (solved results, MW/MVAr/A), bus1_id/bus2_id/connected1/connected2/ voltage_level1_id/voltage_level2_id (topology, from the current LSGrid state, see the class docstring).

get_loads([attributes])

See the one-sided column list above get_generators().

get_shunt_compensators([attributes])

See the one-sided column list above get_generators().

get_static_var_compensators([attributes])

See the one-sided column list above get_generators().

get_vsc_converter_stations([attributes])

Columns: p/q (solved results, MW/MVAr, generation sign convention), bus_id/connected/voltage_level_id (topology, from the current LSGrid state, see the class docstring).

get_2_windings_transformers(attributes: List[str] | None = None) DataFrame[source]

Same columns as get_lines() (this class does not expose tap position / ratio / phase-shift columns).

get_batteries(attributes: List[str] | None = None) DataFrame[source]

See the one-sided column list above get_generators(). No sign flip, same as get_loads().

get_buses(attributes: List[str] | None = None) DataFrame[source]

Columns: v_mag (kV, solved result), v_angle (degree, solved result, offset-aligned to net’s own angle datum – see _build_buses()), voltage_level_id (topology, from net).

get_generators(attributes: List[str] | None = None) DataFrame[source]

See the one-sided column list above get_generators. p/q use the generation sign convention, negated from lightsim2grid’s internal convention (see the module docstring).

get_hvdc_lines(attributes: List[str] | None = None) DataFrame[source]

Columns: p1/q1/p2/q2 (solved results, MW/MVAr, generation sign convention, negated from lightsim2grid’s internal convention), connected1/connected2 (topology, from the current LSGrid state), converter_station1_id / converter_station2_id (the only columns in this whole class read verbatim from the original net and frozen at construction time – see the class docstring).

get_lcc_converter_stations(attributes: List[str] | None = None) DataFrame[source]

Same columns as get_vsc_converter_stations() (this class does not expose power_factor).

get_lines(attributes: List[str] | None = None) DataFrame[source]

Columns: p1/q1/i1/p2/q2/i2 (solved results, MW/MVAr/A), bus1_id/bus2_id/connected1/connected2/ voltage_level1_id/voltage_level2_id (topology, from the current LSGrid state, see the class docstring). See _reconstruct_fused_branches() for how a fused (near-zero-impedance) line’s flow is recovered where possible, instead of reporting 0.

get_loads(attributes: List[str] | None = None) DataFrame[source]

See the one-sided column list above get_generators(). p/q already match pypowsybl’s convention, no sign flip (see the module docstring).

get_shunt_compensators(attributes: List[str] | None = None) DataFrame[source]

See the one-sided column list above get_generators(). No sign flip, same as get_loads(). Does not expose section count / susceptance columns.

get_static_var_compensators(attributes: List[str] | None = None) DataFrame[source]

See the one-sided column list above get_generators(). Assumed to use the same generation sign convention as generators (see the module docstring’s caveat: not independently double-checked against a converged real grid). Does not expose the regulation mode / slope / b_min / b_max columns.

get_vsc_converter_stations(attributes: List[str] | None = None) DataFrame[source]

Columns: p/q (solved results, MW/MVAr, generation sign convention), bus_id/connected/voltage_level_id (topology, from the current LSGrid state, see the class docstring). Does not expose target_v/target_q/voltage_regulator_on.

lightsim2grid.network.bake_outer_loops(network, bake_taps: bool = True, bake_reactive_limits: bool = True, bake_generator_voltage_control_discards: bool = True, bake_active_power: bool = True, bake_active_power_control_participation: bool = True, bake_remote_voltage_control: bool = False, balance_on_loads: bool = False, load_power_factor_constant: bool = False, keep_only_main_comp: bool = True)[source]

Rewrite network input setpoints to the converged outer-loop state.

Call this on a network that has just been solved by OLF with outer loops. Afterwards the network represents a plain power-flow problem: a loop-free OLF run (see get_pypowsybl_loopfree_parameters()) or a lightsim2grid run (via init_from_pypowsybl()) will reproduce the same operating point.

Parameters:
  • network – A pypowsybl network, freshly solved with the outer loops enabled.

  • bake_taps – Copy solved ratio/phase tap positions and shunt sections into the input positions and disable their regulation.

  • bake_reactive_limits – Freeze generators / VSC stations that hit a Q limit to fixed-Q (PQ).

  • bake_generator_voltage_control_discards – Freeze generators OLF’s own voltage-control consistency checks would discard for a reason other than “not started”: too small a reactive range, or an implausible target_v (see _bake_generator_voltage_control_discards()). Also gated by bake_reactive_limits – has no effect if that is off.

  • bake_active_power – Write realized active power back into generator/battery target P (and load p0/q0 if balance_on_loads).

  • bake_active_power_control_participation – Zero out (activePowerControl extension participate=False) slack-distribution participation for generators OLF’s own checkActivePowerControl would exclude (see _bake_active_power_control_participation()). Also gated by bake_active_power – has no effect if that is off.

  • bake_remote_voltage_control – Rewrite remote voltage control to local control at the solved terminal voltage (see _bake_remote_voltage_control()). Needed so that remote-regulating generators can sit on a (distributed) slack bus, which lightsim2grid v1 does not otherwise support.

  • balance_on_loads – Set if the slack was distributed on loads (BalanceType PROPORTIONAL_TO_LOAD / CONFORM_LOAD).

  • load_power_factor_constant – Mirror OLF’s loadPowerFactorConstant: also rewrite load q0 so the power factor is preserved.

  • keep_only_main_comp – Only elements of the main connected component are updated (True by default)

Notes

Operates in place and is idempotent on an already-baked network. The voltage-regulation flag is not used as a switch signal: OLF does not flip it in IIDM, so PV->PQ is detected from the realized Q sitting at a limit.

lightsim2grid.network.compare_baked(network_factory, slack_gen_id: str, line_outages=None, trafo_outages=None, olf_loop_params: Parameters | None = None)[source]

Bake, optionally apply outages, solve in both engines, and compare.

Parameters:
  • network_factory (callable) – Returns a fresh pypowsybl Network. Called twice (once per engine) so the two starts are identical. lightsim2grid mutates/consumes the network it is built from, so a fresh instance is needed for each side.

  • slack_gen_id (str) – Generator id to use as the lightsim2grid slack.

  • line_outages (list of str, optional) – IIDM ids to disconnect identically in both engines after baking.

  • trafo_outages (list of str, optional) – IIDM ids to disconnect identically in both engines after baking.

  • olf_loop_params (pypowsybl.loadflow.Parameters, optional) – Parameters for the initial with-loops OLF solve. Defaults to distributed slack + reactive limits.

Return type:

ComparisonResult

lightsim2grid.network.get_pypowsybl_loopfree_distributed_slack_parameters(slack_bus_ids: str | Iterable[str] | None = None, max_outer_loop_iterations: int = 20, **overrides) Parameters[source]

Loop-free OLF parameters EXCEPT the active-power slack distribution.

Identical to get_pypowsybl_loopfree_parameters() but keeps OLF’s DistributedSlack outer loop active, with balance_type set to PROPORTIONAL_TO_GENERATION_P_MAX – what lightsim2grid’s default distributed slack reproduces. Every other outer loop is removed.

Parameters:
  • slack_bus_ids (str or iterable of str, optional) – Forwarded to remove_outer_loops().

  • max_outer_loop_iterations (int) – Outer-loop iteration cap for the distribution (default 20, the upstream OLF default).

  • **overrides – Any top-level pypowsybl.loadflow.Parameters keyword to set before removing the outer loops. Only applied if the installed pypowsybl accepts that keyword.

lightsim2grid.network.get_pypowsybl_loopfree_parameters(slack_bus_ids: str | Iterable[str] | None = None, **overrides) Parameters[source]

Build a fresh pypowsybl.loadflow.Parameters with every OLF outer loop removed (see remove_outer_loops()).

Everything other than the outer-loop mechanism is left at the installed pypowsybl’s own defaults (or at **overrides, if given) – in particular voltage_init_mode, reactive limits and remote voltage control are not forced, since none of those are outer loops. If a test needs a specific value for one of those to be reproducible across pypowsybl builds, pass it explicitly via **overrides (different pypowsybl builds are known to ship different defaults for these).

Parameters:
  • slack_bus_ids (str or iterable of str, optional) – Forwarded to remove_outer_loops().

  • **overrides – Any top-level pypowsybl.loadflow.Parameters keyword to set before removing the outer loops (e.g. voltage_init_mode=...). Only applied if the installed pypowsybl accepts that keyword.

Returns:

A new object on each call (no shared mutable state).

Return type:

pypowsybl.loadflow.Parameters

lightsim2grid.network.init_from_matpower(source: str | PathLike | dict, n_busbar_per_sub: int | None = None) LSGrid

Convert a MATPOWER case into a LSGrid.

Unlike lightsim2grid.network.init_from_pandapower, this never constructs a pandapower network: it reads MATPOWER’s raw bus / gen / branch / dcline matrices directly and initializes the LSGrid from them. In particular, several generators connected to the same bus are all kept as independent generators (no aggregation).

This can fail to convert the grid and still not throw any error, use with care (for example, you can run a powerflow after this conversion and compare the results against another tool, e.g. pandapower or pypowsybl, on the same case).

Cases for which conversion is not possible include, but are not limited to:

  • mpc.gencost and mpc.areas are ignored (not needed for a powerflow)

  • matpower’s .m files require the optional matpowercaseframes package, .mat files require the optional scipy package.

Parameters:
  • source – Either a path (str or os.PathLike) to a “.m” or “.mat” matpower case file, or an already parsed matpower case: a dict with “bus” / “gen” / “branch” / “baseMVA” keys (e.g. as returned by pypower’s caseN() functions), or any object exposing these as attributes (e.g. a matpowercaseframes.CaseFrames instance built beforehand).

  • n_busbar_per_sub – There is always exactly one substation / voltage level per matpower bus (matpower has no notion of several busbar sections within a bus, so this is not configurable). This parameter only controls how many buses / busbar sections lightsim2grid allocates per substation, which is useful if you intend to perform grid2op-like topology actions on the resulting grid afterwards. Defaults to 1 (no extra busbar section). Any extra busbar section is deactivated, since nothing in the base matpower case is ever connected to it.

Returns:

model – The initialized network

Return type:

lightsim2grid.network.LSGrid

lightsim2grid.network.init_from_pandapower(pp_net: pandapowerNet, n_sub: int | None = None, n_busbar_per_sub: int | None = None, pp_orig_file: Literal['pandapower_v2', 'pandapower_v3'] = 'pandapower_v2') LSGrid

Convert a pandapower network as input into a LSGrid.

This can fail to convert the grid and still not throw any error, use with care (for example, you can run a powerflow after this conversion, run a powerflow with pandapower, and compare the results to make sure they match !)

Cases for which conversion is not possible include, but are not limited to:

  • the pandapower grid has 3 winding transformers

  • the pandapower grid has xwards

  • the pandapower grid has dcline

  • the pandapower grid has switch, motor, assymetric loads, etc.

  • the pandapower grid any parrallel “elements” (at least one of the column “parrallel” is not 1)

  • the bus indexes in pandapower do not start at 0 or are not contiguous (you can check pp_net.bus.index)

  • some g_us_per_km for some lines are not zero ? TODO not sure if that is still the case !

  • some p_mw for some shunts are not zero ? TODO not sure if that is still the case !

if you really need any of the above, please submit a github issue and we will work on their support.

This conversion has been extensively studied for the case118() of pandapower.networks and should work really well for this grid. Actually, this grid is used for testing the LSGrid class.

Parameters:
  • pp_net (pandapower.auxiliary.pandapowerNet) – The initial pandapower network you want to convert

  • pp_orig_file

    Pandapower change the formula they used internally to compute the “equations” parameters of the transformers between pandapower 2.xx and 3.xx.

    If you are using a recent (=> 3.xx) version of pandapower, you can pass use the ad-hoc trafo converter of lightsim2grid.

    For grid2op environment, we recommed NOT to use it if the environment has been released before 2026 as the case files came from pandapower 2 (so it’s better to use the pandapower 2 converter).

Returns:

model – The initialize network

Return type:

lightsim2grid.network.LSGrid

lightsim2grid.network.init_from_pf_delta(row: dict | str | PathLike, n_busbar_per_sub: int | None = None) LSGrid

Convert a PFΔ dataset row into a LSGrid.

Parameters:
  • row – Either a PFΔ row already parsed into a dict (with a top-level “network” key), or a path (str or os.PathLike) to a .json file containing that same structure.

  • n_busbar_per_sub – Passed through directly to lightsim2grid.network.init_from_powermodels.

Returns:

model – The initialized network

Return type:

lightsim2grid.network.LSGrid

lightsim2grid.network.init_from_powermodels(network: dict, n_busbar_per_sub: int | None = None) LSGrid

Convert a PowerModels.jl network data dictionary into a LSGrid.

Parameters:
  • network (dict) – A PowerModels network data dictionary (the top-level dict with “bus” / “branch” / “gen” / … keys – not a full PFΔ dataset row, which wraps this dict under a “network” key; use init_from_pfdelta for that).

  • n_busbar_per_sub – There is always exactly one substation / voltage level per PowerModels bus (PowerModels has no notion of several busbar sections within a bus, so this is not configurable). This parameter only controls how many buses / busbar sections lightsim2grid allocates per substation, which is useful if you intend to perform grid2op-like topology actions on the resulting grid afterwards. Defaults to 1 (no extra busbar section). Any extra busbar section is deactivated, since nothing in the base network is ever connected to it.

Returns:

model – The initialized network

Return type:

lightsim2grid.network.LSGrid

lightsim2grid.network.init_from_pypowsybl(net: Network, gen_slack_id: int | str | Iterable[str] | Dict[str, float] | None = None, slack_bus_id: int | None = None, sn_mva: float = 100.0, sort_index: bool = True, f_hz: float = 50.0, net_pu: Network | None = None, only_main_component: bool = True, return_sub_id: bool = False, n_busbar_per_sub: int | None = None, buses_for_sub: bool | None = None, init_vm_pu: float = 1.06, keep_half_open_lines: bool = False, convert_dangling_lines: bool = False, fuse_zero_impedance_branches: bool = False, zero_impedance_threshold_pu: float = 1e-08) LSGrid

This function is available under the init_from_pypowsybl in lightsim2grid

from lightsim2grid.network import init_from_pypowsybl

Warning

It is not available if the pypowsybl python package is not installed.

Parameters:
  • net (pypo.network.Network) – The pypowsybl network

  • gen_slack_id (Union[int, str]) – The id of the generator that should be used as the slack (either it’s given by id (int) or by name (str))

  • slack_bus_id (int) – If you don’t provide a generator ID as a slack bus, you can provide a bus id (int). We do not recommend setting the slack this way.

  • sn_mva (bool) – The nominal apparent power used when converting the grid to per unit. It is only used if the pypowsybl grid has no _nominal_apparent_power attribute. Advanced usage.

  • sort_index – Whether you want to sort the indexes of all the pypowsybl tables (eg get_loads() or get_buses()) or not. Sorting the grid tables is preferable if you want to be “future proof” and don’t want to depend on pandas version (same order is guaranteed). Not sorting the grid will give easier comparison of results with pypowsybl.

  • f_hz – Not used currently (frequency of the grid)

  • net_pu (Optional[pypo.network.Network]) – If you have already converted the grid in “per unit” then you can pass it as the net_pu argument. Otherwise this function will do it. Advanced usage.

  • only_main_component (bool) – If this is True, then only the main component (ie the one containing the slack bus) will be used. All equipments not part of this component will be deactivated (switched-off). NB currently lightsim2grid will diverge if the grid is not connected, this option might then “hide” some equipements from the grid (silently) but you have higher chances of convergence.

  • return_sub_id (bool) – Advanced usage. If you want to retrieve the id of the equipments as “tables”. Used only for LightSimBackend

  • n_busbar_per_sub (Optional[int]) – Currently, lightsim2grid works well with a constant number of independant buses that can be made at each substations. It can be infered from the grid or set with this attribute. We recommend to leave it to None (which corresponds to the “infer it from the grid” behaviour) in most cases.

  • buses_for_sub (bool) – Whether the lightsim2grid substation will correspond to buses of the pypowsybl grid (if buses_for_sub is True). Alternatively, if buses_for_sub is False, the lightsim2grid susbtation will correspond to pypowsybl voltage level (read from net.get_voltage_levels()). buses_for_sub==`True` is a “legacy” behaviour.

  • init_vm_pu (float) – The voltage magnitude with which the init vector of AC powerflow will be set.

  • keep_half_open_lines (bool) – If True, a powerline or transformer connected on only one terminal (connected1 != connected2, eg a dangling boundary stub in a real grid) is modeled as “half-open”: the energized side is kept in the admittance matrix and the open end is Kron-reduced out, instead of deactivating the whole branch. This sets synch_status_both_side=False on the returned model, so a later one-sided topology change is no longer mirrored to the other side. Branches disconnected on both sides are still fully deactivated. Default False (whole-branch deactivation, as before).

  • convert_dangling_lines (bool) – If True, every IIDM DanglingLine (eg produced by network.reduce_by_ids_and_depths(..., with_boundary_lines=True) when zooming into a sub-area) is converted to its equivalent branch + constant-power load: a fictitious 1-bus “substation” at the boundary end, a line carrying the dangling line’s own r/x/g/b (shunt entirely on the local side, matching transformers’ single h), and a load consuming its p0/q0. Without this (the default), dangling lines are silently ignored – fine for real full grids, which never have any, but it drops a real boundary injection (can be hundreds of MW) whenever they do appear. Off by default to keep existing behaviour unchanged; the reduce/validate debug scripts turn it on.

  • fuse_zero_impedance_branches (bool) –

    If True, a line or 2-winding transformer whose per-unit impedance is (near-)zero – |r_pu| < zero_impedance_threshold_pu and |x_pu| < zero_impedance_threshold_pu – has its two terminal buses fused into a single electrical node instead of contributing a 1/Z admittance (which is Inf for an exact zero, and breaks the sparse LU factorization outright). This mirrors OpenLoadFlow’s lowImpedanceBranchMode / lowImpedanceThreshold. A zero-impedance transformer is only fused if it is also at (near-)neutral tap (rho close to 1 and alpha close to 0) and its two sides are at the same nominal voltage: pypowsybl’s per-unit rho is the deviation from the transformer’s own rated ratio (the tap-changer effect), not its absolute turns ratio, so rho~=1 alone does not mean “no transformation” for a genuine step-down/up transformer – otherwise it is a real ideal ratio/phase-shifting element, not a same-node short, and is left untouched. A zero-impedance line spanning two different nominal voltages raises a RuntimeError (inconsistent grid data) – unlike for transformers, this is never legitimate for a line. The fusing branch itself is kept in the model (for topology-vector bookkeeping) but deactivated, same as any other disconnected branch; substation/topology identity (glop_sub_id) of elements on the two original buses is not changed, only the internal solver bus id – grid2op topology actions still see the original, distinct substations. Off by default to keep existing behaviour unchanged.

    Warning

    This is a static, import-time decision. If a fused transformer’s tap is later moved away from neutral during a simulation, the two buses stay fused in lightsim2grid even though the transformer is no longer electrically a plain wire. Best suited for static / diagnostic use, or grid2op environments known not to actuate the affected transformer’s tap.

  • zero_impedance_threshold_pu (float) – Per-unit impedance magnitude threshold used by fuse_zero_impedance_branches (ignored otherwise). Matches OpenLoadFlow’s lowImpedanceThreshold default.

Returns:

The properly initialized network.

Return type:

LSGrid

lightsim2grid.network.remove_outer_loops(parameters: Parameters, keep: Iterable[str] = (), slack_bus_ids: str | Iterable[str] | None = None, max_outer_loop_iterations: int = 20) Parameters[source]

Return a copy of parameters with OLF’s outer loops removed.

Only the outer-loop mechanism is touched: reactive limits, remote voltage control, voltage initialization, balance type, connected-component mode, and every other field of parameters are left exactly as given.

Parameters:
  • parameters (pypowsybl.loadflow.Parameters) – The parameters to strip outer loops from. Not mutated; a modified copy is returned.

  • keep (iterable of str, optional) – Names of outer loops to leave active instead of removing. Valid names: "TransformerVoltageControl", "ShuntVoltageControl", "PhaseControl" (inline-mode family), "DistributedSlack", "ReactiveLimits", "VoltageMonitoring", "SecondaryVoltageControl", "AreaInterchangeControl", "AutomationSystem" (no-inline-alternative family). Keeping a loop only stops this function from removing it – for a no-inline- alternative loop this function does not force its own creation trigger on, so it still runs only if parameters already enables it (e.g. distributed_slack=True for "DistributedSlack").

  • slack_bus_ids (str or iterable of str, optional) – If given, the slack is pinned by NAME on these bus(es) (slackBusSelectionMode = "NAME") and read_slack_bus is turned off. Unrelated to outer-loop removal; a convenience for matching lightsim2grid’s slack choice.

  • max_outer_loop_iterations (int) – Outer-loop iteration budget, only set when keep is non-empty (so a kept loop, e.g. distributed slack, has room to converge). Ignored otherwise.

Returns:

A new object; parameters is not modified.

Return type:

pypowsybl.loadflow.Parameters