gym_anm.simulator.simulator.Simulator

class gym_anm.simulator.simulator.Simulator(network, delta_t, lamb)[source]

Bases: object

A simulator of an AC electricity distribution network.

baseMVA

The base power of the system (MVA).

Type:

int

delta_t

The fraction of an hour corresponding to the time interval between two consecutive time steps \(\Delta t\) (e.g., 0.25 means an interval of 15 minutes).

Type:

float

lamb

The penalty factor associated with violating operating constraints \(\lambda\), used in the reward signal.

Type:

int

buses

The buses of the grid, where for each {key: value} pair, the key is a unique bus ID.

Type:

dict of {int : Bus}

branches

The transmission lines of the grid, where for each {key: value} pair, the key is a unique transmission line ID.

Type:

dict of {(int, int) : TransmissionLine}

devices

The devices connected to the grid, where for each {key: value} pair, the key is a unique device ID.

Type:

dict of {int : Device}

N_bus, N_device

The number of buses \(|\mathcal N|\) and electrical devices \(|\mathcal D|\) in the network.

Type:

int

N_load, N_non_slack_gen, N_des, N_gen_rer

The number of load \(|\mathcal D_L|\), non-slack generators \(|\mathcal D_G|-1\), DES devices \(|\mathcal D_{DES}|\), and renewable energy generators \(|\mathcal D_{DER}|\).

Type:

int

Y_bus

The (N_bus, N_bus) nodal admittance matrix \(\mathbf Y\) of the network as a sparse matrix.

Type:

scipy.sparse.csc_matrix

state_bounds

The lower and upper bounds that each electrical quantity may take. This is a nested dictionary with keys [quantity][ID][unit], where quantity is the electrical quantity of interest, ID is the unique bus/device/branch ID and unit is the units in which to return the quantity.

Type:

dict of {str : dict}

state

The current state of the system.

Type:

dict of {str : numpy.ndarray}

pfe_converged

True if the load flow converged; otherwise False (possibly infeasible problem).

Type:

bool

reset(np_random, init_soc)[source]

Reset the simulator.

get_network_specs()

Get the operating characteristics of the network.

get_action_space()[source]

Get the control action space available.

transition(P_load, P_potential, P_curt_limit, desired_alpha, Q_storage)[source]

Simulate a transition of the system from time t to time (t+1).

__init__(network, delta_t, lamb)[source]
Parameters:
  • network (dict of {str : numpy.ndarray}) – A network dictionary describing the power grid.

  • delta_t (float) – The interval of time between two consecutive time steps \(\delta t\), in fraction of hour.

  • lamb (int) – A constant factor \(\lambda\) multiplying the penalty associated with violating operational constraints.

Methods

__init__(network, delta_t, lamb)

param network:

A network dictionary describing the power grid.

get_action_space()

Return the range of each possible control action.

get_rendering_specs()

Summarize the specs of the distribution network (useful for rendering).

get_state_space()

Returns the range of potential values for all state variables.

reset(init_state)

Reset the simulator.

transition(P_load, P_potential, ...)

Simulate a transition of the system from time \(t\) to time \(t+1\).

get_action_space()[source]

Return the range of each possible control action.

This function returns the lower and upper bound of the action space \(\mathcal A\) available to the agent as dictionaries. The keys are the unique device IDs and the values are a tuple of (lower bound, upper bound).

Returns:

  • P_gen_bounds (dict of {int : tuple of float}) – The range of active (MW) power injection of generators \([\overline P_g, \underline P_g]\).

  • Q_gen_bounds (dict of {int : tuple of float}) – The range of reactive (MVAr) power injection of generators \([\overline Q_g, \underline Q_g]\).

  • P_des_bounds (dict of {int : tuple of float}) – The range of active (MW) power injection of DES units \([\overline P_d, \underline P_d]\).

  • Q_des_bounds (dict of {int : tuple of float}) – The range of reactive (MVAr) power injection of DES units \([\overline Q_d, \underline Q_d]\).

Notes

The bounds returned by this function are loose, i.e., some parts of those spaces might be physically impossible to achieve due to other operating constraints. This is just an indication of the range of action available to the DSO. Whenever an action is taken through the transition() function, it gets mapped onto the set of physically feasible actions.

get_rendering_specs()[source]

Summarize the specs of the distribution network (useful for rendering).

All values are in p.u. (or p.u. per hour for DES units). This method differs from get_state_space() in that it returns the bounds that should be respected for a successful operation of the network, whereas get_state_space() returns the range of values that state variables can take. For example, this method will return the rate of a branch, whereas get_state_space() will return an upper bound of np.inf, since branch rates may be violated during the simulation.

Returns:

specs – A dictionary where keys are the names of the state variables (e.g., {‘bus_p’, ‘bus_q’, …}) and the values are dictionary, indexed with the device/branch/bus unique ID, that store dictionaries of {units : (lower bound, upper bound)}.

Return type:

dict of {str : dict}

get_state_space()[source]

Returns the range of potential values for all state variables.

These lower and upper bounds are respected at all timesteps in the simulator. For unbounded values, a range of (-inf, inf) is used.

Returns:

specs – A dictionary where keys are the names of the state variables (e.g., {‘bus_p’, ‘bus_q’, …}) and the values are dictionary, indexed with the device/branch/bus unique ID, that store dictionaries of {units : (lower bound, upper bound)}.

Return type:

dict of {str : dict}

reset(init_state)[source]

Reset the simulator.

The init_state vector should have power injections in MW or MVAr and state of charge in MWh.

Parameters:

init_state (numpy.ndarray) – The initial state vector \(s_0\) of the environment.

Returns:

pfe_converged – True if a feasible solution was reached (within the specified tolerance) for the power flow equations. If False, it might indicate that the network has collapsed (e.g., voltage collapse).

Return type:

bool

transition(P_load, P_potential, P_set_points, Q_set_points)[source]

Simulate a transition of the system from time \(t\) to time \(t+1\).

This function simulates a transition of the system after actions were taken by the DSO. The results of these decisions then affect the new state of the system, and the associated reward is returned.

Parameters:
  • P_load (dict of {int : float}) – A dictionary with device IDs as keys and fixed real power injection \(P_l^{(dev)}\) (MW) as values (load devices only).

  • P_potential (dict of {int : float}) – A dictionary with device IDs as keys and maximum potential real power generation \(P_g^{(max)}\) (MW) as values (generators only).

  • P_set_points (dict of {int : float}) – A dictionary with device IDs as keys and real power injection set-points \(a_P\) (MW) set by the DSO (non-slack generators and DES units).

  • Q_set_points (dict of {int : float}) – A dictionary with device IDs as keys and reactive power injection set-points \(a_Q\) (MVAr) set by the DSO (non-slack generators and DES units).

Returns:

  • state (dict of {str : numpy.ndarray}) – The new state of the system \(s_{t+1}\).

  • reward (float) – The reward \(r_t\) associated with the transition.

  • e_loss (float) – The total energy loss \(\Delta E_{t:t+1}\) (MWh).

  • penalty (float) – The total penalty \(\lambda \phi(s_{t+1})\) due to violation of operating constraints.

  • pfe_converged (bool) – True if a feasible solution was reached (within the specified tolerance) for the power flow equations. If False, it might indicate that the network has collapsed (e.g., voltage collapse).