Reading Relations

Introduction to the PSRClassesInterface.get_map method

There are two dispatches for the PSRClassesInterface.get_map function. The first requires the attribute name that represents the relation, while the second needs the PSRClassesInterface.PMD.RelationType between the elements.

Here is how this function works:

Let's say that in our study we have 3 PSRSerie and 2 PSRBus elements. There is a relation between elements of these two collections represented by an attribute 'no2', where PSRSerie is the source and PSRBus is the target.

If we execute the following code:

using PSRClassesInterface
const PSRI = PSRClassesInterface

PSRI.create_element!(data, "PSRSerie")
PSRI.create_element!(data, "PSRSerie")
PSRI.create_element!(data, "PSRSerie")
PSRI.create_element!(data, "PSRBus")
PSRI.create_element!(data, "PSRBus")

PSRI.set_related!(data, "PSRSerie", "PSRBus", 1, 2, relation_type = PSRI.PMD.RELATION_TO)
PSRI.set_related!(data, "PSRSerie", "PSRBus", 3, 1, relation_type = PSRI.PMD.RELATION_TO)

PSRI.get_map(data, "PSRSerie", "PSRBus", "no2")

We could, as an example, get the following vector:

[ 2 , 0 , 1 ]

This means that:

  • the source element of index 1 in the collection PSRSerie is related to the target element of index 2 in the collection PSRBus.
  • the source element of index 2 in the collection PSRSerie is not related to any element from collection PSRBus
  • the source element of index 3 in the collection PSRSerie is related to the target element of index 1 in the collection PSRBus.

Note: There is also a PSRClassesInterface.get_vector_map method that works just as PSRClassesInterface.get_map.

Now we can move to a more practical example.

Determining subsystem from a certain hydro plant

In this example we will demonstrate how to make a simple use of a relationship map. That will be achieved by determining a subsystem from a certain hydro plant through its parameters. The program will initiate by the standard reading procedure:


PATH_CASE_EXAMPLE_GAUGING = joinpath(pathof(PSRI) |> dirname |> dirname, "test", "data", "case2")

data = PSRI.load_study(
    PSRI.OpenInterface(),
    data_path = PATH_CASE_EXAMPLE_GAUGING
)
; nothing # hide

Next, the maps between hydroplants and systems is retrieved by the get_map method:

hyd2sys = PSRI.get_map(data, "PSRHydroPlant","PSRSystem", "system")
; nothing # hide

Determining buses from a certain thermal plant

This case consists of a more advanced use of a relationship map. We'll determine which buses are linked to a given target thermal plant, while there is no direct relationship between both. Firstly, the study data is read:

import PSRClassesInterface
const PSRI = PSRClassesInterface

PATH_CASE_EXAMPLE_BUS = joinpath(pathof(PSRI) |> dirname |> dirname, "test", "data", "case1")

data = PSRI.load_study(
    PSRI.OpenInterface(),
    data_path = PATH_CASE_EXAMPLE_BUS
)

Whereas there is no direct link between buses and thermal plants, both are indirectly related through generators. Therefore, we must identify those relationships by calling get_map for each:

gen2thermal = PSRI.get_map(data, "PSRGenerator","PSRThermalPlant", "plant")
gen2bus = PSRI.get_map(data, "PSRGenerator", "PSRBus", "bus")

Next, we can find which generators are linked to our target thermal plant by the indexes of gen2the:

target_thermal = 1
target_generator = findall(isequal(target_thermal), gen2thermal)

target_generator now holds the indexes of generators that are linked to the buses we are trying to identify. With those at hand, the indexes of the buses are easily identifiable by:

targetBus = gen2bus[target_generator]

Determining which buses are connected by each circuit

Each circuit connects two buses, it starts from a bus and goes to another. In this example we'll discover these buses for each circuit and then we'll build an incidence matrix of buses by circuits. The first step is to read the data:


PATH_CASE_EXAMPLE_CIR_BUS = joinpath(pathof(PSRI) |> dirname |> dirname, "test", "data", "case1")

data = PSRI.load_study(
    PSRI.OpenInterface(),
    data_path = PATH_CASE_EXAMPLE_CIR_BUS
)
; nothing # hide

Next, we get from which bus each circuit starts and which bus it goes to with get_map:

cir2bus_to = PSRI.get_map(data, "PSRSerie", "PSRBus", "no1")
cir2bus_from = PSRI.get_map(data, "PSRSerie", "PSRBus", "no2")
; nothing # hide

Now we can build the incidence matrix. Each row corresponds to a circuit and each column corresponds to a bus. The element at the index (i,j) is -1 if the circuit i starts from the bus j, 1 if it goes to this bus, and 0 if they both have no relation:

bus_size = PSRI.max_elements(data, "PSRBus")
cir_size = PSRI.max_elements(data, "PSRSerie")
incidence_matrix = zeros(Float64, cir_size, bus_size)
for cir = 1:cir_size
    incidence_matrix[cir, cir2bus_from[cir]] = -1.0
    incidence_matrix[cir, cir2bus_to[cir]] = 1.0
end
incidence_matrix