Time Series (doc in progress)
The documentation of this section is in progress. It is rather incomplete for the moment, and only expose the most basic features.
If you are interested in collaborating to improve this section, let us know.
Goal
This class aims to make faster (and easier) the computations of the current flows (measured in Amps) at a certain side of a powerline / transformer when the topology is not modified.
It can be used as:
from lightsim2grid import TimeSerie
import grid2op
from lightsim2grid.lightSimBackend import LightSimBackend
env_name = ...
env = grid2op.make(env_name, backend=LightSimBackend())
time_series = TimeSerie(env)
res_p, res_a, res_v = time_series.get_flows(scenario_id=..., seed=...)
# we have:
# res_p[row_id] will be the active power flows (origin side), on all powerlines corresponding to step "row_id"
# res_a[row_id] will be the current flows, on all powerlines corresponding to step "row_id"
# res_v[row_id] will be the complex voltage, on all bus of the grid at step "row_id"
For now this relies on grid2op, but we could imagine a version of this class that can read
to / from other data sources (for now please use the more basic lightsim2grid.timeSerie.Computers
for such purpose)
Importantly, this method is around 13x faster than simulating “do nothing” (or “one change then nothing”) with grid2op (see section Benchmarks (Time Series) )
Note
A more detailed example is given in the examples\time_serie.py file from the lightsim2grid package.
Warning
Topology and injections
The topology is taken from the initial provided grid and cannot be changed when evaluating a given “time serie”.
Then, the call to time_series.compute_V(scenario_id=…, seed=…) will only read the injections (productions and loads) from grid2op to compute the voltages.
Note
As this class calls a long c++ function, it is possible to use the python Threading module to achieve high efficient parrallelism. An example is provided in the examples\computers_with_grid2op_multithreading.py file.
Benchmarks (Time Series)
Here are some benchmarks made with:
system: Linux 5.11.0-40-generic
OS: ubuntu 20.04
processor: Intel(R) Core(TM) i7-4790K CPU @ 4.00GHz
python version: 3.8.10.final.0 (64 bit)
numpy version: 1.18.5
pandas version: 1.1.4
pandapower version: 2.7.0
lightsim2grid version: 0.6.0
grid2op version: 1.6.4
Where lightsim2grid has been installed from source with all optimization enabled.
This benchmark is available by running, from the root of the lightsim2grid repository:
cd examples
python3 time_serie.py
For this setting the outputs are:
For environment: l2rpn_neurips_2020_track2
Total time spent in "computer" to solve everything: 0.05s (12277 pf / s), 0.08 ms / pf)
- time to pre process the injections: 0.00s
- time to perform powerflows: 0.05s (12697 pf / s, 0.08 ms / pf)
In addition, it took 0.00 s to retrieve the current from the complex voltages (in total 11681.3 pf /s, 0.09 ms / pf)
Comparison with raw grid2op timings
It took grid2op (with lightsim2grid): 0.66s to perform the same computation
This is a 13.4 speed up from TimeSerie over raw grid2op (lightsim2grid)
It took grid2op (with pandapower): 14.94s to perform the same computation
This is a 302.9 speed up from TimeSerie over raw grid2op (pandapower)
All results match !
In this case then, the TimeSerie module is more than 15 times faster than raw grid2op.
Detailed usage
Classes:
alias of |
|
alias of |
|
Allows the computation of time series, that is, the same grid topology is used while the active / reactive power injected at each buse vary. |
- lightsim2grid.timeSerie.Computers
alias of
TimeSeriesCPP
- lightsim2grid.timeSerie.TimeSerie
alias of
___TimeSerie
- class lightsim2grid.timeSerie.TimeSeriesCPP
Allows the computation of time series, that is, the same grid topology is used while the active / reactive power injected at each buse vary. The grid topology is fixed, the injections vary.
This is a “raw” c++ class, for an easier to use interface, please refer to the python documentation of the
lightsim2grid.timeSerie.TimeSerie
class.Methods:
amps_computation_time
(self)Time spent in computing the flows (in amps) after the voltages have been computed at each nodes
available_solvers
(self)Return the list of solver available on the current lightsim2grid installation.
change_solver
(self, arg0)This function allows to control which solver is used during the powerflow.
clear
(self)Clear the solver and to as if the class never performed any powerflow.
close
(self)Clear the solver and to as if the class never performed any powerflow.
compute_Vs
(self, arg0, arg1, arg2, arg3, ...)Compute the voltages (at each bus of the grid model) for some time series of injections (productions, loads, storage units, etc.)
compute_flows
(self)Retrieve the flows (in amps, at the origin of each powerlines / high voltage size of each transformers.
compute_power_flows
(self)Retrieve the active flows (in MW, at the origin of each powerlines / high voltage size of each transformers.
get_flows
(self)Get the current flows (in kA) at the origin side / high voltage side of each transformers / powerlines.
get_power_flows
(self)Get the active flows (in MW) at the origin side / high voltage side of each transformers / powerlines.
get_sbuses
(self)Get the complex power injected at each (solver id) bus of the powergrid.
get_solver_type
(self)Return the type of the solver currently used.
get_status
(self)Status of the solvers (1: success, 0: failure).
get_voltages
(self)Get the complex voltage angles at each bus of the powergrid.
nb_solved
(self)Total number of powerflows solved.
preprocessing_time
(self)Time spent in pre processing the data (this involves, but is not limited to the computation of the Sbus)
solver_time
(self)Total time spent only in solving the powerflows (excluding pre processing the data, post processing them, initializing everything etc.)
total_time
(self)Total time spent in solving the powerflows, pre processing the data, post processing them, initializing everything etc.
- amps_computation_time(self: lightsim2grid_cpp.TimeSeriesCPP) float
Time spent in computing the flows (in amps) after the voltages have been computed at each nodes
It is given in seconds (
float
).
- available_solvers(self: lightsim2grid_cpp.TimeSeriesCPP) list[lightsim2grid_cpp.SolverType]
Return the list of solver available on the current lightsim2grid installation.
This is a list of
lightsim2grid.solver.SolverType
.
- change_solver(self: lightsim2grid_cpp.TimeSeriesCPP, arg0: lightsim2grid_cpp.SolverType) None
This function allows to control which solver is used during the powerflow. See the section Even more advanced usage for more information about them.
See also
lightsim2grid.solver.SolverType
for a list of the available solver (NB: some solvers might not be available on all platform)Note
If the solver type entered is a DC solver (eg from
lightsim2grid.solver.SolverType
, DC, KLUDC or NICSLUDC), it will change the _dc_solver otherwise the regular _solver is modified.Examples
from lightsim2grid.solver import SolverType # init the grid model from lightsim2grid.gridmodel import init pp_net = ... # any pandapower grid lightsim_grid_model = init(pp_net) # some warnings might be issued as well as some warnings # change the solver used for the powerflow # to use internally a solver based on Newton Raphson algorithme using Eigen sparse LU lightsim_grid_model.change_solver(SolverType.SparseLUSolver)
- clear(self: lightsim2grid_cpp.TimeSeriesCPP) None
Clear the solver and to as if the class never performed any powerflow.
- close(self: lightsim2grid_cpp.TimeSeriesCPP) None
Clear the solver and to as if the class never performed any powerflow.
- compute_Vs(self: lightsim2grid_cpp.TimeSeriesCPP, arg0: numpy.ndarray[numpy.float64[m, n], flags.c_contiguous], arg1: numpy.ndarray[numpy.float64[m, n], flags.c_contiguous], arg2: numpy.ndarray[numpy.float64[m, n], flags.c_contiguous], arg3: numpy.ndarray[numpy.float64[m, n], flags.c_contiguous], arg4: numpy.ndarray[numpy.complex128[m, 1]], arg5: int, arg6: float) int
Compute the voltages (at each bus of the grid model) for some time series of injections (productions, loads, storage units, etc.)
Note
This function must be called before
lightsim2grid.timeSerie.Computers.compute_flows()
andlightsim2grid.timeSerie.Computers.get_flows()
,lightsim2grid.timeSerie.Computers.get_voltages()
orlightsim2grid.timeSerie.Computers.get_sbuses()
.Note
During this computation, the GIL is released, allowing easier parrallel computation
- Parameters:
gen_p (
numy.ndarray
, float) – Active generation for each generators. Its counts as many column as the number of generators on the grid and as many rows as the number of steps to compute.sgen_p (
numy.ndarray
, float) – Active generation for each static generator. Its counts as many column as the number of static generators on the grid and as many rows as the number of steps to compute.load_p (
numy.ndarray
, float) – Active consumption for each loads. Its counts as many column as the number of loads on the grid and as many rows as the number of steps to compute.load_q (
numy.ndarray
, float) – Reactive consumption for each loads. Its counts as many column as the number of loads on the grid and as many rows as the number of steps to compute.Vinit (
numy.ndarray
, complex) – First voltage at each bus of the grid model (including the disconnected buses)max_iter (
int
) – Total number of iteration (>0 integer)tol (
float
) – Solver tolerance (> 0. float)
- Returns:
status – The status of the computation. 1 means “success”: all powerflows were computed sucessfully, 0 means there were some errors and that the computation stopped after a certain number of steps.
- Return type:
int
- compute_flows(self: lightsim2grid_cpp.TimeSeriesCPP) numpy.ndarray[numpy.float64[m, n], flags.writeable, flags.c_contiguous]
Retrieve the flows (in amps, at the origin of each powerlines / high voltage size of each transformers.
Warning
This function must be called after
lightsim2grid.timeSerie.Computers.compute_Vs()
has been called.Note
This function must be called before
lightsim2grid.timeSerie.Computers.get_flows()
Note
During this computation, the GIL is released, allowing easier parrallel computation
- compute_power_flows(self: lightsim2grid_cpp.TimeSeriesCPP) numpy.ndarray[numpy.float64[m, n], flags.writeable, flags.c_contiguous]
Retrieve the active flows (in MW, at the origin of each powerlines / high voltage size of each transformers.
Warning
This function must be called after
lightsim2grid.timeSerie.Computers.compute_Vs()
has been called.Note
This function must be called before
lightsim2grid.timeSerie.Computers.get_flows()
Note
During this computation, the GIL is released, allowing easier parrallel computation
- get_flows(self: lightsim2grid_cpp.TimeSeriesCPP) numpy.ndarray[numpy.float64[m, n]]
Get the current flows (in kA) at the origin side / high voltage side of each transformers / powerlines.
Each rows correspond to a time step, each column to a powerline / transformer
Warning
This function must be called after
lightsim2grid.timeSerie.Computers.compute_flows()
has been called. (compute_flows also requires thatlightsim2grid.timeSerie.Computers.compute_Vs()
has been caleed)- Returns:
As – The flows (in kA) at the origin side / high voltage side of each transformers / powerlines.
- Return type:
numpy.ndarry
(matrix)
- get_power_flows(self: lightsim2grid_cpp.TimeSeriesCPP) numpy.ndarray[numpy.float64[m, n]]
Get the active flows (in MW) at the origin side / high voltage side of each transformers / powerlines.
Each rows correspond to a time step, each column to a powerline / transformer
Warning
This function must be called after
lightsim2grid.timeSerie.Computers.compute_power_flows()
has been called. (compute_flows also requires thatlightsim2grid.timeSerie.Computers.compute_Vs()
has been caleed)- Returns:
As – The flows (in kA) at the origin side / high voltage side of each transformers / powerlines.
- Return type:
numpy.ndarry
(matrix)
- get_sbuses(self: lightsim2grid_cpp.TimeSeriesCPP) numpy.ndarray[numpy.complex128[m, n], flags.c_contiguous]
Get the complex power injected at each (solver id) bus of the powergrid. Results are given in pair unit. We do not recommend to use it as it uses the solver id and NOT the powergrid bus id (you can refer to
lightsim2grid.gridmodel.GridModel.id_me_to_ac_solver()
andlightsim2grid.gridmodel.GridModel.id_ac_solver_to_me()
for more information)Each rows correspond to a time step, each column to a bus (bus are identified by their solver id !)
Warning
This function must be called after
lightsim2grid.timeSerie.Computers.compute_Vs()
.- Returns:
Sbuses – The complex power injected at each bus (pair unit, load sign convention)
- Return type:
numpy.ndarry
(matrix)
- get_solver_type(self: lightsim2grid_cpp.TimeSeriesCPP) lightsim2grid_cpp.SolverType
Return the type of the solver currently used.
This is equivalent to the get_type of the
lightsim2grid.solver.AnySolver.get_type()
of the solver used.
- get_status(self: lightsim2grid_cpp.TimeSeriesCPP) int
Status of the solvers (1: success, 0: failure).
Note
Even if the solver failed at some point, some results might still be available (but not totally).
- get_voltages(self: lightsim2grid_cpp.TimeSeriesCPP) numpy.ndarray[numpy.complex128[m, n]]
Get the complex voltage angles at each bus of the powergrid.
Each rows correspond to a time step, each column to a bus.
Warning
This function must be called after
lightsim2grid.timeSerie.Computers.compute_Vs()
.- Returns:
Vs – The complex voltage angles at each bus of the powergrid.
- Return type:
numpy.ndarry
(matrix)
- nb_solved(self: lightsim2grid_cpp.TimeSeriesCPP) int
Total number of powerflows solved.
- preprocessing_time(self: lightsim2grid_cpp.TimeSeriesCPP) float
Time spent in pre processing the data (this involves, but is not limited to the computation of the Sbus)
It is given in seconds (
float
).
- solver_time(self: lightsim2grid_cpp.TimeSeriesCPP) float
Total time spent only in solving the powerflows (excluding pre processing the data, post processing them, initializing everything etc.)
It is given in seconds (
float
).
- total_time(self: lightsim2grid_cpp.TimeSeriesCPP) float
Total time spent in solving the powerflows, pre processing the data, post processing them, initializing everything etc.
It is given in seconds (
float
).