#!/usr/bin/env python # coding: utf-8 # # Create Networks - Advanced # This tutorial shows how to create a more complex pandapower network step by step. The network includes every element which is availiable in the pandapower framework. # # The final network looks like this: # # # The structural information about this network are stored in csv tables in the example_advanced folder. # # For a better overview the creation of the individual components is divided in three steps. Each step handles one of the three voltage levels: high, medium and low voltage. We star by initializing an empty pandapower network: # In[1]: #import the pandapower module import pandapower as pp import pandas as pd #create an empty network net = pp.create_empty_network() # ## High voltage level # ### Buses # # # # There are two 380 kV and five 110 kV busbars (type="b"). The 380/110 kV substation is modeled in detail with all nodes and switches, which is why we need additional nodes (type="b") to connect the switches. # In[2]: # Double busbar pp.create_bus(net, name='Double Busbar 1', vn_kv=380, type='b') pp.create_bus(net, name='Double Busbar 2', vn_kv=380, type='b') for i in range(10): pp.create_bus(net, name='Bus DB T%s' % i, vn_kv=380, type='n') for i in range(1, 5): pp.create_bus(net, name='Bus DB %s' % i, vn_kv=380, type='n') # Single busbar pp.create_bus(net, name='Single Busbar', vn_kv=110, type='b') for i in range(1, 6): pp.create_bus(net, name='Bus SB %s' % i, vn_kv=110, type='n') for i in range(1, 6): for j in [1, 2]: pp.create_bus(net, name='Bus SB T%s.%s' % (i, j), vn_kv=110, type='n') # Remaining buses for i in range(1, 5): pp.create_bus(net, name='Bus HV%s' % i, vn_kv=110, type='n') # show bustable net.bus # ### Lines # # # The information about the 6 HV lines are stored in a csv file that we load from the hard drive: # In[3]: hv_lines = pd.read_csv('example_advanced/hv_lines.csv', sep=';', header=0, decimal=',') hv_lines # and use to create all lines: # In[4]: # create lines for _, hv_line in hv_lines.iterrows(): from_bus = pp.get_element_index(net, "bus", hv_line.from_bus) to_bus = pp.get_element_index(net, "bus", hv_line.to_bus) pp.create_line(net, from_bus, to_bus, length_km=hv_line.length,std_type=hv_line.std_type, name=hv_line.line_name, parallel=hv_line.parallel) # show line table net.line # ### Transformer # # # The 380/110 kV transformer connects the buses "Bus DB 1" and "Bus DB 2". We use the get_element_index function from the pandapower toolbox to find the bus indices of the buses with these names and create a transformer by directly specifying the parameters: # In[5]: hv_bus = pp.get_element_index(net, "bus", "Bus DB 2") lv_bus = pp.get_element_index(net, "bus", "Bus SB 1") pp.create_transformer_from_parameters(net, hv_bus, lv_bus, sn_kva=300000, vn_hv_kv=380, vn_lv_kv=110, vscr_percent=0.06, vsc_percent=8, pfe_kw=0, i0_percent=0, tp_pos=0, shift_degree=0, name='EHV-HV-Trafo') net.trafo # show trafo table # ### Switches # # # Now we create the switches to connect the buses in the transformer station. The switch configuration is stored in the following csv table: # In[6]: hv_bus_sw = pd.read_csv('example_advanced/hv_bus_sw.csv', sep=';', header=0, decimal=',') hv_bus_sw # In[7]: # Bus-bus switches for _, switch in hv_bus_sw.iterrows(): from_bus = pp.get_element_index(net, "bus", switch.from_bus) to_bus = pp.get_element_index(net, "bus", switch.to_bus) pp.create_switch(net, from_bus, to_bus, et=switch.et, closed=switch.closed, type=switch.type, name=switch.bus_name) # Bus-line switches hv_buses = net.bus[(net.bus.vn_kv == 380) | (net.bus.vn_kv == 110)].index hv_ls = net.line[(net.line.from_bus.isin(hv_buses)) & (net.line.to_bus.isin(hv_buses))] for _, line in hv_ls.iterrows(): pp.create_switch(net, line.from_bus, line.name, et='l', closed=True, type='LBS', name='Switch %s - %s' % (net.bus.name.at[line.from_bus], line['name'])) pp.create_switch(net, line.to_bus, line.name, et='l', closed=True, type='LBS', name='Switch %s - %s' % (net.bus.name.at[line.to_bus], line['name'])) # Trafo-line switches pp.create_switch(net, pp.get_element_index(net, "bus", 'Bus DB 2'), pp.get_element_index(net, "trafo", 'EHV-HV-Trafo'), et='t', closed=True, type='LBS', name='Switch DB2 - EHV-HV-Trafo') pp.create_switch(net, pp.get_element_index(net, "bus", 'Bus SB 1'), pp.get_element_index(net, "trafo", 'EHV-HV-Trafo'), et='t', closed=True, type='LBS', name='Switch SB1 - EHV-HV-Trafo') # show switch table net.switch # ### External Grid # # # We equip the high voltage side of the transformer with an external grid connection: # In[8]: pp.create_ext_grid(net, pp.get_element_index(net, "bus", 'Double Busbar 1'), vm_pu=1.03, va_degree=0, name='External grid', s_sc_max_mva=10000, rx_max=0.1, rx_min=0.1) net.ext_grid # show external grid table # ### Loads # # # The five loads in the HV network are defined in the following csv file: # In[9]: hv_loads = pd.read_csv('example_advanced/hv_loads.csv', sep=';', header=0, decimal=',') hv_loads # In[10]: for _, load in hv_loads.iterrows(): bus_idx = pp.get_element_index(net, "bus", load.bus) pp.create_load(net, bus_idx, p_kw=load.p, q_kvar=load.q, name=load.load_name) # show load table net.load # ### Generator # # # The voltage controlled generator is created with an active power of 100 MW (negative for generation) and a voltage set point of 1.03 per unit: # In[11]: pp.create_gen(net, pp.get_element_index(net, "bus", 'Bus HV4'), vm_pu=1.03, p_kw=-100e3, name='Gas turbine') # show generator table net.gen # ### Static generators # # # We create this wind park with an active power of 20 MW (negative for generation) and a reactive power of -4 Mvar. To classify the generation as a wind park, we set type to "WP": # In[12]: pp.create_sgen(net, pp.get_element_index(net, "bus", 'Bus SB 5'), p_kw=-20e3, q_kvar=-4e3, sn_kva=45e3, type='WP', name='Wind Park') # show static generator table net.sgen # ### Shunt # # # In[13]: pp.create_shunt(net, pp.get_element_index(net, "bus", 'Bus HV1'), p_kw=0, q_kvar=-960, name='Shunt') # show shunt table net.shunt # ### External network equivalents # # # # The two remaining elements are impedances and extended ward equivalents: # In[16]: # Impedance pp.create_impedance(net, pp.get_element_index(net, "bus", 'Bus HV3'), pp.get_element_index(net, "bus", 'Bus HV1'), rft_pu=0.074873, xft_pu=0.198872, sn_kva=100000, name='Impedance') # show impedance table net.impedance # In[17]: # xwards pp.create_xward(net, pp.get_element_index(net, "bus", 'Bus HV3'), ps_kw=23942, qs_kvar=-12241.87, pz_kw=2814.571, qz_kvar=0, r_ohm=0, x_ohm=12.18951, vm_pu=1.02616, name='XWard 1') pp.create_xward(net, pp.get_element_index(net, "bus", 'Bus HV1'), ps_kw=3776, qs_kvar=-7769.979, pz_kw=9174.917, qz_kvar=0, r_ohm=0, x_ohm=50.56217, vm_pu=1.024001, name='XWard 2') # show xward table net.xward # ## Medium voltage level # ### Buses # # # In[18]: pp.create_bus(net, name='Bus MV0 20kV', vn_kv=20, type='n') for i in range(8): pp.create_bus(net, name='Bus MV%s' % i, vn_kv=10, type='n') #show only medium voltage bus table mv_buses = net.bus[(net.bus.vn_kv == 10) | (net.bus.vn_kv == 20)] mv_buses # ### Lines # # # In[19]: mv_lines = pd.read_csv('example_advanced/mv_lines.csv', sep=';', header=0, decimal=',') for _, mv_line in mv_lines.iterrows(): from_bus = pp.get_element_index(net, "bus", mv_line.from_bus) to_bus = pp.get_element_index(net, "bus", mv_line.to_bus) pp.create_line(net, from_bus, to_bus, length_km=mv_line.length, std_type=mv_line.std_type, name=mv_line.line_name) # show only medium voltage lines net.line[net.line.from_bus.isin(mv_buses.index)] # ### 3 Winding Transformer # # # The three winding transformer transforms its high voltage level to two different lower voltage levels, in this case from 110 kV to 20 kV and 10 kV. # In[20]: hv_bus = pp.get_element_index(net, "bus", "Bus HV2") mv_bus = pp.get_element_index(net, "bus", "Bus MV0 20kV") lv_bus = pp.get_element_index(net, "bus", "Bus MV0") pp.create_transformer3w_from_parameters(net, hv_bus, mv_bus, lv_bus, vn_hv_kv=110, vn_mv_kv=20, vn_lv_kv=10, sn_hv_kva=40000, sn_mv_kva=15000, sn_lv_kva=25000, vsc_hv_percent=10.1, vsc_mv_percent=10.1, vsc_lv_percent=10.1, vscr_hv_percent=0.266667, vscr_mv_percent=0.033333, vscr_lv_percent=0.04, pfe_kw=0, i0_percent=0, shift_mv_degree=30, shift_lv_degree=30, tp_side="hv", tp_mid=0, tp_min=-8, tp_max=8, tp_st_percent=1.25, tp_pos=0, name='HV-MV-MV-Trafo') # show transformer3w table net.trafo3w # ### Switches # In[21]: # Bus-line switches mv_buses = net.bus[(net.bus.vn_kv == 10) | (net.bus.vn_kv == 20)].index mv_ls = net.line[(net.line.from_bus.isin(mv_buses)) & (net.line.to_bus.isin(mv_buses))] for _, line in mv_ls.iterrows(): pp.create_switch(net, line.from_bus, line.name, et='l', closed=True, type='LBS', name='Switch %s - %s' % (net.bus.name.at[line.from_bus], line['name'])) pp.create_switch(net, line.to_bus, line.name, et='l', closed=True, type='LBS', name='Switch %s - %s' % (net.bus.name.at[line.to_bus], line['name'])) # open switch open_switch_id = net.switch[(net.switch.name == 'Switch Bus MV5 - MV Line5')].index net.switch.closed.loc[open_switch_id] = False #show only medium voltage switch table net.switch[net.switch.bus.isin(mv_buses)] # ### Loads # # # In[22]: mv_loads = pd.read_csv('example_advanced/mv_loads.csv', sep=';', header=0, decimal=',') for _, load in mv_loads.iterrows(): bus_idx = pp.get_element_index(net, "bus", load.bus) pp.create_load(net, bus_idx, p_kw=load.p, q_kvar=load.q, name=load.load_name) # show only medium voltage loads net.load[net.load.bus.isin(mv_buses)] # ### Static generators # # # In[23]: mv_sgens = pd.read_csv('example_advanced/mv_sgens.csv', sep=';', header=0, decimal=',') for _, sgen in mv_sgens.iterrows(): bus_idx = pp.get_element_index(net, "bus", sgen.bus) pp.create_sgen(net, bus_idx, p_kw=sgen.p, q_kvar=sgen.q, sn_kva=sgen.sn, type=sgen.type, name=sgen.sgen_name) # show only medium voltage static generators net.sgen[net.sgen.bus.isin(mv_buses)] # ## Low voltage level # ### Busses # # # In[24]: pp.create_bus(net, name='Bus LV0', vn_kv=0.4, type='n') for i in range(1, 6): pp.create_bus(net, name='Bus LV1.%s' % i, vn_kv=0.4, type='m') for i in range(1, 5): pp.create_bus(net, name='Bus LV2.%s' % i, vn_kv=0.4, type='m') pp.create_bus(net, name='Bus LV2.2.1', vn_kv=0.4, type='m') pp.create_bus(net, name='Bus LV2.2.2', vn_kv=0.4, type='m') # show only low voltage buses lv_buses = net.bus[net.bus.vn_kv == 0.4] lv_buses # ### Lines # # # In[25]: # create lines lv_lines = pd.read_csv('example_advanced/lv_lines.csv', sep=';', header=0, decimal=',') for _, lv_line in lv_lines.iterrows(): from_bus = pp.get_element_index(net, "bus", lv_line.from_bus) to_bus = pp.get_element_index(net, "bus", lv_line.to_bus) pp.create_line(net, from_bus, to_bus, length_km=lv_line.length, std_type=lv_line.std_type, name=lv_line.line_name) # show only low voltage lines net.line[net.line.from_bus.isin(lv_buses.index)] # ### Transformer # # # In[26]: hv_bus = pp.get_element_index(net, "bus", "Bus MV4") lv_bus = pp.get_element_index(net, "bus","Bus LV0") pp.create_transformer_from_parameters(net, hv_bus, lv_bus, sn_kva=400, vn_hv_kv=10, vn_lv_kv=0.4, vscr_percent=1.325, vsc_percent=4, pfe_kw=0.95, i0_percent=0.2375, tp_side="hv", tp_mid=0, tp_min=-2, tp_max=2, tp_st_percent=2.5, tp_pos=0, shift_degree=150, name='MV-LV-Trafo') #show only low voltage transformer net.trafo[net.trafo.lv_bus.isin(lv_buses.index)] # ### Switches # In[27]: # Bus-line switches lv_ls = net.line[(net.line.from_bus.isin(lv_buses)) & (net.line.to_bus.isin(lv_buses))] for _, line in lv_ls.iterrows(): pp.create_switch(net, line.from_bus, line.name, et='l', closed=True, type='LBS', name='Switch %s - %s' % (net.bus.name.at[line.from_bus], line['name'])) pp.create_switch(net, line.to_bus, line.name, et='l', closed=True, type='LBS', name='Switch %s - %s' % (net.bus.name.at[line.to_bus], line['name'])) # Trafo-line switches pp.create_switch(net, pp.get_element_index(net, "bus", 'Bus MV4'), pp.get_element_index(net, "trafo", 'MV-LV-Trafo'), et='t', closed=True, type='LBS', name='Switch MV4 - MV-LV-Trafo') pp.create_switch(net, pp.get_element_index(net, "bus", 'Bus LV0'), pp.get_element_index(net, "trafo", 'MV-LV-Trafo'), et='t', closed=True, type='LBS', name='Switch LV0 - MV-LV-Trafo') # show only low vvoltage switches net.switch[net.switch.bus.isin(lv_buses.index)] # ### Loads # # # In[28]: lv_loads = pd.read_csv('example_advanced/lv_loads.csv', sep=';', header=0, decimal=',') for _, load in lv_loads.iterrows(): bus_idx = pp.get_element_index(net, "bus", load.bus) pp.create_load(net, bus_idx, p_kw=load.p, q_kvar=load.q, name=load.load_name) # show only low voltage loads net.load[net.load.bus.isin(lv_buses.index)] # ### Static generators # # # In[29]: lv_sgens = pd.read_csv('example_advanced/lv_sgens.csv', sep=';', header=0, decimal=',') for _, sgen in lv_sgens.iterrows(): bus_idx = pp.get_element_index(net, "bus", sgen.bus) pp.create_sgen(net, bus_idx, p_kw=sgen.p, q_kvar=sgen.q, sn_kva=sgen.sn, type=sgen.type, name=sgen.sgen_name) # show only low voltage static generators net.sgen[net.sgen.bus.isin(lv_buses.index)] # ## Run a Power Flow # In[30]: pp.runpp(net, calculate_voltage_angles=True, init="dc") net