Skip to content
Snippets Groups Projects
Sonja Happ's avatar
Sonja Happ authored
Resolve "Add -merge-nodes option"

Closes #1

See merge request !2
7f1c78fe
History

DistAIX Scenario Generator

This is the DistAIX Scenario Generator to generate scenarios in the format of the DistAIX simulator. The tool is capable of creating new electrical grids / scenarios based on existing grids, as well as from scratch. Custom topologies (networks of Slack/Trafo/Nodes) can be created and assembled with different types of consumers and producers (Load/CHP/EV/Wind...).

Repo Structure

  • src folder containing the actual python script and modules of the ScenarioGenerator

    • run.py Main script used to the run the ScenarioGenerator
    • scenarioGenerator.py Module containing the main functions of the ScenarioGenerator
    • inputReader.py Module that realizes reading of user given inputs
    • csvReaderWriter.py Module used to write and read different csv-Files
    • componentCreator.py Module used to attach components to topology grids
    • plotter.py Module used to plot the resulting grid as a graph using pydot
  • subtypes folder contains files including the different subtypes of components and cables needed during grid creation

  • generated grids folder contains the newly generated grids as well as different scenarios which can be used to test the ScenarioGenerator / create new scenarios

  • basicgrids folder contains medium as well as low voltage grids representing rural and urban environments

    • 1x_lv_rural folder contains the 1x_lv_rural grid with variable cable lengths
    • 1x_lv_urban folder contains a script to create the 1x_lv_urban grid with cariable cable lenghts as well as one version of the grid
    • 1x_mv_rural folder contains a script to create the 1x_mv_rural grid with cariable cable lenghts as well as one version of the grid
    • 1x_mv_urban folder contains a script to create the 1x_mv_urban grid with cariable cable lenghts as well as one version of the grid

Requirements

Due to the use of the pathlib module, at least Python 3.4.0 has to be used.

When using the integrated plotting functionality to create a graph representing the created grid, the pydot module has to be installed.

All input and output files are in comma-seperated values (csv) format.

Input files have to follow certain structures to ensure proper compatibility / usage of the ScenarioGenerator.

  • components.csv:
    • Nodes: id, type, trafoID,*
    • Other: id, type,*
    • Arguments marked with * are not used by the ScenarioGenerator and therefore can have arbitrary order and content

  • el_grid.csv:
    • id1, id2, cabletype, arg1*, arg2*, arg3*, arg4*, arg5*, arg6*, arg7*
    • Arguments marked with * are not used by the ScenarioGenerator and therefore can have arbitrary order and content

  • lv_grids.csv: (Only needed for -full-random and -full-fixed options) Each row includes the relative path of the directories of the low voltage grids, which can be attached to the corresponding medium voltage grid.
    By default, ../ is added to each path!

  • wished_connections.csv: (Only needed for -full-fixed option) Required per LV grid to be connected and has two columns: id_mv | id_lv. The id_mv column contains the node ID of the MV grid to which the LV grid shall be connected, the id_lv column contains the ID of the LV node/transformer to which the connection shall be established. The file can contain multiple rows for as many times as a LV grid shall be connected to a given MV grid.

  • autoTopConf.csv: (Only needed when using -top -auto | Can have arbitrary name, path has to be given by the user) Each row defines one of the grids to be created. Each row has the following structure: grid_name,voltage_level,number_of_feeders,nodes_per_feeder,transformer_type,cable_type,cable_length

  • wished_nominal_power.csv: (Optional for -mv and -lv) Each row contains a component type (e.g. load, chp, etc.) and a wished nominal power in kWs

  • subtypes_perc.csv: (Only needed for -mv and -lv) Each row has to start with the identifier of the wished component type 'load_lv / chp_mv / ...' Followed by that, a percentage value [0.0,1.0] for each possible subtype has to follow in the same order, the subtypes are arranged in the corresponding subtypes file.
    !! It is possible NOT to give percentages for a component type, then the generator distributes the nominal power equally !!

Usage

General

All the different functionalities are accessed by executing the main script run.py with different parameters.

python3.6 run.py -args
  • -top starts the creation of a new topology from scratch
  • -mv enables the user to attach medium voltage producers and consumers to a given grid
  • -lv enables the user to attach low voltage producers and consumers to a given grid
  • -full enables the user to attach multiple low voltage grids to given medium voltage topologies
  • -auto enables automated creation of simple topologies from a given configuration file (has to be used with -top)
  • -plot calls the plot function (has to be used with one of the prior parameters)
  • -merge-scenarios merges two scenarios into one by adding components from the second scenario to the grid of the first scenario

Topology Creation

New topologies (feeder based networks of Slack/Trafo/Nodes) can be created using -top.

python3.6 run.py -top

First, the user is asked for the voltage level of the topology. For this example, a medium voltage grid is going to be created.

>> Voltage level? [mv/lv]:
<< mv

Next, the amount of feeders and a transformer subtype has to be specified.

>> How many feeders should be created?
<< 2

>> Type of transformer?
<< MV_LV_rural

The transformer subtype has to match one of the subtypes defined in subtypes/transformer.csv.
If the chosen subtype does not match the previously given voltage level, the ScenarioGenerator will notify the user and give him the possibility to change it.

Transformer does not match voltage level... Continue? [y/n]

Next, the desired number of feeders will be created one after another. The recursive nature of this method makes it possible to create as many levels of subfeeders as wished.

>> Number of nodes feeder 1:
<< 2

>> Type of cable?
<< MV_RURAL_CABLE_1

>> Length of cable in km?
<< 1.5

>> Dynamic cable length? [y/n]...
<< y

>> Wished variance in cable length in percentage [0.0-1.0]:
<< 0.2

>> Create subfeeders in feeder 1? 

The type of cable has to fit a subtype defined in subtypes/cable.csv.
If a dynamic cable length is wished, the user can give an additional percentage value between 0.0 and 1.0. Then the ScenarioGenerator will randomly select a length, which can differ from the specified cable length by the given percentage.
If subfeeder creation is used, the creation of subfeeders will only differ from the previous example in one additional dialog.

>> Attach subfeeder at which node?
<< 5

Here, the id of the node, where the subfeeder should be attached to, has to be given.

Medium Voltage Grid Creation

Existing medium voltage topologies can be extended with different producer and consumer components using this method.

<< python3.6 run.py -mv

At first, the relative path to the directory of the medium voltage topology has to be given.
By default ../ is added to the relative path!

>> Medium voltage grid:
<< generatedgrids/gentest_mv_top

In the example, the medium voltage generator testgrid without producer or consumer components was chosen.
If the directory does not include a subtypes_per.csv file, defining the distribution of nominal power to the different subtypes, the user will be notified and has the chance to change the directory.

>> No subtypes_perc.csv file found...
>> Medium voltage grid:

After reading and evaluating the subtypes_perc.csv file, the user will be asked if he wishes to create components for the given grid.

>> Medium voltage component creation wished? [y/n]
<< y

Hint: Answering with "n", when calling the script with the additional argument -plot yields an easy way to plot a given grid.

In the following dialog, the user has to decide if the wished nominal powers should be read from a file or given manually.

>> Read wished nominal powers from file? [y/n]
<< y

If the user decides to read in the wished nominal powers from a corresponding csv file, wished_nominal_power.csv has to exist in the grids directory.
If this file does not exist or the user decides to put in the nominal powers manually, the wished nominal powers for the different component types have to be given to the ScenarioGenerator.

>> Wished number of kilowatts per medium voltage component reqiured...
>> kW - load:
<< 3
>> kW - pv: 
<< 2.5
>> kW - chp: 
<< 100
>> kW - hp: 
<< 23.2
>> kW - compensator: 
<< 0
>> kW - biofuel: 
<< 100
>> kW - wind: 
<< 0.1
>> kW - storage: 
<< 2
>> #####################

As it can be seen in the example, int as well as float values are valid.
Followed by this, the ScenarioGenerator tries to randomly select subtypes of the different component types, based on the percentages given in subtypers_perc.csv, until it converges to the desired nominal power.
The given nominal power will not always be met exactly, but the actual created nominal powers will be written to generatedgrids/YYYY-DD-MM_HH-MM-SS/nominal_power.csv.

>> echo nominal_power.csv

load_mv,750.0
pv_mv,100.0
chp_mv,107.5
hp_mv,18.0
compensator_mv,0.0
biofuel_mv,111.11000000000003
wind_mv,36.0
storage_mv,3.125

In a last step, the user is able to add an additional flag to all existing nodes, indicating if this node should participate in the communication based negotiations.

>> Adding new communication flag feature? This will add another column for nodes! Currently not compatible with Simulator!...[y/n]

If the user decides to add the additional flag, percentage values have to be given for each component type. Each node, connected to a component, will then set its flag with the percentage value given to the connected component types. This allows to realize scenarios like: "23% of Nodes, connected to PV components, should participate in communication procedures".

>> Percentage values with which different component types participate in communication required...
>> Percentage - load:
<< 23
>> Percentage - pv:
<< 100
>> Percentage - chp:
<< 11
>> Percentage - hp:
<< 0
>> Percentage - compensator:
<< 75
>> Percentage - ev:
<< 5
>> Percentage - wind:
<< 62
>> Percentage - storage:
<< 81

Flags will only be flipped to 1 and wont be changed back to 0, no matter of the percentage values of other connected componentsm, i.e. if a node in the upper example is connected to a PV as well as a HP component, it will always participate in communication procedures.

Automated Topology Creation

For the creation of numerous simple (no bifurcations inside the feeders!) grids, including only one given load component per node, the previously described method can be automated.

<< python3.6 run.py -top -auto

Next, only the path to a previously generated configuration file has to be given to the ScenarioGenerator.

<< Path configuration file: 
>> testConfig.csv

In the given example, this configuration file, named testConfig, is located in the src folder, but any other path can be given.
All of the created grids will be stored in seperate folders in the the generatedgrids folder. For a clear identification of the generated grids, additionally the grid_name, given for each grid in the configuration file, is attached to the folders name (YYYY-DD-MM_HH-MM-SS_grid_name).
The needed structure of the configuration file has been described in the Requirements section above.
At each created node, one component will be attached. The favored subtype (and with that the type implicitly) can be defined in subtypes/lv_auto.csv and subtypes/mv_auto.csv respectively. Simply copy and paste a given subtype from one of the subtype files into the given csv files. Take care to only have one subtype in those files at a time!!

Low Voltage Grid Creation

Existing low voltage topologies can be extended with different producer and consumer components using this method.

<< python3.6 run.py -lv

Works similar to the Medium Voltage Grid Creation but only low voltage producer and consumer components will be considered...

Full Grid Creation with random selection of LV grids

The Full Grid Creation enables the user to attach multiple low voltage grids to specified nodes of a medium voltage grid.

<< python3.6 run.py -full-random

At first, the relative path to the medium voltage grid has to be given.
By default ../ is added to the relative path!

>> Medium voltage grid:
<< generatedgrids/gentest_mv_comp

In the example, the medium voltage generator testgrid with attached consumer and producer components was chosen.
Next, the generator will inform the user how many nodes are unoccupied and therefore suited as connection points for the low voltage grids. Based on this information, the user has to give the wished number of low voltage grids he wants to attach.

>> 16 free nodes available...
>> How many LV grids should be created?
<< 16

Followed by that, the ScenarioGenerator will read and evaluate the lv_grids.csv file, which has to be located in the medium voltage grid directory.
Next, the specified low voltage grids will be chosen randomly and attached to a random unoccupied node, until as many low voltage grids are created as the user desired.

If the number of LV grids to be created is larger than the number of unoccupied nodes, the user is asked if it is ok to connect multiple LV grids to the same node:

>> Can multiple LV grids be connected to one node (y or n)?
<< n 
>> Wished number of LV grids is bigger than the number of free nodes!! Only %i low voltage grids will be attached! 

or alternatively:

>> Can multiple LV grids be connected to one node (y or n)?
<< y  

This feature is especially useful if multiple LV grids shall be connected to the same slack node as MV grid.

Full Grid Creation with fixed connections for LV grids

This feature has been added by Kaying Lee in the course of her Master's Thesis. It allows to connect LV grid to an MV grid with pre-defined fixed positions for the LV grids in the MV grid.

<< python3.6 run.py -full-fixed
>> connect LV grid to a fix MV node...

The function asks the user if the file wished_connections.csv contained in folders of LV grids shall be used as input:

>> read wished_connections.csv?[y/n]
<< y

Answering with n results in executing the random variant of the full grid creation (see above). Similar to the other version, first the MV grid to be used has to be specified:

>> Medium voltage grid:
<< generatedgrids/gentest_mv_comp

The folder of the MV grid should contain a file lv_grids.csv specifying which LV grids are available for connection. Based on this list of paths and the wished_connections.csv file, the LV grids are connected to the respective nodes of the MV grid.

Plotting

The argument -plot can be used to create a graph representing the created grid.
To use this feature, the pydot module has to be installed.
Plotting can be used in combination with each of the grid creation variations. In the corresponding graph, the nodes colors indicate the corresponding voltage level / creation method.

  • Green nodes indicate a created topology
  • Red nodes indicate medium voltage grid nodes
  • Blue nodes indicate low voltage grid nodes

Note: This plotting feature is only recommended for small grids (<150 nodes).

Hint: For simply plotting a given grid without manipulating it, call the script for the corresponding voltage level -lv/-mv and decline component creation...

<< python3.6 run.py -mv -plot

>> Medium voltage grid:
<< generatedgrids/gentest_mv_top

>> Medium voltage component creation wished? [y/n]
<< n
...

Merging scenarios

In order to merge two scenarios the scenariogenerator has to be started with the -merge-scenarios argument. The user is requested to enter the path to the first and the second grid. ../ is added automatically as a prefix to the paths entered by the user. If the two provided scenarios comprise a different number of nodes, a warning will be displayed. The entire process is depicted in the listing below.

<< python3.6 run.py -merge-scenarios
>> Scenario merge started..

>> First grid:
<< path/to/first/grid
>> Reading component files...

>> Opening ../path/to/first/grid/components.csv...

>> highestNodeId 0 = 10
>> Reading electrical grid files...

>> Opening ../path/to/first/grid/el_grid.csv...

>> Second grid:
<< path/to/second/grid
>> Reading component files...

>> Opening ../path/to/second/grid/components.csv...

>> highestNodeId 0 = 12
>> Reading electrical grid files...

>> Opening ../path/to/second/grid/el_grid.csv...

>> Warning: The two scenarios have a different number of nodes

The scenariogenerator opens the two scenarios and merges them. For that purpose the first scenario is used as a basis. Components from the second grid are added to the first grid and connected to the nodes, with the same ID as in the second grid. For example, a load connected to node 8 in the second grid will be connected to node 8 in the frist grid. If the second scenario comprises more nodes than the first scenario, all components connected to nodes with a higher ID than the highest node ID in the first scenario will be ignored. In the example above that means that components in the second scenario connected to nodes 11 or 12 will be ignored.

The resulting scenario is stored in the generatedgrids directory.

Copyright

2019, Institute for Automation of Complex Power Systems, EONERC

License

This project is released under the terms of the GPL version 3.

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.

For other licensing options please consult Prof. Antonello Monti.

Contact

Institute for Automation of Complex Power Systems (ACS)
EON Energy Research Center (EONERC)
RWTH University Aachen, Germany