diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index 67f55cb2f..48a9bb151 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -32,9 +32,9 @@ body: Please follow [this guide](https://matthewrocklin.com/blog/work/2018/02/28/minimal-bug-reports) on how to provide a minimal, copy-pastable example. placeholder: > - import pandapower as pp + from pandapower.create import create_empty_network - net = pp.create_empty_network() + net = create_empty_network() ... render: python diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index b48024dc6..a48ef9b5e 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -145,8 +145,8 @@ Making sure you don't break anything If you make changes to pandapower that you plan to submit, first make sure that all tests are still passing. You can do this locally with: :: - import pandapower.test - pandapower.test.run_all_tests() + from pandapower.test import run_all_tests + run_all_tests() When you submit a pull request, github actions will run the same tests with actual, by pandapower supported Python versions. In most cases, if tests pass for you locally, they will also pass on github actions. But it can also happen that the tests pass for you locally, but still fail on github actions, because the new code is not compatible with all Python versions. In this case you will have to update your pull request until the tests pass in all Python versions. Pull requests that lead to failing tests will not be accepted. diff --git a/doc/about/update20.rst b/doc/about/update20.rst index 0227e5f9a..252fe469b 100644 --- a/doc/about/update20.rst +++ b/doc/about/update20.rst @@ -39,10 +39,10 @@ it will be for the convert_format function to apply all necessary changes. There With pandapower 2.0, we also advice to save networks in the .json format. It is much more robust to updates of libraries (for example, a .p file created with pandas < 0.20 can not be loaded with pandas 0.20 due to a change in the internal data structures. This is not an issue when saving the networks as .json files). So resave your pickle files as .json files such as :: - import pandapower as pp - net = pp.from_pickle("C:\\my_file.p") - pp.runpp(net) - pp.to_json(net, "C:\\my_file_2.0.json") + from pandapower import from_pickle, runpp, to_json + net = from_pickle("C:\\my_file.p") + runpp(net) + to_json(net, "C:\\my_file_2.0.json") Transformer parameter naming diff --git a/doc/control/run.rst b/doc/control/run.rst index cbd9ec3d3..a317d2a86 100644 --- a/doc/control/run.rst +++ b/doc/control/run.rst @@ -12,8 +12,8 @@ Then, run a power flow with the run_control option set to true: .. code:: - import pandapower as pp - pp.runpp(net, run_control=True) + from pandapower import runpp + runpp(net, run_control=True) The runpp function will now run multiple power flow calculations until all registered controllers are converged. @@ -22,8 +22,8 @@ Instead of calling runpp it is also possible to call run_control from the contro .. code:: - import pandapower.control as control - control.run_control(net) + from pandapower.control import run_control + run_control(net) By default, this will do the same as runpp with run_control=True. Calling the run_control function however gives you more flexibility to configurate diff --git a/doc/gridequivalent/gridequivalent_example.rst b/doc/gridequivalent/gridequivalent_example.rst index 85749573e..e154a85d0 100644 --- a/doc/gridequivalent/gridequivalent_example.rst +++ b/doc/gridequivalent/gridequivalent_example.rst @@ -13,12 +13,13 @@ First, we create an example network. .. code:: python - import pandapower as pp + from pandapower import runpp + from pandapower.networks import case9 - net = pp.case9() + net = case9() # getting power flow results - pp.runpp(net) + runpp(net) Define Grid Areas diff --git a/doc/networks/cigre.rst b/doc/networks/cigre.rst index 91750e2e7..c59ddcebb 100644 --- a/doc/networks/cigre.rst +++ b/doc/networks/cigre.rst @@ -21,10 +21,10 @@ High voltage transmission network .. code:: python - import pandapower.networks as pn + from pandapower.networks import create_cigre_network_hv # You may specify a length for the connection line between buses 6a and 6b - net = pn.create_cigre_network_hv(length_km_6a_6b=0.1) + net = create_cigre_network_hv(length_km_6a_6b=0.1) ''' This pandapower network includes the following parameter tables: @@ -53,9 +53,9 @@ Medium voltage distribution network .. code:: python - import pandapower.networks as pn + from pandapower.networks import create_cigre_network_mv - net = pn.create_cigre_network_mv(with_der=False) + net = create_cigre_network_mv(with_der=False) ''' This pandapower network includes the following parameter tables: @@ -94,9 +94,9 @@ Although the case study mentions the High Voltage as 220 kV, we assume 110 kV ag .. code:: python - import pandapower.networks as pn + from pandapower.networks import create_cigre_network_mv - net = pn.create_cigre_network_mv(with_der="pv_wind") + net = create_cigre_network_mv(with_der="pv_wind") ''' This pandapower network includes the following parameter tables: @@ -138,9 +138,9 @@ considered. Although the case study mentions the High Voltage as 220 kV, we assu .. code:: python - import pandapower.networks as pn + from pandapower.networks import create_cigre_network_mv - net = pn.create_cigre_network_mv(with_der="all") + net = create_cigre_network_mv(with_der="all") ''' This pandapower network includes the following parameter tables: @@ -170,9 +170,9 @@ Low voltage distribution network .. code:: python - import pandapower.networks as pn + from pandapower.networks import create_cigre_network_lv - net = pn.create_cigre_network_lv() + net = create_cigre_network_lv() ''' This pandapower network includes the following parameter tables: diff --git a/doc/networks/kerber.rst b/doc/networks/kerber.rst index ce4ef9e4f..0c43adc43 100644 --- a/doc/networks/kerber.rst +++ b/doc/networks/kerber.rst @@ -65,9 +65,9 @@ You can include the kerber networks by simply using: .. code:: python - import pandapower.networks as pn + from pandapower.networks import create_kerber_net - net1 = pn.create_kerber_net() + net1 = create_kerber_net() @@ -81,9 +81,9 @@ Kerber Landnetze .. code:: python - import pandapower.networks as pn + from pandapower.networks import create_kerber_landnetz_freileitung_1, create_kerber_landnetz_freileitung_2 - net1 = pn.create_kerber_landnetz_freileitung_1() + net1 = create_kerber_landnetz_freileitung_1() ''' This pandapower network includes the following parameter tables: @@ -94,7 +94,7 @@ Kerber Landnetze - ext_grid (1 elements) ''' - net2 = pn.create_kerber_landnetz_freileitung_2() + net2 = create_kerber_landnetz_freileitung_2() ''' This pandapower network includes the following parameter tables: @@ -121,9 +121,9 @@ Kerber Landnetze .. code:: python - import pandapower.networks as pn + from pandapower.networks import create_kerber_landnetz_kabel_1, create_kerber_landnetz_kabel_2 - net1 = pn.create_kerber_landnetz_kabel_1() + net1 = create_kerber_landnetz_kabel_1() ''' This pandapower network includes the following parameter tables: @@ -134,7 +134,7 @@ Kerber Landnetze - ext_grid (1 elements) ''' - net2 = pn.create_kerber_landnetz_kabel_2() + net2 = create_kerber_landnetz_kabel_2() ''' This pandapower network includes the following parameter tables: @@ -161,9 +161,9 @@ Kerber Dorfnetz .. code:: python - import pandapower.networks as pn + from pandapower.networks import create_kerber_dorfnetz - net = pn.create_kerber_dorfnetz() + net = create_kerber_dorfnetz() ''' This pandapower network includes the following parameter tables: @@ -192,9 +192,9 @@ Kerber Vorstadtnetze .. code:: python - import pandapower.networks as pn + from pandapower.networks import create_kerber_vorstadtnetz_kabel_1 - net1 = pn.create_kerber_vorstadtnetz_kabel_1() + net1 = create_kerber_vorstadtnetz_kabel_1() ''' This pandapower network includes the following parameter tables: @@ -220,9 +220,9 @@ Kerber Vorstadtnetze .. code:: python - import pandapower.networks as pn + from pandapower.networks import create_kerber_vorstadtnetz_kabel_2 - net2 = pn.create_kerber_vorstadtnetz_kabel_2() + net2 = create_kerber_vorstadtnetz_kabel_2() ''' This pandapower network includes the following parameter tables: @@ -293,14 +293,14 @@ Extreme Kerber Landnetze .. code:: python - import pandapower.networks as pn + from pandapower.networks import kb_extrem_landnetz_freileitung, kb_extrem_landnetz_kabel '''Extrem Landnetz Freileitung Typ I''' - net = pn.kb_extrem_landnetz_freileitung() + net = kb_extrem_landnetz_freileitung() '''Extrem Landnetz Kabel Typ I''' - net = pn.kb_extrem_landnetz_kabel() + net = kb_extrem_landnetz_kabel() @@ -318,14 +318,14 @@ Extreme Kerber Landnetze .. code:: python - import pandapower.networks as pn + from pandapower.networks import kb_extrem_landnetz_freileitung_trafo, kb_extrem_landnetz_kabel_trafo '''Extrem Landnetz Freileitung Typ II''' - net = pn.kb_extrem_landnetz_freileitung_trafo() + net = kb_extrem_landnetz_freileitung_trafo() '''Extrem Landnetz Kabel Typ II''' - net = pn.kb_extrem_landnetz_kabel_trafo() + net = kb_extrem_landnetz_kabel_trafo() @@ -344,10 +344,10 @@ Extreme Kerber Dorfnetze .. code:: python - import pandapower.networks as pn + from pandapower.networks import kb_extrem_dorfnetz '''Extrem Dorfnetz Kabel Typ I''' - net = pn.kb_extrem_dorfnetz() + net = kb_extrem_dorfnetz() @@ -364,10 +364,10 @@ Extreme Kerber Dorfnetze .. code:: python - import pandapower.networks as pn + from pandapower.networks import kb_extrem_dorfnetz_trafo '''Extrem Dorfnetz Kabel Typ II''' - net = pn.kb_extrem_dorfnetz_trafo() + net = kb_extrem_dorfnetz_trafo() @@ -383,10 +383,10 @@ Extreme Kerber Vorstadtnetze .. code:: python - import pandapower.networks as pn + from pandapower.networks import kb_extrem_vorstadtnetz_1 '''Extrem Vorstadtnetz Kabel_a Typ I''' - net = pn.kb_extrem_vorstadtnetz_1() + net = kb_extrem_vorstadtnetz_1() .. image:: /pics/networks/kerber//kerber_extrem_vorstadt_a_typ_1.png @@ -401,10 +401,10 @@ Extreme Kerber Vorstadtnetze .. code:: python - import pandapower.networks as pn + from pandapower.networks import kb_extrem_vorstadtnetz_2 '''Extrem Vorstadtnetz Kabel_b Typ I''' - net = pn.kb_extrem_vorstadtnetz_2() + net = kb_extrem_vorstadtnetz_2() .. image:: /pics/networks/kerber//kerber_extrem_vorstadt_b_typ_1.png @@ -419,10 +419,10 @@ Extreme Kerber Vorstadtnetze .. code:: python - import pandapower.networks as pn + from pandapower.networks import kb_extrem_vorstadtnetz_trafo_1 '''Extrem Vorstadtnetz Kabel_c Typ II''' - net = pn.kb_extrem_vorstadtnetz_trafo_1() + net = kb_extrem_vorstadtnetz_trafo_1() .. image:: /pics/networks/kerber//kerber_extrem_vorstadt_c_typ_2.png @@ -437,10 +437,10 @@ Extreme Kerber Vorstadtnetze .. code:: python - import pandapower.networks as pn + from pandapower.networks import kb_extrem_vorstadtnetz_trafo_2 '''Extrem Vorstadtnetz Kabel_d Typ II''' - net = pn.kb_extrem_vorstadtnetz_trafo_2() + net = kb_extrem_vorstadtnetz_trafo_2() .. image:: /pics/networks/kerber//kerber_extrem_vorstadt_d_typ_2.png diff --git a/doc/shortcircuit/run.rst b/doc/shortcircuit/run.rst index a713411af..da2090a4d 100644 --- a/doc/shortcircuit/run.rst +++ b/doc/shortcircuit/run.rst @@ -9,13 +9,13 @@ The short circuit calculation is carried out with the calc_sc function: .. code:: python - import pandapower.shortcircuit as sc - import pandapower.networks as nw + from pandapower.shortcircuit import calc_sc + from pandapower.networks import mv_oberrhein - net = nw.mv_oberrhein() + net = mv_oberrhein() net.ext_grid["s_sc_min_mva"] = 100 net.ext_grid["rx_min"] = 0.1 net.line["endtemp_degree"] = 20 - sc.calc_sc(net, case="min") + calc_sc(net, case="min") print(net.res_bus_sc) diff --git a/doc/std_types/save_pp_std_types.py b/doc/std_types/save_pp_std_types.py index a147846ff..50502fd60 100644 --- a/doc/std_types/save_pp_std_types.py +++ b/doc/std_types/save_pp_std_types.py @@ -4,19 +4,20 @@ @author: thurner """ -import pandapower as pp +from pandapower.std_types import available_std_types +from pandapower.create import create_empty_network -net = pp.create_empty_network() +net = create_empty_network() -linetypes = pp.available_std_types(net, "line") +linetypes = available_std_types(net, "line") columns = [c for c in net.line.columns if c in linetypes.columns] + ["q_mm2", "alpha"] linetypes = linetypes.reindex(columns, axis=1) linetypes.to_csv("linetypes.csv", sep=";") -trafotypes = pp.available_std_types(net, "trafo") +trafotypes = available_std_types(net, "trafo") trafotypes = trafotypes.reindex([c for c in net.trafo.columns if c in trafotypes.columns], axis=1) trafotypes.to_csv("trafotypes.csv", sep=";") -trafo3wtypes = pp.available_std_types(net, "trafo3w") +trafo3wtypes = available_std_types(net, "trafo3w") trafo3wtypes = trafo3wtypes.reindex([c for c in net.trafo3w.columns if c in trafo3wtypes.columns], axis=1) -trafo3wtypes.to_csv("trafo3wtypes.csv", sep=";") \ No newline at end of file +trafo3wtypes.to_csv("trafo3wtypes.csv", sep=";") diff --git a/doc/timeseries/timeseries_example.rst b/doc/timeseries/timeseries_example.rst index b717ed718..970acfccb 100644 --- a/doc/timeseries/timeseries_example.rst +++ b/doc/timeseries/timeseries_example.rst @@ -33,13 +33,13 @@ This structure is saved to a ``*.csv`` file and can be read by pandas and passed import numpy as np import pandas as pd - import pandapower.control as control - import pandapower.networks as nw - import pandapower.timeseries as timeseries + from pandapower.control import ConstControl + from pandapower.networks import mv_oberrhein + from pandapower.timeseries import run_timeseries, OutputWriter from pandapower.timeseries.data_sources.frame_data import DFData # load a pandapower network - net = nw.mv_oberrhein(scenario='generation') + net = mv_oberrhein(scenario='generation') # number of time steps n_ts = 95 # load your timeseries from a file (here csv file) @@ -54,8 +54,8 @@ This structure is saved to a ``*.csv`` file and can be read by pandas and passed # the element_index specifies which elements to update (here all sgens in the net since net.sgen.index is passed) # the controlled variable is "p_mw" # the profile_name are the columns in the csv file (here this is also equal to the sgen indices 0-N ) - const_sgen = control.ConstControl(net, element='sgen', element_index=net.sgen.index, - variable='p_mw', data_source=ds, profile_name=net.sgen.index) + const_sgen = ConstControl(net, element='sgen', element_index=net.sgen.index, + variable='p_mw', data_source=ds, profile_name=net.sgen.index) # do the same for loads # df = pd.read_csv("load_timeseries.csv") @@ -63,11 +63,11 @@ This structure is saved to a ``*.csv`` file and can be read by pandas and passed df = pd.DataFrame(np.random.normal(1., 0.1, size=(n_ts, len(net.load.index))), index=list(range(n_ts)), columns=net.load.index) * net.load.p_mw.values ds = DFData(df) - const_load = control.ConstControl(net, element='load', element_index=net.load.index, - variable='p_mw', data_source=ds, profile_name=net.load.index) + const_load = ConstControl(net, element='load', element_index=net.load.index, + variable='p_mw', data_source=ds, profile_name=net.load.index) # starting the timeseries simulation for one day -> 96 15 min values. - timeseries.run_timeseries(net) + run_timeseries(net) We created a ``DataSource`` and passed it to the ``ConstControl``, while also providing the name of the @@ -76,13 +76,13 @@ P-profile. To get the time series calculation results and save it to separate fi :: # initialising the outputwriter to save data to excel files in the current folder. You can change this to .json, .csv, or .pickle as well - ow = timeseries.OutputWriter(net, output_path="./", output_file_type=".xlsx") + ow = OutputWriter(net, output_path="./", output_file_type=".xlsx") # adding vm_pu of all buses and line_loading in percent of all lines as outputs to be stored ow.log_variable('res_bus', 'vm_pu') ow.log_variable('res_line', 'loading_percent') # starting the timeseries simulation for one day -> 96 15 min values. - timeseries.run_timeseries(net) + run_timeseries(net) # now checkout the folders res_bus and res_line in your current working dir We created an ``OutputWriter`` and stored the voltage magnitude **vm_pu** for each bus and the line loading in percent diff --git a/doc/topology/examples.rst b/doc/topology/examples.rst index a1898a967..ccf101018 100644 --- a/doc/topology/examples.rst +++ b/doc/topology/examples.rst @@ -11,48 +11,49 @@ Here are a few examples of what you can do: .. code:: python - import pandapower as pp + from pandapower.create import create_empty_network, create_bus, create_ext_grid, create_line, \ + create_transformer_from_parameters, create_load, create_switch - net = pp.create_empty_network() + net = create_empty_network() - pp.create_bus(net, name = "110 kV bar", vn_kv = 110, type = 'b') - pp.create_bus(net, name = "20 kV bar", vn_kv = 20, type = 'b') - pp.create_bus(net, name = "bus 2", vn_kv = 20, type = 'b') - pp.create_bus(net, name = "bus 3", vn_kv = 20, type = 'b') - pp.create_bus(net, name = "bus 4", vn_kv = 20, type = 'b') - pp.create_bus(net, name = "bus 5", vn_kv = 20, type = 'b') - pp.create_bus(net, name = "bus 6", vn_kv = 20, type = 'b') + create_bus(net, name = "110 kV bar", vn_kv = 110, type = 'b') + create_bus(net, name = "20 kV bar", vn_kv = 20, type = 'b') + create_bus(net, name = "bus 2", vn_kv = 20, type = 'b') + create_bus(net, name = "bus 3", vn_kv = 20, type = 'b') + create_bus(net, name = "bus 4", vn_kv = 20, type = 'b') + create_bus(net, name = "bus 5", vn_kv = 20, type = 'b') + create_bus(net, name = "bus 6", vn_kv = 20, type = 'b') - pp.create_ext_grid(net, 0, vm_pu = 1) + create_ext_grid(net, 0, vm_pu = 1) - pp.create_line(net, name = "line 0", from_bus = 1, to_bus = 2, length_km = 1, std_type = "NAYY 4x150 SE") - pp.create_line(net, name = "line 1", from_bus = 2, to_bus = 3, length_km = 1, std_type = "NAYY 4x150 SE") - pp.create_line(net, name = "line 2", from_bus = 3, to_bus = 4, length_km = 1, std_type = "NAYY 4x150 SE") - pp.create_line(net, name = "line 3", from_bus = 4, to_bus = 5, length_km = 1, std_type = "NAYY 4x150 SE") - pp.create_line(net, name = "line 4", from_bus = 5, to_bus = 6, length_km = 1, std_type = "NAYY 4x150 SE") - pp.create_line(net, name = "line 5", from_bus = 6, to_bus = 1, length_km = 1, std_type = "NAYY 4x150 SE") + create_line(net, name = "line 0", from_bus = 1, to_bus = 2, length_km = 1, std_type = "NAYY 4x150 SE") + create_line(net, name = "line 1", from_bus = 2, to_bus = 3, length_km = 1, std_type = "NAYY 4x150 SE") + create_line(net, name = "line 2", from_bus = 3, to_bus = 4, length_km = 1, std_type = "NAYY 4x150 SE") + create_line(net, name = "line 3", from_bus = 4, to_bus = 5, length_km = 1, std_type = "NAYY 4x150 SE") + create_line(net, name = "line 4", from_bus = 5, to_bus = 6, length_km = 1, std_type = "NAYY 4x150 SE") + create_line(net, name = "line 5", from_bus = 6, to_bus = 1, length_km = 1, std_type = "NAYY 4x150 SE") - pp.create_transformer_from_parameters(net, hv_bus=0, lv_bus=1, i0_percent=0.038, pfe_kw=11.6, + create_transformer_from_parameters(net, hv_bus=0, lv_bus=1, i0_percent=0.038, pfe_kw=11.6, vkr_percent=0.322, sn_mva=40, vn_lv_kv=22.0, vn_hv_kv=110.0, vk_percent=17.8) - pp.create_load(net, 2, p_mw = 1, q_mvar = 0.2, name = "load 0") - pp.create_load(net, 3, p_mw = 1, q_mvar = 0.2, name = "load 1") - pp.create_load(net, 4, p_mw = 1, q_mvar = 0.2, name = "load 2") - pp.create_load(net, 5, p_mw = 1, q_mvar = 0.2, name = "load 3") - pp.create_load(net, 6, p_mw = 1, q_mvar = 0.2, name = "load 4") - - pp.create_switch(net, bus = 1, element = 0, et = 'l') - pp.create_switch(net, bus = 2, element = 0, et = 'l') - pp.create_switch(net, bus = 2, element = 1, et = 'l') - pp.create_switch(net, bus = 3, element = 1, et = 'l') - pp.create_switch(net, bus = 3, element = 2, et = 'l') - pp.create_switch(net, bus = 4, element = 2, et = 'l') - pp.create_switch(net, bus = 4, element = 3, et = 'l', closed = 0) - pp.create_switch(net, bus = 5, element = 3, et = 'l') - pp.create_switch(net, bus = 5, element = 4, et = 'l') - pp.create_switch(net, bus = 6, element = 4, et = 'l') - pp.create_switch(net, bus = 6, element = 5, et = 'l') - pp.create_switch(net, bus = 1, element = 5, et = 'l') + create_load(net, 2, p_mw = 1, q_mvar = 0.2, name = "load 0") + create_load(net, 3, p_mw = 1, q_mvar = 0.2, name = "load 1") + create_load(net, 4, p_mw = 1, q_mvar = 0.2, name = "load 2") + create_load(net, 5, p_mw = 1, q_mvar = 0.2, name = "load 3") + create_load(net, 6, p_mw = 1, q_mvar = 0.2, name = "load 4") + + create_switch(net, bus = 1, element = 0, et = 'l') + create_switch(net, bus = 2, element = 0, et = 'l') + create_switch(net, bus = 2, element = 1, et = 'l') + create_switch(net, bus = 3, element = 1, et = 'l') + create_switch(net, bus = 3, element = 2, et = 'l') + create_switch(net, bus = 4, element = 2, et = 'l') + create_switch(net, bus = 4, element = 3, et = 'l', closed = 0) + create_switch(net, bus = 5, element = 3, et = 'l') + create_switch(net, bus = 5, element = 4, et = 'l') + create_switch(net, bus = 6, element = 4, et = 'l') + create_switch(net, bus = 6, element = 5, et = 'l') + create_switch(net, bus = 1, element = 5, et = 'l') Using NetworkX algorithms: shortest path @@ -63,10 +64,10 @@ Finding the shortest path between two buses is a good example for that. .. code:: python - import pandapower.topology as top + from pandapower.topology import create_nxgraph import networkx as nx - mg = top.create_nxgraph(net) + mg = create_nxgraph(net) nx.shortest_path(mg, 0, 5) .. code:: python @@ -85,10 +86,10 @@ With *unsupplied_buses* you can easily find buses that are not connected to an e .. code:: python - import pandapower.topology as top + from pandapower.topology import unsupplied_buses net.switch.closed.at[11] = 0 - top.unsupplied_buses(net) + unsupplied_buses(net) .. code:: python @@ -109,11 +110,11 @@ This is possible since line lengths are being transferred into the MultiGraph as .. code:: python - import pandapower.topology as top + from pandapower.topology import calc_distance_to_bus net.switch.closed.at[6] = 1 net.switch.closed.at[8] = 0 - top.calc_distance_to_bus(net, 1) + calc_distance_to_bus(net, 1) .. code:: python @@ -139,10 +140,10 @@ Find connected buses with the same voltage level .. code:: python - import pandapower.topology as top + from pandapower.topology import create_nxgraph, connected_components - mg_no_trafos = top.create_nxgraph(net, include_trafos = False) - cc = top.connected_components(mg_no_trafos) + mg_no_trafos = create_nxgraph(net, include_trafos = False) + cc = connected_components(mg_no_trafos) .. code:: python @@ -166,10 +167,10 @@ be set as a nogobuses. With *respect_switches = True* you get the ring sections, .. code:: python - import pandapower.topology as top + from pandapower.topology import create_nxgraph, connected_components - mg_ring_sections = top.create_nxgraph(net, nogobuses = [0, 1]) - cc_ring_sections = top.connected_components(mg_ring_sections) + mg_ring_sections = create_nxgraph(net, nogobuses = [0, 1]) + cc_ring_sections = connected_components(mg_ring_sections) .. code:: python @@ -188,10 +189,10 @@ be set as a nogobuses. With *respect_switches = True* you get the ring sections, .. code:: python - import pandapower.topology as top + from pandapower.topology import create_nxgraph, connected_components - mg_ring = top.create_nxgraph(net, respect_switches = False, nogobuses = [0,1]) - cc_ring = top.connected_components(mg_ring) + mg_ring = create_nxgraph(net, respect_switches = False, nogobuses = [0,1]) + cc_ring = connected_components(mg_ring) .. code:: python @@ -226,8 +227,8 @@ This is a small extension for the example network: .. code:: python - import pandapower.topology as top - top.determine_stubs(net, roots = [0,1]) + from pandapower.topology import determine_stubs + determine_stubs(net, roots = [0,1]) .. code:: python diff --git a/pandapower/auxiliary.py b/pandapower/auxiliary.py index 0f0098783..9518eecb7 100644 --- a/pandapower/auxiliary.py +++ b/pandapower/auxiliary.py @@ -27,33 +27,33 @@ # (https://github.com/bcj/AttrDict/blob/master/LICENSE.txt) import copy -from collections.abc import MutableMapping +import numbers import warnings -from importlib.metadata import version as version_str +from collections.abc import MutableMapping from importlib.metadata import PackageNotFoundError -from typing_extensions import deprecated +from importlib.metadata import version as version_str -from geojson import loads, GeoJSON import numpy as np import pandas as pd from pandas.api.types import is_numeric_dtype, is_string_dtype, is_object_dtype # from pandas.api.types import is_integer_dtype, is_float_dtype import scipy as sp -import numbers +from geojson import loads, GeoJSON from packaging.version import Version +from typing_extensions import deprecated from pandapower.pypower.idx_brch import F_BUS, T_BUS, BR_STATUS from pandapower.pypower.idx_brch_dc import DC_BR_STATUS, DC_F_BUS, DC_T_BUS from pandapower.pypower.idx_bus import BUS_I, BUS_TYPE, NONE, PD, QD, VM, VA, REF, PQ, VMIN, VMAX, PV +from pandapower.pypower.idx_bus_dc import DC_VMAX, DC_VMIN, DC_BUS_I, DC_BUS_TYPE, DC_NONE, DC_REF, DC_B2B, DC_P from pandapower.pypower.idx_gen import PMIN, PMAX, QMIN, QMAX from pandapower.pypower.idx_ssc import SSC_STATUS, SSC_BUS, SSC_INTERNAL_BUS from pandapower.pypower.idx_tcsc import TCSC_STATUS, TCSC_F_BUS, TCSC_T_BUS -from pandapower.pypower.idx_vsc import VSC_STATUS, VSC_BUS, VSC_INTERNAL_BUS, VSC_BUS_DC, VSC_MODE_AC, VSC_MODE_AC_SL, \ - VSC_INTERNAL_BUS_DC -from .pypower.idx_bus_dc import DC_VMAX, DC_VMIN, DC_BUS_I, DC_BUS_TYPE, DC_NONE, DC_REF, DC_B2B, DC_P +from pandapower.pypower.idx_vsc import VSC_STATUS, VSC_BUS, VSC_INTERNAL_BUS, VSC_BUS_DC, VSC_INTERNAL_BUS_DC try: from lightsim2grid.newtonpf import newtonpf_new as newtonpf_ls + lightsim2grid_available = True except ImportError: lightsim2grid_available = False @@ -64,6 +64,7 @@ try: from geopandas import GeoSeries from shapely import from_geojson + geopandas_available = True except ImportError: geopandas_available = False @@ -87,10 +88,9 @@ def log_to_level(msg, passed_logger, level): def version_check(package_name, level="UserWarning", ignore_not_installed=False): - minimum_version = {'plotly': "3.1.1", 'numba': "0.25", - } + } if ignore_not_installed and package_name not in minimum_version.keys(): return @@ -110,6 +110,7 @@ def version_check(package_name, level="UserWarning", ignore_not_installed=False) try: from numba import jit + try: version_check("numba") NUMBA_INSTALLED = True @@ -119,6 +120,7 @@ def version_check(package_name, level="UserWarning", ignore_not_installed=False) NUMBA_INSTALLED = False except ImportError: from .pf.no_numba import jit + NUMBA_INSTALLED = False @@ -318,7 +320,7 @@ def __init__(self, *args, **kwargs): for key in self: if isinstance(self[key], list): self[key] = pd.DataFrame(np.zeros(0, dtype=self[key]), index=pd.Index([], - dtype=np.int64)) + dtype=np.int64)) @deprecated("Use copy.deepcopy(net) instead of net.deepcopy()") def deepcopy(self): @@ -349,7 +351,7 @@ def __repr__(self): # pragma: no cover if len(res): res = [" and the following results tables:"] + res lines = ["This pandapower network includes the following parameter tables:"] + \ - par + res + res_cost + par + res + res_cost return "\n".join(lines) @@ -359,6 +361,7 @@ class GeoAccessor: pandas Series accessor for the geo column. It facilitates the use of geojson strings. NaN entrys are dropped using the accessor! """ + def __init__(self, pandas_obj): self._validate(pandas_obj) self._obj = pandas_obj @@ -426,6 +429,7 @@ def __getattr__(self, item): if callable(geoms_item): def wrapper(*args, **kwargs): return geoms_item(*args, **kwargs) + return wrapper else: return geoms_item @@ -436,7 +440,6 @@ def plural_s(number): return "" if number == 1 else "s" - def ets_to_element_types(ets=None): ser = pd.Series(["bus", "line", "trafo", "trafo3w", "impedance"], index=["b", "l", "t", "t3", "i"]) @@ -772,7 +775,7 @@ def _write_to_object_attribute(net, element, index, variable, values): def _set_isolated_nodes_out_of_service(ppc, bus_not_reachable, dc=False): isolated_nodes = np.where(bus_not_reachable)[0] if len(isolated_nodes) > 0: - logger.debug("There are isolated buses in the network! (%i nodes in the PPC)"%len(isolated_nodes)) + logger.debug("There are isolated buses in the network! (%i nodes in the PPC)" % len(isolated_nodes)) # set buses in ppc out of service if dc: ppc['bus_dc'][isolated_nodes, DC_BUS_TYPE] = DC_NONE @@ -1059,7 +1062,8 @@ def _select_is_elements_numba(net, isolated_nodes=None, isolated_nodes_dc=None, net._ppc["bus"][vsc_aux_isolated, BUS_TYPE] = NONE # if there are no in service VSC that define the DC slack node, we must change the DC slack to type P bus_dc_slack = net._ppc["bus_dc"][:, DC_BUS_TYPE] == DC_REF - bus_dc_with_vsc = np.r_[net._ppc["vsc"][is_elements["vsc"], VSC_BUS_DC], net._ppc["vsc"][is_elements["vsc"], VSC_INTERNAL_BUS_DC]] + bus_dc_with_vsc = np.r_[ + net._ppc["vsc"][is_elements["vsc"], VSC_BUS_DC], net._ppc["vsc"][is_elements["vsc"], VSC_INTERNAL_BUS_DC]] bus_dc_to_change = bus_dc_slack & (~np.isin(net._ppc["bus_dc"][:, DC_BUS_I], bus_dc_with_vsc)) net._ppc["bus_dc"][bus_dc_to_change, DC_BUS_TYPE] = DC_P @@ -1245,11 +1249,12 @@ def _set_isolated_buses_out_of_service(net, ppc): # first check if buses are connected to branches # I don't know why this dance with [X, :][:, [Y, Z]] (instead of [X, [Y, Z]]) is necessary: disco = np.setxor1d(ppc["bus"][:, BUS_I].astype(np.int64), - ppc["branch"][ppc["branch"][:, BR_STATUS] == 1, :][:, [F_BUS,T_BUS]].real.astype(np.int64).flatten()) + ppc["branch"][ppc["branch"][:, BR_STATUS] == 1, :][:, [F_BUS, T_BUS]].real.astype( + np.int64).flatten()) # but also check if they may be the only connection to an ext_grid net._isolated_buses = np.setdiff1d(disco, ppc['bus'][ppc['bus'][:, BUS_TYPE] == REF, - BUS_I].real.astype(np.int64)) + BUS_I].real.astype(np.int64)) ppc["bus"][net._isolated_buses, BUS_TYPE] = NONE # check DC buses - not connected to DC lines and not connected to VSC DC side @@ -1260,7 +1265,7 @@ def _set_isolated_buses_out_of_service(net, ppc): # but also check if they may be the only connection to an ext_grid net._isolated_buses_dc = np.setdiff1d(disco_dc, ppc['bus_dc'][ppc['bus_dc'][:, DC_BUS_TYPE] == REF, - DC_BUS_I].real.astype(np.int64)) + DC_BUS_I].real.astype(np.int64)) ppc["bus_dc"][net._isolated_buses_dc, DC_BUS_TYPE] = DC_NONE @@ -1283,9 +1288,8 @@ def _check_if_numba_is_installed(level="warning"): return NUMBA_INSTALLED - def _check_lightsim2grid_compatibility(net, lightsim2grid, voltage_depend_loads, algorithm, distributed_slack, tdpf): - """ + r""" Implement some checks to decide whether the package lightsim2grid can be used. These checks are documentated in :code:`doc\powerflow\ac.rst` The package implements a backend for power flow calculation in C++ and provides a speed-up. If lightsim2grid @@ -1839,7 +1843,6 @@ def _init_rundcopp_options(net, check_connectivity, switch_rx_ratio, delta, traf def _init_runse_options(net, v_start, delta_start, calculate_voltage_angles, **kwargs): - check_connectivity = kwargs.get("check_connectivity", True) trafo_model = kwargs.get("trafo_model", "t") trafo3w_losses = kwargs.get("trafo3w_losses", "hv") diff --git a/pandapower/contingency/contingency.py b/pandapower/contingency/contingency.py index 2ff440203..b82d20608 100644 --- a/pandapower/contingency/contingency.py +++ b/pandapower/contingency/contingency.py @@ -9,16 +9,12 @@ import warnings from packaging.version import Version -import pandapower as pp - try: import pandaplan.core.pplog as logging except ImportError: import logging logger = logging.getLogger(__name__) - - try: import lightsim2grid v = Version(lightsim2grid.__version__) @@ -41,9 +37,11 @@ except ImportError: KLU_solver_available = False +from pandapower.run import runpp + def run_contingency(net, nminus1_cases, pf_options=None, pf_options_nminus1=None, write_to_net=True, - contingency_evaluation_function=pp.runpp, **kwargs): + contingency_evaluation_function=runpp, **kwargs): """ Obtain either loading (N-0) or max. loading (N-0 and all N-1 cases), and min/max bus voltage magnitude. The variable "temperature_degree_celsius" can be used in addition to "loading_percent" to obtain max. temperature. @@ -141,7 +139,7 @@ def run_contingency(net, nminus1_cases, pf_options=None, pf_options_nminus1=None return contingency_results -def run_contingency_ls2g(net, nminus1_cases, contingency_evaluation_function=pp.runpp, **kwargs): +def run_contingency_ls2g(net, nminus1_cases, contingency_evaluation_function=runpp, **kwargs): """ Execute contingency analysis using the lightsim2grid library. This works much faster than using pandapower. diff --git a/pandapower/control/__init__.py b/pandapower/control/__init__.py index 04d9e5cdf..040ff7eb8 100644 --- a/pandapower/control/__init__.py +++ b/pandapower/control/__init__.py @@ -1,23 +1,19 @@ -from pandapower.auxiliary import ControllerNotConverged - import pandapower.control.basic_controller import pandapower.control.controller - +from pandapower.control.controller.DERController.der_control import DERController +from pandapower.control.controller.characteristic_control import CharacteristicControl # --- Controller --- from pandapower.control.controller.const_control import ConstControl from pandapower.control.controller.pq_control import PQController -from pandapower.control.controller.characteristic_control import CharacteristicControl +from pandapower.control.controller.shunt_control import DiscreteShuntController +from pandapower.control.controller.station_control import BinarySearchControl, DroopControl from pandapower.control.controller.trafo.ContinuousTapControl import ContinuousTapControl from pandapower.control.controller.trafo.DiscreteTapControl import DiscreteTapControl -from pandapower.control.controller.trafo.VmSetTapControl import VmSetTapControl from pandapower.control.controller.trafo.TapDependentImpedance import TapDependentImpedance +from pandapower.control.controller.trafo.VmSetTapControl import VmSetTapControl from pandapower.control.controller.trafo_control import TrafoController -from pandapower.control.controller.station_control import BinarySearchControl, DroopControl -from pandapower.control.controller.DERController.der_control import DERController -from pandapower.control.controller.shunt_control import DiscreteShuntController - # --- Other --- from pandapower.control.run_control import * -from pandapower.control.util.characteristic import Characteristic, SplineCharacteristic from pandapower.control.util.auxiliary import get_controller_index, plot_characteristic, create_trafo_characteristics +from pandapower.control.util.characteristic import Characteristic, SplineCharacteristic from pandapower.control.util.diagnostic import control_diagnostic, trafo_characteristics_diagnostic diff --git a/pandapower/control/controller/DERController/der_control.py b/pandapower/control/controller/DERController/der_control.py index 567e70e28..15cf0e677 100644 --- a/pandapower/control/controller/DERController/der_control.py +++ b/pandapower/control/controller/DERController/der_control.py @@ -6,9 +6,9 @@ import numpy as np from pandapower.auxiliary import ensure_iterability -from pandapower.control.controller.pq_control import PQController -from pandapower.control.controller.DERController.QModels import QModel from pandapower.control.controller.DERController.PQVAreas import BaseArea, PQVArea4110, QVArea4110 +from pandapower.control.controller.DERController.QModels import QModel +from pandapower.control.controller.pq_control import PQController try: import pandaplan.core.pplog as logging @@ -98,16 +98,18 @@ class DERController(PQController): Example ------- - >>> import pandapower as pp - >>> import pandapower.control.controller.DERController as DERModels + >>> from pandapower.networks.cigre_networks import create_cigre_network_mv + >>> from pandapower.control.controller.DERController import DERController, QModelCosphiP, PQVArea4120V2 + >>> from pandapower.run import runpp >>> net = create_cigre_network_mv(with_der=True) - >>> controlled_sgens = pp.control.DERController( + >>> controlled_sgens = DERController( ... net, net.sgen.index, - ... q_model=DERModels.QModelCosphiP(cosphi=-0.95), - ... pqv_area=DERModels.PQVArea4120V2() - ... ) - ... pp.runpp(net, run_control=True) + ... q_model=QModelCosphiP(cosphi=-0.95), + ... pqv_area=PQVArea4120V2() + ... ) + >>> runpp(net, run_control=True) """ + def __init__(self, net, element_index, element="sgen", q_model=None, pqv_area=None, saturate_sn_mva=np.nan, q_prio=True, damping_coef=2, @@ -157,13 +159,13 @@ def time_step(self, net, time): self.p_series_mw = self.p_mw self.q_series_mvar = self.q_mvar -# self.write_to_net(net) + # self.write_to_net(net) def is_converged(self, net): self._determine_target_powers(net) - return np.allclose(self.target_q_mvar, self.q_mvar, atol=self.max_q_error) and\ + return np.allclose(self.target_q_mvar, self.q_mvar, atol=self.max_q_error) and \ np.allclose(self.target_p_mw, self.p_mw, atol=self.max_p_error) def control_step(self, net): @@ -207,7 +209,7 @@ def _step_p(self, p_series_mw=None): def _step_q(self, p_series_mw=None, q_series_mvar=None, vm_pu=None): """Q priority: Q setpoint > Q model > Q series""" if self.q_model is not None: - q_pu = self.q_model.step(vm_pu=vm_pu, p_pu=p_series_mw/self.sn_mva) + q_pu = self.q_model.step(vm_pu=vm_pu, p_pu=p_series_mw / self.sn_mva) else: if q_series_mvar is None: raise Exception("No Q_model and no q_profile available.") @@ -232,29 +234,28 @@ def _saturate(self, p_pu, q_pu, vm_pu): def _saturate_sn_mva_step(self, p_pu, q_pu, vm_pu): # Saturation on SnMVA according to priority mode - sat_s_pu = self.saturate_sn_mva / self.sn_mva # sat_s is relative to sn_mva - to_saturate = p_pu**2 + q_pu**2 > sat_s_pu**2 + sat_s_pu = self.saturate_sn_mva / self.sn_mva # sat_s is relative to sn_mva + to_saturate = p_pu ** 2 + q_pu ** 2 > sat_s_pu ** 2 if any(to_saturate): if self.q_prio: if ( - isinstance(self.pqv_area, PQVArea4110) or isinstance(self.pqv_area, QVArea4110) - ) and any( + isinstance(self.pqv_area, PQVArea4110) or isinstance(self.pqv_area, QVArea4110) + ) and any( (0.95 < vm[to_saturate]) & (vm[to_saturate] < 1.05) & (-0.328684 < q_pu[to_saturate]) & any(q_pu[to_saturate] < 0.328684) - ): + ): logger.warning(f"Such kind of saturation is performed that is not in line with" " VDE AR N 4110: p reduction within 0.95 < vm < 1.05 and " "0.95 < cosphi.") q_pu[to_saturate] = np.clip(q_pu[to_saturate], -sat_s_pu[to_saturate], sat_s_pu[to_saturate]) - p_pu[to_saturate] = np.sqrt(sat_s_pu[to_saturate]**2 - q_pu[to_saturate]**2) + p_pu[to_saturate] = np.sqrt(sat_s_pu[to_saturate] ** 2 - q_pu[to_saturate] ** 2) else: p_pu[to_saturate] = np.clip(p_pu[to_saturate], 0., sat_s_pu[to_saturate]) - q_pu[to_saturate] = np.sqrt(sat_s_pu[to_saturate]**2 - p_pu[to_saturate]**2) * \ - np.sign(q_pu[to_saturate]) + q_pu[to_saturate] = np.sqrt(sat_s_pu[to_saturate] ** 2 - p_pu[to_saturate] ** 2) * \ + np.sign(q_pu[to_saturate]) return p_pu, q_pu - def __str__(self): el_id_str = f"len(element_index)={len(self.element_index)}" if len(self.element_index) > 6 \ else f"element_index={self.element_index}" diff --git a/pandapower/control/controller/DERController/der_control_plot.py b/pandapower/control/controller/DERController/der_control_plot.py index 29ec63a8d..e3a76354a 100644 --- a/pandapower/control/controller/DERController/der_control_plot.py +++ b/pandapower/control/controller/DERController/der_control_plot.py @@ -126,21 +126,21 @@ def generate_circle_segment(center_x, center_y, radius, start, stop, step): if __name__ == "__main__": - import pandapower.control.controller.DERController as DERModels + from pandapower.control.controller.DERController import PQVArea4120V1, PQVArea4120V2, PQVArea4120V3 - pq_area = DERModels.PQVArea4120V1() + pq_area = PQVArea4120V1() plot_pq_area(pq_area, "PQVArea4120V1") plt.show() plot_qv_area(pq_area, "PQVArea4120V1") plt.show() - pq_area = DERModels.PQVArea4120V2() + pq_area = PQVArea4120V2() plot_pq_area(pq_area, "PQVArea4120V2") plt.show() plot_qv_area(pq_area, "PQVArea4120V2") plt.show() - pq_area = DERModels.PQVArea4120V3() + pq_area = PQVArea4120V3() plot_pq_area(pq_area, "PQVArea4120V3") plt.show() plot_qv_area(pq_area, "PQVArea4120V3") diff --git a/pandapower/control/controller/trafo_control.py b/pandapower/control/controller/trafo_control.py index d3cb3ae44..0598c63d9 100644 --- a/pandapower/control/controller/trafo_control.py +++ b/pandapower/control/controller/trafo_control.py @@ -4,7 +4,8 @@ # and Energy System Technology (IEE), Kassel. All rights reserved. import numpy as np -from pandapower.auxiliary import read_from_net, write_to_net, _detect_read_write_flag + +from pandapower.auxiliary import read_from_net, _detect_read_write_flag from pandapower.control.basic_controller import Controller try: @@ -79,7 +80,8 @@ def nothing_to_do(self, net): element_in_service = read_from_net(net, self.element, self.element_index, 'in_service', self._read_write_flag) ext_grid_bus = np.isin(self.trafobus, net.ext_grid.loc[net.ext_grid.in_service, 'bus'].values) element_index_in_net = np.isin(self.element_index, net[self.element].index.values) - self.controlled = np.logical_and(np.logical_and(element_in_service, element_index_in_net), np.logical_not(ext_grid_bus)) + self.controlled = np.logical_and(np.logical_and(element_in_service, element_index_in_net), + np.logical_not(ext_grid_bus)) if isinstance(self.element_index, np.int64) or isinstance(self.element_index, int): # if the controller shouldn't do anything, return True if not element_in_service or ext_grid_bus or not element_index_in_net or ( @@ -88,7 +90,8 @@ def nothing_to_do(self, net): return False else: # if the controller shouldn't do anything, return True - if np.all(~element_in_service[self.controlled]) or np.all(ext_grid_bus[self.controlled]) or np.all(~element_index_in_net[self.controlled]) or ( + if np.all(~element_in_service[self.controlled]) or np.all(ext_grid_bus[self.controlled]) or np.all( + ~element_index_in_net[self.controlled]) or ( self._read_write_flag != 'single_index' and len(self.element_index) == 0): return True return False @@ -96,7 +99,7 @@ def nothing_to_do(self, net): def _set_tap_side_coeff(self, net): tap_side = read_from_net(net, self.element, self.element_index, 'tap_side', self._read_write_flag) if (len(np.setdiff1d(tap_side, ['hv', 'lv'])) > 0 and self.element == "trafo") or \ - (len(np.setdiff1d(tap_side, ['hv', 'lv', 'mv'])) > 0 and self.element == "trafo3w"): + (len(np.setdiff1d(tap_side, ['hv', 'lv', 'mv'])) > 0 and self.element == "trafo3w"): raise ValueError("Trafo tap side (in net.%s) has to be either hv or lv, " "but received: %s for trafo %s" % (self.element, tap_side, self.element_index)) @@ -107,7 +110,7 @@ def _set_tap_side_coeff(self, net): if self.tap_step_percent < 0: self.tap_side_coeff *= -1 else: - self.tap_side_coeff = np.where(tap_side=='hv', 1, -1) + self.tap_side_coeff = np.where(tap_side == 'hv', 1, -1) self.tap_side_coeff[self.side == "hv"] *= -1 self.tap_side_coeff[self.tap_step_percent < 0] *= -1 @@ -129,7 +132,8 @@ def _set_valid_controlled_index_and_bus(self, net): element_in_service = read_from_net(net, self.element, self.element_index, 'in_service', self._read_write_flag) ext_grid_bus = np.isin(self.trafobus, net.ext_grid.loc[net.ext_grid.in_service, 'bus'].values) element_index_in_net = np.isin(self.element_index, net[self.element].index.values) - self.controlled = np.logical_and(np.logical_and(element_in_service, element_index_in_net), np.logical_not(ext_grid_bus)) + self.controlled = np.logical_and(np.logical_and(element_in_service, element_index_in_net), + np.logical_not(ext_grid_bus)) if self._read_write_flag != 'single_index': self.element_index = self.element_index[self.controlled] self.trafobus = self.trafobus[self.controlled] @@ -141,8 +145,10 @@ def _set_tap_parameters(self, net): self.tap_min = read_from_net(net, self.element, self.element_index, "tap_min", self._read_write_flag) self.tap_max = read_from_net(net, self.element, self.element_index, "tap_max", self._read_write_flag) self.tap_neutral = read_from_net(net, self.element, self.element_index, "tap_neutral", self._read_write_flag) - self.tap_step_percent = read_from_net(net, self.element, self.element_index, "tap_step_percent", self._read_write_flag) - self.tap_step_degree = read_from_net(net, self.element, self.element_index, "tap_step_degree", self._read_write_flag) + self.tap_step_percent = read_from_net(net, self.element, self.element_index, "tap_step_percent", + self._read_write_flag) + self.tap_step_degree = read_from_net(net, self.element, self.element_index, "tap_step_degree", + self._read_write_flag) self.tap_pos = read_from_net(net, self.element, self.element_index, "tap_pos", self._read_write_flag) if self._read_write_flag == "single_index": @@ -152,7 +158,8 @@ def _set_tap_parameters(self, net): if np.isnan(self.tap_pos): self.tap_pos = self.tap_neutral else: - self.tap_sign = np.where(np.isnan(self.tap_step_degree), 1, np.sign(np.cos(np.deg2rad(self.tap_step_degree)))) + self.tap_sign = np.where(np.isnan(self.tap_step_degree), 1, + np.sign(np.cos(np.deg2rad(self.tap_step_degree)))) self.tap_sign = np.where((self.tap_sign == 0) | (np.isnan(self.tap_sign)), 1, self.tap_sign) self.tap_pos = np.where(np.isnan(self.tap_pos), self.tap_neutral, self.tap_pos) diff --git a/pandapower/control/run_control.py b/pandapower/control/run_control.py index 87b425727..ba8a424eb 100644 --- a/pandapower/control/run_control.py +++ b/pandapower/control/run_control.py @@ -3,7 +3,6 @@ # Copyright (c) 2016-2024 by University of Kassel and Fraunhofer Institute for Energy Economics # and Energy System Technology (IEE), Kassel. All rights reserved. -import pandapower as pp import numpy as np try: @@ -18,6 +17,8 @@ logger = pplog.getLogger(__name__) +from pandapower.run import runpp + def get_controller_order(nets, controller): """ @@ -87,7 +88,7 @@ def ctrl_variables_default(net, **kwargs): ctrl_variables["level"], ctrl_variables["controller_order"] = [0], [[]] else: ctrl_variables["level"], ctrl_variables["controller_order"] = get_controller_order(net, net.controller) - ctrl_variables["run"] = kwargs.pop('run', pp.runpp) + ctrl_variables["run"] = kwargs.pop('run', runpp) ctrl_variables["initial_run"] = check_for_initial_run(ctrl_variables["controller_order"]) ctrl_variables['continue_on_divergence'] = False ctrl_variables['check_each_level'] = True diff --git a/pandapower/control/util/auxiliary.py b/pandapower/control/util/auxiliary.py index 570c45012..a78b82c8a 100644 --- a/pandapower/control/util/auxiliary.py +++ b/pandapower/control/util/auxiliary.py @@ -8,7 +8,7 @@ from pandas import Index, Series from pandapower.auxiliary import soft_dependency_error, ensure_iterability -from .characteristic import SplineCharacteristic +from pandapower.control.util.characteristic import SplineCharacteristic try: import matplotlib.pyplot as plt @@ -52,6 +52,7 @@ def get_controller_index_by_type(net, ctrl_type, idx=[]): is_of_type = net.controller.object.apply(lambda x: isinstance(x, ctrl_type)) return list(net.controller.index.values[net.controller.index.isin(idx) & is_of_type]) + def get_controller_index_by_typename(net, typename, idx=[], case_sensitive=False): """ Returns controller indices of a given name of type as list. diff --git a/pandapower/control/util/characteristic.py b/pandapower/control/util/characteristic.py index 9ca60afef..ac64e74d4 100644 --- a/pandapower/control/util/characteristic.py +++ b/pandapower/control/util/characteristic.py @@ -3,12 +3,10 @@ # Copyright (c) 2016-2024 by University of Kassel and Fraunhofer Institute for Energy Economics # and Energy System Technology (IEE), Kassel. All rights reserved. -from builtins import zip -from builtins import object import numpy as np - from numpy import interp from scipy.interpolate import interp1d, PchipInterpolator + from pandapower.io_utils import JSONSerializableClass try: @@ -74,6 +72,7 @@ class Characteristic(JSONSerializableClass): >>> c.satisfies(x=2.5, measured=3.1, epsilon=0.1) False """ + def __init__(self, net, x_values, y_values, **kwargs): super().__init__() self.x_vals = x_values diff --git a/pandapower/convert_format.py b/pandapower/convert_format.py index 227c2fe9a..e4012300b 100644 --- a/pandapower/convert_format.py +++ b/pandapower/convert_format.py @@ -11,10 +11,9 @@ from pandapower._version import __version__, __format_version__ from pandapower.create import create_empty_network, create_poly_cost -from pandapower.plotting import geo from pandapower.results import reset_results from pandapower.control import TrafoController -import pandapower.plotting.geo as geo +from pandapower.plotting.geo import convert_geodata_to_geojson try: import pandaplan.core.pplog as logging @@ -72,7 +71,7 @@ def _convert_geo_data(net, elements_to_deserialize=None): if Version(str(net.format_version)) < Version("1.6"): net.bus_geodata = pd.DataFrame.from_dict(net.bus_geodata) net.line_geodata = pd.DataFrame.from_dict(net.line_geodata) - geo.convert_geodata_to_geojson(net) + convert_geodata_to_geojson(net) def _restore_index_names(net): diff --git a/pandapower/converter/cim/cim2pp/build_pp_net.py b/pandapower/converter/cim/cim2pp/build_pp_net.py index 4686fc9b2..20d3e0b13 100644 --- a/pandapower/converter/cim/cim2pp/build_pp_net.py +++ b/pandapower/converter/cim/cim2pp/build_pp_net.py @@ -8,8 +8,10 @@ import pandas as pd -import pandapower as pp -import pandapower.auxiliary +from pandapower.toolbox.grid_modification import fuse_buses +from pandapower.run import runpp +from pandapower.create import create_empty_network +from pandapower.auxiliary import pandapowerNet from .convert_measurements import CreateMeasurements from .. import cim_classes from .. import cim_tools @@ -28,7 +30,7 @@ def __init__(self, cim_parser: cim_classes.CimParser, converter_classes: Dict, * self.cim_parser: cim_classes.CimParser = cim_parser self.kwargs = kwargs self.cim: Dict[str, Dict[str, pd.DataFrame]] = self.cim_parser.get_cim_dict() - self.net: pandapower.auxiliary.pandapowerNet = pp.create_empty_network() + self.net: pandapowerNet = create_empty_network() self.bus_merge: pd.DataFrame = pd.DataFrame() self.power_trafo2w: pd.DataFrame = pd.DataFrame() self.power_trafo3w: pd.DataFrame = pd.DataFrame() @@ -66,9 +68,9 @@ def copy_to_pp(self, pp_type: str, input_df: pd.DataFrame): ignore_index=True, sort=False) # noinspection PyShadowingNames - def convert_to_pp(self, convert_line_to_switch: bool = False, line_r_limit: float = 0.1, - line_x_limit: float = 0.1, **kwargs) \ - -> pandapower.auxiliary.pandapowerNet: + def convert_to_pp( + self, convert_line_to_switch: bool = False, line_r_limit: float = 0.1, line_x_limit: float = 0.1, **kwargs + ) -> pandapowerNet: """ Build the pandapower net. @@ -167,7 +169,7 @@ def convert_to_pp(self, convert_line_to_switch: bool = False, line_r_limit: floa level=LogLevel.INFO, code=ReportCode.INFO, message="Running a power flow.")) if kwargs.get('run_powerflow', False): try: - pp.runpp(self.net) + runpp(self.net) except Exception as e: self.logger.error("Failed running a powerflow.") self.logger.exception(e) @@ -216,7 +218,7 @@ def convert_to_pp(self, convert_line_to_switch: bool = False, line_r_limit: floa if bus_drop.index.size > 0: for b1, b2 in bus_drop[['b1', 'b2']].itertuples(index=False): self.logger.info("Fusing buses: b1: %s, b2: %s" % (b1, b2)) - pp.fuse_buses(self.net, b1, b2, drop=True, fuse_bus_measurements=True) + fuse_buses(self.net, b1, b2, drop=True, fuse_bus_measurements=True) # finally a fix for EquivalentInjections: If an EquivalentInjection is attached to boundary node, check if the # network behind this boundary node is attached. In this case, disable the EquivalentInjection. ward_t = self.net.ward.copy() diff --git a/pandapower/converter/cim/cim2pp/convert_measurements.py b/pandapower/converter/cim/cim2pp/convert_measurements.py index 35bbbc0e7..f4b24cca9 100644 --- a/pandapower/converter/cim/cim2pp/convert_measurements.py +++ b/pandapower/converter/cim/cim2pp/convert_measurements.py @@ -7,13 +7,13 @@ from typing import Dict import pandas as pd import numpy as np -import pandapower.auxiliary +from pandapower.auxiliary import pandapowerNet from .. import cim_tools class CreateMeasurements: - def __init__(self, net: pandapower.auxiliary.pandapowerNet, cim: Dict): + def __init__(self, net: pandapowerNet, cim: Dict): self.logger = logging.getLogger(self.__class__.__name__) self.net = net self.cim = cim diff --git a/pandapower/converter/cim/cim2pp/converter_classes/transformers/tapController.py b/pandapower/converter/cim/cim2pp/converter_classes/transformers/tapController.py index a940d5d44..7eaaa538a 100644 --- a/pandapower/converter/cim/cim2pp/converter_classes/transformers/tapController.py +++ b/pandapower/converter/cim/cim2pp/converter_classes/transformers/tapController.py @@ -4,7 +4,7 @@ import pandas as pd -import pandapower.auxiliary +from pandapower.control.util.auxiliary import create_trafo_characteristics from pandapower.control.controller.trafo.ContinuousTapControl import ContinuousTapControl from pandapower.control.controller.trafo.DiscreteTapControl import DiscreteTapControl from pandapower.converter.cim import cim_tools @@ -59,7 +59,7 @@ def _create_characteristic_object(self, net, trafo_type: str, trafo_id: List, ch for variable in ['vkr_percent', 'vk_percent', 'vk_hv_percent', 'vkr_hv_percent', 'vk_mv_percent', 'vkr_mv_percent', 'vk_lv_percent', 'vkr_lv_percent']: if variable in characteristic_df.columns: - pandapower.control.create_trafo_characteristics(net, trafo_type, trafo_id, variable, + create_trafo_characteristics(net, trafo_type, trafo_id, variable, [characteristic_df['step'].to_list()], [characteristic_df[variable].to_list()]) diff --git a/pandapower/converter/cim/cim2pp/from_cim.py b/pandapower/converter/cim/cim2pp/from_cim.py index d93dd8d21..152cd928d 100644 --- a/pandapower/converter/cim/cim2pp/from_cim.py +++ b/pandapower/converter/cim/cim2pp/from_cim.py @@ -5,11 +5,12 @@ import logging import time from typing import Union, List, Type, Dict -import pandapower.auxiliary + +from pandapower.auxiliary import pandapowerNet from . import build_pp_net +from . import converter_classes as std_converter_classes from .. import cim_classes from .. import interfaces -from . import converter_classes as std_converter_classes logger = logging.getLogger('cim.cim2pp.from_cim') @@ -21,7 +22,7 @@ def from_cim_dict(cim_parser: cim_classes.CimParser, log_debug=False, convert_li repair_pp: Union[str, interfaces.PandapowerRepair] = None, repair_pp_class: Type[interfaces.PandapowerRepair] = None, custom_converter_classes: Dict = None, - **kwargs) -> pandapower.auxiliary.pandapowerNet: + **kwargs) -> pandapowerNet: """ Create a pandapower net from a CIM data structure. @@ -62,7 +63,7 @@ def from_cim_dict(cim_parser: cim_classes.CimParser, log_debug=False, convert_li def get_converter_classes(): - converter_classes: Dict[str,classmethod] = { + converter_classes: Dict[str, classmethod] = { 'ConnectivityNodesCim16': std_converter_classes.connectivitynodes.connectivityNodesCim16.ConnectivityNodesCim16, 'externalNetworkInjectionsCim16': std_converter_classes.externalnetworks.externalNetworkInjectionsCim16.ExternalNetworkInjectionsCim16, @@ -101,8 +102,7 @@ def from_cim(file_list: List[str] = None, encoding: str = None, convert_line_to_ repair_pp: Union[str, interfaces.PandapowerRepair] = None, repair_pp_class: Type[interfaces.PandapowerRepair] = None, custom_converter_classes: Dict = None, - cgmes_version: str = '2.4.15', **kwargs) -> \ - pandapower.auxiliary.pandapowerNet: + cgmes_version: str = '2.4.15', **kwargs) -> pandapowerNet: # Nur zum Testen, kann wieder gelöscht werden """ Convert a CIM net to a pandapower net from XML files. diff --git a/pandapower/converter/cim/pp_classes.py b/pandapower/converter/cim/pp_classes.py index f78211cb0..92017894a 100644 --- a/pandapower/converter/cim/pp_classes.py +++ b/pandapower/converter/cim/pp_classes.py @@ -5,22 +5,23 @@ import logging from typing import Dict import json -import pandapower as pp -import pandapower.auxiliary from . import cim_tools +from pandapower.diagnostic import diagnostic +from pandapower.auxiliary import pandapowerNet + class PandapowerDiagnostic: """ Create a pandapower diagnostic dictionary with CIM IDs instead of pandapower IDs. :param net: The pandapower network. - :param diagnostic: The pandapower diagnostic. If None a pp.diagnostic(net) will be run. Optional, default: None. + :param diagnostic_: The pandapower diagnostic. If None a pp.diagnostic(net) will be run. Optional, default: None. :return: The pandapower diagnostic with CIM IDs. """ - def __init__(self, net: pandapower.auxiliary.pandapowerNet, diagnostic: Dict = None): + def __init__(self, net: pandapowerNet, diagnostic_: Dict = None): self.logger = logging.getLogger(self.__class__.__name__) self.net = net - self.diagnostic = diagnostic + self.diagnostic = diagnostic_ def _rec_replace_pp_diagnostic_with_cim_ids(self, input_obj, element_type: str = None): sc = cim_tools.get_pp_net_special_columns_dict() @@ -73,7 +74,7 @@ def replace_pp_diagnostic_with_cim_ids(self) -> Dict: :return: The pandapower diagnostic with CIM IDs. """ if self.diagnostic is None: - self.diagnostic = pp.diagnostic(self.net) + self.diagnostic = diagnostic(self.net) result_diagnostic = dict() for key, item in self.diagnostic.items(): result_diagnostic[key] = self._rec_replace_pp_diagnostic_with_cim_ids(item) diff --git a/pandapower/converter/cim/pp_tools.py b/pandapower/converter/cim/pp_tools.py index 53de04d88..093d9f542 100644 --- a/pandapower/converter/cim/pp_tools.py +++ b/pandapower/converter/cim/pp_tools.py @@ -4,12 +4,14 @@ # and Energy System Technology (IEE), Kassel. All rights reserved. from typing import Union, Dict, List import pandas as pd -import pandapower.auxiliary -import pandapower as pp import logging import time from . import cim_tools +from pandapower.auxiliary import pandapowerNet +from pandapower.std_types import create_std_type +from pandapower.create import create_bus, create_ext_grid, create_lines + logger = logging.getLogger(__name__) @@ -21,8 +23,7 @@ def _set_column_to_type(input_df: pd.DataFrame, column: str, data_type): logger.exception(e) -def set_pp_col_types(net: Union[pandapower.auxiliary.pandapowerNet, Dict], ignore_errors: bool = False) -> \ - pandapower.auxiliary.pandapowerNet: +def set_pp_col_types(net: Union[pandapowerNet, Dict], ignore_errors: bool = False) -> pandapowerNet: """ Set the data types for some columns from pandapower assets. This mainly effects bus columns (to int, e.g. sgen.bus or line.from_bus) and in_service and other boolean columns (to bool, e.g. line.in_service or gen.slack). @@ -63,7 +64,7 @@ def set_pp_col_types(net: Union[pandapower.auxiliary.pandapowerNet, Dict], ignor return net -def add_slack_and_lines_to_boundary_nodes(net: pandapower.auxiliary.pandapowerNet, voltage_levels: List[int] = None): +def add_slack_and_lines_to_boundary_nodes(net: pandapowerNet, voltage_levels: List[int] = None): """ Add lines with low impedance and a slack to the boundary nodes with highest voltage. :param net: The pandapower network @@ -78,19 +79,19 @@ def add_slack_and_lines_to_boundary_nodes(net: pandapower.auxiliary.pandapowerNe max_voltage = busses['vn_kv'].max() logger.info("Highest voltage level: %skV" % max_voltage) voltage_levels = [max_voltage] - pp.create_std_type(net, data=dict({'r_ohm_per_km': 0, 'x_ohm_per_km': .05, 'c_nf_per_km': 0, 'max_i_ka': 9999}), + create_std_type(net, data=dict({'r_ohm_per_km': 0, 'x_ohm_per_km': .05, 'c_nf_per_km': 0, 'max_i_ka': 9999}), name='low_impedance_line', element='line') for one_voltage_level in voltage_levels: logger.info("Processing voltage level %skV" % one_voltage_level) busses_t = busses.loc[busses['vn_kv'] == one_voltage_level] - new_bus_id = pp.create_bus(net, vn_kv=one_voltage_level, + new_bus_id = create_bus(net, vn_kv=one_voltage_level, name='virtual slack bus at voltage level ' + str(one_voltage_level)) logger.info("Added virtual slack bus with ID: %s" % new_bus_id) - pp.create_ext_grid(net, bus=new_bus_id, vm_pu=1.0, + create_ext_grid(net, bus=new_bus_id, vm_pu=1.0, name='virtual slack at voltage level ' + str(one_voltage_level)) logger.info("Added slack at bus ID: %s" % new_bus_id) new_bus_id_array = [new_bus_id for _ in busses_t.index.values] - pp.create_lines(net, from_buses=busses_t.index.values, to_buses=new_bus_id_array, std_type='low_impedance_line', + create_lines(net, from_buses=busses_t.index.values, to_buses=new_bus_id_array, std_type='low_impedance_line', name='virtual line to slack node with voltage level ' + str(one_voltage_level), length_km=1) logger.info("Created %s low impedance lines." % len(busses_t.index.values)) del busses_t diff --git a/pandapower/converter/matpower/from_mpc.py b/pandapower/converter/matpower/from_mpc.py index c399ef2db..195d05755 100644 --- a/pandapower/converter/matpower/from_mpc.py +++ b/pandapower/converter/matpower/from_mpc.py @@ -4,6 +4,7 @@ # and Energy System Technology (IEE), Kassel. All rights reserved. import os + import numpy as np import pandas as pd import scipy.io @@ -12,6 +13,7 @@ try: from matpowercaseframes import CaseFrames + matpowercaseframes_imported = True except ImportError: matpowercaseframes_imported = False @@ -52,12 +54,10 @@ def from_mpc(mpc_file, f_hz=50, casename_mpc_file='mpc', validate_conversion=Fal **net** - The pandapower network EXAMPLE: - - import pandapower.converter as pc - - pp_net1 = cv.from_mpc('case9.mat', f_hz=60) - pp_net2 = cv.from_mpc('case9.m', f_hz=60) - + >>> from pandapower.converter import from_mpc + >>> + >>> pp_net1 = from_mpc('case9.mat', f_hz=60) + >>> pp_net2 = from_mpc('case9.m', f_hz=60) """ ending = os.path.splitext(os.path.basename(mpc_file))[1] if ending == ".mat": @@ -131,8 +131,8 @@ def _copy_data_from_mpc_to_ppc(ppc, mpc, casename_mpc_file): logger.info('gencost is not in mpc') for k in mpc[casename_mpc_file]._fieldnames: - if k not in ppc: - ppc.setdefault("mpc_additional_data", dict())[k] = getattr(mpc[casename_mpc_file], k) + if k not in ppc: + ppc.setdefault("mpc_additional_data", dict())[k] = getattr(mpc[casename_mpc_file], k) else: logger.error('Matfile does not contain a valid mpc structure.') diff --git a/pandapower/converter/matpower/to_mpc.py b/pandapower/converter/matpower/to_mpc.py index 4af46f736..b06981211 100644 --- a/pandapower/converter/matpower/to_mpc.py +++ b/pandapower/converter/matpower/to_mpc.py @@ -34,11 +34,11 @@ def to_mpc(net, filename=None, **kwargs): ****kwargs** - please look at to_ppc() documentation EXAMPLE: - import pandapower.converter as pc - import pandapower.networks as pn - net = pn.case9() - pc.to_mpc(net, "case9.mat") - + >>> from pandapower.converter import to_mpc + >>> from pandapower.networks.power_system_test_cases import case9 + >>> + >>> net = case9() + >>> to_mpc(net, "case9.mat") """ ppc = to_ppc(net, **kwargs) diff --git a/pandapower/converter/powerfactory/export_pfd_to_pp.py b/pandapower/converter/powerfactory/export_pfd_to_pp.py index 84dc16ad4..dc7513352 100644 --- a/pandapower/converter/powerfactory/export_pfd_to_pp.py +++ b/pandapower/converter/powerfactory/export_pfd_to_pp.py @@ -1,4 +1,4 @@ -import pandapower as pp +from pandapower.file_io import to_json, to_pickle from .echo_off import echo_off, echo_on from .logger_setup import AppHandler, set_PF_level from .pf_export_functions import run_load_flow, create_network_dict @@ -63,7 +63,7 @@ def from_pfd(app, prj_name: str, path_dst=None, pv_as_slack=False, pf_variable_p prj.Deactivate() echo_on(app) if path_dst is not None: - pp.to_json(net, path_dst) + to_json(net, path_dst) logger.info('saved net as %s', path_dst) return net @@ -105,7 +105,7 @@ def execute(app, path_src, path_dst, pv_as_slack, scale_feeder_loads=False, var_ prj.Deactivate() echo_on(app) - pp.to_pickle(net, path_dst) + to_pickle(net, path_dst) return net, trafo_name, trafo_desc diff --git a/pandapower/converter/powerfactory/main_pf.py b/pandapower/converter/powerfactory/main_pf.py index b1bd65e36..ceb1dcc2b 100644 --- a/pandapower/converter/powerfactory/main_pf.py +++ b/pandapower/converter/powerfactory/main_pf.py @@ -5,9 +5,6 @@ from tkinter.filedialog import askdirectory import pandas -import pandapower as pp -from pandapower import diagnostic - try: import pandaplan.core.pplog as logging except ImportError: @@ -16,6 +13,9 @@ logger = logging.getLogger(__name__) root_logger = logging.getLogger() +from pandapower.file_io import to_json, to_excel +from pandapower.toolbox.grid_modification import create_replacement_switch_for_branch, replace_xward_by_ward +from pandapower.diagnostic import diagnostic from pandapower.converter.powerfactory.echo_off import echo_off, echo_on from pandapower.converter.powerfactory.pp_import_functions import from_pf from pandapower.converter.powerfactory import pf_export_functions as pef @@ -70,9 +70,9 @@ def get_filename(entry_fname, save_as="JSON"): def save_net(net, filepath, save_as): if save_as == "JSON": - pp.to_json(net, filepath) + to_json(net, filepath) elif save_as == "Excel": - pp.to_excel(net, filepath) + to_excel(net, filepath) else: raise ValueError('tried to save grid as %s to %s and failed :(' % (save_as, filepath)) @@ -173,7 +173,7 @@ def calc(app, input_panel, entry_path_dst, entry_fname, pv_as_slack, export_cont to_replace = (np.abs(net.line.x_ohm_per_km * net.line.length_km) <= min_ohm) & net.line.in_service for i in net.line.loc[to_replace].index.values: - pp.create_replacement_switch_for_branch(net, "line", i) + create_replacement_switch_for_branch(net, "line", i) net.line.at[i, "in_service"] = False if np.any(to_replace): logger.info(f"replaced {sum(to_replace)} lines with switches") @@ -182,7 +182,7 @@ def calc(app, input_panel, entry_path_dst, entry_fname, pv_as_slack, export_cont # net.xward.in_service].index.values xward = net.xward[(np.abs(net.xward.x_ohm) <= min_ohm) & net.xward.in_service].index.values if len(xward) > 0: - pp.replace_xward_by_ward(net, index=xward, drop=False) + replace_xward_by_ward(net, index=xward, drop=False) logger.info(f"replaced {len(xward)} xwards with wards") zb_f_ohm = np.square(net.bus.loc[net.impedance.from_bus.values, "vn_kv"].values) / net.impedance.sn_mva @@ -193,7 +193,7 @@ def calc(app, input_panel, entry_path_dst, entry_fname, pv_as_slack, export_cont impedance = ((np.abs(net.impedance.xft_pu) <= min_ohm / zb_f_ohm) | (np.abs(net.impedance.xtf_pu) <= min_ohm / zb_t_ohm)) & net.impedance.in_service for i in net.impedance.loc[impedance].index.values: - pp.create_replacement_switch_for_branch(net, "impedance", i) + create_replacement_switch_for_branch(net, "impedance", i) net.impedance.at[i, "in_service"] = False if any(impedance): logger.info(f"replaced {sum(impedance)} impedance elements with switches") diff --git a/pandapower/converter/powerfactory/pp_import_functions.py b/pandapower/converter/powerfactory/pp_import_functions.py index cac736d4b..22d8117f3 100644 --- a/pandapower/converter/powerfactory/pp_import_functions.py +++ b/pandapower/converter/powerfactory/pp_import_functions.py @@ -10,10 +10,21 @@ import numpy as np from pandas import DataFrame -import pandapower as pp +from pandapower.auxiliary import ADict, get_free_id +from pandapower.control import ContinuousTapControl, DiscreteTapControl, create_trafo_characteristics, \ + BinarySearchControl, \ + DroopControl +from pandapower.create import create_empty_network, create_bus_dc, create_switch, create_line_from_parameters, \ + create_line_dc, create_sgen, create_gen, create_ext_grid, create_asymmetric_sgen, create_line_dc_from_parameters, \ + create_asymmetric_load, create_transformer, create_transformer_from_parameters, \ + create_transformer3w_from_parameters, create_impedance, create_xward, create_ward, \ + create_series_reactor_as_impedance from pandapower.results import reset_results -from pandapower.auxiliary import ADict -import pandapower.control as control +from pandapower.run import set_user_pf_options +from pandapower.std_types import add_zero_impedance_parameters, std_type_exists, create_std_type, available_std_types, \ + load_std_type +from pandapower.toolbox.grid_modification import set_isolated_areas_out_of_service, drop_inactive_elements, drop_buses +from pandapower.topology import create_nxgraph try: import pandaplan.core.pplog as logging @@ -57,11 +68,11 @@ def from_pf( logger.debug('collecting grid') grid_name = dict_net['ElmNet'].loc_name base_sn_mva = dict_net['global_parameters']['base_sn_mva'] - net = pp.create_empty_network(grid_name, sn_mva=base_sn_mva) + net = create_empty_network(grid_name, sn_mva=base_sn_mva) reset_results(net, mode="pf_3ph") if max_iter is not None: - pp.set_user_pf_options(net, max_iteration=max_iter) + set_user_pf_options(net, max_iteration=max_iter) logger.info('creating grid %s' % grid_name) if 'res_switch' not in net.keys(): net['res_switch'] = DataFrame(columns=['pf_closed', 'pf_in_service'], dtype='bool') @@ -172,7 +183,7 @@ def from_pf( create_trafo3w(net=net, item=trafo, tap_opt=tap_opt) if n > 0: logger.info('imported %d 3w-trafos' % n) - pp.set_user_pf_options(net, trafo3w_losses='star') + set_user_pf_options(net, trafo3w_losses='star') logger.debug('creating switches (couplings)') # create switches (ElmCoup): @@ -187,43 +198,43 @@ def from_pf( for n, fuse in enumerate(dict_net['RelFuse'], 1): create_coup(net=net, item=fuse, is_fuse=True) if n > 0: logger.info('imported %d fuses' % n) - + logger.debug('creating shunts') # create shunts (ElmShnt): n = 0 for n, shunt in enumerate(dict_net['ElmShnt'], 1): create_shunt(net=net, item=shunt) if n > 0: logger.info('imported %d shunts' % n) - + logger.debug('creating impedances') # create zpu (ElmZpu): n = 0 for n, zpu in enumerate(dict_net['ElmZpu'], 1): create_zpu(net=net, item=zpu) if n > 0: logger.info('imported %d impedances' % n) - + logger.debug('creating series inductivity as impedance') # create series inductivity as impedance (ElmSind): n = 0 for n, sind in enumerate(dict_net['ElmSind'], 1): create_sind(net=net, item=sind) if n > 0: logger.info('imported %d SIND' % n) - + logger.debug('creating series capacity as impedance') # create series capacity as impedance (ElmScap): n = 0 for n, scap in enumerate(dict_net['ElmScap'], 1): create_scap(net=net, item=scap) if n > 0: logger.info('imported %d SCAP' % n) - + logger.debug('creating static var compensator') # create static var compensator (SVC) with control same as voltage controlled synchron machine (ElmSvs): n = 0 for n, svc in enumerate(dict_net['ElmSvs'], 1): create_svc(net=net, item=svc, pv_as_slack=pv_as_slack, - pf_variable_p_gen=pf_variable_p_gen, dict_net=dict_net) + pf_variable_p_gen=pf_variable_p_gen, dict_net=dict_net) if n > 0: logger.info('imported %d SVC' % n) - + # create vac (ElmVac): n = 0 for n, vac in enumerate(dict_net['ElmVac'], 1): @@ -266,11 +277,11 @@ def from_pf( logger.info('imported %d lines' % (len(net.line.line_idx.unique())) if len(net.line) else 0) net.line['section_idx'] = 0 if dict_net['global_parameters']["iopt_tem"] == 1: - pp.set_user_pf_options(net, consider_line_temperature=True) + set_user_pf_options(net, consider_line_temperature=True) if dict_net['global_parameters']["global_load_voltage_dependency"] == 1: - pp.set_user_pf_options(net, voltage_depend_loads=True) + set_user_pf_options(net, voltage_depend_loads=True) else: - pp.set_user_pf_options(net, voltage_depend_loads=False) + set_user_pf_options(net, voltage_depend_loads=False) if len(dict_net['ElmLodlvp']) > 0: lvp_dict = get_lvp_for_lines(dict_net) @@ -318,16 +329,16 @@ def from_pf( if handle_us == "Deactivate": logger.info('deactivating unsupplied elements') - pp.set_isolated_areas_out_of_service(net) + set_isolated_areas_out_of_service(net) elif handle_us == "Drop": logger.info('dropping inactive elements') - pp.drop_inactive_elements(net) + drop_inactive_elements(net) elif handle_us != "Nothing": raise ValueError("handle_us should be 'Deactivate', 'Drop' or 'Nothing', " "received: %s" % handle_us) if is_unbalanced: - pp.add_zero_impedance_parameters(net) + add_zero_impedance_parameters(net) logger.info('imported net') return net @@ -423,10 +434,10 @@ def create_bus(net, item, flag_graphics, is_unbalanced): logger.debug(f">> creating {system_type} bus <{params['name']}>") if system_type == "ac": - bid = pp.create_bus(net, **params) + bid = create_bus(net, **params) table = "bus" elif system_type == "dc": - bid = pp.create_bus_dc(net, **params) + bid = create_bus_dc(net, **params) table = "bus_dc" else: raise NotImplementedError(f"Only buses with system type AC or DC are supported, " @@ -601,9 +612,9 @@ def get_connection_nodes(net, item, num_nodes): for b, vv in zip(buses, v): if b is None: if table == "bus": - aux_bus = pp.create_bus(net, vv, type="n", name=name) + aux_bus = create_bus(net, vv, type="n", name=name) else: - aux_bus = pp.create_bus_dc(net, vv, type="n", name=name) + aux_bus = create_bus_dc(net, vv, type="n", name=name) new_buses.append(aux_bus) logger.debug("Created new bus '%s' for disconected line " % name) else: @@ -644,11 +655,11 @@ def create_connection_switches(net, item, number_switches, et, buses, elements): switch_is_closed, switch_usage, switch_name = import_switch(item, i) logger.debug('switch closed: %s, switch_usage: %s' % (switch_is_closed, switch_usage)) if switch_is_closed is not None: - cd = pp.create_switch(net, bus=buses[i], element=elements[i], et=et, - closed=switch_is_closed, type=switch_usage, name=switch_name) + cd = create_switch(net, bus=buses[i], element=elements[i], et=et, + closed=switch_is_closed, type=switch_usage, name=switch_name) net.res_switch.loc[cd, ['pf_closed', 'pf_in_service']] = switch_is_closed, True new_switch_idx.append(cd) - new_switch_closed.append(switch_is_closed) + new_switch_closed.append(switch_is_closed) return new_switch_idx, new_switch_closed @@ -732,7 +743,7 @@ def create_line(net, item, flag_graphics, create_sections, is_unbalanced): ac = bus_table == "bus" line_table = "line" if ac else "line_dc" - corridor = pp.create.get_free_id(net[line_table]) + corridor = get_free_id(net[line_table]) line_sections = item.GetContents('*.ElmLnesec') # geodata if flag_graphics == 'no geodata': @@ -773,13 +784,14 @@ def create_line(net, item, flag_graphics, create_sections, is_unbalanced): if ac: new_elements = (sid_list[0], sid_list[-1]) - new_switch_idx, new_switch_closed = create_connection_switches(net, item, 2, 'l', (params['bus1'], params['bus2']), + new_switch_idx, new_switch_closed = create_connection_switches(net, item, 2, 'l', + (params['bus1'], params['bus2']), new_elements) - # correct in_service of lines if station switch is open - # update_in_service_depending_station_switch(net, element_type="line", - # new_elements=new_elements, + # correct in_service of lines if station switch is open + # update_in_service_depending_station_switch(net, element_type="line", + # new_elements=new_elements, # new_switch_idx=new_switch_idx, - # new_switch_closed=new_switch_closed) + # new_switch_closed=new_switch_closed) logger.debug('line <%s> created' % params['name']) @@ -917,7 +929,7 @@ def segment_buses(net, bus1, bus2, num_sections, line_name): # , sec_len, start bus_name = f"{line_name} (Muff {m})" vn_kv = net.bus.at[bus1, "vn_kv"] zone = net.bus.at[bus1, "zone"] - bus = pp.create_bus(net, name=bus_name, type='ls', vn_kv=vn_kv, zone=zone) + bus = create_bus(net, name=bus_name, type='ls', vn_kv=vn_kv, zone=zone) # TODO: implement coords for segmentation buses. # Handle coords if line has multiple coords. @@ -1022,14 +1034,14 @@ def create_line_no_sections(net, main_item, item_list, bus1, bus2, coords, is_un # max_temperature_degree_celsius = min([item.tmax for item in item_list]) temperature_degree_celsius = max([item.Top for item in item_list]) - lid = pp.create_line_from_parameters(net=net, from_bus=bus1, to_bus=bus2, length_km=total_len, - r_ohm_per_km=r_ohm_per_km, x_ohm_per_km=x_ohm_per_km, c_nf_per_km=c_nf_per_km, - max_i_ka=max_i_ka, name=line_name, type=None, geodata=coords, - g_us_per_km=g_us_per_km, alpha=alpha, parallel=main_item.nlnum, - temperature_degree_celsius=temperature_degree_celsius, - r0_ohm_per_km=r0_ohm_per_km, x0_ohm_per_km=x0_ohm_per_km, - c0_nf_per_km=c0_nf_per_km, g0_us_per_km=g0_us_per_km, - endtemp_degree=endtemp_degree) + lid = create_line_from_parameters(net=net, from_bus=bus1, to_bus=bus2, length_km=total_len, + r_ohm_per_km=r_ohm_per_km, x_ohm_per_km=x_ohm_per_km, c_nf_per_km=c_nf_per_km, + max_i_ka=max_i_ka, name=line_name, type=None, geodata=coords, + g_us_per_km=g_us_per_km, alpha=alpha, parallel=main_item.nlnum, + temperature_degree_celsius=temperature_degree_celsius, + r0_ohm_per_km=r0_ohm_per_km, x0_ohm_per_km=x0_ohm_per_km, + c0_nf_per_km=c0_nf_per_km, g0_us_per_km=g0_us_per_km, + endtemp_degree=endtemp_degree) net.line.loc[lid, 'description'] = ' \n '.join(main_item.desc) if len(main_item.desc) > 0 else '' if hasattr(main_item, "cimRdfId"): @@ -1063,9 +1075,9 @@ def create_line_normal(net, item, bus1, bus2, name, parallel, is_unbalanced, ac, params["std_type"] = std_type logger.debug('creating normal line with type <%s>' % std_type) if ac: - lid = pp.create_line(net, from_bus=bus1, to_bus=bus2, **params) + lid = create_line(net, from_bus=bus1, to_bus=bus2, **params) else: - lid = pp.create_line_dc(net, from_bus_dc=bus1, to_bus_dc=bus2, **params) + lid = create_line_dc(net, from_bus_dc=bus1, to_bus_dc=bus2, **params) else: logger.debug('creating normal line <%s> from parameters' % name) r_ohm = item.R1 @@ -1107,9 +1119,9 @@ def create_line_normal(net, item, bus1, bus2, name, parallel, is_unbalanced, ac, else: params['type'] = None - lid = pp.create_line_from_parameters(net=net, from_bus=bus1, to_bus=bus2, **params) + lid = create_line_from_parameters(net=net, from_bus=bus1, to_bus=bus2, **params) else: - lid = pp.create_line_dc_from_parameters(net, from_bus_dc=bus1, to_bus_dc=bus2, **params) + lid = create_line_dc_from_parameters(net, from_bus_dc=bus1, to_bus_dc=bus2, **params) net["line" if ac else "line_dc"].loc[lid, 'description'] = ' \n '.join(item.desc) if len(item.desc) > 0 else '' if hasattr(item, "cimRdfId"): @@ -1163,7 +1175,7 @@ def create_line_type(net, item, cable_in_air=False): pf_folder = item.fold_id.loc_name name = "%s\\%s" % (pf_folder, item.loc_name) if not cable_in_air else "%s\\%s_%s" % ( pf_folder, item.loc_name, 'air') - if pp.std_type_exists(net, name, "line" if ac else "line_dc"): + if std_type_exists(net, name, "line" if ac else "line_dc"): logger.debug('type <%s> exists already' % name) return name, False @@ -1184,7 +1196,7 @@ def create_line_type(net, item, cable_in_air=False): "c0_nf_per_km": item.cline0 * item.frnom / 50 * 1e3, # internal unit for C in PF is uF "alpha": item.alpha } - pp.create_std_type(net, type_data, name, "line") + create_std_type(net, type_data, name, "line") logger.debug('>> created line type <%s>' % name) else: type_data = { @@ -1194,7 +1206,7 @@ def create_line_type(net, item, cable_in_air=False): "type": line_or_cable, "alpha": item.alpha } - pp.create_std_type(net, type_data, name, "line_dc") + create_std_type(net, type_data, name, "line_dc") logger.debug('>> created line_dc type <%s>' % name) return name, True @@ -1249,21 +1261,21 @@ def create_ext_net(net, item, pv_as_slack, is_unbalanced): # create... if node_type == 'PQ': logger.debug('node type is "PQ", creating sgen') - xid = pp.create_sgen(net, bus1, p_mw=p_mw, q_mvar=q_mvar, name=name, - in_service=in_service) + xid = create_sgen(net, bus1, p_mw=p_mw, q_mvar=q_mvar, name=name, + in_service=in_service) elm = 'sgen' elif node_type == 'PV' and not pv_as_slack: logger.debug('node type is "PV" and pv_as_slack is False, creating gen') - xid = pp.create_gen(net, bus1, p_mw=p_mw, vm_pu=vm_set_pu, name=name, - in_service=in_service) + xid = create_gen(net, bus1, p_mw=p_mw, vm_pu=vm_set_pu, name=name, + in_service=in_service) elm = 'gen' else: logger.debug('node type is <%s>, pv_as_slack=%s, creating ext_grid' % (node_type, pv_as_slack)) - xid = pp.create_ext_grid(net, bus=bus1, name=name, vm_pu=vm_set_pu, - va_degree=phi, s_sc_max_mva=s_max, - s_sc_min_mva=s_min, rx_max=rx_max, rx_min=rx_min, - in_service=in_service) + xid = create_ext_grid(net, bus=bus1, name=name, vm_pu=vm_set_pu, + va_degree=phi, s_sc_max_mva=s_max, + s_sc_min_mva=s_min, rx_max=rx_max, rx_min=rx_min, + in_service=in_service) try: net.ext_grid.loc[xid, "r0x0_max"] = item.r0tx0 net.ext_grid.loc[xid, "x0x_max"] = item.x0tx1 @@ -1542,15 +1554,15 @@ def split_line_add_bus(net, split_dict): for i in range(len(len_sections)): # create bus name = 'Muff Partial Load' - bus = pp.create_bus(net, name=name, vn_kv=vn_kv, geodata=list_bus_coords[i]) + bus = create_bus(net, name=name, vn_kv=vn_kv, geodata=list_bus_coords[i]) # create new line from_bus = net.line.at[lix, 'from_bus'] to_bus = net.line.at[lix, 'to_bus'] std_type = net.line.at[lix, 'std_type'] name = net.line.at[lix, 'name'] - new_lix = pp.create_line(net, from_bus=from_bus, to_bus=to_bus, - length_km=len_sections[i], - std_type=std_type, name=name) + new_lix = create_line(net, from_bus=from_bus, to_bus=to_bus, + length_km=len_sections[i], + std_type=std_type, name=name) # change old line net.line.at[lix, 'to_bus'] = bus net.line.at[lix, 'length_km'] = net.line.at[lix, 'length_km'] - len_sections[i] @@ -1656,12 +1668,12 @@ def split_line_add_bus_old(net, item, parent): # create new bus vn_kv = net.bus.at[net.line.at[sid, 'from_bus'], 'vn_kv'] name = 'LodLV-%s' % item.loc_name - bus = pp.create_bus(net, vn_kv=vn_kv, name=name, geodata=bus_coords, type='n') + bus = create_bus(net, vn_kv=vn_kv, name=name, geodata=bus_coords, type='n') net.bus.loc[bus, 'description'] = 'Partial load %s = %.3f kW' % (item.loc_name, item.plini) logger.debug('created new bus in net: %s' % net.bus.loc[bus]) # create new line - lid = pp.create_line( + lid = create_line( net, from_bus=bus, to_bus=net.line.at[sid, 'to_bus'], @@ -1800,9 +1812,9 @@ def create_load(net, item, pf_variable_p_loads, dict_net, is_unbalanced): # net, bus, p_mw, q_mvar=0, sn_mva=np.nan, name=None, scaling=1., index=None, # in_service=True, type=None if is_unbalanced: - ld = pp.create_asymmetric_load(net, **params) + ld = create_asymmetric_load(net, **params) else: - ld = pp.create_load(net, **params) + ld = create_load(net, **params) logger.debug('created load with index <%d>' % ld) except Exception as err: logger.error('While creating %s.%s, error occured: %s' % (params.name, load_class, err)) @@ -1989,18 +2001,18 @@ def create_sgen_genstat(net, item, pv_as_slack, pf_variable_p_gen, dict_net, is_ logger.debug('av_mode: %s - creating as gen' % av_mode) params.vm_pu = item.usetp del params['q_mvar'] - + # add reactive and active power limits params.min_q_mvar = item.cQ_min params.max_q_mvar = item.cQ_max params.min_p_mw = item.Pmin_uc params.max_p_mw = item.Pmax_uc - - sg = pp.create_gen(net, **params) + + sg = create_gen(net, **params) element = 'gen' else: if is_unbalanced: - sg = pp.create_asymmetric_sgen(net, **params) + sg = create_asymmetric_sgen(net, **params) element = "asymmetric_sgen" else: # add reactive and active power limits @@ -2008,8 +2020,8 @@ def create_sgen_genstat(net, item, pv_as_slack, pf_variable_p_gen, dict_net, is_ params.max_q_mvar = item.cQ_max params.min_p_mw = item.Pmin_uc params.max_p_mw = item.Pmax_uc - - sg = pp.create_sgen(net, **params) + + sg = create_sgen(net, **params) element = 'sgen' logger.debug('created sgen at index <%d>' % sg) @@ -2032,11 +2044,11 @@ def create_sgen_genstat(net, item, pv_as_slack, pf_variable_p_gen, dict_net, is_ # # net, bus, p_mw, q_mvar=0, sn_mva=np.nan, name=None, scaling=1., index=None, # # in_service=True, type=None # if is_unbalanced: -# sg = pp.create_asymmetric_sgen(net, **params) +# sg = create_asymmetric_sgen(net, **params) # logger.info("CREATING UNBALANCED SGEN") # else: # logger.info("CREATING BALANCED SGEN") -# sg = pp.create_sgen_genstat(net, **params) +# sg = create_sgen_genstat(net, **params) # logger.debug('created sgen with index <%d>' % sg) # except Exception as err: # logger.error('While creating %s.%s, error occured: %s' % (params.name, sgen_class, err)) @@ -2125,7 +2137,7 @@ def create_sgen_neg_load(net, item, pf_variable_p_loads, dict_net): params.in_service = monopolar_in_service(item) # create... - sg = pp.create_sgen(net, **params) + sg = create_sgen(net, **params) net.sgen.loc[sg, 'description'] = ' \n '.join(item.desc) if len(item.desc) > 0 else '' add_additional_attributes(item, net, "sgen", sg, attr_dict={"for_name": "equipment"}, @@ -2214,31 +2226,31 @@ def create_sgen_sym(net, item, pv_as_slack, pf_variable_p_gen, dict_net, export_ logger.debug('creating sym %s as gen' % name) vm_pu = item.usetp if item.iqtype == 1: - type = item.typ_id - sid = pp.create_gen(net, bus=bus1, p_mw=p_mw, vm_pu=vm_pu, - min_q_mvar=type.Q_min, max_q_mvar=type.Q_max, - min_p_mw=item.Pmin_uc, max_p_mw=item.Pmax_uc, - name=name, type=cat, in_service=in_service, scaling=global_scaling) + type = item.typ_id + sid = create_gen(net, bus=bus1, p_mw=p_mw, vm_pu=vm_pu, + min_q_mvar=type.Q_min, max_q_mvar=type.Q_max, + min_p_mw=item.Pmin_uc, max_p_mw=item.Pmax_uc, + name=name, type=cat, in_service=in_service, scaling=global_scaling) else: - sid = pp.create_gen(net, bus=bus1, p_mw=p_mw, vm_pu=vm_pu, - min_q_mvar=item.cQ_min, max_q_mvar=item.cQ_max, - min_p_mw=item.Pmin_uc, max_p_mw=item.Pmax_uc, - name=name, type=cat, in_service=in_service, scaling=global_scaling) + sid = create_gen(net, bus=bus1, p_mw=p_mw, vm_pu=vm_pu, + min_q_mvar=item.cQ_min, max_q_mvar=item.cQ_max, + min_p_mw=item.Pmin_uc, max_p_mw=item.Pmax_uc, + name=name, type=cat, in_service=in_service, scaling=global_scaling) element = 'gen' elif av_mode == 'constq': q_mvar = ngnum * item.qgini * multiplier if item.iqtype == 1: - type = item.typ_id - sid = pp.create_sgen(net, bus=bus1, p_mw=p_mw, q_mvar=q_mvar, - min_q_mvar=type.Q_min, max_q_mvar=type.Q_max, - min_p_mw=item.Pmin_uc, max_p_mw=item.Pmax_uc, - name=name, type=cat, in_service=in_service, scaling=global_scaling) + type = item.typ_id + sid = create_sgen(net, bus=bus1, p_mw=p_mw, q_mvar=q_mvar, + min_q_mvar=type.Q_min, max_q_mvar=type.Q_max, + min_p_mw=item.Pmin_uc, max_p_mw=item.Pmax_uc, + name=name, type=cat, in_service=in_service, scaling=global_scaling) else: - sid = pp.create_sgen(net, bus=bus1, p_mw=p_mw, q_mvar=q_mvar, - min_q_mvar=item.cQ_min, max_q_mvar=item.cQ_max, - min_p_mw=item.Pmin_uc, max_p_mw=item.Pmax_uc, - name=name, type=cat, in_service=in_service, scaling=global_scaling) - + sid = create_sgen(net, bus=bus1, p_mw=p_mw, q_mvar=q_mvar, + min_q_mvar=item.cQ_min, max_q_mvar=item.cQ_max, + min_p_mw=item.Pmin_uc, max_p_mw=item.Pmax_uc, + name=name, type=cat, in_service=in_service, scaling=global_scaling) + element = 'sgen' if sid is None or element is None: @@ -2298,7 +2310,7 @@ def create_sgen_asm(net, item, pf_variable_p_gen, dict_net): logger.debug('params: %s' % params) - sid = pp.create_sgen(net, **params) + sid = create_sgen(net, **params) net.sgen.loc[sid, 'description'] = ' \n '.join(item.desc) if len(item.desc) > 0 else '' add_additional_attributes(item, net, "sgen", sid, attr_dict={"for_name": "equipment", "cimRdfId": "origin_id"}, @@ -2323,7 +2335,7 @@ def create_trafo_type(net, item): pf_folder = item.fold_id.loc_name name = "%s\\%s" % (pf_folder, item.loc_name) - if pp.std_type_exists(net, name): + if std_type_exists(net, name): logger.debug('trafo type <%s> already exists' % name) return name, False @@ -2383,7 +2395,7 @@ def create_trafo_type(net, item): if 'tap_side' in type_data.keys() and (type_data.get('tap_side') == 'ext' or type_data.get('tap_side') == 'ext'): logger.warning('controlled node of trafo "EXT" not implemented (type <%s>)' % name) - pp.create_std_type(net, type_data, name, "trafo") + create_std_type(net, type_data, name, "trafo") logger.debug('created trafo type <%s> with params: %s' % (name, type_data)) return name, True @@ -2435,15 +2447,15 @@ def create_trafo(net, item, export_controller=True, tap_opt="nntap", is_unbalanc tap_pos2 = item.GetAttribute("c:nntap2") if std_type is not None: - tid = pp.create_transformer(net, hv_bus=bus1, lv_bus=bus2, name=name, - std_type=std_type, tap_pos=tap_pos, - in_service=in_service, parallel=item.ntnum, df=item.ratfac, tap2_pos=tap_pos2, - leakage_resistance_ratio_hv=pf_type.itrdr, leakage_reactance_ratio_hv=pf_type.itrdl) + tid = create_transformer(net, hv_bus=bus1, lv_bus=bus2, name=name, + std_type=std_type, tap_pos=tap_pos, + in_service=in_service, parallel=item.ntnum, df=item.ratfac, tap2_pos=tap_pos2, + leakage_resistance_ratio_hv=pf_type.itrdr, leakage_reactance_ratio_hv=pf_type.itrdl) trafo_dict[item] = tid logger.debug('created trafo at index <%d>' % tid) else: logger.info("Create Trafo 3ph") - tid = pp.create_transformer_from_parameters( + tid = create_transformer_from_parameters( net, hv_bus=bus1, lv_bus=bus2, @@ -2478,15 +2490,15 @@ def create_trafo(net, item, export_controller=True, tap_opt="nntap", is_unbalanc get_pf_trafo_results(net, item, tid, is_unbalanced) # adding switches - # False if open, True if closed, None if no switch + # False if open, True if closed, None if no switch new_elements = (tid, tid) - new_switch_idx, new_switch_closed = create_connection_switches(net, item, 2, 't', (bus1, bus2), + new_switch_idx, new_switch_closed = create_connection_switches(net, item, 2, 't', (bus1, bus2), new_elements) - # correct in_service of trafo if station switch is open - # update_in_service_depending_station_switch(net, element_type="trafo", - # new_elements=new_elements, + # correct in_service of trafo if station switch is open + # update_in_service_depending_station_switch(net, element_type="trafo", + # new_elements=new_elements, # new_switch_idx=new_switch_idx, - # new_switch_closed=new_switch_closed) + # new_switch_closed=new_switch_closed) # adding tap changer if (export_controller and pf_type.itapch and item.HasAttribute('ntrcn') and @@ -2502,11 +2514,10 @@ def create_trafo(net, item, export_controller=True, tap_opt="nntap", is_unbalanc logger.debug('trafo <%s> has continuous tap controller with vm_set_pu = %.3f, side = %s' % (name, vm_set_pu, side)) try: - tap_changer = control.ContinuousTapControl(net, tid, side=side, vm_set_pu=vm_set_pu) + ContinuousTapControl(net, tid, side=side, vm_set_pu=vm_set_pu) except BaseException as err: logger.error('error while creating continuous tap controller at trafo <%s>' % name) logger.error('Error: %s' % err) - tap_changer = None else: logger.debug('created discrete tap controller at trafo <%s>' % name) else: @@ -2515,8 +2526,8 @@ def create_trafo(net, item, export_controller=True, tap_opt="nntap", is_unbalanc logger.debug('trafo <%s> has discrete tap controller with ' 'u_low = %.3f, u_up = %.3f, side = %s' % (name, vm_lower_pu, vm_upper_pu, side)) try: - control.DiscreteTapControl(net, tid, side=side, vm_lower_pu=vm_lower_pu, vm_upper_pu=vm_upper_pu, - hunting_limit=hunting_limit) + DiscreteTapControl(net, tid, side=side, vm_lower_pu=vm_lower_pu, vm_upper_pu=vm_upper_pu, + hunting_limit=hunting_limit) except BaseException as err: logger.error('error while creating discrete tap controller at trafo <%s>' % name) logger.error('Error: %s' % err) @@ -2534,10 +2545,10 @@ def create_trafo(net, item, export_controller=True, tap_opt="nntap", is_unbalanc # todo # vk0_min, vk0_max = pf_type.uk0tmn, pf_type.uk0tmx # vkr0_min, vkr0_max = pf_type.uk0rtmn, pf_type.uk0rtmx - pp.control.create_trafo_characteristics(net, trafotable="trafo", trafo_index=tid, variable="vk_percent", - x_points=x_points, y_points=(vk_min, vk_neutral, vk_max)) - pp.control.create_trafo_characteristics(net, trafotable="trafo", trafo_index=tid, variable="vkr_percent", - x_points=x_points, y_points=(vkr_min, vkr_neutral, vkr_max)) + create_trafo_characteristics(net, trafotable="trafo", trafo_index=tid, variable="vk_percent", + x_points=x_points, y_points=(vk_min, vk_neutral, vk_max)) + create_trafo_characteristics(net, trafotable="trafo", trafo_index=tid, variable="vkr_percent", + x_points=x_points, y_points=(vkr_min, vkr_neutral, vkr_max)) def get_pf_trafo_results(net, item, tid, is_unbalanced): @@ -2654,19 +2665,19 @@ def create_trafo3w(net, item, tap_opt='nntap'): logger.debug('collected params: %s' % params) logger.debug('creating trafo3w from parameters') - tid = pp.create_transformer3w_from_parameters(net, **params) # type:int + tid = create_transformer3w_from_parameters(net, **params) # type:int # adding switches # False if open, True if closed, None if no switch new_elements = (tid, tid, tid) new_switch_idx, new_switch_closed = create_connection_switches(net, item, 3, 't3', (bus1, bus2, bus3), new_elements) - - # correct in_service of trafo3w if station switch is open - # update_in_service_depending_station_switch(net, element_type="trafo3w", - # new_elements=new_elements, + + # correct in_service of trafo3w if station switch is open + # update_in_service_depending_station_switch(net, element_type="trafo3w", + # new_elements=new_elements, # new_switch_idx=new_switch_idx, - # new_switch_closed=new_switch_closed) + # new_switch_closed=new_switch_closed) logger.debug('successfully created trafo3w from parameters: %d' % tid) # testen @@ -2702,12 +2713,12 @@ def create_trafo3w(net, item, tap_opt='nntap'): vkr_neutral = net.trafo3w.at[tid, f"vkr_{side}_percent"] vkr_max = pf_type.GetAttribute(f"uktrr3mx_{side[0]}") # todo zero-sequence parameters (must be implemented in build_branch first) - pp.control.create_trafo_characteristics(net, trafotable="trafo3w", trafo_index=tid, - variable=f"vk_{side}_percent", x_points=x_points, - y_points=(vk_min, vk_neutral, vk_max)) - pp.control.create_trafo_characteristics(net, trafotable="trafo3w", trafo_index=tid, - variable=f"vkr_{side}_percent", x_points=x_points, - y_points=(vkr_min, vkr_neutral, vkr_max)) + create_trafo_characteristics(net, trafotable="trafo3w", trafo_index=tid, + variable=f"vk_{side}_percent", x_points=x_points, + y_points=(vk_min, vk_neutral, vk_max)) + create_trafo_characteristics(net, trafotable="trafo3w", trafo_index=tid, + variable=f"vkr_{side}_percent", x_points=x_points, + y_points=(vkr_min, vkr_neutral, vkr_max)) def propagate_bus_coords(net, bus1, bus2): @@ -2738,9 +2749,9 @@ def create_coup(net, item, is_fuse=False): switch_is_closed = switch_is_closed and in_service switch_usage = switch_types.get(item.aUsage, 'unknown') - cd = pp.create_switch(net, name=name, bus=bus1, element=bus2, et='b', - closed=switch_is_closed, - type=switch_usage) + cd = create_switch(net, name=name, bus=bus1, element=bus2, et='b', + closed=switch_is_closed, + type=switch_usage) switch_dict[item] = cd add_additional_attributes(item, net, element='switch', element_id=cd, @@ -2774,7 +2785,7 @@ def create_coup(net, item, is_fuse=False): # switch_is_closed = bool(item.GetAttribute('on_off')) # switch_usage = switch_types[item.GetAttribute('aUsage')] # -# cd = pp.create_switch(net, name=name, bus=bus1, element=bus2, et='b', +# cd = create_switch(net, name=name, bus=bus1, element=bus2, et='b', # closed=switch_is_closed, type=switch_usage) # logger.debug('created switch at index <%d>, closed = %s, usage = %s' % (cd, # switch_is_closed, switch_usage)) @@ -2817,8 +2828,8 @@ def calc_p_mw_and_q_mvar(r: float, x: float) -> tuple[float, float]: x_val = item.xrea elif item.shtype == 2: # Shunt is a capacitor bank - b = item.bcap*1e-6 - g = item.gparac*1e-6 + b = item.bcap * 1e-6 + g = item.gparac * 1e-6 r_val = g / (g ** 2 + b ** 2) x_val = -b / (g ** 2 + b ** 2) @@ -2845,7 +2856,7 @@ def calc_p_mw_and_q_mvar(r: float, x: float) -> tuple[float, float]: if 0 <= item.shtype <= 4: p_mw, params['q_mvar'] = calc_p_mw_and_q_mvar(r_val, x_val) - sid = pp.create_shunt(net, p_mw=p_mw, **params) + sid = create_shunt(net, p_mw=p_mw, **params) add_additional_attributes( item, @@ -2867,7 +2878,7 @@ def calc_p_mw_and_q_mvar(r: float, x: float) -> tuple[float, float]: def _add_shunt_to_impedance_bus(net, item, bus): - pp.create_shunt(net, bus, -item.bi_pu * net.sn_mva, p_mw=-item.gi_pu * net.sn_mva) + create_shunt(net, bus, -item.bi_pu * net.sn_mva, p_mw=-item.gi_pu * net.sn_mva) def create_zpu(net, item): @@ -2904,48 +2915,48 @@ def create_zpu(net, item): } logger.debug('params = %s' % params) - + # create auxilary buses - aux_bus1 = pp.create_bus(net, vn_kv=net.bus.vn_kv.at[bus1], name=net.bus.name.at[bus1]+'_aux', - type="b", zone=net.bus.zone.at[bus1], in_service=True) + aux_bus1 = create_bus(net, vn_kv=net.bus.vn_kv.at[bus1], name=net.bus.name.at[bus1] + '_aux', + type="b", zone=net.bus.zone.at[bus1], in_service=True) net.bus.loc[aux_bus1, 'geo'] = net.bus.geo.at[bus1] params['from_bus'] = aux_bus1 - aux_bus2 = pp.create_bus(net, vn_kv=net.bus.vn_kv.at[bus2], name=net.bus.name.at[bus2]+'_aux', - type="b", zone=net.bus.zone.at[bus2], in_service=True) + aux_bus2 = create_bus(net, vn_kv=net.bus.vn_kv.at[bus2], name=net.bus.name.at[bus2] + '_aux', + type="b", zone=net.bus.zone.at[bus2], in_service=True) net.bus.loc[aux_bus2, 'geo'] = net.bus.geo.at[bus2] params['to_bus'] = aux_bus2 - - xid = pp.create_impedance(net, **params) + + xid = create_impedance(net, **params) add_additional_attributes(item, net, element='impedance', element_id=xid, attr_list=["cpSite.loc_name"], attr_dict={"cimRdfId": "origin_id"}) - + # consider and create station switches new_elements = (aux_bus1, aux_bus2) new_switch_idx, new_switch_closed = create_connection_switches(net, item, 2, 'b', (bus1, bus2), new_elements) - - if len(new_switch_idx)==0: + + if len(new_switch_idx) == 0: net.impedance.loc[xid, 'from_bus'] = bus1 net.impedance.loc[xid, 'to_bus'] = bus2 # drop auxilary buses, not needed - pp.drop_buses(net, buses=[aux_bus1, aux_bus2]) - elif len(new_switch_idx)==1: + drop_buses(net, buses=[aux_bus1, aux_bus2]) + elif len(new_switch_idx) == 1: sw_bus = net.switch.loc[new_switch_idx[0], 'bus'] - if sw_bus==bus1: + if sw_bus == bus1: net.impedance.loc[xid, 'to_bus'] = bus2 # drop one auxilary bus, where no switch exists, not needed - pp.drop_buses(net, buses=[aux_bus2]) - elif sw_bus==bus2: + drop_buses(net, buses=[aux_bus2]) + elif sw_bus == bus2: net.impedance.loc[xid, 'from_bus'] = bus1 # drop one auxilary bus, where no switch exists, not needed - pp.drop_buses(net, buses=[aux_bus1]) - - # correct in_service of series reactor if station switch is open - # update_in_service_depending_station_switch(net, element_type="impedance", - # new_elements=new_elements, + drop_buses(net, buses=[aux_bus1]) + + # correct in_service of series reactor if station switch is open + # update_in_service_depending_station_switch(net, element_type="impedance", + # new_elements=new_elements, # new_switch_idx=new_switch_idx, # new_switch_closed=new_switch_closed) - + logger.debug('created ZPU %s as impedance at index %d' % (net.impedance.at[xid, 'name'], xid)) @@ -2959,7 +2970,7 @@ def create_vac(net, item): except IndexError: logger.error("Cannot add VAC '%s': not connected" % item.loc_name) return - + in_service = monopolar_in_service(item) params = { 'name': item.loc_name, @@ -2984,12 +2995,12 @@ def create_vac(net, item): logger.warning("Element %s has x_ohm == 0, setting to 1e-6. Check impedance of the " "created xward" % item.loc_name) - xid = pp.create_xward(net, **params) + xid = create_xward(net, **params) elm = 'xward' elif item.itype == 2: # ward - xid = pp.create_ward(net, **params) + xid = create_ward(net, **params) elm = 'ward' elif item.itype == 0: @@ -2998,7 +3009,7 @@ def create_vac(net, item): 'vm_pu': item.usetp, 'va_degree': item.phisetp, }) - xid = pp.create_ext_grid(net, **params) + xid = create_ext_grid(net, **params) elm = 'ext_grid' else: raise NotImplementedError( @@ -3018,12 +3029,13 @@ def create_vac(net, item): logger.debug('added pf_p and pf_q to {} {}: {}'.format(elm, xid, net['res_' + elm].loc[ xid, ["pf_p", 'pf_q']].values)) + def update_in_service_depending_station_switch(net, element_type, new_elements, new_switch_idx, new_switch_closed): ### fcn is not used! - if len(new_switch_idx)!= 0: + if len(new_switch_idx) != 0: for i in range(len(new_switch_idx)): if new_switch_closed[i] == 0: - if net[element_type].loc[new_elements[i], 'in_service']==False: + if net[element_type].loc[new_elements[i], 'in_service'] == False: continue else: net[element_type].loc[new_elements[i], 'in_service'] = False @@ -3033,6 +3045,7 @@ def update_in_service_depending_station_switch(net, element_type, new_elements, else: pass + def create_sind(net, item): # series reactor is modelled as per-unit impedance, values in Ohm are calculated into values in # per unit at creation @@ -3041,47 +3054,47 @@ def create_sind(net, item): except IndexError: logger.error("Cannot add Sind '%s': not connected" % item.loc_name) return - - # create auxilary buses - aux_bus1 = pp.create_bus(net, vn_kv=net.bus.vn_kv.at[bus1], name=net.bus.name.at[bus1]+'_aux', - type="b", zone=net.bus.zone.at[bus1], in_service=True) + + # create auxilary buses + aux_bus1 = create_bus(net, vn_kv=net.bus.vn_kv.at[bus1], name=net.bus.name.at[bus1] + '_aux', + type="b", zone=net.bus.zone.at[bus1], in_service=True) net.bus.loc[aux_bus1, 'geo'] = net.bus.geo.at[bus1] - aux_bus2 = pp.create_bus(net, vn_kv=net.bus.vn_kv.at[bus2], name=net.bus.name.at[bus2]+'_aux', - type="b", zone=net.bus.zone.at[bus2], in_service=True) + aux_bus2 = create_bus(net, vn_kv=net.bus.vn_kv.at[bus2], name=net.bus.name.at[bus2] + '_aux', + type="b", zone=net.bus.zone.at[bus2], in_service=True) net.bus.loc[aux_bus2, 'geo'] = net.bus.geo.at[bus2] - - sind = pp.create_series_reactor_as_impedance(net, from_bus=aux_bus1, to_bus=aux_bus2, - r_ohm=item.rrea, x_ohm=item.xrea, sn_mva=item.Sn, - name=item.loc_name, - in_service=not bool(item.outserv)) - + + sind = create_series_reactor_as_impedance(net, from_bus=aux_bus1, to_bus=aux_bus2, + r_ohm=item.rrea, x_ohm=item.xrea, sn_mva=item.Sn, + name=item.loc_name, + in_service=not bool(item.outserv)) + # consider and create station switches new_elements = (aux_bus1, aux_bus2) new_switch_idx, new_switch_closed = create_connection_switches(net, item, 2, 'b', (bus1, bus2), new_elements) - - if len(new_switch_idx)==0: + + if len(new_switch_idx) == 0: net.impedance.loc[sind, 'from_bus'] = bus1 net.impedance.loc[sind, 'to_bus'] = bus2 # drop auxilary buses, not needed - pp.drop_buses(net, buses=[aux_bus1, aux_bus2]) - elif len(new_switch_idx)==1: + drop_buses(net, buses=[aux_bus1, aux_bus2]) + elif len(new_switch_idx) == 1: sw_bus = net.switch.loc[new_switch_idx[0], 'bus'] - if sw_bus==bus1: + if sw_bus == bus1: net.impedance.loc[sind, 'to_bus'] = bus2 # drop one auxilary bus, where no switch exists, not needed - pp.drop_buses(net, buses=[aux_bus2]) - elif sw_bus==bus2: + drop_buses(net, buses=[aux_bus2]) + elif sw_bus == bus2: net.impedance.loc[sind, 'from_bus'] = bus1 # drop one auxilary bus, where no switch exists, not needed - pp.drop_buses(net, buses=[aux_bus1]) - - # correct in_service of series reactor if station switch is open - # update_in_service_depending_station_switch(net, element_type="impedance", - # new_elements=new_elements, + drop_buses(net, buses=[aux_bus1]) + + # correct in_service of series reactor if station switch is open + # update_in_service_depending_station_switch(net, element_type="impedance", + # new_elements=new_elements, # new_switch_idx=new_switch_idx, # new_switch_closed=new_switch_closed) - + logger.debug('created series reactor %s as per unit impedance at index %d' % (net.impedance.at[sind, 'name'], sind)) @@ -3095,95 +3108,96 @@ def create_scap(net, item): logger.error("Cannot add Scap '%s': not connected" % item.loc_name) return - if (item.gcap==0) and (item.bcap==0): + if (item.gcap == 0) and (item.bcap == 0): logger.info('not creating series capacitor for %s' % item.loc_name) else: - r_ohm = item.gcap/(item.gcap**2 + item.bcap**2) - x_ohm = -item.bcap/(item.gcap**2 + item.bcap**2) - - # create auxilary buses - aux_bus1 = pp.create_bus(net, vn_kv=net.bus.vn_kv.at[bus1], name=net.bus.name.at[bus1]+'_aux', - type="b", zone=net.bus.zone.at[bus1], in_service=True) + r_ohm = item.gcap / (item.gcap ** 2 + item.bcap ** 2) + x_ohm = -item.bcap / (item.gcap ** 2 + item.bcap ** 2) + + # create auxilary buses + aux_bus1 = create_bus(net, vn_kv=net.bus.vn_kv.at[bus1], name=net.bus.name.at[bus1] + '_aux', + type="b", zone=net.bus.zone.at[bus1], in_service=True) net.bus.loc[aux_bus1, 'geo'] = net.bus.geo.at[bus1] - aux_bus2 = pp.create_bus(net, vn_kv=net.bus.vn_kv.at[bus2], name=net.bus.name.at[bus2]+'_aux', - type="b", zone=net.bus.zone.at[bus2], in_service=True) + aux_bus2 = create_bus(net, vn_kv=net.bus.vn_kv.at[bus2], name=net.bus.name.at[bus2] + '_aux', + type="b", zone=net.bus.zone.at[bus2], in_service=True) net.bus.loc[aux_bus2, 'geo'] = net.bus.geo.at[bus2] - - scap = pp.create_series_reactor_as_impedance(net, from_bus=aux_bus1, to_bus=aux_bus2, r_ohm=r_ohm, - x_ohm=x_ohm, sn_mva=item.Sn, - name=item.loc_name, - in_service=not bool(item.outserv)) - + + scap = create_series_reactor_as_impedance(net, from_bus=aux_bus1, to_bus=aux_bus2, r_ohm=r_ohm, + x_ohm=x_ohm, sn_mva=item.Sn, + name=item.loc_name, + in_service=not bool(item.outserv)) + # consider and create station switches new_elements = (aux_bus1, aux_bus2) new_switch_idx, new_switch_closed = create_connection_switches(net, item, 2, 'b', (bus1, bus2), new_elements) - - if len(new_switch_idx)==0: + + if len(new_switch_idx) == 0: net.impedance.loc[scap, 'from_bus'] = bus1 net.impedance.loc[scap, 'to_bus'] = bus2 # drop auxilary buses, not needed - pp.drop_buses(net, buses=[aux_bus1, aux_bus2]) - elif len(new_switch_idx)==1: + drop_buses(net, buses=[aux_bus1, aux_bus2]) + elif len(new_switch_idx) == 1: sw_bus = net.switch.loc[new_switch_idx[0], 'bus'] - if sw_bus==bus1: + if sw_bus == bus1: net.impedance.loc[scap, 'to_bus'] = bus2 # drop one auxilary bus, where no switch exists, not needed - pp.drop_buses(net, buses=[aux_bus2]) - elif sw_bus==bus2: + drop_buses(net, buses=[aux_bus2]) + elif sw_bus == bus2: net.impedance.loc[scap, 'from_bus'] = bus1 # drop one auxilary bus, where no switch exists, not needed - pp.drop_buses(net, buses=[aux_bus1]) - - # correct in_service of series capacitor if station switch is open - # update_in_service_depending_station_switch(net, element_type="impedance", - # new_elements=new_elements, + drop_buses(net, buses=[aux_bus1]) + + # correct in_service of series capacitor if station switch is open + # update_in_service_depending_station_switch(net, element_type="impedance", + # new_elements=new_elements, # new_switch_idx=new_switch_idx, # new_switch_closed=new_switch_closed) logger.debug('created series capacitor %s as per unit impedance at index %d' % (net.impedance.at[scap, 'name'], scap)) - + + def create_svc(net, item, pv_as_slack, pf_variable_p_gen, dict_net): # SVC is voltage controlled and therefore modelled the same way as a voltage controlled synchron machine (gen) # TODO: at least implement a uncontrolled svc as synchron machine with const. Q - # TODO: transfer item entries for usage of pp.create_svc, x_l_ohm, x_cvar_ohm, + # TODO: transfer item entries for usage of pp.create_svc, x_l_ohm, x_cvar_ohm, # thyristor_firing_angle must be computed name = item.loc_name sid = None element = None logger.debug('>> creating synchronous machine <%s>' % name) - + try: bus1 = get_connection_nodes(net, item, 1) except IndexError: logger.error("Cannot add SVC '%s': not connected" % name) return - - if item.i_ctrl==1: # 0: no control, 1: voltage control, 2: reactive power control + + if item.i_ctrl == 1: # 0: no control, 1: voltage control, 2: reactive power control logger.debug('creating SVC %s as gen' % name) vm_pu = item.usetp in_service = monopolar_in_service(item) - svc = pp.create_gen(net, bus=bus1, p_mw=0, vm_pu=vm_pu, - name=name, type="SVC", in_service=in_service) + svc = create_gen(net, bus=bus1, p_mw=0, vm_pu=vm_pu, + name=name, type="SVC", in_service=in_service) element = 'gen' - + if svc is None or element is None: logger.error('Error! SVC not created') logger.debug('created svc at index <%s>' % svc) - + net[element].loc[svc, 'description'] = ' \n '.join(item.desc) if len(item.desc) > 0 else '' add_additional_attributes(item, net, element, svc, attr_dict={"for_name": "equipment"}, attr_list=["sernum", "chr_name", "cpSite.loc_name"]) - + if item.HasResults(0): # 'm' results... logger.debug('<%s> has results' % name) - net['res_' + element].at[svc, "pf_p"] = ga(item, 'm:P:bus1') #* multiplier - net['res_' + element].at[svc, "pf_q"] = ga(item, 'm:Q:bus1') #* multiplier + net['res_' + element].at[svc, "pf_p"] = item.GetAttribute('m:P:bus1') #* multiplier + net['res_' + element].at[svc, "pf_q"] = item.GetAttribute('m:Q:bus1') #* multiplier else: net['res_' + element].at[svc, "pf_p"] = np.nan net['res_' + element].at[svc, "pf_q"] = np.nan - else: + else: logger.info('not creating SVC for %s' % item.loc_name) @@ -3261,7 +3275,7 @@ def create_vscmono(net, item): f"VSCmono element {params['name']} has no DC resistive loss factor - power flow will not converge!" ) - vid = pp.create_vsc(net, **params) + vid = create_vsc(net, **params) logger.debug(f'created VSC {vid} for vscmono {item.loc_name}') result_variables = {"pf_p_mw": "m:P:busac", @@ -3310,8 +3324,8 @@ def create_vsc(net, item): if params["r_dc_ohm"] == 0: logger.warning(f"VSC element {params['name']} has no DC resistive loss factor - power flow will not converge!") - vid_1 = pp.create_vsc(net, bus=bus, bus_dc=bus_dc_n, **params) - vid_2 = pp.create_vsc(net, bus=bus, bus_dc=bus_dc_p, **params) + vid_1 = create_vsc(net, bus=bus, bus_dc=bus_dc_n, **params) + vid_2 = create_vsc(net, bus=bus, bus_dc=bus_dc_p, **params) logger.debug(f'created two vsc mono {vid_1}, {vid_2} for vsc {item.loc_name}') result_variables = {"pf_p_mw": "m:P:busac", @@ -3478,9 +3492,9 @@ def create_stactrl(net, item): for index in gen_element_index: output_busses.append(net.sgen.at[index, 'bus']) - top = pp.topology.create_nxgraph(net, respect_switches=True, include_lines=True, include_trafos=True, - include_impedances=True, nogobuses=None, notravbuses=None, multi=True, - calc_branch_impedances=False, branch_impedance_unit='ohm') + top = create_nxgraph(net, respect_switches=True, include_lines=True, include_trafos=True, + include_impedances=True, nogobuses=None, notravbuses=None, multi=True, + calc_branch_impedances=False, branch_impedance_unit='ohm') has_path = False for n in range(len(input_busses)): for m in range(len(output_busses)): @@ -3499,24 +3513,24 @@ def create_stactrl(net, item): v_setpoint_pu = controlled_node.vtarget # Bus target voltage if item.i_droop: # Enable Droop - bsc = pp.control.BinarySearchControl(net, ctrl_in_service=stactrl_in_service, - output_element=gen_element, output_variable="q_mvar", - output_element_index=gen_element_index, - output_element_in_service=gen_element_in_service, - output_values_distribution=distribution, - input_element=res_element_table, input_variable=variable, - input_element_index=res_element_index, - set_point=v_setpoint_pu, voltage_ctrl=True, bus_idx=bus, tol=1e-3) - pp.control.DroopControl(net, q_droop_mvar=item.Srated * 100 / item.ddroop, bus_idx=bus, - vm_set_pu=v_setpoint_pu, controller_idx=bsc.index, voltage_ctrl=True) + bsc = BinarySearchControl(net, ctrl_in_service=stactrl_in_service, + output_element=gen_element, output_variable="q_mvar", + output_element_index=gen_element_index, + output_element_in_service=gen_element_in_service, + output_values_distribution=distribution, + input_element=res_element_table, input_variable=variable, + input_element_index=res_element_index, + set_point=v_setpoint_pu, voltage_ctrl=True, bus_idx=bus, tol=1e-3) + DroopControl(net, q_droop_mvar=item.Srated * 100 / item.ddroop, bus_idx=bus, + vm_set_pu=v_setpoint_pu, controller_idx=bsc.index, voltage_ctrl=True) else: - pp.control.BinarySearchControl(net, ctrl_in_service=stactrl_in_service, - output_element=gen_element, output_variable="q_mvar", - output_element_index=gen_element_index, - output_element_in_service=gen_element_in_service, input_element="res_bus", - output_values_distribution=distribution, damping_factor=0.9, - input_variable="vm_pu", input_element_index=bus, - set_point=v_setpoint_pu, voltage_ctrl=True, tol=1e-6) + BinarySearchControl(net, ctrl_in_service=stactrl_in_service, + output_element=gen_element, output_variable="q_mvar", + output_element_index=gen_element_index, + output_element_in_service=gen_element_in_service, input_element="res_bus", + output_values_distribution=distribution, damping_factor=0.9, + input_variable="vm_pu", input_element_index=bus, + set_point=v_setpoint_pu, voltage_ctrl=True, tol=1e-6) elif control_mode == 1: # Q Control mode if item.iQorient != 0: if not stactrl_in_service: @@ -3525,7 +3539,7 @@ def create_stactrl(net, item): # q_control_mode = item.qu_char # 0: "Const Q", 1: "Q(V) Characteristic", 2: "Q(P) Characteristic" # q_control_terminal = q_control_cubicle.cterm # terminal of the cubicle if item.qu_char == 0: - pp.control.BinarySearchControl( + BinarySearchControl( net, ctrl_in_service=stactrl_in_service, output_element=gen_element, output_variable="q_mvar", @@ -3542,7 +3556,7 @@ def create_stactrl(net, item): elif item.qu_char == 1: controlled_node = item.refbar bus = bus_dict[controlled_node] # controlled node - bsc = pp.control.BinarySearchControl( + bsc = BinarySearchControl( net, ctrl_in_service=stactrl_in_service, output_element=gen_element, output_variable="q_mvar", @@ -3558,7 +3572,7 @@ def create_stactrl(net, item): bus_idx=bus, tol=1e-6 ) - pp.control.DroopControl( + DroopControl( net, q_droop_mvar=item.Srated * 100 / item.ddroop, bus_idx=bus, @@ -3585,7 +3599,7 @@ def split_line_at_length(net, line, length_pos): vn_kv = net.bus.at[bus1, "vn_kv"] zone = net.bus.at[bus1, "zone"] - bus = pp.create_bus(net, name=bus_name, type='ls', vn_kv=vn_kv, zone=zone) + bus = create_bus(net, name=bus_name, type='ls', vn_kv=vn_kv, zone=zone) net.line.at[line, 'to_bus'] = bus old_length = net.line.at[line, 'length_km'] @@ -3594,7 +3608,7 @@ def split_line_at_length(net, line, length_pos): std_type = net.line.at[line, 'std_type'] name = net.line.at[line, 'name'] - new_line = pp.create_line( + new_line = create_line( net, from_bus=bus, to_bus=bus2, @@ -3693,7 +3707,7 @@ def split_line(net, line_idx, pos_at_line, line_item): bus_j = net.line.at[line_idx, 'to_bus'] u = net.bus.at[bus_i, 'vn_kv'] - new_bus = pp.create_bus(net, name="Partial Load", vn_kv=u, type='n') + new_bus = create_bus(net, name="Partial Load", vn_kv=u, type='n') logger.debug("created new split bus %s" % new_bus) line_type = net.line.at[line_idx, 'std_type'] @@ -3705,7 +3719,7 @@ def split_line(net, line_idx, pos_at_line, line_item): # connect the existing line to the new bus net.line.at[line_idx, 'to_bus'] = new_bus - new_line = pp.create_line(net, new_bus, bus_j, len_b, line_type, name=name) + new_line = create_line(net, new_bus, bus_j, len_b, line_type, name=name) # change the connection of the bus-line switch to the new line sw = net.switch.query("et=='l' & bus==@bus_j & element==@line_idx").index if len(sw) > 0: @@ -3957,14 +3971,14 @@ def split_all_lines(net, lvp_dict): if p >= 0 or True: # TODO: set const_i_percent to 100 after the pandapower bug is fixed - new_load = pp.create_load(net, new_bus, name=load_item.loc_name, p_mw=p, q_mvar=q, - const_i_percent=0) + new_load = create_load(net, new_bus, name=load_item.loc_name, p_mw=p, q_mvar=q, + const_i_percent=0) logger.debug('created load %s' % new_load) net.res_load.at[new_load, 'pf_p'] = p net.res_load.at[new_load, 'pf_q'] = q else: # const I is not implemented for sgen - new_load = pp.create_sgen(net, new_bus, name=load_item.loc_name, p_mw=p, q_mvar=q) + new_load = create_sgen(net, new_bus, name=load_item.loc_name, p_mw=p, q_mvar=q) logger.debug('created sgen %s' % new_load) net.res_sgen.at[new_load, 'pf_p'] = p net.res_sgen.at[new_load, 'pf_q'] = q @@ -3976,13 +3990,13 @@ def remove_folder_of_std_types(net): duplicates have the same parameters """ for element in ["line", "trafo", "trafo3w"]: - std_types = pp.available_std_types(net, element=element).index + std_types = available_std_types(net, element=element).index reduced_std_types = {name.split("\\")[-1] for name in std_types} for std_type in reduced_std_types: all_types = [st for st in std_types if st.split('\\')[-1] == std_type] if len(all_types) > 1: types_equal = [ - pp.load_std_type(net, type1, element) == pp.load_std_type(net, type2, element) + load_std_type(net, type1, element) == load_std_type(net, type2, element) for type1, type2 in combinations(all_types, 2)] if not all(types_equal): continue diff --git a/pandapower/converter/powerfactory/validate.py b/pandapower/converter/powerfactory/validate.py index d16b8c0df..e0506ba8c 100644 --- a/pandapower/converter/powerfactory/validate.py +++ b/pandapower/converter/powerfactory/validate.py @@ -2,9 +2,10 @@ import pandas as pd import numpy as np -import pandapower as pp + +from pandapower.run import runpp +from pandapower.pf.runpp_3ph import runpp_3ph from pandapower.toolbox import replace_zero_branches_with_switches -from pandapower import diagnostic try: import pandaplan.core.pplog as logging @@ -265,10 +266,10 @@ def validate_pf_conversion(net, is_unbalanced=False, **kwargs): kwargs.pop(arg) if is_unbalanced: logger.info("running pandapower 3ph loadflow") - pp.runpp_3ph(net, trafo_model="t", check_connectivity=True, run_control=run_control, **kwargs) + runpp_3ph(net, trafo_model="t", check_connectivity=True, run_control=run_control, **kwargs) else: logger.info("running pandapower loadflow") - pp.runpp(net, trafo_model="t", check_connectivity=True, run_control=run_control, **kwargs) + runpp(net, trafo_model="t", check_connectivity=True, run_control=run_control, **kwargs) all_diffs = dict() logger.info('pandapower net converged: %s' % net.converged) diff --git a/pandapower/converter/pypower/to_ppc.py b/pandapower/converter/pypower/to_ppc.py index 7323f8e18..8e3550917 100644 --- a/pandapower/converter/pypower/to_ppc.py +++ b/pandapower/converter/pypower/to_ppc.py @@ -6,8 +6,8 @@ from numpy import allclose, delete, any from pandapower.auxiliary import _add_ppc_options -from pandapower.powerflow import _pd2ppc from pandapower.opf.validate_opf_input import _check_necessary_opf_parameters +from pandapower.powerflow import _pd2ppc from pandapower.pypower.idx_brch import BR_G, BR_G_ASYM, BR_B_ASYM, BR_R_ASYM, BR_X_ASYM try: @@ -79,14 +79,15 @@ def to_ppc(net, calculate_voltage_angles=True, trafo_model="t", switch_rx_ratio= **ppc** - The Pypower casefile for usage with pypower EXAMPLE: - >>> import pandapower.converter as pc - >>> import pandapower.networks as pn - >>> net = pn.case9() - >>> ppc = pc.to_ppc(net) + >>> from pandapower.converter import to_ppc + >>> from pandapower.networks.power_system_test_cases import case9 + >>> + >>> net = case9() + >>> ppc = to_ppc(net) """ if (not (net["poly_cost"].empty and net["pwl_cost"].empty) and - mode is None) or mode == "opf": + mode is None) or mode == "opf": mode = "opf" _check_necessary_opf_parameters(net, logger) else: diff --git a/pandapower/diagnostic.py b/pandapower/diagnostic.py index 29a32157f..64ed44588 100644 --- a/pandapower/diagnostic.py +++ b/pandapower/diagnostic.py @@ -7,7 +7,8 @@ import copy import pandas as pd import numpy as np -import pandapower as pp + +from pandapower import create_impedance, create_switch try: import pandaplan.core.pplog as logging @@ -24,7 +25,7 @@ from pandapower.diagnostic_reports import diagnostic_report # separator between log messages -log_message_sep = ("\n --------\n") +log_message_sep = "\n --------\n" expected_exceptions = (LoadflowNotConverged, OPFNotConverged, ControllerNotConverged, NetCalculationNotConverged) @@ -648,19 +649,19 @@ def implausible_impedance_values(net, min_r_ohm, min_x_ohm, max_r_ohm, max_x_ohm replace_xward_by_ward(net, implausible_idx) elif key == 'trafo': for idx in implausible_idx: - pp.create_impedance(net, net.trafo.at[idx, "hv_bus"], net.trafo.at[idx, "lv_bus"], + create_impedance(net, net.trafo.at[idx, "hv_bus"], net.trafo.at[idx, "lv_bus"], 0, 0.01, 100) elif key == 'trafo3w': for idx in implausible_idx: - pp.create_impedance(net, net.trafo3w.at[idx, "hv_bus"], net.trafo3w.at[idx, "mv_bus"], + create_impedance(net, net.trafo3w.at[idx, "hv_bus"], net.trafo3w.at[idx, "mv_bus"], 0, 0.01, 100) - pp.create_impedance(net, net.trafo3w.at[idx, "mv_bus"], net.trafo3w.at[idx, "lv_bus"], + create_impedance(net, net.trafo3w.at[idx, "mv_bus"], net.trafo3w.at[idx, "lv_bus"], 0, 0.01, 100) - pp.create_impedance(net, net.trafo3w.at[idx, "hv_bus"], net.trafo3w.at[idx, "lv_bus"], + create_impedance(net, net.trafo3w.at[idx, "hv_bus"], net.trafo3w.at[idx, "lv_bus"], 0, 0.01, 100) else: for idx in implausible_idx: - pp.create_switch(net, net[key].from_bus.at[idx], net[key].to_bus.at[idx], et="b") + create_switch(net, net[key].from_bus.at[idx], net[key].to_bus.at[idx], et="b") run(net) switch_replacement = True except expected_exceptions: @@ -827,9 +828,9 @@ def disconnected_elements(net): 'disconnected sgens' : sgen_indices} """ - import pandapower.topology as top - mg = top.create_nxgraph(net) - sections = top.connected_components(mg) + from pandapower.topology import create_nxgraph, connected_components + mg = create_nxgraph(net) + sections = connected_components(mg) disc_elements = [] for section in sections: @@ -1025,7 +1026,6 @@ def parallel_switches(net): parallels_bus_and_element = list( net.switch.groupby(compare_parameters).count().query('closed > 1').index) for bus, element, et in parallels_bus_and_element: - parallel_switches.append(list(net.switch.query( - 'bus==@bus & element==@element & et==@et').index)) + parallel_switches.append(list(net.switch.query('bus==@bus & element==@element & et==@et').index)) if parallel_switches: return parallel_switches diff --git a/pandapower/estimation/algorithm/optimization.py b/pandapower/estimation/algorithm/optimization.py index e49c16a27..8767cc0e5 100644 --- a/pandapower/estimation/algorithm/optimization.py +++ b/pandapower/estimation/algorithm/optimization.py @@ -5,11 +5,13 @@ from scipy.optimize import minimize -from pandapower.estimation.ppc_conversion import ExtendedPPCI from pandapower.estimation.algorithm.base import BaseAlgorithm from pandapower.estimation.algorithm.estimator import BaseEstimatorOpt, get_estimator +from pandapower.estimation.ppc_conversion import ExtendedPPCI DEFAULT_OPT_METHOD = "Newton-CG" + + # DEFAULT_OPT_METHOD = "TNC" # DEFAULT_OPT_METHOD = "SLSQP" # DEFAULT_OPT_METHOD = 'L-BFGS-B' @@ -33,4 +35,4 @@ def estimate(self, eppci: ExtendedPPCI, estimator="wls", verbose=True, **kwargs) eppci.update_E(E) return eppci else: - raise Exception("Optimiaztion failed! State Estimation not successful!") + raise Exception("Optimization failed! State Estimation not successful!") diff --git a/pandapower/estimation/ppc_conversion.py b/pandapower/estimation/ppc_conversion.py index 29ada0e2e..d928be612 100644 --- a/pandapower/estimation/ppc_conversion.py +++ b/pandapower/estimation/ppc_conversion.py @@ -9,7 +9,7 @@ import numpy as np import pandas as pd -import pandapower.pypower.idx_bus as idx_bus +from pandapower.pypower.idx_bus import BUS_TYPE as pypower_BUS_TYPE, VM as pypower_VM, VA as pypower_VA from pandapower.auxiliary import _init_runse_options from pandapower.estimation.util import estimate_voltage_vector from pandapower.pd2ppc import _pd2ppc @@ -549,8 +549,8 @@ def __init__(self, ppci, algorithm): self.any_degree_meas = False # check slack bus - self.non_slack_buses = np.argwhere(ppci["bus"][:, idx_bus.BUS_TYPE] != 3).ravel() - self.non_slack_bus_mask = (ppci['bus'][:, idx_bus.BUS_TYPE] != 3).ravel() + self.non_slack_buses = np.argwhere(ppci["bus"][:, pypower_BUS_TYPE] != 3).ravel() + self.non_slack_bus_mask = (ppci['bus'][:, pypower_BUS_TYPE] != 3).ravel() self.num_non_slack_bus = np.sum(self.non_slack_bus_mask) self.delta_v_bus_mask = np.r_[self.non_slack_bus_mask, np.ones(self.non_slack_bus_mask.shape[0], dtype=bool)].ravel() @@ -560,8 +560,8 @@ def __init__(self, ppci, algorithm): self._initialize_meas() # Initialize state variable - self.v_init = ppci["bus"][:, idx_bus.VM] - self.delta_init = np.radians(ppci["bus"][:, idx_bus.VA]) + self.v_init = ppci["bus"][:, pypower_VM] + self.delta_init = np.radians(ppci["bus"][:, pypower_VA]) self.E_init = np.r_[self.delta_init[self.non_slack_bus_mask], self.v_init] self.v = self.v_init.copy() self.delta = self.delta_init.copy() diff --git a/pandapower/estimation/util.py b/pandapower/estimation/util.py index 6fdb1efae..4766c68c9 100644 --- a/pandapower/estimation/util.py +++ b/pandapower/estimation/util.py @@ -7,7 +7,8 @@ import pandas as pd from pandas import DataFrame, notnull, isnull -import pandapower as pp +from pandapower.run import runpp +from pandapower.create import create_measurement from pandapower.topology import create_nxgraph, connected_component @@ -60,9 +61,9 @@ def _get_bus_ppc_mapping(net, bus_to_be_fused): set(net.ext_grid.bus)).union(set(net.ward.bus)).union( set(net.xward.bus)) # Run dc pp to get the ppc we need - #pp.rundcpp(net) + #rundcpp(net) - pp.runpp(net, calculate_voltage_angles=True) + runpp(net, calculate_voltage_angles=True) bus_ppci = pd.DataFrame(data=net._pd2ppc_lookups['bus'], columns=["bus_ppci"]) bus_ppci['bus_with_elements'] = bus_ppci.index.isin(bus_with_elements) @@ -152,10 +153,10 @@ def add_virtual_meas_from_loadflow(net, v_std_dev=0.01, p_std_dev=0.03, q_std_de for meas_type in bus_meas_types.keys(): meas_value = float(bus_res[bus_meas_types[meas_type]]) if meas_type in ('p', 'q'): - pp.create_measurement(net, meas_type=meas_type, element_type='bus', element=bus_ix, + create_measurement(net, meas_type=meas_type, element_type='bus', element=bus_ix, value=meas_value, std_dev=1) else: - pp.create_measurement(net, meas_type=meas_type, element_type='bus', element=bus_ix, + create_measurement(net, meas_type=meas_type, element_type='bus', element=bus_ix, value=meas_value, std_dev=v_std_dev) remove_shunt_injection_from_meas(net,"shunt") remove_shunt_injection_from_meas(net,"ward") @@ -165,7 +166,7 @@ def add_virtual_meas_from_loadflow(net, v_std_dev=0.01, p_std_dev=0.03, q_std_de for br_ix, br_res in net['res_' + br_type].iterrows(): for side in branch_meas_type[br_type]['side']: for meas_type in branch_meas_type[br_type]['meas_type']: - pp.create_measurement(net, meas_type=meas_type[0], element_type=br_type, + create_measurement(net, meas_type=meas_type[0], element_type=br_type, element=br_ix, side=side, value=br_res[meas_type[0] + '_' + side + meas_type[1:]], std_dev=1) @@ -217,10 +218,10 @@ def add_virtual_pmu_meas_from_loadflow(net, v_std_dev=0.001, i_std_dev=0.1, for meas_type in bus_meas_types.keys(): meas_value = float(bus_res[bus_meas_types[meas_type]]) if meas_type in ('p', 'q'): - pp.create_measurement(net, meas_type=meas_type, element_type='bus', element=bus_ix, + create_measurement(net, meas_type=meas_type, element_type='bus', element=bus_ix, value=meas_value, std_dev=1) else: - pp.create_measurement(net, meas_type=meas_type, element_type='bus', element=bus_ix, + create_measurement(net, meas_type=meas_type, element_type='bus', element=bus_ix, value=meas_value, std_dev=v_std_dev) for br_type in branch_meas_type.keys(): @@ -228,7 +229,7 @@ def add_virtual_pmu_meas_from_loadflow(net, v_std_dev=0.001, i_std_dev=0.1, for br_ix, br_res in net['res_' + br_type].iterrows(): for side in branch_meas_type[br_type]['side']: for meas_type in branch_meas_type[br_type]['meas_type']: - pp.create_measurement(net, meas_type=meas_type.split("_")[0], element_type=br_type, + create_measurement(net, meas_type=meas_type.split("_")[0], element_type=br_type, element=br_ix, side=side, value=br_res[meas_type.split("_")[0] + '_' + side + '_' + meas_type.split("_")[1]], std_dev=1) diff --git a/pandapower/file_io.py b/pandapower/file_io.py index a864e4fbc..cb92609c8 100644 --- a/pandapower/file_io.py +++ b/pandapower/file_io.py @@ -4,15 +4,17 @@ # and Energy System Technology (IEE), Kassel. All rights reserved. -import json -import os import pickle -from warnings import warn +import os +import sys +import json +from warnings import warn import numpy import pandas as pd from packaging.version import Version -import sys + + try: import xlsxwriter xlsxwriter_INSTALLED = True @@ -25,12 +27,14 @@ openpyxl_INSTALLED = False from pandapower._version import __version__ as pp_version -from pandapower.auxiliary import soft_dependency_error, _preserve_dtypes +from pandapower.auxiliary import soft_dependency_error from pandapower.auxiliary import pandapowerNet from pandapower.std_types import basic_std_types from pandapower.create import create_empty_network from pandapower.convert_format import convert_format -import pandapower.io_utils as io_utils +from pandapower.io_utils import to_dict_with_coord_transform, to_dict_of_dfs, PPJSONEncoder, encrypt_string, \ + get_raw_data_from_pickle, transform_net_with_df_and_geo, check_net_version, from_dict_of_dfs, decrypt_string, \ + PPJSONDecoder try: import pandaplan.core.pplog as logging @@ -52,8 +56,9 @@ def to_pickle(net, filename): EXAMPLE: - >>> pp.to_pickle(net, os.path.join("C:", "example_folder", "example1.p")) # absolute path - >>> pp.to_pickle(net, "example2.p") # relative path + >>> from pandapower import to_pickle + >>> to_pickle(net, os.path.join("C:", "example_folder", "example1.p")) # absolute path + >>> to_pickle(net, "example2.p") # relative path """ if hasattr(filename, 'write'): @@ -61,7 +66,7 @@ def to_pickle(net, filename): return if not filename.endswith(".p"): raise Exception("Please use .p to save pandapower networks!") - save_net = io_utils.to_dict_with_coord_transform(net, ["bus_geodata"], ["line_geodata"]) + save_net = to_dict_with_coord_transform(net, ["bus_geodata"], ["line_geodata"]) with open(filename, "wb") as f: pickle.dump(save_net, f, protocol=2) # use protocol 2 for py2 / py3 compatibility @@ -83,14 +88,15 @@ def to_excel(net, filename, include_empty_tables=False, include_results=True): EXAMPLE: - >>> pp.to_excel(net, os.path.join("C:", "example_folder", "example1.xlsx")) # absolute path - >>> pp.to_excel(net, "example2.xlsx") # relative path + >>> from pandapower import to_excel + >>> to_excel(net, os.path.join("C:", "example_folder", "example1.xlsx")) # absolute path + >>> to_excel(net, "example2.xlsx") # relative path """ if not xlsxwriter_INSTALLED: soft_dependency_error(str(sys._getframe().f_code.co_name)+"()", "xlsxwriter") writer = pd.ExcelWriter(filename, engine='xlsxwriter') - dict_net = io_utils.to_dict_of_dfs(net, include_results=include_results, + dict_net = to_dict_of_dfs(net, include_results=include_results, include_empty_tables=include_empty_tables) for item, table in dict_net.items(): table.to_excel(writer, sheet_name=item) @@ -129,9 +135,9 @@ def to_json(net, filename=None, encryption_key=None, store_index_names=None): else: raise DeprecationWarning(msg) - json_string = json.dumps(net, cls=io_utils.PPJSONEncoder, indent=2) + json_string = json.dumps(net, cls=PPJSONEncoder, indent=2) if encryption_key is not None: - json_string = io_utils.encrypt_string(json_string, encryption_key) + json_string = encrypt_string(json_string, encryption_key) if filename is None: return json_string @@ -159,19 +165,20 @@ def from_pickle(filename, convert=True): EXAMPLE: - >>> net1 = pp.from_pickle(os.path.join("C:", "example_folder", "example1.p")) #absolute path - >>> net2 = pp.from_pickle("example2.p") #relative path + >>> from pandapower import from_pickle + >>> net1 = from_pickle(os.path.join("C:", "example_folder", "example1.p")) #absolute path + >>> net2 = from_pickle("example2.p") #relative path """ - net = pandapowerNet(io_utils.get_raw_data_from_pickle(filename)) - io_utils.transform_net_with_df_and_geo(net, ["bus_geodata"], ["line_geodata"]) + net = pandapowerNet(get_raw_data_from_pickle(filename)) + transform_net_with_df_and_geo(net, ["bus_geodata"], ["line_geodata"]) if convert: convert_format(net) # compare pandapowerNet-format_version and package-version - io_utils.check_net_version(net) + check_net_version(net) return net @@ -190,8 +197,9 @@ def from_excel(filename, convert=True): EXAMPLE: - >>> net1 = pp.from_excel(os.path.join("C:", "example_folder", "example1.xlsx")) - >>> net2 = pp.from_excel("example2.xlsx") #relative path + >>> from pandapower import from_excel + >>> net1 = from_excel(os.path.join("C:", "example_folder", "example1.xlsx")) + >>> net2 = from_excel("example2.xlsx") #relative path """ @@ -202,14 +210,14 @@ def from_excel(filename, convert=True): xls = pd.read_excel(filename, sheet_name=None, index_col=0, engine="openpyxl") try: - net = io_utils.from_dict_of_dfs(xls) + net = from_dict_of_dfs(xls) except: net = _from_excel_old(xls) if convert: convert_format(net) # compare pandapowerNet-format_version and package-version - io_utils.check_net_version(net) + check_net_version(net) return net @@ -342,7 +350,8 @@ def from_json_string(json_string, convert=False, encryption_key=None, elements_t EXAMPLE: - >>> net = pp.from_json_string(json_str) + >>> from pandapower import from_json_string + >>> net = from_json_string(json_str) """ if replace_elements is not None: @@ -350,14 +359,14 @@ def from_json_string(json_string, convert=False, encryption_key=None, elements_t json_string = json_string.replace(k, v) if encryption_key is not None: - json_string = io_utils.decrypt_string(json_string, encryption_key) + json_string = decrypt_string(json_string, encryption_key) if elements_to_deserialize is None: - net = json.loads(json_string, cls=io_utils.PPJSONDecoder, + net = json.loads(json_string, cls=PPJSONDecoder, empty_dict_like_object=empty_dict_like_object, ignore_unknown_objects=ignore_unknown_objects) else: - net = json.loads(json_string, cls=io_utils.PPJSONDecoder, deserialize_pandas=False, + net = json.loads(json_string, cls=PPJSONDecoder, deserialize_pandas=False, empty_dict_like_object=empty_dict_like_object, ignore_unknown_objects=ignore_unknown_objects) net_dummy = create_empty_network() @@ -366,7 +375,7 @@ def from_json_string(json_string, convert=False, encryption_key=None, elements_t 'Convert and save your net first.') if keep_serialized_elements: for key in elements_to_deserialize: - net[key] = json.loads(net[key], cls=io_utils.PPJSONDecoder) + net[key] = json.loads(net[key], cls=PPJSONDecoder) else: if (('version' not in net.keys()) or (net['version'] != net_dummy.version)) and \ not convert: @@ -377,7 +386,7 @@ def from_json_string(json_string, convert=False, encryption_key=None, elements_t % (net['version'], net_dummy.version)) for key in net.keys(): if key in elements_to_deserialize: - net[key] = json.loads(net[key], cls=io_utils.PPJSONDecoder) + net[key] = json.loads(net[key], cls=PPJSONDecoder) elif not isinstance(net[key], str): continue elif 'pandas' in net[key]: @@ -397,7 +406,7 @@ def from_json_string(json_string, convert=False, encryption_key=None, elements_t convert_format(net, elements_to_deserialize=elements_to_deserialize) # compare pandapowerNet-format_version and package-version - io_utils.check_net_version(net) + check_net_version(net) if add_basic_std_types: # get std-types and add only new keys ones for key, std_types in basic_std_types().items(): @@ -420,7 +429,8 @@ def from_json_dict(json_dict): EXAMPLE: - >>> net = pp.from_json_dict(json.loads(json_str)) + >>> from pandapower import from_json_dict + >>> net = from_json_dict(json.loads(json_str)) """ name = json_dict["name"] if "name" in json_dict else None diff --git a/pandapower/grid_equivalents/auxiliary.py b/pandapower/grid_equivalents/auxiliary.py index f063bf18b..2b2d78a85 100644 --- a/pandapower/grid_equivalents/auxiliary.py +++ b/pandapower/grid_equivalents/auxiliary.py @@ -1,17 +1,23 @@ import os -from pathlib import Path +import uuid from copy import deepcopy +from pathlib import Path + import numpy as np import pandas as pd -import pandapower.toolbox +from pandapower.auxiliary import _init_runpp_options, _add_dcline_gens, LoadflowNotConverged +from pandapower.create import create_ext_grid, create_bus, create_impedance, create_transformer_from_parameters, \ + create_load +from pandapower.diagnostic import diagnostic +from pandapower.file_io import to_json from pandapower.pd2ppc import _pd2ppc from pandapower.pf.ppci_variables import _get_pf_variables_from_ppci from pandapower.pf.run_newton_raphson_pf import _get_numba_functions, _get_Y_bus -from pandapower.run import _passed_runpp_parameters -from pandapower.auxiliary import _init_runpp_options, _add_dcline_gens -import pandapower as pp -import uuid +from pandapower.run import _passed_runpp_parameters, runpp +from pandapower.toolbox.element_selection import pp_elements, get_connected_elements_dict, branch_element_bus_dict +from pandapower.toolbox.grid_modification import drop_lines, drop_trafos, drop_measurements_at_elements, \ + drop_controllers_at_buses try: import pandaplan.core.pplog as logging @@ -26,14 +32,14 @@ def _runpp_except_voltage_angles(net, **kwargs): if "calculate_voltage_angles" not in kwargs or not kwargs["calculate_voltage_angles"]: - pp.runpp(net, **kwargs) + runpp(net, **kwargs) else: try: - pp.runpp(net, **kwargs) - except pp.LoadflowNotConverged: + runpp(net, **kwargs) + except LoadflowNotConverged: kwargs1 = deepcopy(kwargs) kwargs1["calculate_voltage_angles"] = False - pp.runpp(net, **kwargs1) + runpp(net, **kwargs1) logger.warning("In grid equivalent generation, the power flow did converge only without" " calculate_voltage_angles.") return net @@ -63,15 +69,15 @@ def add_ext_grids_to_boundaries(net, boundary_buses, adapt_va_degree=False, vms.loc[pd.Index(net.gen.bus.loc[net.gen.in_service]).intersection(vms.index)] = \ net.gen.vm_pu.loc[net.gen.in_service & net.gen.bus.isin(vms.index) & ~net.gen.bus.duplicated()].values # avoid - # different vm_pu setpoints at same buses + # different vm_pu setpoints at same buses vas.loc[btaegwr] = net.res_bus.va_degree.loc[btaegwr] for ext_bus, vm, va in zip(buses_to_add_ext_grids, vms, vas): - add_eg += [pp.create_ext_grid(net, ext_bus, - vm, va, name="assist_ext_grid")] - new_bus = pp.create_bus(net, net.bus.vn_kv[ext_bus], name="assist_bus") - pp.create_impedance(net, ext_bus, new_bus, 1e6, 1e6, net.sn_mva, - name="assist_impedance") + add_eg += [create_ext_grid(net, ext_bus, + vm, va, name="assist_ext_grid")] + new_bus = create_bus(net, net.bus.vn_kv[ext_bus], name="assist_bus") + create_impedance(net, ext_bus, new_bus, 1e6, 1e6, net.sn_mva, + name="assist_impedance") # works fine if there is only one slack in net: if adapt_va_degree and net.gen.slack.any() and net.ext_grid.shape[0]: @@ -80,7 +86,7 @@ def add_ext_grids_to_boundaries(net, boundary_buses, adapt_va_degree=False, try: runpp_fct(net, calculate_voltage_angles=calc_volt_angles, max_iteration=100, **kwargs) - except pp.LoadflowNotConverged as e: + except LoadflowNotConverged as e: if allow_net_change_for_convergence: # --- various fix trials @@ -93,9 +99,9 @@ def add_ext_grids_to_boundaries(net, boundary_buses, adapt_va_degree=False, try: runpp_fct(net, calculate_voltage_angles=True, max_iteration=100, **kwargs) logger.warning("The sign of these impedances were changed to enable a power" - f" flow: {imp_neg[:no]}") + f" flow: {imp_neg[:no]}") break - except pp.LoadflowNotConverged as e: + except LoadflowNotConverged as e: pass if not net.converged: @@ -111,30 +117,29 @@ def add_ext_grids_to_boundaries(net, boundary_buses, adapt_va_degree=False, if changes: try: runpp_fct(net, calculate_voltage_angles=calc_volt_angles, - max_iteration=100, **kwargs) + max_iteration=100, **kwargs) logger.warning("Reactances of these impedances has been increased to " - f"enable a power flow: {is2small}") - except pp.LoadflowNotConverged as e: - diag = pp.diagnostic(net) + f"enable a power flow: {is2small}") + except LoadflowNotConverged as e: + diag = diagnostic(net) print(net) print(diag.keys()) - pp.to_json(net, os.path.join(desktop, "diverged_net.json")) - raise pp.LoadflowNotConverged(e) + to_json(net, os.path.join(desktop, "diverged_net.json")) + raise LoadflowNotConverged(e) else: - diag = pp.diagnostic(net) + diag = diagnostic(net) print(net) print(diag.keys()) - pp.to_json(net, os.path.join(desktop, "diverged_net.json")) - raise pp.LoadflowNotConverged(e) + to_json(net, os.path.join(desktop, "diverged_net.json")) + raise LoadflowNotConverged(e) else: - raise pp.LoadflowNotConverged(e) - + raise LoadflowNotConverged(e) va = net.res_bus.va_degree.loc[slack_buses] va_ave = va.sum() / va.shape[0] net.ext_grid.va_degree.loc[add_eg] -= va_ave runpp_fct(net, calculate_voltage_angles=calc_volt_angles, - max_iteration=100, **kwargs) + max_iteration=100, **kwargs) return orig_slack_gens @@ -143,21 +148,21 @@ def drop_internal_branch_elements(net, internal_buses, branch_elements=None): This function drops all branch elements which have 'internal_buses' connected at all sides of the branch element (e.g. for lines at 'from_bus' and 'to_bus'). """ - bebd = pandapower.toolbox.branch_element_bus_dict() + bebd = branch_element_bus_dict() if branch_elements is not None: bebd = {elm: bus_types for elm, - bus_types in bebd.items() if elm in branch_elements} + bus_types in bebd.items() if elm in branch_elements} for elm, bus_types in bebd.items(): n_elms = net[elm].shape[0] if n_elms: - should_be_dropped = np.ones((n_elms, ), dtype=bool) + should_be_dropped = np.ones((n_elms,), dtype=bool) for bus_type in bus_types: should_be_dropped &= net[elm][bus_type].isin(internal_buses) idx_to_drop = net[elm].index[should_be_dropped] if elm == "line": - pp.drop_lines(net, idx_to_drop) + drop_lines(net, idx_to_drop) elif "trafo" in elm: - pp.drop_trafos(net, idx_to_drop, table=elm) + drop_trafos(net, idx_to_drop, table=elm) else: net[elm] = net[elm].drop(idx_to_drop) @@ -172,14 +177,14 @@ def calc_zpbn_parameters(net, boundary_buses, all_external_buses, slack_as="gen" **v** - voltage at new buses """ -# runpp_fct(net, calculate_voltage_angles=True) + # runpp_fct(net, calculate_voltage_angles=True) be_buses = boundary_buses + all_external_buses - if ((net.trafo.hv_bus.isin(be_buses)) & (net.trafo.shift_degree!=0)).any() \ - or ((net.trafo3w.hv_bus.isin(be_buses)) & \ - ((net.trafo3w.shift_mv_degree!=0) | (net.trafo3w.shift_lv_degree!=0))).any(): - existing_shift_degree = True - logger.info("Transformers with non-zero shift-degree are existed," + - " they could cause small inaccuracy.") + if ((net.trafo.hv_bus.isin(be_buses)) & (net.trafo.shift_degree != 0)).any() \ + or ((net.trafo3w.hv_bus.isin(be_buses)) & \ + ((net.trafo3w.shift_mv_degree != 0) | (net.trafo3w.shift_lv_degree != 0))).any(): + existing_shift_degree = True + logger.info("Transformers with non-zero shift-degree are existed," + + " they could cause small inaccuracy.") # creata dataframe to collect the current injections of the external area nb_ext_buses = len(all_external_buses) S = pd.DataFrame(np.zeros((nb_ext_buses, 15)), dtype=complex) @@ -208,48 +213,48 @@ def calc_zpbn_parameters(net, boundary_buses, all_external_buses, slack_as="gen" ind = list(net[ele].index[net[ele].bus == i].values) # act. values --> ref. values: S.loc[k, power] += sum(net[res_ele].p_mw[ind].values * sign) / net.sn_mva + \ - 1j * sum(net[res_ele].q_mvar[ind].values * - sign) / net.sn_mva + 1j * sum(net[res_ele].q_mvar[ind].values * + sign) / net.sn_mva S.loc[k, sn] = sum(net[ele].sn_mva[ind].values) + \ - 1j * 0 if ele != "ext_grid" else 1e6 + 1j * 0 + 1j * 0 if ele != "ext_grid" else 1e6 + 1j * 0 S[power.replace('_separate', '_integrated')] += S[power][k] S[sn.replace('_separate', '_integrated')] += S[sn][k] S.loc[k, 'ext_bus'] = all_external_buses[k] S.loc[k, 'v_m'] = net.res_bus.vm_pu[i] S.loc[k, 'v_cpx'] = S.v_m[k] * \ - np.exp(1j * net.res_bus.va_degree[i] * np.pi / 180) + np.exp(1j * net.res_bus.va_degree[i] * np.pi / 180) k = k + 1 # create dataframe to calculate the impedance of the ZPBN-network Y = pd.DataFrame(np.zeros((nb_ext_buses, 10)), dtype=complex) Y.columns = ["ext_bus", "load_ground", "load_integrated_total", "load_separate_total", - "gen_ground", "gen_integrated_total", "gen_separate_total", - "sgen_ground", "sgen_integrated_total", "sgen_separate_total"] + "gen_ground", "gen_integrated_total", "gen_separate_total", + "sgen_ground", "sgen_integrated_total", "sgen_separate_total"] v = pd.DataFrame(dtype=complex) Y.ext_bus, v["ext_bus"] = all_external_buses, all_external_buses for elm in ["load", "gen", "sgen"]: if existing_shift_degree: - Y[elm+"_ground"] = (S[elm+"_separate"].values / S.v_cpx.values).conjugate() / \ - S.v_cpx.values + Y[elm + "_ground"] = (S[elm + "_separate"].values / S.v_cpx.values).conjugate() / \ + S.v_cpx.values else: - Y[elm+"_ground"] = S[elm+"_separate"].values.conjugate() / \ - np.square(S.v_m) - I_elm_integrated_total = sum((S[elm+"_separate"].values / + Y[elm + "_ground"] = S[elm + "_separate"].values.conjugate() / \ + np.square(S.v_m) + I_elm_integrated_total = sum((S[elm + "_separate"].values / S.v_cpx.values).conjugate()) if I_elm_integrated_total == 0: - Y[elm+"_integrated_total"] = float("nan") + Y[elm + "_integrated_total"] = float("nan") else: - vm_elm_integrated_total = S[elm+"_integrated"][0] / \ - I_elm_integrated_total.conjugate() + vm_elm_integrated_total = S[elm + "_integrated"][0] / \ + I_elm_integrated_total.conjugate() if existing_shift_degree: - Y[elm+"_integrated_total"] = (-S[elm+"_integrated"][0] / \ - vm_elm_integrated_total).conjugate() / \ - vm_elm_integrated_total + Y[elm + "_integrated_total"] = (-S[elm + "_integrated"][0] / \ + vm_elm_integrated_total).conjugate() / \ + vm_elm_integrated_total else: - Y[elm+"_integrated_total"] = -S[elm+"_integrated"][0].conjugate() / \ - np.square(abs(vm_elm_integrated_total)) - Y[elm+"_separate_total"] = -Y[elm+"_ground"] + Y[elm + "_integrated_total"] = -S[elm + "_integrated"][0].conjugate() / \ + np.square(abs(vm_elm_integrated_total)) + Y[elm + "_separate_total"] = -Y[elm + "_ground"] if elm == "gen" and any(S.gen_separate): v["gen_integrated_vm_total"] = abs(vm_elm_integrated_total) v["gen_separate_vm_total"] = S.v_m @@ -286,12 +291,12 @@ def drop_assist_elms_by_creating_ext_net(net, elms=None): elms = ["ext_grid", "bus", "impedance"] for elm in elms: target_elm_idx = net[elm].index[net[elm].name.astype(str).str.contains( - "assist_"+elm, na=False, regex=False)] + "assist_" + elm, na=False, regex=False)] net[elm] = net[elm].drop(target_elm_idx) - if net["res_"+elm].shape[0]: + if net["res_" + elm].shape[0]: res_target_elm_idx = net["res_" + elm].index.intersection(target_elm_idx) - net["res_"+elm] = net["res_"+elm].drop(res_target_elm_idx) + net["res_" + elm] = net["res_" + elm].drop(res_target_elm_idx) if "name_equivalent" in net.bus.columns.tolist(): net.bus = net.bus.drop(columns=["name_equivalent"]) @@ -331,21 +336,21 @@ def drop_measurements_and_controllers(net, buses, skip_controller=False): Also, the related controller parameters will be removed. """ # --- dropping measurements if len(net.measurement): - pp.drop_measurements_at_elements(net, "bus", idx=buses) + drop_measurements_at_elements(net, "bus", idx=buses) lines = net.line.index[(net.line.from_bus.isin(buses)) & (net.line.from_bus.isin(buses))] - pp.drop_measurements_at_elements(net, "line", idx=lines) + drop_measurements_at_elements(net, "line", idx=lines) trafos = net.trafo3w.index[(net.trafo3w.hv_bus.isin(buses)) & - (net.trafo3w.mv_bus.isin(buses)) & - (net.trafo3w.lv_bus.isin(buses))] - pp.drop_measurements_at_elements(net, "trafo", idx=trafos) + (net.trafo3w.mv_bus.isin(buses)) & + (net.trafo3w.lv_bus.isin(buses))] + drop_measurements_at_elements(net, "trafo", idx=trafos) trafo3ws = net.trafo3w.index[(net.trafo3w.hv_bus.isin(buses)) & - (net.trafo3w.mv_bus.isin(buses)) & - (net.trafo3w.lv_bus.isin(buses))] - pp.drop_measurements_at_elements(net, "trafo3w", idx=trafo3ws) + (net.trafo3w.mv_bus.isin(buses)) & + (net.trafo3w.lv_bus.isin(buses))] + drop_measurements_at_elements(net, "trafo3w", idx=trafo3ws) # --- dropping controller - pp.drop_controllers_at_buses(net, buses) + drop_controllers_at_buses(net, buses) def ensure_origin_id(net, elms=None): @@ -353,11 +358,11 @@ def ensure_origin_id(net, elms=None): Ensures completely filled column 'origin_id' in every pp element. """ if elms is None: - elms = pandapower.toolbox.pp_elements() + elms = pp_elements() for elm in elms: if "origin_id" not in net[elm].columns: - net[elm]["origin_id"] = pd.Series([None]*net[elm].shape[0], dtype=object) + net[elm]["origin_id"] = pd.Series([None] * net[elm].shape[0], dtype=object) idxs = net[elm].index[net[elm].origin_id.isnull()] net[elm].loc[idxs, "origin_id"] = ["%s_%i_%s" % (elm, idx, str(uuid.uuid4())) for idx in idxs] @@ -434,16 +439,17 @@ def _check_network(net): # --- check controller names if len(net.controller): - for i in net.controller.index: - et = net.controller.object[i].__dict__.get("element") - if et is not None and len(net[et]) != len(set(net[et].name.values)): - raise ValueError("if controllers are used, please give a name for every " - "element ("+et+"), and make sure the name is unique.") + for i in net.controller.index: + et = net.controller.object[i].__dict__.get("element") + if et is not None and len(net[et]) != len(set(net[et].name.values)): + raise ValueError("if controllers are used, please give a name for every " + "element (" + et + "), and make sure the name is unique.") def get_boundary_vp(net_eq, bus_lookups): v_boundary = net_eq.ext_grid - p_boundary = net_eq.res_ext_grid.values + net_eq.res_bus[["p_mw", "q_mvar"]].loc[bus_lookups["bus_lookup_pd"]["b_area_buses"]].values + p_boundary = net_eq.res_ext_grid.values + net_eq.res_bus[["p_mw", "q_mvar"]].loc[ + bus_lookups["bus_lookup_pd"]["b_area_buses"]].values p_boundary = pd.DataFrame(p_boundary, index=bus_lookups["bus_lookup_pd"]["b_area_buses"], columns=["p_mw", "q_mvar"]) return v_boundary, p_boundary @@ -452,9 +458,9 @@ def get_boundary_vp(net_eq, bus_lookups): def adaptation_phase_shifter(net, v_boundary, p_boundary): target_buses = list(v_boundary.bus.values) phase_errors = v_boundary.va_degree.values - \ - net.res_bus.va_degree[target_buses].values + net.res_bus.va_degree[target_buses].values vm_errors = v_boundary.vm_pu.values - \ - net.res_bus.vm_pu[target_buses].values + net.res_bus.vm_pu[target_buses].values # p_errors = p_boundary.p_mw.values - \ # net.res_bus.p_mw[target_buses].values # q_errors = p_boundary.q_mvar.values - \ @@ -462,14 +468,14 @@ def adaptation_phase_shifter(net, v_boundary, p_boundary): # print(q_errors) for idx, lb in enumerate(target_buses): if abs(vm_errors[idx]) > 1e-6 and abs(vm_errors[idx]) > 1e-6: - hb = pp.create_bus(net, net.bus.vn_kv[lb]*(1-vm_errors[idx]), - name="phase_shifter_adapter_"+str(lb)) - elm_dict = pp.get_connected_elements_dict(net, lb) + hb = create_bus(net, net.bus.vn_kv[lb] * (1 - vm_errors[idx]), + name="phase_shifter_adapter_" + str(lb)) + elm_dict = get_connected_elements_dict(net, lb) for e, e_list in elm_dict.items(): for i in e_list: name = str(net[e].name[i]) if "eq_" not in name and "_integrated_" not in name and \ - "_separate_" not in name: + "_separate_" not in name: if e in ["impedance", "line"]: if net[e].from_bus[i] == lb: net[e].from_bus[i] = hb @@ -491,15 +497,15 @@ def adaptation_phase_shifter(net, v_boundary, p_boundary): pass else: net[e].loc[i, 'bus'] = hb - pp.create_transformer_from_parameters(net, hb, lb, 1e5, - net.bus.vn_kv[hb]*(1-vm_errors[idx]), - net.bus.vn_kv[lb], - vkr_percent=0, vk_percent=100, - pfe_kw=.0, i0_percent=.0, - # shift_degree=-phase_errors[idx], - tap_step_degree=-phase_errors[idx], - # tap_phase_shifter=True, - name="phase_shifter_adapter_"+str(lb)) + create_transformer_from_parameters(net, hb, lb, 1e5, + net.bus.vn_kv[hb] * (1 - vm_errors[idx]), + net.bus.vn_kv[lb], + vkr_percent=0, vk_percent=100, + pfe_kw=.0, i0_percent=.0, + # shift_degree=-phase_errors[idx], + tap_step_degree=-phase_errors[idx], + # tap_phase_shifter=True, + name="phase_shifter_adapter_" + str(lb)) # pp.create_load(net, lb, -p_errors[idx], -q_errors[idx], # name="phase_shifter_adapter_"+str(lb)) # runpp_fct(net, calculate_voltage_angles=True) @@ -516,9 +522,9 @@ def replace_motor_by_load(net, all_external_buses): p_mech = m.pn_mech_mw / (m.efficiency_percent / 100) p_mw = p_mech * m.loading_percent / 100 * m.scaling s = p_mw / m.cos_phi - q_mvar = np.sqrt(s**2 - p_mw**2) - li = pp.create_load(net, m.bus, p_mw, q_mvar, sn_mva=s, scalling=m.scaling, - in_service=m.in_service, name="equivalent_"+str(m["name"])+"_"+str(mi)) + q_mvar = np.sqrt(s ** 2 - p_mw ** 2) + li = create_load(net, m.bus, p_mw, q_mvar, sn_mva=s, scalling=m.scaling, + in_service=m.in_service, name="equivalent_" + str(m["name"]) + "_" + str(mi)) p = p_mw if not np.isnan(net.res_bus.vm_pu[m.bus]) and m.in_service else 0.0 q = q_mvar if not np.isnan(net.res_bus.vm_pu[m.bus]) and m.in_service else 0.0 net.res_load.loc[li] = p, q diff --git a/pandapower/grid_equivalents/get_equivalent.py b/pandapower/grid_equivalents/get_equivalent.py index 2cd5ef8c9..62eb67494 100644 --- a/pandapower/grid_equivalents/get_equivalent.py +++ b/pandapower/grid_equivalents/get_equivalent.py @@ -1,7 +1,7 @@ -import pandapower as pp -import pandapower.topology as top import time from copy import deepcopy + +from pandapower.create import create_group_from_dict from pandapower.grid_equivalents.auxiliary import drop_assist_elms_by_creating_ext_net, \ drop_internal_branch_elements, add_ext_grids_to_boundaries, \ _ensure_unique_boundary_bus_names, match_cost_functions_and_eq_net, \ @@ -15,6 +15,13 @@ _calculate_xward_and_impedance_parameters, \ create_passive_external_net_for_ward_admittance, \ _replace_external_area_by_wards, _replace_external_area_by_xwards +from pandapower.groups import isin_group, set_group_reference_column +from pandapower.run import runpp +from pandapower.toolbox.data_modification import reindex_buses +from pandapower.toolbox.grid_modification import replace_ward_by_internal_elements, replace_xward_by_internal_elements, \ + drop_buses, drop_elements_at_buses, merge_nets, fuse_buses +from pandapower.topology.create_graph import create_nxgraph +from pandapower.topology.graph_searches import connected_component, connected_components try: import pandaplan.core.pplog as logging @@ -162,10 +169,10 @@ def get_equivalent(net, eq_type, boundary_buses, internal_buses, ext_buses_with_xward = net.xward.bus[net.xward.bus.isin(all_external_buses)] if len(ext_buses_with_ward): logger.debug("ward elements of the external network are replaced by internal elements.") - pp.replace_ward_by_internal_elements(net, wards=ext_buses_with_ward.index) + replace_ward_by_internal_elements(net, wards=ext_buses_with_ward.index) if len(ext_buses_with_xward): logger.debug("xward elements of the external network are replaced by internal elements.") - pp.replace_xward_by_internal_elements(net, xwards=ext_buses_with_xward.index) + replace_xward_by_internal_elements(net, xwards=ext_buses_with_xward.index) # --- switch from ward injection to ward addmittance if requested if eq_type in ["ward", "xward"] and ward_type == "ward_admittance": @@ -176,9 +183,9 @@ def get_equivalent(net, eq_type, boundary_buses, internal_buses, if eq_type == "rei": # --- create zero power balance network net_zpbn, net_internal, _ = _create_net_zpbn( - net, boundary_buses, all_internal_buses, - all_external_buses, calc_volt_angles=calculate_voltage_angles, - runpp_fct=runpp_fct, **kwargs) + net, boundary_buses, all_internal_buses, + all_external_buses, calc_volt_angles=calculate_voltage_angles, + runpp_fct=runpp_fct, **kwargs) # --- determine bus-lookups for the following calculation bus_lookups = _create_bus_lookups( @@ -210,7 +217,7 @@ def get_equivalent(net, eq_type, boundary_buses, internal_buses, calc_volt_angles=calculate_voltage_angles, runpp_fct=runpp_fct) # --- remove buses without power flow results in net_eq - pp.drop_buses(net_external, net_external.res_bus.index[net_external.res_bus.vm_pu.isnull()]) + drop_buses(net_external, net_external.res_bus.index[net_external.res_bus.vm_pu.isnull()]) # --- determine bus-lookups for the following calculation bus_lookups = _create_bus_lookups( @@ -218,7 +225,7 @@ def get_equivalent(net, eq_type, boundary_buses, internal_buses, all_external_buses, boundary_buses_inclusive_bswitch) # --- cacluate equivalent Ybus accourding to gaussian elimination - Ybus_eq = _calculate_equivalent_Ybus(net_external, bus_lookups, + Ybus_eq = _calculate_equivalent_Ybus(net_external, bus_lookups, eq_type, show_computing_time, check_validity=False) @@ -279,7 +286,7 @@ def get_equivalent(net, eq_type, boundary_buses, internal_buses, match_cost_functions_and_eq_net(net_eq, boundary_buses, eq_type) time_end = time.perf_counter() - logger.info("%s equivalent finished in %.2f seconds." % (eq_type, time_end-time_start)) + logger.info("%s equivalent finished in %.2f seconds." % (eq_type, time_end - time_start)) if kwargs.get("add_group", True): # declare a group for the new equivalent @@ -316,15 +323,15 @@ def get_equivalent(net, eq_type, boundary_buses, internal_buses, # will be considered here which is wrong. Furthermore, the indices may have changed # from net to net_eq, so that already existing groups with reference_columns == None # may fail their functionality - new_idx = new_idx[~pp.isin_group(net_eq, elm, new_idx)] + new_idx = new_idx[~isin_group(net_eq, elm, new_idx)] if len(new_idx): eq_elms[elm] = list(new_idx) - gr_idx = pp.create_group_from_dict(net_eq, eq_elms, name=kwargs.get("group_name", eq_type)) + gr_idx = create_group_from_dict(net_eq, eq_elms, name=kwargs.get("group_name", eq_type)) reference_column = kwargs.get("reference_column", None) if reference_column is not None: - pp.set_group_reference_column(net_eq, gr_idx, reference_column) + set_group_reference_column(net_eq, gr_idx, reference_column) return net_eq @@ -365,13 +372,13 @@ def merge_internal_net_and_equivalent_external_net( # --- drop bus elements attached to boundary buses in the internal net if kwargs.pop("drop_boundary_buses", True): - pp.drop_elements_at_buses(net_internal, boundary_buses_inclusive_bswitch, - branch_elements=False) + drop_elements_at_buses(net_internal, boundary_buses_inclusive_bswitch, branch_elements=False) # --- merge equivalent external net and internal net - merged_net = pp.merge_nets( + merged_net = merge_nets( net_internal, net_eq, validate=kwargs.pop("validate", False), - net2_reindex_log_level=kwargs.pop("net2_reindex_log_level", "debug"), **kwargs) + net2_reindex_log_level=kwargs.pop("net2_reindex_log_level", "debug"), **kwargs + ) # --- fuse or combine the boundary buses in external and internal nets if fuse_bus_column == "auto": @@ -395,7 +402,7 @@ def merge_internal_net_and_equivalent_external_net( "The code expects all boundary buses to occur double. One because " "of net_eq and one because of net_internal. However target_buses is " "'%s'." % str(target_buses)) - pp.fuse_buses(merged_net, target_buses[0], target_buses[1]) + fuse_buses(merged_net, target_buses[0], target_buses[1]) # --- drop assist elements drop_assist_elms_by_creating_ext_net(merged_net) @@ -408,13 +415,13 @@ def merge_internal_net_and_equivalent_external_net( if sum(is_total_bus): max_non_total_bus_idx = merged_net.bus[~is_total_bus].index.values.max() lookup = dict(zip(merged_net.bus.index[is_total_bus], range( - max_non_total_bus_idx+1, max_non_total_bus_idx + sum(is_total_bus)+1))) - pp.reindex_buses(merged_net, lookup) + max_non_total_bus_idx + 1, max_non_total_bus_idx + sum(is_total_bus) + 1))) + reindex_buses(merged_net, lookup) t_end = time.perf_counter() if show_computing_time: logger.info("'merge_int_and_eq_net' finished in %s seconds." % - round((t_end-t_start), 2)) + round((t_end - t_start), 2)) return merged_net @@ -431,8 +438,7 @@ def drop_repeated_characteristic(net): net.characteristic = net.characteristic.drop(repeated_idxs) -def _determine_bus_groups(net, boundary_buses, internal_buses, - show_computing_time=False): +def _determine_bus_groups(net, boundary_buses, internal_buses, show_computing_time=False): """ Defines bus groups according to the given boundary buses and internal buses. @@ -477,16 +483,16 @@ def _determine_bus_groups(net, boundary_buses, internal_buses, if internal_buses & boundary_buses: logger.info("Some internal buses are also contained in the boundary buses, " + - "this could cause small inaccuracy.") + "this could cause small inaccuracy.") # --- determine buses connected to boundary buses via bus-bus-switch boundary_buses_inclusive_bswitch = set() - mg_sw = top.create_nxgraph(net, respect_switches=True, include_lines=False, include_impedances=False, - include_tcsc=False, include_trafos=False, include_trafo3ws=False) + mg_sw = create_nxgraph(net, respect_switches=True, include_lines=False, include_impedances=False, + include_tcsc=False, include_trafos=False, include_trafo3ws=False) for bbus in boundary_buses: - boundary_buses_inclusive_bswitch |= set(top.connected_component(mg_sw, bbus)) + boundary_buses_inclusive_bswitch |= set(connected_component(mg_sw, bbus)) if len(boundary_buses_inclusive_bswitch) > len(boundary_buses): - logger.info("There are some buses connected to the boundary buses via "+ + logger.info("There are some buses connected to the boundary buses via " + "bus-bus-switches. They could be the nodes on the same bus bar " + "of the boundary buses. It is suggested to consider all these " + "buses (the connected buses and the given boundary buses) " + @@ -498,8 +504,8 @@ def _determine_bus_groups(net, boundary_buses, internal_buses, internal_buses = set() else: internal_buses = set(internal_buses) - mg = top.create_nxgraph(net) - cc = top.connected_components(mg, notravbuses=boundary_buses_inclusive_bswitch) + mg = create_nxgraph(net) + cc = connected_components(mg, notravbuses=boundary_buses_inclusive_bswitch) while True: try: buses = next(cc) @@ -511,20 +517,20 @@ def _determine_bus_groups(net, boundary_buses, internal_buses, # --- determine all external buses all_external_buses = set(net.bus.index) - unsupplied_buses - \ - all_internal_buses - boundary_buses_inclusive_bswitch + all_internal_buses - boundary_buses_inclusive_bswitch # --- move all slack buses from external net to boundary if no slack is # in boundary or internal - slack_buses = set(net.ext_grid.bus[net.ext_grid.in_service]) |\ - set(net.gen.bus[net.gen.in_service & net.gen.slack]) + slack_buses = set(net.ext_grid.bus[net.ext_grid.in_service]) | \ + set(net.gen.bus[net.gen.in_service & net.gen.slack]) if len(all_internal_buses) and not len(( - all_internal_buses | boundary_buses_inclusive_bswitch) & - slack_buses): + all_internal_buses | boundary_buses_inclusive_bswitch) & + slack_buses): if not len(slack_buses): raise ValueError("There is no active slack in the net.") for bbus in slack_buses & all_external_buses: boundary_buses |= {bbus} - bbus_bswitch = set(top.connected_component(mg_sw, bbus)) + bbus_bswitch = set(connected_component(mg_sw, bbus)) boundary_buses_inclusive_bswitch |= bbus_bswitch all_external_buses -= {bbus} | bbus_bswitch @@ -534,25 +540,24 @@ def _determine_bus_groups(net, boundary_buses, internal_buses, t_end = time.perf_counter() if show_computing_time: logger.info("\"determine_bus_groups\" finished in %s seconds." % - round((t_end-t_start), 2)) + round((t_end - t_start), 2)) return sorted(all_internal_buses), sorted(all_external_buses), \ sorted(boundary_buses_inclusive_bswitch), sorted(boundary_buses) -def _check_bus_groups(all_internal_buses, all_external_buses, internal_buses, - boundary_buses): +def _check_bus_groups(all_internal_buses, all_external_buses, internal_buses, boundary_buses): """ Checks the plausibility of the bus groups. """ missing_internals = internal_buses - all_internal_buses if len(missing_internals) and not (missing_internals & boundary_buses): raise ValueError("These internal buses miss in 'all_internal_buses': " + str(sorted( - missing_internals))) + missing_internals))) in_and_extern_buses = all_internal_buses & all_external_buses if len(in_and_extern_buses): raise ValueError("These buses are in 'all_internal_buses' and 'all_external_buses': " + str( - sorted(in_and_extern_buses))) + sorted(in_and_extern_buses))) def _get_buses_after_merge(net_eq, net_internal, bus_lookups, return_internal): @@ -568,7 +573,7 @@ def _get_buses_after_merge(net_eq, net_internal, bus_lookups, return_internal): else: ib_buses_after_merge = bus_lookups["bus_lookup_pd"]["b_area_buses"] be_buses_after_merge = bus_lookups["bus_lookup_pd"]["b_area_buses"] + \ - bus_lookups["bus_lookup_pd"]["e_area_buses"] + bus_lookups["bus_lookup_pd"]["e_area_buses"] return ib_buses_after_merge, be_buses_after_merge @@ -576,8 +581,9 @@ def _get_buses_after_merge(net_eq, net_internal, bus_lookups, return_internal): """ --- quick test --- """ # pp.logger.setLevel(logging.ERROR) # logger.setLevel(logging.DEBUG) - import pandapower.networks as pn - net = pn.case9() + from pandapower.networks import case9 + + net = case9() net.ext_grid.vm_pu = 1.04 net.gen.vm_pu[0] = 1.025 net.gen.vm_pu[1] = 1.025 @@ -590,7 +596,7 @@ def _get_buses_after_merge(net_eq, net_internal, bus_lookups, return_internal): internal_buses = [0] return_internal = True show_computing_time = False - pp.runpp(net, calculate_voltage_angles=True) + runpp(net, calculate_voltage_angles=True) net_org = deepcopy(net) eq_type = "rei" net_eq = get_equivalent(net, eq_type, boundary_buses, @@ -605,7 +611,3 @@ def _get_buses_after_merge(net_eq, net_internal, bus_lookups, return_internal): # net_eq.sn_mva = 10 # pp.runpp(net_eq, calculate_voltage_angles=True) # print(net_eq.res_bus.loc[[0,3]]) - - - - diff --git a/pandapower/grid_equivalents/rei_generation.py b/pandapower/grid_equivalents/rei_generation.py index c217776e7..ceb79f047 100644 --- a/pandapower/grid_equivalents/rei_generation.py +++ b/pandapower/grid_equivalents/rei_generation.py @@ -1,19 +1,25 @@ -from pandas.api.types import is_bool_dtype, is_numeric_dtype #, is_integer_dtype -import pandapower as pp -from pandapower.grid_equivalents.auxiliary import calc_zpbn_parameters, \ - drop_internal_branch_elements, \ - build_ppc_and_Ybus, drop_measurements_and_controllers, \ - drop_and_edit_cost_functions, _runpp_except_voltage_angles, \ - replace_motor_by_load, impedance_columns +from pandas.api.types import is_bool_dtype, is_numeric_dtype + +from pandapower.auxiliary import LoadflowNotConverged +from pandapower.create import create_buses, create_bus, create_load, create_sgen, create_gen, create_impedance +from pandapower.toolbox.grid_modification import drop_buses +from pandapower.grid_equivalents.auxiliary import ( + calc_zpbn_parameters, + drop_internal_branch_elements, + build_ppc_and_Ybus, drop_measurements_and_controllers, + drop_and_edit_cost_functions, _runpp_except_voltage_angles, + replace_motor_by_load, + impedance_columns +) from pandapower.grid_equivalents.toolbox import get_connected_switch_buses_groups from copy import deepcopy import pandas as pd import numpy as np import operator import time -import uuid import re from functools import reduce + try: import pandaplan.core.pplog as logging except ImportError: @@ -65,25 +71,25 @@ def _calculate_equivalent_Ybus(net_zpbn, bus_lookups, eq_type, nb_dict = {} for key in bus_lookup_ppc.keys(): if key != "b_area_buses_no_switch": - nb_dict["nb_"+key.split("_")[0]] = len(bus_lookup_ppc[key]) + nb_dict["nb_" + key.split("_")[0]] = len(bus_lookup_ppc[key]) Ybus_buses = list(bus_lookup_ppc.values()) Ybus_new_sequence = reduce(operator.concat, Ybus_buses) # --- transform Ybus_origin to Ybus_new according to the Ybus_new_sequence Ybus_sorted = Ybus_origin[:, Ybus_new_sequence][Ybus_new_sequence] if eq_type == "xward": - idx_large_y = np.linspace(0, len(Ybus_new_sequence)-1, len(Ybus_new_sequence)) - idx_large_y = ((idx_large_y >= nb_dict["nb_i"]+nb_dict["nb_b"]) & + idx_large_y = np.linspace(0, len(Ybus_new_sequence) - 1, len(Ybus_new_sequence)) + idx_large_y = ((idx_large_y >= nb_dict["nb_i"] + nb_dict["nb_b"]) & (np.isin(Ybus_new_sequence[:], net_zpbn._ppc["gen"][:, 0]))) Ybus_sorted[idx_large_y, idx_large_y] = 1e8 # --- calculate calculate equivalent Ybus and equivalent Ybus without_internals Ybus_bb = Ybus_sorted[nb_dict["nb_i"]:(nb_dict["nb_i"] + nb_dict["nb_b"] + nb_dict["nb_t"]), - nb_dict["nb_i"]:(nb_dict["nb_i"] + nb_dict["nb_b"] + nb_dict["nb_t"])] + nb_dict["nb_i"]:(nb_dict["nb_i"] + nb_dict["nb_b"] + nb_dict["nb_t"])] Ybus_ee = Ybus_sorted[-(nb_dict["nb_e"] + nb_dict["nb_g"]):, - -(nb_dict["nb_e"] + nb_dict["nb_g"]):] + -(nb_dict["nb_e"] + nb_dict["nb_g"]):] Ybus_eb = Ybus_sorted[-(nb_dict["nb_e"] + nb_dict["nb_g"]):, - nb_dict["nb_i"]:(nb_dict["nb_i"] + nb_dict["nb_b"] + nb_dict["nb_t"])] + nb_dict["nb_i"]:(nb_dict["nb_i"] + nb_dict["nb_b"] + nb_dict["nb_t"])] Ybus_be = Ybus_eb.T try: @@ -95,14 +101,14 @@ def _calculate_equivalent_Ybus(net_zpbn, bus_lookups, eq_type, inverse_Ybus_ee = np.linalg.pinv(Ybus_ee) Ybus_eq_boundary = Ybus_bb - (Ybus_be * inverse_Ybus_ee * Ybus_eb) Ybus_eq = np.copy(Ybus_sorted[0: nb_dict["nb_i"] + nb_dict["nb_b"] + nb_dict["nb_t"], - 0: nb_dict["nb_i"] + nb_dict["nb_b"] + nb_dict["nb_t"]]) + 0: nb_dict["nb_i"] + nb_dict["nb_b"] + nb_dict["nb_t"]]) Ybus_eq[-(nb_dict["nb_b"] + nb_dict["nb_t"]):, -(nb_dict["nb_b"] + nb_dict["nb_t"]):] = Ybus_eq_boundary t_end = time.perf_counter() if show_computing_time: logger.info("\"calculate_equivalent_Ybus\" finished in %s seconds:" % round(( - t_end-t_start), 2)) + t_end - t_start), 2)) return Ybus_eq @@ -112,8 +118,8 @@ def adapt_impedance_params(Z, sign=1, adaption=1e-15): zpbn network is singular. The routine is unsolvalbe with it. In response, an impedance adaption is created and added. """ - rft_pu = Z.real + sign*adaption - xft_pu = Z.imag + sign*adaption + rft_pu = Z.real + sign * adaption + xft_pu = Z.imag + sign * adaption return rft_pu, xft_pu @@ -154,11 +160,11 @@ def _create_net_zpbn(net, boundary_buses, all_internal_buses, all_external_buses """ net_internal, net_external = _get_internal_and_external_nets( - net, boundary_buses, all_internal_buses, all_external_buses, - show_computing_time, calc_volt_angles=calc_volt_angles, runpp_fct=runpp_fct, **kwargs) + net, boundary_buses, all_internal_buses, all_external_buses, + show_computing_time, calc_volt_angles=calc_volt_angles, runpp_fct=runpp_fct, **kwargs) net_zpbn = net_external # --- remove buses without power flow results in net_eq - pp.drop_buses(net_zpbn, net_zpbn.res_bus.index[net_zpbn.res_bus.vm_pu.isnull()]) + drop_buses(net_zpbn, net_zpbn.res_bus.index[net_zpbn.res_bus.vm_pu.isnull()]) Z, S, v, limits = calc_zpbn_parameters(net_zpbn, boundary_buses, all_external_buses) # --- remove the original load, sgen and gen in exteranl area, @@ -171,41 +177,41 @@ def _create_net_zpbn(net, boundary_buses, all_internal_buses, all_external_buses if elm == "ext_grid": continue - if not np.isnan(Z[elm+"_ground"].values).all(): + if not np.isnan(Z[elm + "_ground"].values).all(): if separate: - Z = Z.drop([elm+"_integrated_total"], axis=1) + Z = Z.drop([elm + "_integrated_total"], axis=1) # add buses - idxs = Z.index[~np.isnan(Z[elm+"_ground"].values)] + idxs = Z.index[~np.isnan(Z[elm + "_ground"].values)] vn_kvs = net_zpbn.bus.vn_kv[Z.ext_bus.loc[idxs]] - new_g_buses = pp.create_buses(net_zpbn, len(idxs), vn_kvs, name=[ + new_g_buses = create_buses(net_zpbn, len(idxs), vn_kvs, name=[ "%s_separate-ground %s" % (elm, str(Z.ext_bus.loc[i])) for i in idxs]) - new_t_buses = pp.create_buses(net_zpbn, len(idxs), vn_kvs, name=[ + new_t_buses = create_buses(net_zpbn, len(idxs), vn_kvs, name=[ "%s_separate-total %s" % (elm, str(Z.ext_bus.loc[i])) for i in idxs], - max_vm_pu = limits.max_vm_pu.loc[idxs], min_vm_pu=limits.min_vm_pu.loc[idxs]) + max_vm_pu=limits.max_vm_pu.loc[idxs], min_vm_pu=limits.min_vm_pu.loc[idxs]) # add impedances - rft_pu_g, xft_pu_g = adapt_impedance_params(Z[elm+"_ground"].loc[idxs].values) + rft_pu_g, xft_pu_g = adapt_impedance_params(Z[elm + "_ground"].loc[idxs].values) max_idx = net_zpbn.impedance.index.max() if net_zpbn.impedance.shape[0] else 0 new_imps_g = pd.DataFrame({ "from_bus": Z.ext_bus.loc[idxs].astype(np.int64).values, "to_bus": new_g_buses, "rft_pu": rft_pu_g, "xft_pu": xft_pu_g, "rtf_pu": rft_pu_g, "xtf_pu": xft_pu_g, "gf_pu": 0, "bf_pu": 0, "gt_pu": 0, "bt_pu": 0}, - index=range(max_idx+1, max_idx+1+len(new_g_buses))) + index=range(max_idx + 1, max_idx + 1 + len(new_g_buses))) new_imps_g["name"] = "eq_impedance_ext_to_ground" new_imps_g["sn_mva"] = sn_mva new_imps_g["in_service"] = True - rft_pu_t, xft_pu_t = adapt_impedance_params(Z[elm+"_separate_total"].loc[ - idxs].values) + rft_pu_t, xft_pu_t = adapt_impedance_params(Z[elm + "_separate_total"].loc[ + idxs].values) new_imps_t = pd.DataFrame({ "from_bus": new_g_buses, "to_bus": new_t_buses, "rft_pu": rft_pu_t, "xft_pu": xft_pu_t, "rtf_pu": rft_pu_t, "xtf_pu": xft_pu_t, "gf_pu": 0, "bf_pu": 0, "gt_pu": 0, "bt_pu": 0}, - index=range(new_imps_g.index.max()+1, - new_imps_g.index.max()+1+len(new_g_buses))) + index=range(new_imps_g.index.max() + 1, + new_imps_g.index.max() + 1 + len(new_g_buses))) new_imps_t["name"] = "eq_impedance_ground_to_total" new_imps_t["sn_mva"] = sn_mva new_imps_t["in_service"] = True @@ -214,29 +220,29 @@ def _create_net_zpbn(net, boundary_buses, all_internal_buses, all_external_buses g_buses += list(new_g_buses) t_buses += list(new_t_buses) else: - Z = Z.drop([elm+"_separate_total"], axis=1) + Z = Z.drop([elm + "_separate_total"], axis=1) vn_kv = net_zpbn.bus.vn_kv[all_external_buses].values[0] - new_g_bus = pp.create_bus(net_zpbn, vn_kv, name=elm+"_integrated-ground ") + new_g_bus = create_bus(net_zpbn, vn_kv, name=elm + "_integrated-ground ") i_all_integrated = [] - for i in Z.index[~np.isnan(Z[elm+"_ground"].values)]: - rft_pu, xft_pu = adapt_impedance_params(Z[elm+"_ground"][i]) - pp.create_impedance(net_zpbn, Z.ext_bus[i], new_g_bus, rft_pu, xft_pu, - sn_mva,name="eq_impedance_ext_to_ground") + for i in Z.index[~np.isnan(Z[elm + "_ground"].values)]: + rft_pu, xft_pu = adapt_impedance_params(Z[elm + "_ground"][i]) + create_impedance(net_zpbn, Z.ext_bus[i], new_g_bus, rft_pu, xft_pu, + sn_mva, name="eq_impedance_ext_to_ground") i_all_integrated.append(i) # in case of integrated, the tightest vm limits are assumed - ext_buses = Z.ext_bus[~np.isnan(Z[elm+"_ground"])].values + ext_buses = Z.ext_bus[~np.isnan(Z[elm + "_ground"])].values ext_buses_name = "/".join([str(eb) for eb in ext_buses]) - new_t_bus = pp.create_bus( - net_zpbn, vn_kv, name=elm+"_integrated-total "+ext_buses_name, + new_t_bus = create_bus( + net_zpbn, vn_kv, name=elm + "_integrated-total " + ext_buses_name, max_vm_pu=limits.max_vm_pu.loc[i_all_integrated].min(), min_vm_pu=limits.min_vm_pu.loc[i_all_integrated].max()) - rft_pu, xft_pu = adapt_impedance_params(Z[elm+"_integrated_total"][0]) - pp.create_impedance(net_zpbn, new_g_bus, new_t_bus, rft_pu, xft_pu, - sn_mva, name="eq_impedance_ground_to_total") + rft_pu, xft_pu = adapt_impedance_params(Z[elm + "_integrated_total"][0]) + create_impedance(net_zpbn, new_g_bus, new_t_bus, rft_pu, xft_pu, + sn_mva, name="eq_impedance_ground_to_total") g_buses += [new_g_bus.tolist()] t_buses += [new_t_bus.tolist()] else: - Z.drop([elm+"_ground", elm+"_separate_total", elm+"_integrated_total"], axis=1, + Z.drop([elm + "_ground", elm + "_separate_total", elm + "_integrated_total"], axis=1, inplace=True) # --- create load, sgen and gen @@ -252,19 +258,19 @@ def _create_net_zpbn(net, boundary_buses, all_internal_buses, all_external_buses idx = S.index[S.ext_bus == bus].values[0] P = S[key][idx].real * sn_mva Q = S[key][idx].imag * sn_mva - Sn = S["sn_"+key][idx].real + Sn = S["sn_" + key][idx].real if elm == "load": - elm_idx = pp.create_load(net_zpbn, i, -float(P), -float(Q), name=key+"_rei_"+busstr, - sn_mva=Sn, index=max_load_idx+len(net_zpbn.load)+1) + elm_idx = create_load(net_zpbn, i, -float(P), -float(Q), name=key + "_rei_" + busstr, + sn_mva=Sn, index=max_load_idx + len(net_zpbn.load) + 1) elif elm == "sgen": - elm_idx = pp.create_sgen(net_zpbn, i, float(P), float(Q), name=key+"_rei_"+busstr, - sn_mva=Sn, index=max_sgen_idx+len(net_zpbn.sgen)+1) + elm_idx = create_sgen(net_zpbn, i, float(P), float(Q), name=key + "_rei_" + busstr, + sn_mva=Sn, index=max_sgen_idx + len(net_zpbn.sgen) + 1) elif elm == "gen": - vm_pu = v[key+"_vm_total"][v.ext_bus == int(re.findall(r"\d+", busstr)[0])].values.real - elm_idx = pp.create_gen(net_zpbn, i, float(P), float(vm_pu.item()), name=key+"_rei_"+busstr, - sn_mva=Sn, index=max_gen_idx+len(net_zpbn.gen)+1) + vm_pu = v[key + "_vm_total"][v.ext_bus == int(re.findall(r"\d+", busstr)[0])].values.real + elm_idx = create_gen(net_zpbn, i, float(P), float(vm_pu.item()), name=key + "_rei_" + busstr, + sn_mva=Sn, index=max_gen_idx + len(net_zpbn.gen) + 1) - # ---- match other columns + # ---- match other columns elm_org = net[elm] if elm_old is None or elm_old != elm: other_cols = set(elm_org.columns) - \ @@ -289,7 +295,7 @@ def _create_net_zpbn(net, boundary_buses, all_internal_buses, all_external_buses other_cols_bool |= {c} elif value_types[0] == str: other_cols_str |= {c} - else: # value_types[0] is None: + else: # value_types[0] is None: other_cols_none |= {c} other_cols -= {c} assert len(other_cols) == 0 @@ -301,9 +307,10 @@ def _create_net_zpbn(net, boundary_buses, all_internal_buses, all_external_buses net_zpbn[elm].loc[elm_idx, list(other_cols_number)] = \ elm_org[list(other_cols_number)][elm_org.bus.isin(all_external_buses)].sum(axis=0) net_zpbn[elm].loc[elm_idx, list(other_cols_bool)] = elm_org[list(other_cols_bool)][ - elm_org.bus.isin(all_external_buses)].values.sum(axis=0) > 0 - all_str_values = list(zip(*elm_org[list(other_cols_str)]\ - [elm_org.bus.isin(all_external_buses)].values[::-1])) + elm_org.bus.isin(all_external_buses)].values.sum( + axis=0) > 0 + all_str_values = list(zip(*elm_org[list(other_cols_str)] \ + [elm_org.bus.isin(all_external_buses)].values[::-1])) for asv, colid in zip(all_str_values, other_cols_str): if len(set(asv)) == 1: net_zpbn[elm].loc[elm_idx, colid] = asv[0] @@ -317,9 +324,10 @@ def _create_net_zpbn(net, boundary_buses, all_internal_buses, all_external_buses if elm == "gen" and bus in net.ext_grid.bus.values and \ net.ext_grid.in_service[net.ext_grid.bus == bus].values[0]: net_zpbn[elm].loc[elm_idx, 'name'] = str(net.ext_grid.name[ - net.ext_grid.bus == bus].values[0]) + "-" + net_zpbn[elm].name[elm_idx] + net.ext_grid.bus == bus].values[0]) + "-" + \ + net_zpbn[elm].name[elm_idx] ext_grid_cols = list(set(elm_org.columns) & set(net.ext_grid.columns) - \ - {"name", "bus", "p_mw", "sn_mva", "in_service", "scaling"}) + {"name", "bus", "p_mw", "sn_mva", "in_service", "scaling"}) net_zpbn[elm].loc[elm_idx, ext_grid_cols] = net.ext_grid[ext_grid_cols][ net.ext_grid.bus == bus].values[0] else: @@ -335,8 +343,8 @@ def _create_net_zpbn(net, boundary_buses, all_internal_buses, all_external_buses net_zpbn[elm].loc[elm_idx, list(other_cols_bool)] = \ elm_org[list(other_cols_bool)][elm_org.bus == bus].values.sum(axis=0) > 0 - all_str_values = list(zip(*elm_org[list(other_cols_str)]\ - [elm_org.bus == bus].values[::-1])) + all_str_values = list(zip(*elm_org[list(other_cols_str)] \ + [elm_org.bus == bus].values[::-1])) for asv, colid in zip(all_str_values, other_cols_str): if len(set(asv)) == 1: net_zpbn[elm].loc[elm_idx, colid] = asv[0] @@ -361,9 +369,9 @@ def _create_net_zpbn(net, boundary_buses, all_internal_buses, all_external_buses if len(net[cost_elm]): df = net_zpbn[cost_elm].copy() df.loc[(df.et == "ext_grid") & - (~df.bus.isin(boundary_buses)), 'et'] = "gen" + (~df.bus.isin(boundary_buses)), 'et'] = "gen" df.loc[(df.et.isin(["storage", "dcline"]) & - (~df.bus.isin(boundary_buses))), 'et'] = "load" + (~df.bus.isin(boundary_buses))), 'et'] = "load" logger.debug("During the equivalencing, also in polt_cost, " + "storages and dclines are treated as loads, and" + @@ -426,9 +434,9 @@ def _create_bus_lookups(net_zpbn, boundary_buses, all_internal_buses, bus_lookup_pd = {"i_area_buses": [], "b_area_buses": boundary_buses, "t_area_buses": net_zpbn.bus.index[net_zpbn.bus.name.str.contains( - "-total", na=False)].tolist(), + "-total", na=False)].tolist(), "g_area_buses": net_zpbn.bus.index[net_zpbn.bus.name.str.contains( - "-ground", na=False)].tolist(), + "-ground", na=False)].tolist(), "e_area_buses": all_external_buses, "b_area_buses_no_switch": []} @@ -436,12 +444,12 @@ def _create_bus_lookups(net_zpbn, boundary_buses, all_internal_buses, bus_lookup_ppc = bus_lookup_pd.copy() bus_lookup_ppc_origin = bus_lookup_pd.copy() for key in ["b", "i", "e", "g", "t"]: - bus_lookup_ppc[key+"_area_buses"] = pd2ppc_bus_lookup[list(bus_lookup_pd[ - key+"_area_buses"])].tolist() - origin_sequence = bus_lookup_ppc[key+"_area_buses"].copy() + bus_lookup_ppc[key + "_area_buses"] = pd2ppc_bus_lookup[list(bus_lookup_pd[ + key + "_area_buses"])].tolist() + origin_sequence = bus_lookup_ppc[key + "_area_buses"].copy() # remove repeated "neg." (e.g. bus-bus-switch) ppc buses - bus_lookup_ppc[key+"_area_buses"] = sorted(set(bus_lookup_ppc[ - key+"_area_buses"]), key=origin_sequence.index) + bus_lookup_ppc[key + "_area_buses"] = sorted(set(bus_lookup_ppc[ + key + "_area_buses"]), key=origin_sequence.index) if key == "b": # bus_lookup_pd["b_area_buses_no_switch"] = bus_lookup_pd[key+"_area_buses"].copy() # for i in range(len(bus_lookup_ppc[key+"_area_buses"])): @@ -449,9 +457,9 @@ def _create_bus_lookups(net_zpbn, boundary_buses, all_internal_buses, # pd2ppc_bus_lookup[bus_lookup_pd["b_area_buses_no_switch"][i]]: # del bus_lookup_pd["b_area_buses_no_switch"][i] - bus_lookup_pd["b_area_buses_no_switch"] = bus_lookup_pd[key+"_area_buses"].copy() + bus_lookup_pd["b_area_buses_no_switch"] = bus_lookup_pd[key + "_area_buses"].copy() val_ppc = [] - for val in bus_lookup_pd[key+"_area_buses"].copy(): + for val in bus_lookup_pd[key + "_area_buses"].copy(): if pd2ppc_bus_lookup[val] in val_ppc: bus_lookup_pd["b_area_buses_no_switch"].remove(val) else: @@ -460,9 +468,9 @@ def _create_bus_lookups(net_zpbn, boundary_buses, all_internal_buses, # remove ppc buses appearing in b_area as well as in i_area or e_area if key != "b": common_ppc_busese = set(bus_lookup_ppc["b_area_buses"]) & set(bus_lookup_ppc[ - key+"_area_buses"]) + key + "_area_buses"]) if common_ppc_busese: - bus_lookup_ppc[key+"_area_buses"].remove(list(common_ppc_busese)) + bus_lookup_ppc[key + "_area_buses"].remove(list(common_ppc_busese)) if key == "b" and len(bus_lookup_ppc["b_area_buses"]) != len(bus_lookup_pd["b_area_buses"]): logger.info("some boundary buses are connetected via switches") @@ -470,7 +478,7 @@ def _create_bus_lookups(net_zpbn, boundary_buses, all_internal_buses, Ybus_size = net_zpbn._ppc["internal"]["Ybus"]._shape[0] all_ppc_buses_lists = list(bus_lookup_ppc.values()) all_ppc_buses = reduce(operator.concat, all_ppc_buses_lists) - pos_aux_buses_ppc = set(np.arange(Ybus_size))-set(all_ppc_buses) + pos_aux_buses_ppc = set(np.arange(Ybus_size)) - set(all_ppc_buses) # --- identify the "pos." (eg. bus-line-switch) ppc buses belongs zu which bus group if pos_aux_buses_ppc: @@ -502,7 +510,7 @@ def _create_bus_lookups(net_zpbn, boundary_buses, all_internal_buses, "origin_all_internal_buses": all_internal_buses}) t_end = time.perf_counter() if show_computing_time: - logger.info("\"create_bus_lookup\" finished in %s seconds:" % round((t_end-t_start), 2)) + logger.info("\"create_bus_lookup\" finished in %s seconds:" % round((t_end - t_start), 2)) return bus_lookups @@ -518,9 +526,9 @@ def _get_internal_and_external_nets(net, boundary_buses, all_internal_buses, net_internal = deepcopy(net) drop_measurements_and_controllers(net_internal, all_external_buses, True) drop_and_edit_cost_functions(net_internal, - all_external_buses+boundary_buses, + all_external_buses + boundary_buses, True, True) - pp.drop_buses(net_internal, all_external_buses) + drop_buses(net_internal, all_external_buses) net_external = deepcopy(net) if "group" in net_external: @@ -528,17 +536,17 @@ def _get_internal_and_external_nets(net, boundary_buses, all_internal_buses, drop_and_edit_cost_functions(net_external, all_internal_buses, True, True) drop_measurements_and_controllers(net_external, net_external.bus.index.tolist()) - pp.drop_buses(net_external, all_internal_buses) + drop_buses(net_external, all_internal_buses) replace_motor_by_load(net_external, all_external_buses) -# add_ext_grids_to_boundaries(net_external, boundary_buses, runpp_fct=runpp_fct, **kwargs) -# runpp_fct(net_external, calculate_voltage_angles=calc_volt_angles, **kwargs) + # add_ext_grids_to_boundaries(net_external, boundary_buses, runpp_fct=runpp_fct, **kwargs) + # runpp_fct(net_external, calculate_voltage_angles=calc_volt_angles, **kwargs) _integrate_power_elements_connected_with_switch_buses(net, net_external, - all_external_buses) # for sgens, gens, and loads + all_external_buses) # for sgens, gens, and loads runpp_fct(net_external, calculate_voltage_angles=calc_volt_angles, **kwargs) t_end = time.perf_counter() if show_computing_time: logger.info("\"get_int_and_ext_nets\" " + - "finished in %s seconds:" % round((t_end-t_start), 2)) + "finished in %s seconds:" % round((t_end - t_start), 2)) return net_internal, net_external @@ -562,9 +570,9 @@ def _calclate_equivalent_element_params(net_zpbn, Ybus_eq, bus_lookups, t_start = time.perf_counter() # --- calculate impedance paramter bt_buses_ppc = list(bus_lookups["bus_lookup_ppc"]["b_area_buses"]) + \ - list(bus_lookups["bus_lookup_ppc"]["t_area_buses"]) + list(bus_lookups["bus_lookup_ppc"]["t_area_buses"]) bt_buses_pd = list(bus_lookups["bus_lookup_pd"]["b_area_buses_no_switch"]) + \ - list(bus_lookups["bus_lookup_pd"]["t_area_buses"]) + list(bus_lookups["bus_lookup_pd"]["t_area_buses"]) nb_bt_buses_ppc = len(bt_buses_ppc) shunt_params = pd.DataFrame(columns=["bus_pd", "bus_ppc", "parameter"]) @@ -575,9 +583,8 @@ def _calclate_equivalent_element_params(net_zpbn, Ybus_eq, bus_lookups, # --- calculate impedance paramter params = Ybus_eq[-nb_bt_buses_ppc:, -nb_bt_buses_ppc:] - nl = (nb_bt_buses_ppc) * (nb_bt_buses_ppc - 1) // 2 tri_upper = np.triu(params, k=1) - non_zero = np.abs(tri_upper) > 1/max_allowed_impedance + non_zero = np.abs(tri_upper) > 1 / max_allowed_impedance rows = (np.arange(params.shape[0]).reshape(-1, 1) * np.ones(params.shape)).astype(np.int64)[non_zero] cols = (np.arange(params.shape[1]) * np.ones(params.shape)).astype(np.int64)[non_zero] @@ -587,7 +594,7 @@ def _calclate_equivalent_element_params(net_zpbn, Ybus_eq, bus_lookups, impedance_params["rft_pu"] = (-1 / params[rows, cols]).real impedance_params["xft_pu"] = (-1 / params[rows, cols]).imag - non_zero_cr = np.abs(params[cols, rows]) > 1/max_allowed_impedance + non_zero_cr = np.abs(params[cols, rows]) > 1 / max_allowed_impedance impedance_params["rtf_pu"] = 1e5 impedance_params["xtf_pu"] = 1e5 impedance_params.loc[non_zero_cr, "rtf_pu"] = (-1 / params[cols, rows]).real[non_zero_cr] @@ -596,7 +603,7 @@ def _calclate_equivalent_element_params(net_zpbn, Ybus_eq, bus_lookups, t_end = time.perf_counter() if show_computing_time: logger.info("\"calclate_equivalent_element_params\" finished in %s seconds:" % - round((t_end-t_start), 2)) + round((t_end - t_start), 2)) return shunt_params, impedance_params @@ -609,32 +616,32 @@ def _replace_ext_area_by_impedances_and_shunts( """ # --- drop all external elements eg_buses_pd = bus_lookups["bus_lookup_pd"]["e_area_buses"] + \ - bus_lookups["bus_lookup_pd"]["g_area_buses"] - pp.drop_buses(net_eq, eg_buses_pd) + bus_lookups["bus_lookup_pd"]["g_area_buses"] + drop_buses(net_eq, eg_buses_pd) try: runpp_fct(net_eq, calculate_voltage_angles=calc_volt_angles, - tolerance_mva=1e-6, max_iteration=100, **kwargs) - except pp.LoadflowNotConverged: + tolerance_mva=1e-6, max_iteration=100, **kwargs) + except LoadflowNotConverged: logger.error("The power flow did not converge.") # --- drop all branch elements except switches between boundary buses drop_internal_branch_elements(net_eq, bus_lookups["boundary_buses_inclusive_bswitch"]) # --- drop shunt elements attached to boundary buses traget_shunt_idx = net_eq.shunt.index[net_eq.shunt.bus.isin(bus_lookups[ - "boundary_buses_inclusive_bswitch"])] + "boundary_buses_inclusive_bswitch"])] net_eq.shunt = net_eq.shunt.drop(traget_shunt_idx) # --- create impedance not_very_low_imp = (impedance_params.rft_pu.abs() > imp_threshold) | ( - impedance_params.xft_pu.abs() > imp_threshold) | ( - impedance_params.rtf_pu.abs() > imp_threshold) | ( - impedance_params.xtf_pu.abs() > imp_threshold) | ( - impedance_params.from_bus.isin(set(net_eq.gen.bus)|set(net_eq.ext_grid.bus)) & - impedance_params.to_bus.isin(set(net_eq.gen.bus)|set(net_eq.ext_grid.bus))) + impedance_params.xft_pu.abs() > imp_threshold) | ( + impedance_params.rtf_pu.abs() > imp_threshold) | ( + impedance_params.xtf_pu.abs() > imp_threshold) | ( + impedance_params.from_bus.isin(set(net_eq.gen.bus) | set(net_eq.ext_grid.bus)) & + impedance_params.to_bus.isin(set(net_eq.gen.bus) | set(net_eq.ext_grid.bus))) new_imps = impedance_params.loc[not_very_low_imp, impedance_columns] max_idx = net_eq.impedance.index.max() if net_eq.impedance.shape[0] else 0 - new_imps.index = range(max_idx+1, max_idx+1+sum(not_very_low_imp)) + new_imps.index = range(max_idx + 1, max_idx + 1 + sum(not_very_low_imp)) new_imps["name"] = "eq_impedance" new_imps["sn_mva"] = net_eq.sn_mva new_imps["in_service"] = True @@ -644,7 +651,7 @@ def _replace_ext_area_by_impedances_and_shunts( new_sws = impedance_params[["from_bus", "to_bus"]].loc[~not_very_low_imp].astype(np.int64) new_sws = new_sws.rename(columns={"from_bus": "bus", "to_bus": "element"}) max_idx = net_eq.switch.index.max() if net_eq.switch.shape[0] else 0 - new_sws.index = range(max_idx+1, max_idx+1+sum(~not_very_low_imp)) + new_sws.index = range(max_idx + 1, max_idx + 1 + sum(~not_very_low_imp)) new_sws["et"] = "b" new_sws["name"] = "eq_switch" new_sws["closed"] = True @@ -668,7 +675,7 @@ def _replace_ext_area_by_impedances_and_shunts( new_shunts = pd.DataFrame({"bus": shunt_buses, "q_mvar": -shunt_params.parameter.values.imag * net_eq.sn_mva, "p_mw": shunt_params.parameter.values.real * net_eq.sn_mva - }, index=range(max_idx+1, max_idx+1+shunt_params.shape[0])) + }, index=range(max_idx + 1, max_idx + 1 + shunt_params.shape[0])) new_shunts["name"] = "eq_shunt" isin_sh = new_shunts.bus.isin(net_eq.bus.index) new_shunts.loc[isin_sh, "vn_kv"] = net_eq.bus.vn_kv.loc[new_shunts.bus.loc[isin_sh]].values @@ -686,8 +693,8 @@ def _replace_ext_area_by_impedances_and_shunts( def _integrate_power_elements_connected_with_switch_buses(net, net_external, all_external_buses): _, bus_dict = get_connected_switch_buses_groups(net_external, all_external_buses) - active_sgen = net.sgen[(net.sgen.in_service) & ~((net["sgen"].p_mw==0) & (net["sgen"].q_mvar==0))] - active_load = net.load[(net.load.in_service) & ~((net["load"].p_mw==0) & (net["load"].q_mvar==0))] + active_sgen = net.sgen[(net.sgen.in_service) & ~((net["sgen"].p_mw == 0) & (net["sgen"].q_mvar == 0))] + active_load = net.load[(net.load.in_service) & ~((net["load"].p_mw == 0) & (net["load"].q_mvar == 0))] active_gen = net.gen[net.gen.in_service] for elm in ["sgen", "load", "gen"]: @@ -704,7 +711,7 @@ def _integrate_power_elements_connected_with_switch_buses(net, net_external, all if len(connected_elms) <= 1: continue else: # There ars some "external" elements connected with bus-bus switches. - # They will be aggregated. + # They will be aggregated. elm1 = connected_elms[0] net[elm].loc[connected_elms, 'bus'] = net[elm].bus[elm1] net_external[elm].loc[connected_elms, 'bus'] = net_external[elm].bus[elm1] diff --git a/pandapower/grid_equivalents/toolbox.py b/pandapower/grid_equivalents/toolbox.py index b365d7117..02956fed9 100644 --- a/pandapower/grid_equivalents/toolbox.py +++ b/pandapower/grid_equivalents/toolbox.py @@ -3,10 +3,12 @@ import operator import numpy as np import pandas as pd -import pandapower as pp -import pandapower.toolbox -import pandapower.topology as top -from pandapower.grid_equivalents.auxiliary import drop_internal_branch_elements + +from pandapower.auxiliary import ensure_iterability +from pandapower.toolbox.element_selection import pp_elements, element_bus_tuples +from pandapower.topology.create_graph import create_nxgraph +from pandapower.topology.graph_searches import connected_component, connected_components + try: from pandaplan.core import pplog as logging @@ -50,17 +52,17 @@ def setSetInDict(dict_, keys, set_): def append_set_to_dict(dict_, set_, keys): """ Appends a nested dict by the values of a set, independant if the keys already exist or not. """ - keys = pp.ensure_iterability(keys) + keys = ensure_iterability(keys) # ensure that the dict way to the last key exist for pos, _ in enumerate(keys[:-1]): if isinstance(getFromDict(dict_, keys[:pos]), dict): if keys[pos] not in getFromDict(dict_, keys[:pos]).keys(): - setInDict(dict_, keys[:pos+1], dict()) + setInDict(dict_, keys[:pos + 1], dict()) else: raise ValueError("This function expects a dict for 'getFromDict(dict_, " + str(keys[:pos]) + ")', not a" + str(type(getFromDict( - dict_, keys[:pos])))) + dict_, keys[:pos])))) # set the value setSetInDict(dict_, keys, set_) @@ -84,9 +86,9 @@ def set_bus_zone_by_boundary_branches(net, all_boundary_branches): else: include[elm] = True - mg = top.create_nxgraph(net, include_lines=include["line"], include_impedances=include[ + mg = create_nxgraph(net, include_lines=include["line"], include_impedances=include[ "impedance"], include_trafos=include["trafo"], include_trafo3ws=include["trafo3w"]) - cc = top.connected_components(mg) + cc = connected_components(mg) ccl = [set_ for set_ in cc] areas = [] @@ -153,6 +155,7 @@ def get_boundaries_by_bus_zone_with_boundary_branches(net): 3: {"line": {1}} } """ + def append_boundary_buses_externals_per_zone(boundary_buses, boundaries, zone, other_zone_cols): """ iterate throw all boundaries which matches this_zone and add the other_zone_bus to boundary_buses """ @@ -167,20 +170,20 @@ def append_boundary_buses_externals_per_zone(boundary_buses, boundaries, zone, o if "all" in set(net.bus.zone.values): raise ValueError("'all' is not a proper zone name.") # all is used later for other purpose - branch_elms = pandapower.toolbox.pp_elements(bus=False, bus_elements=False, branch_elements=True, - other_elements=False, res_elements=False) - branch_tuples = pandapower.toolbox.element_bus_tuples(bus_elements=False, branch_elements=True, - res_elements=False) + [("switch", "element")] + branch_elms = pp_elements(bus=False, bus_elements=False, branch_elements=True, + other_elements=False, res_elements=False) + branch_tuples = element_bus_tuples(bus_elements=False, branch_elements=True, + res_elements=False) + [("switch", "element")] branch_dict = {branch_elm: [] for branch_elm in branch_elms} for elm, bus in branch_tuples: branch_dict[elm] += [bus] zones = net.bus.zone.unique() boundary_branches = {zone if net.bus.zone.dtype == object else zone.item(): - dict() for zone in zones} + dict() for zone in zones} boundary_branches["all"] = dict() boundary_buses = {zone if net.bus.zone.dtype == object else zone.item(): - {"all": set(), "internal": set(), "external": set()} for zone in zones} + {"all": set(), "internal": set(), "external": set()} for zone in zones} boundary_buses["all"] = set() for elm, buses in branch_dict.items(): @@ -200,7 +203,7 @@ def append_boundary_buses_externals_per_zone(boundary_buses, boundaries, zone, o boundaries["is_boundary"] = False # reduce the DataFrame 'boundaries' to those branches which actually are boundaries boundaries = boundaries.loc[boundaries["is_boundary"], - boundaries.columns.difference(["is_boundary"])] + boundaries.columns.difference(["is_boundary"])] # determine boundary_branches and boundary_buses if len(boundaries): @@ -210,7 +213,7 @@ def append_boundary_buses_externals_per_zone(boundary_buses, boundaries, zone, o for zone in set(boundaries[zone_cols].values.flatten()): # determine which columns belong to this zone and which not - this_zone_col = np.zeros(boundaries.shape[0])*np.nan + this_zone_col = np.zeros(boundaries.shape[0]) * np.nan for i, _ in enumerate(buses): this_zone_col[boundaries[zone_cols[i]] == zone] = i this_zone_col = pd.Series(this_zone_col).dropna().astype(np.int64) @@ -220,7 +223,7 @@ def append_boundary_buses_externals_per_zone(boundary_buses, boundaries, zone, o other_zone_col1.loc[other_zone_col1 < 0] = 0 other_zone_col2 = pd.Series(3 * np.ones(this_zone_col.shape, dtype=np.int64), index=this_zone_col.index) - \ - this_zone_col - other_zone_col1 + this_zone_col - other_zone_col1 # fill zone dependant values to boundary_branches and boundary_buses boundary_branches[zone][elm] = set(boundaries.index[this_zone_col.index]) @@ -232,7 +235,7 @@ def append_boundary_buses_externals_per_zone(boundary_buses, boundaries, zone, o boundary_buses[zone]["all"] |= ext | nint if len(buses) == 3: ext = set(boundaries[buses].values[ - other_zone_col2.index, other_zone_col2.values]) + other_zone_col2.index, other_zone_col2.values]) boundary_buses[zone]["external"] |= ext boundary_buses[zone]["all"] |= ext @@ -257,15 +260,15 @@ def append_boundary_buses_externals_per_zone(boundary_buses, boundaries, zone, o def get_connected_switch_buses_groups(net, buses): all_buses = set() bus_dict = [] - mg_sw = top.create_nxgraph(net, include_trafos=False, - include_trafo3ws=False, - respect_switches=True, - include_lines=False, - include_impedances=False) + mg_sw = create_nxgraph(net, include_trafos=False, + include_trafo3ws=False, + respect_switches=True, + include_lines=False, + include_impedances=False) for bbus in buses: if bbus in all_buses: continue - new_bus_set = set(top.connected_component(mg_sw, bbus)) + new_bus_set = set(connected_component(mg_sw, bbus)) all_buses |= new_bus_set bus_dict.append(list(new_bus_set)) return all_buses, bus_dict diff --git a/pandapower/grid_equivalents/ward_generation.py b/pandapower/grid_equivalents/ward_generation.py index 9c0468b36..3c9ee99c1 100644 --- a/pandapower/grid_equivalents/ward_generation.py +++ b/pandapower/grid_equivalents/ward_generation.py @@ -1,4 +1,3 @@ -import pandapower as pp import time from pandapower.grid_equivalents.auxiliary import drop_internal_branch_elements, \ _runpp_except_voltage_angles, impedance_columns @@ -10,6 +9,9 @@ except ImportError: import logging +from pandapower.create import create_shunt, create_impedance, create_switch, create_ward, create_xward +from pandapower.toolbox.grid_modification import drop_buses + logger = logging.getLogger(__name__) @@ -26,7 +28,7 @@ def _calculate_ward_and_impedance_parameters(Ybus_eq, bus_lookups, show_computin ward_parameter["bus_ppc"] = b_buses_ppc ward_parameter["bus_pd"] = b_buses_pd ward_parameter["shunt"] = Ybus_eq.sum(axis=1)[-nb_b_buses_ppc:] - ward_parameter["power_eq"] = 0 + 1j*0 # power_eq.power_eq.values + ward_parameter["power_eq"] = 0 + 1j * 0 # power_eq.power_eq.values # --- calculate impedance paramter params = Ybus_eq[-nb_b_buses_ppc:, -nb_b_buses_ppc:] @@ -51,7 +53,7 @@ def _calculate_ward_and_impedance_parameters(Ybus_eq, bus_lookups, show_computin t_end = time.perf_counter() if show_computing_time: logger.info("\"calculate_ward_and_impedance_parameters\" finished in %s seconds:" % round(( - t_end-t_start), 2)) + t_end - t_start), 2)) return ward_parameter, impedance_parameter @@ -62,21 +64,21 @@ def _calculate_xward_and_impedance_parameters(net_external, Ybus_eq, bus_lookups xward_parameter, impedance_parameter = \ _calculate_ward_and_impedance_parameters(Ybus_eq, bus_lookups, False) xward_parameter["r_ohm"] = 0 - xward_parameter["x_ohm"] = -1/xward_parameter.shunt.values.imag / \ - net_external.sn_mva*net_external.bus.vn_kv[xward_parameter.bus_pd].values**2 #/2 - # np.square(net_external.bus.vn_kv[xward_parameter.bus_pd.values].values) / \ - # net_external.sn_mva/2 + xward_parameter["x_ohm"] = -1 / xward_parameter.shunt.values.imag / \ + net_external.sn_mva * net_external.bus.vn_kv[xward_parameter.bus_pd].values ** 2 #/2 + # np.square(net_external.bus.vn_kv[xward_parameter.bus_pd.values].values) / \ + # net_external.sn_mva/2 xward_parameter["vm_pu"] = net_external.res_bus.vm_pu[xward_parameter.bus_pd.values].values t_end = time.perf_counter() if show_computing_time: logger.info("\"calculate_xward_and_impedance_parameters\" finished in %s seconds:" % round(( - t_end-t_start), 2)) + t_end - t_start), 2)) return xward_parameter, impedance_parameter def create_passive_external_net_for_ward_admittance( - net, all_external_buses, boundary_buses, calc_volt_angles=True, - runpp_fct=_runpp_except_voltage_angles, **kwargs): + net, all_external_buses, boundary_buses, calc_volt_angles=True, + runpp_fct=_runpp_except_voltage_angles, **kwargs): """ This function replace the wards and xward in external network by internal elements, and replace the power injections in external area by shunts @@ -95,12 +97,12 @@ def create_passive_external_net_for_ward_admittance( v_m = net.res_bus.vm_pu[all_external_buses].values current_injections = (net.res_bus.p_mw[all_external_buses].values - 1j * net.res_bus.q_mvar[all_external_buses].values) - shunt_params = list(current_injections / v_m**2) + shunt_params = list(current_injections / v_m ** 2) # creats shunts for i in range(len(all_external_buses)): if abs(np.nan_to_num(shunt_params[i])) != 0: - pp.create_shunt(net, all_external_buses[i], -shunt_params[i].imag, - shunt_params[i].real) + create_shunt(net, all_external_buses[i], -shunt_params[i].imag, + shunt_params[i].real) # drops all power injections for elm in ["sgen", "gen", "load", "storage"]: target_idx = net[elm].index[net[elm].bus.isin(all_external_buses)] @@ -116,13 +118,13 @@ def _replace_external_area_by_wards(net_external, bus_lookups, ward_parameter_no """replaces the external networks by wards and equivalent impedance""" # --- drop all external elements e_buses_pd = bus_lookups["bus_lookup_pd"]["e_area_buses"] - pp.drop_buses(net_external, e_buses_pd) + drop_buses(net_external, e_buses_pd) drop_internal_branch_elements(net_external, bus_lookups["boundary_buses_inclusive_bswitch"]) -# runpp_fct(net_external, calculate_voltage_angles=True, **kwargs) + # runpp_fct(net_external, calculate_voltage_angles=True, **kwargs) # --- drop shunt elements attached to boundary buses traget_shunt_idx = net_external.shunt.index[net_external.shunt.bus.isin(bus_lookups[ - "boundary_buses_inclusive_bswitch"])] + "boundary_buses_inclusive_bswitch"])] net_external.shunt = net_external.shunt.drop(traget_shunt_idx) # --- creat impedance @@ -131,28 +133,28 @@ def _replace_external_area_by_wards(net_external, bus_lookups, ward_parameter_no from_bus = impedance_parameter.from_bus[idx] to_bus = impedance_parameter.to_bus[idx] if abs(impedance_parameter.rft_pu[idx]) > 1e-8 or \ - abs(impedance_parameter.xft_pu[idx]) > 1e-8 or \ - abs(impedance_parameter.rtf_pu[idx]) > 1e-8 or \ - abs(impedance_parameter.xtf_pu[idx]) > 1e-8: - pp.create_impedance(net_external, from_bus, to_bus, - impedance_parameter.rft_pu[idx], - impedance_parameter.xft_pu[idx], - sn_mva=sn, - rtf_pu=impedance_parameter.rtf_pu[idx], - xtf_pu=impedance_parameter.xtf_pu[idx], - name="eq_impedance") + abs(impedance_parameter.xft_pu[idx]) > 1e-8 or \ + abs(impedance_parameter.rtf_pu[idx]) > 1e-8 or \ + abs(impedance_parameter.xtf_pu[idx]) > 1e-8: + create_impedance(net_external, from_bus, to_bus, + impedance_parameter.rft_pu[idx], + impedance_parameter.xft_pu[idx], + sn_mva=sn, + rtf_pu=impedance_parameter.rtf_pu[idx], + xtf_pu=impedance_parameter.xtf_pu[idx], + name="eq_impedance") else: - pp.create_switch(net_external, from_bus, to_bus, "b", name="eq_switch") + create_switch(net_external, from_bus, to_bus, "b", name="eq_switch") # --- creata ward for i in ward_parameter_no_power.index: target_bus = ward_parameter_no_power.bus_pd[i] - pp.create_ward(net_external, target_bus, - 0.0, # np.nan_to_num(-ward_parameter.power_eq[i].real), - 0.0, # np.nan_to_num(-ward_parameter.power_eq[i].imag), - ward_parameter_no_power.shunt[i].real * sn / (net_external.res_bus.vm_pu[target_bus] ** 2), - -ward_parameter_no_power.shunt[i].imag * sn / (net_external.res_bus.vm_pu[target_bus] ** 2), - name="network_equivalent") + create_ward(net_external, target_bus, + 0.0, # np.nan_to_num(-ward_parameter.power_eq[i].real), + 0.0, # np.nan_to_num(-ward_parameter.power_eq[i].imag), + ward_parameter_no_power.shunt[i].real * sn / (net_external.res_bus.vm_pu[target_bus] ** 2), + -ward_parameter_no_power.shunt[i].imag * sn / (net_external.res_bus.vm_pu[target_bus] ** 2), + name="network_equivalent") eq_power = net_external.res_ext_grid.copy() eq_power["bus"] = net_external.ext_grid.bus.values @@ -161,8 +163,8 @@ def _replace_external_area_by_wards(net_external, bus_lookups, ward_parameter_no if len(slack_gen) != 0: for i in slack_gen: new_eq_power = \ - [net_external.res_gen.p_mw[i], net_external.res_gen.q_mvar[i],\ - net_external.gen.bus[i], "gen"] + [net_external.res_gen.p_mw[i], net_external.res_gen.q_mvar[i], \ + net_external.gen.bus[i], "gen"] eq_power.loc[len(eq_power)] = new_eq_power assert len(eq_power.bus) == len(set(eq_power.bus)) # only one slack at individual bus @@ -173,22 +175,22 @@ def _replace_external_area_by_wards(net_external, bus_lookups, ward_parameter_no eq_power.q_mvar -= \ pd.concat([net_external.res_ext_grid.q_mvar, net_external.res_gen.q_mvar[slack_gen]]) for bus in eq_power.bus: - net_external.ward.loc[net_external.ward.bus==bus, 'ps_mw'] = \ - eq_power.p_mw[eq_power.bus==bus].values - net_external.ward.loc[net_external.ward.bus==bus, 'qs_mvar'] = \ - eq_power.q_mvar[eq_power.bus==bus].values + net_external.ward.loc[net_external.ward.bus == bus, 'ps_mw'] = \ + eq_power.p_mw[eq_power.bus == bus].values + net_external.ward.loc[net_external.ward.bus == bus, 'qs_mvar'] = \ + eq_power.q_mvar[eq_power.bus == bus].values net_external.poly_cost = net_external.poly_cost[0:0] net_external.pwl_cost = net_external.pwl_cost[0:0] if len(ext_buses_with_xward): - pp.drop_buses(net_external, - net_external.bus.index.tolist()[-(len(ext_buses_with_xward)):]) + drop_buses(net_external, + net_external.bus.index.tolist()[-(len(ext_buses_with_xward)):]) # net_external.ward.qs_mvar[i] = eq_power.q_mvar[ # net_external.ext_grid.bus == ward_parameter_no_power.bus_pd[i]] t_end = time.perf_counter() if show_computing_time: logger.info("\"replace_external_area_by_wards\" finished in %s seconds:" % round(( - t_end-t_start), 2)) + t_end - t_start), 2)) def _replace_external_area_by_xwards(net_external, bus_lookups, xward_parameter_no_power, @@ -199,11 +201,11 @@ def _replace_external_area_by_xwards(net_external, bus_lookups, xward_parameter_ t_start = time.perf_counter() # --- drop all external elements e_buses_pd = bus_lookups["bus_lookup_pd"]["e_area_buses"] - pp.drop_buses(net_external, e_buses_pd) + drop_buses(net_external, e_buses_pd) drop_internal_branch_elements(net_external, bus_lookups["boundary_buses_inclusive_bswitch"]) # --- drop shunt elements attached to boundary buses traget_shunt_idx = net_external.shunt.index[net_external.shunt.bus.isin(bus_lookups[ - "boundary_buses_inclusive_bswitch"])] + "boundary_buses_inclusive_bswitch"])] net_external.shunt = net_external.shunt.drop(traget_shunt_idx) # --- creat impedance @@ -212,30 +214,31 @@ def _replace_external_area_by_xwards(net_external, bus_lookups, xward_parameter_ from_bus = impedance_parameter.from_bus[idx] to_bus = impedance_parameter.to_bus[idx] if abs(impedance_parameter.rft_pu[idx]) > 1e-8 or \ - abs(impedance_parameter.xft_pu[idx]) > 1e-8 or \ - abs(impedance_parameter.rtf_pu[idx]) > 1e-8 or \ - abs(impedance_parameter.xtf_pu[idx]) > 1e-8: - pp.create_impedance(net_external, from_bus, to_bus, - impedance_parameter.rft_pu[idx], - impedance_parameter.xft_pu[idx], - sn_mva=net_external.sn_mva, - rtf_pu=impedance_parameter.rtf_pu[idx], - xtf_pu=impedance_parameter.xtf_pu[idx], - name="eq_impedance") + abs(impedance_parameter.xft_pu[idx]) > 1e-8 or \ + abs(impedance_parameter.rtf_pu[idx]) > 1e-8 or \ + abs(impedance_parameter.xtf_pu[idx]) > 1e-8: + create_impedance(net_external, from_bus, to_bus, + impedance_parameter.rft_pu[idx], + impedance_parameter.xft_pu[idx], + sn_mva=net_external.sn_mva, + rtf_pu=impedance_parameter.rtf_pu[idx], + xtf_pu=impedance_parameter.xtf_pu[idx], + name="eq_impedance") else: - pp.create_switch(net_external, from_bus, to_bus, "b", name="eq_switch") + create_switch(net_external, from_bus, to_bus, "b", name="eq_switch") # --- creata xward for i in xward_parameter_no_power.index: target_bus = xward_parameter_no_power.bus_pd[i] - pp.create_xward(net_external, target_bus, - 0.0, # np.nan_to_num(-xward_parameter.power_eq[i].real), - 0.0, # np.nan_to_num(-xward_parameter.power_eq[i].imag), - xward_parameter_no_power.shunt[i].real * sn / xward_parameter_no_power.vm_pu[i]**2, - 0.0, - xward_parameter_no_power.r_ohm[i], - np.nan_to_num(xward_parameter_no_power.x_ohm[i]), # neginf=1e100 is commented since this led to error - xward_parameter_no_power.vm_pu[i], - name="network_equivalent") + create_xward(net_external, target_bus, + 0.0, # np.nan_to_num(-xward_parameter.power_eq[i].real), + 0.0, # np.nan_to_num(-xward_parameter.power_eq[i].imag), + xward_parameter_no_power.shunt[i].real * sn / xward_parameter_no_power.vm_pu[i] ** 2, + 0.0, + xward_parameter_no_power.r_ohm[i], + np.nan_to_num(xward_parameter_no_power.x_ohm[i]), + # neginf=1e100 is commented since this led to error + xward_parameter_no_power.vm_pu[i], + name="network_equivalent") eq_power = net_external.res_ext_grid.copy() eq_power["bus"] = net_external.ext_grid.bus.values @@ -244,30 +247,24 @@ def _replace_external_area_by_xwards(net_external, bus_lookups, xward_parameter_ if len(slack_gen) != 0: for i in slack_gen: new_eq_power = \ - [net_external.res_gen.p_mw[i], net_external.res_gen.q_mvar[i],\ - net_external.gen.bus[i], "gen"] + [net_external.res_gen.p_mw[i], net_external.res_gen.q_mvar[i], \ + net_external.gen.bus[i], "gen"] eq_power.loc[len(eq_power)] = new_eq_power assert len(eq_power.bus) == len(set(eq_power.bus)) # only one slack at individual bus runpp_fct(net_external, calculate_voltage_angles=calc_volt_angles, - tolerance_mva=1e-6, max_iteration=100, **kwargs) + tolerance_mva=1e-6, max_iteration=100, **kwargs) - eq_power.p_mw -= \ - pd.concat([net_external.res_ext_grid.p_mw, net_external.res_gen.p_mw[slack_gen]]) - eq_power.q_mvar -= \ - pd.concat([net_external.res_ext_grid.q_mvar, net_external.res_gen.q_mvar[slack_gen]]) + eq_power.p_mw -= pd.concat([net_external.res_ext_grid.p_mw, net_external.res_gen.p_mw[slack_gen]]) + eq_power.q_mvar -= pd.concat([net_external.res_ext_grid.q_mvar, net_external.res_gen.q_mvar[slack_gen]]) for bus in eq_power.bus: - net_external.xward.loc[net_external.xward.bus==bus, "ps_mw"] = \ - eq_power.p_mw[eq_power.bus==bus].values - net_external.xward.loc[net_external.xward.bus==bus, "qs_mvar"] = \ - eq_power.q_mvar[eq_power.bus==bus].values + net_external.xward.loc[net_external.xward.bus == bus, "ps_mw"] = eq_power.p_mw[eq_power.bus == bus].values + net_external.xward.loc[net_external.xward.bus == bus, "qs_mvar"] = eq_power.q_mvar[eq_power.bus == bus].values net_external.poly_cost = net_external.poly_cost[0:0] net_external.pwl_cost = net_external.pwl_cost[0:0] if len(ext_buses_with_xward): - pp.drop_buses(net_external, - net_external.bus.index.tolist()[-(len(ext_buses_with_xward)):]) + drop_buses(net_external, net_external.bus.index.tolist()[-(len(ext_buses_with_xward)):]) t_end = time.perf_counter() if show_computing_time: - logger.info("\"replace_external_area_by_xwards\" finished in %s seconds:" % round(( - t_end-t_start), 2)) \ No newline at end of file + logger.info("\"replace_external_area_by_xwards\" finished in %s seconds:" % round((t_end - t_start), 2)) diff --git a/pandapower/groups.py b/pandapower/groups.py index a4ec0beb1..39fb8da16 100644 --- a/pandapower/groups.py +++ b/pandapower/groups.py @@ -840,12 +840,12 @@ def group_res_power_per_bus(net, index): Examples -------- - >>> import pandapower as pp - >>> import pandapower.networks as nw - >>> net = nw.create_cigre_network_mv(with_der="all") - >>> pp.runpp(net) - >>> gr_idx = pp.create_group(net, ["sgen", "line"], [[0, 1], [0, 1]], name="test group") - >>> pp.group_res_power_per_bus(net, gr_idx) + >>> from pandapower import runpp, create_group, group_res_power_per_bus + >>> from pandapower.networks import create_cigre_network_mv + >>> net = create_cigre_network_mv(with_der="all") + >>> runpp(net) + >>> gr_idx = create_group(net, ["sgen", "line"], [[0, 1], [0, 1]], name="test group") + >>> group_res_power_per_bus(net, gr_idx) p_mw q_mvar bus 1 2.953004e+00 1.328978e+00 @@ -895,14 +895,14 @@ def group_res_p_mw(net, index): Examples -------- - >>> import pandapower as pp - >>> import pandapower.networks as nw - >>> net = nw.create_cigre_network_mv(with_der="all") - >>> pp.runpp(net) - >>> gr_idx = pp.create_group(net, ["sgen", "line"], [[0, 1], [0, 1]], name="test group") + >>> from pandapower import runpp, create_group, group_res_p_mw + >>> from pandapower.networks import create_cigre_network_mv + >>> net = create_cigre_network_mv(with_der="all") + >>> runpp(net) + >>> gr_idx = create_group(net, ["sgen", "line"], [[0, 1], [0, 1]], name="test group") >>> net.res_line.pl_mw.loc[[0, 1]].sum() - net.res_sgen.p_mw.loc[[0, 1]].sum() # expected value 0.057938 - >>> pp.group_res_p_mw(net, gr_idx) + >>> group_res_p_mw(net, gr_idx) 0.057938 """ return _sum_powers(net, index, "p", "mw") @@ -920,14 +920,14 @@ def group_res_q_mvar(net, index): Examples -------- - >>> import pandapower as pp - >>> import pandapower.networks as nw - >>> net = nw.create_cigre_network_mv(with_der="all") - >>> pp.runpp(net) - >>> gr_idx = pp.create_group(net, ["sgen", "line"], [[0, 1], [0, 1]], name="test group") + >>> from pandapower import runpp, create_group, group_res_q_mvar + >>> from pandapower.networks import create_cigre_network_mv + >>> net = create_cigre_network_mv(with_der="all") + >>> runpp(net) + >>> gr_idx = create_group(net, ["sgen", "line"], [[0, 1], [0, 1]], name="test group") >>> net.res_line.ql_mvar.loc[[0, 1]].sum() - net.res_sgen.q_mvar.loc[[0, 1]].sum() # expected value 0.010114 - >>> pp.group_res_q_mvar(net, gr_idx) + >>> group_res_q_mvar(net, gr_idx) 0.010114 """ return _sum_powers(net, index, "q", "mvar") @@ -1173,12 +1173,12 @@ def element_type_for_switch_et(element_type): if __name__ == "__main__": - import pandapower as pp + from pandapower import create_buses, create_gens, create_group, count_group_elements net = create_empty_network() - pp.create_buses(net, 3, 10) - pp.create_gens(net, [0]*5, [10]*5) - pp.create_group(net, ["bus", "gen"], [[2, 1], [1, 2]], name="hello") - pp.create_group(net, "bus", [[0]], name="hello") + create_buses(net, 3, 10) + create_gens(net, [0]*5, [10]*5) + create_group(net, ["bus", "gen"], [[2, 1], [1, 2]], name="hello") + create_group(net, "bus", [[0]], name="hello") print(net.group) - print(pp.count_group_elements(net, 0)) + print(count_group_elements(net, 0)) diff --git a/pandapower/networks/cigre_networks.py b/pandapower/networks/cigre_networks.py index 5dfc31f64..a635d08d1 100644 --- a/pandapower/networks/cigre_networks.py +++ b/pandapower/networks/cigre_networks.py @@ -3,11 +3,13 @@ # Copyright (c) 2016-2024 by University of Kassel and Fraunhofer Institute for Energy Economics # and Energy System Technology (IEE), Kassel. All rights reserved. -import io -import geojson -from pandas import read_json from numpy import nan -import pandapower as pp + +from pandapower.create import create_empty_network, create_bus, create_line, create_load, \ + create_transformer_from_parameters, create_shunt, create_gen, create_ext_grid, create_buses, create_switch, \ + create_load_from_cosphi, create_sgen, create_storage +from pandapower.std_types import create_std_type + try: import pandaplan.core.pplog as logging except ImportError: @@ -28,7 +30,7 @@ def create_cigre_network_hv(length_km_6a_6b=0.1): OUTPUT: **net** - The pandapower format network. """ - net_cigre_hv = pp.create_empty_network() + net_cigre_hv = create_empty_network() # Linedata # Line220kV @@ -36,96 +38,87 @@ def create_cigre_network_hv(length_km_6a_6b=0.1): 'x_ohm_per_km': 0.398, 'max_i_ka': 1.14, 'type': 'ol'} - pp.create_std_type(net_cigre_hv, line_data, 'Line220kV', element='line') + create_std_type(net_cigre_hv, line_data, 'Line220kV', element='line') # Line380kV line_data = {'c_nf_per_km': 11.5, 'r_ohm_per_km': 0.0328, 'x_ohm_per_km': 0.312, 'max_i_ka': 1.32, 'type': 'ol'} - pp.create_std_type(net_cigre_hv, line_data, 'Line380kV', element='line') + create_std_type(net_cigre_hv, line_data, 'Line380kV', element='line') # Busses - bus1 = pp.create_bus(net_cigre_hv, name='Bus 1', vn_kv=220, type='b', zone='CIGRE_HV') - bus2 = pp.create_bus(net_cigre_hv, name='Bus 2', vn_kv=220, type='b', zone='CIGRE_HV') - bus3 = pp.create_bus(net_cigre_hv, name='Bus 3', vn_kv=220, type='b', zone='CIGRE_HV') - bus4 = pp.create_bus(net_cigre_hv, name='Bus 4', vn_kv=220, type='b', zone='CIGRE_HV') - bus5 = pp.create_bus(net_cigre_hv, name='Bus 5', vn_kv=220, type='b', zone='CIGRE_HV') - bus6a = pp.create_bus(net_cigre_hv, name='Bus 6a', vn_kv=220, type='b', zone='CIGRE_HV') - bus6b = pp.create_bus(net_cigre_hv, name='Bus 6b', vn_kv=220, type='b', zone='CIGRE_HV') - bus7 = pp.create_bus(net_cigre_hv, name='Bus 7', vn_kv=380, type='b', zone='CIGRE_HV') - bus8 = pp.create_bus(net_cigre_hv, name='Bus 8', vn_kv=380, type='b', zone='CIGRE_HV') - bus9 = pp.create_bus(net_cigre_hv, name='Bus 9', vn_kv=22, type='b', zone='CIGRE_HV') - bus10 = pp.create_bus(net_cigre_hv, name='Bus 10', vn_kv=22, type='b', zone='CIGRE_HV') - bus11 = pp.create_bus(net_cigre_hv, name='Bus 11', vn_kv=22, type='b', zone='CIGRE_HV') - bus12 = pp.create_bus(net_cigre_hv, name='Bus 12', vn_kv=22, type='b', zone='CIGRE_HV') + bus1 = create_bus(net_cigre_hv, name='Bus 1', vn_kv=220, type='b', zone='CIGRE_HV') + bus2 = create_bus(net_cigre_hv, name='Bus 2', vn_kv=220, type='b', zone='CIGRE_HV') + bus3 = create_bus(net_cigre_hv, name='Bus 3', vn_kv=220, type='b', zone='CIGRE_HV') + bus4 = create_bus(net_cigre_hv, name='Bus 4', vn_kv=220, type='b', zone='CIGRE_HV') + bus5 = create_bus(net_cigre_hv, name='Bus 5', vn_kv=220, type='b', zone='CIGRE_HV') + bus6a = create_bus(net_cigre_hv, name='Bus 6a', vn_kv=220, type='b', zone='CIGRE_HV') + bus6b = create_bus(net_cigre_hv, name='Bus 6b', vn_kv=220, type='b', zone='CIGRE_HV') + bus7 = create_bus(net_cigre_hv, name='Bus 7', vn_kv=380, type='b', zone='CIGRE_HV') + bus8 = create_bus(net_cigre_hv, name='Bus 8', vn_kv=380, type='b', zone='CIGRE_HV') + bus9 = create_bus(net_cigre_hv, name='Bus 9', vn_kv=22, type='b', zone='CIGRE_HV') + bus10 = create_bus(net_cigre_hv, name='Bus 10', vn_kv=22, type='b', zone='CIGRE_HV') + bus11 = create_bus(net_cigre_hv, name='Bus 11', vn_kv=22, type='b', zone='CIGRE_HV') + bus12 = create_bus(net_cigre_hv, name='Bus 12', vn_kv=22, type='b', zone='CIGRE_HV') # Lines - pp.create_line(net_cigre_hv, bus1, bus2, length_km=100, - std_type='Line220kV', name='Line 1-2') - pp.create_line(net_cigre_hv, bus1, bus6a, length_km=300, - std_type='Line220kV', name='Line 1-6a') - pp.create_line(net_cigre_hv, bus2, bus5, length_km=300, - std_type='Line220kV', name='Line 2-5') - pp.create_line(net_cigre_hv, bus3, bus4, length_km=100, - std_type='Line220kV', name='Line 3-4') - pp.create_line(net_cigre_hv, bus3, bus4, length_km=100, - std_type='Line220kV', name='Line 3-4_2') - pp.create_line(net_cigre_hv, bus4, bus5, length_km=300, - std_type='Line220kV', name='Line 4-5') - pp.create_line(net_cigre_hv, bus4, bus6a, length_km=300, - std_type='Line220kV', name='Line 4-6a') - pp.create_line(net_cigre_hv, bus7, bus8, length_km=600, - std_type='Line380kV', name='Line 7-8') - pp.create_line(net_cigre_hv, bus6a, bus6b, length_km=length_km_6a_6b, - std_type='Line220kV', name='Line 6a-6b') + create_line(net_cigre_hv, bus1, bus2, length_km=100, std_type='Line220kV', name='Line 1-2') + create_line(net_cigre_hv, bus1, bus6a, length_km=300, std_type='Line220kV', name='Line 1-6a') + create_line(net_cigre_hv, bus2, bus5, length_km=300, std_type='Line220kV', name='Line 2-5') + create_line(net_cigre_hv, bus3, bus4, length_km=100, std_type='Line220kV', name='Line 3-4') + create_line(net_cigre_hv, bus3, bus4, length_km=100, std_type='Line220kV', name='Line 3-4_2') + create_line(net_cigre_hv, bus4, bus5, length_km=300, std_type='Line220kV', name='Line 4-5') + create_line(net_cigre_hv, bus4, bus6a, length_km=300, std_type='Line220kV', name='Line 4-6a') + create_line(net_cigre_hv, bus7, bus8, length_km=600, std_type='Line380kV', name='Line 7-8') + create_line(net_cigre_hv, bus6a, bus6b, length_km=length_km_6a_6b, std_type='Line220kV', name='Line 6a-6b') # Trafos - pp.create_transformer_from_parameters(net_cigre_hv, bus7, bus1, sn_mva=1000, - vn_hv_kv=380, vn_lv_kv=220, vkr_percent=0.0, - vk_percent=13.0, pfe_kw=0, i0_percent=0, - shift_degree=0.0, name='Trafo 1-7') - pp.create_transformer_from_parameters(net_cigre_hv, bus8, bus3, sn_mva=1000, - vn_hv_kv=380, vn_lv_kv=220, vkr_percent=0.0, - vk_percent=13.0, pfe_kw=0, i0_percent=0, - shift_degree=0.0, name='Trafo 3-8') - - pp.create_transformer_from_parameters(net_cigre_hv, bus1, bus9, sn_mva=1000, - vn_hv_kv=220, vn_lv_kv=22, vkr_percent=0.0, - vk_percent=13.0, pfe_kw=0, i0_percent=0, - shift_degree=330.0, name='Trafo 9-1') - pp.create_transformer_from_parameters(net_cigre_hv, bus2, bus10, sn_mva=1000, - vn_hv_kv=220, vn_lv_kv=22, vkr_percent=0.0, - vk_percent=13.0, pfe_kw=0, i0_percent=0, - shift_degree=330.0, name='Trafo 10-2') - pp.create_transformer_from_parameters(net_cigre_hv, bus3, bus11, sn_mva=1000, - vn_hv_kv=220, vn_lv_kv=22, vkr_percent=0.0, - vk_percent=13.0, pfe_kw=0, i0_percent=0, - shift_degree=330.0, name='Trafo 11-3') - pp.create_transformer_from_parameters(net_cigre_hv, bus6b, bus12, sn_mva=500, - vn_hv_kv=220, vn_lv_kv=22, vkr_percent=0.0, - vk_percent=13.0, pfe_kw=0, i0_percent=0, - shift_degree=330.0, name='Trafo 12-6b') + create_transformer_from_parameters(net_cigre_hv, bus7, bus1, sn_mva=1000, + vn_hv_kv=380, vn_lv_kv=220, vkr_percent=0.0, + vk_percent=13.0, pfe_kw=0, i0_percent=0, + shift_degree=0.0, name='Trafo 1-7') + create_transformer_from_parameters(net_cigre_hv, bus8, bus3, sn_mva=1000, + vn_hv_kv=380, vn_lv_kv=220, vkr_percent=0.0, + vk_percent=13.0, pfe_kw=0, i0_percent=0, + shift_degree=0.0, name='Trafo 3-8') + + create_transformer_from_parameters(net_cigre_hv, bus1, bus9, sn_mva=1000, + vn_hv_kv=220, vn_lv_kv=22, vkr_percent=0.0, + vk_percent=13.0, pfe_kw=0, i0_percent=0, + shift_degree=330.0, name='Trafo 9-1') + create_transformer_from_parameters(net_cigre_hv, bus2, bus10, sn_mva=1000, + vn_hv_kv=220, vn_lv_kv=22, vkr_percent=0.0, + vk_percent=13.0, pfe_kw=0, i0_percent=0, + shift_degree=330.0, name='Trafo 10-2') + create_transformer_from_parameters(net_cigre_hv, bus3, bus11, sn_mva=1000, + vn_hv_kv=220, vn_lv_kv=22, vkr_percent=0.0, + vk_percent=13.0, pfe_kw=0, i0_percent=0, + shift_degree=330.0, name='Trafo 11-3') + create_transformer_from_parameters(net_cigre_hv, bus6b, bus12, sn_mva=500, + vn_hv_kv=220, vn_lv_kv=22, vkr_percent=0.0, + vk_percent=13.0, pfe_kw=0, i0_percent=0, + shift_degree=330.0, name='Trafo 12-6b') # Loads - pp.create_load(net_cigre_hv, bus2, p_mw=285, q_mvar=200, name='Load 2') - pp.create_load(net_cigre_hv, bus3, p_mw=325, q_mvar=244, name='Load 3') - pp.create_load(net_cigre_hv, bus4, p_mw=326, q_mvar=244, name='Load 4') - pp.create_load(net_cigre_hv, bus5, p_mw=103, q_mvar=62, name='Load 5') - pp.create_load(net_cigre_hv, bus6a, p_mw=435, q_mvar=296, name='Load 6a') + create_load(net_cigre_hv, bus2, p_mw=285, q_mvar=200, name='Load 2') + create_load(net_cigre_hv, bus3, p_mw=325, q_mvar=244, name='Load 3') + create_load(net_cigre_hv, bus4, p_mw=326, q_mvar=244, name='Load 4') + create_load(net_cigre_hv, bus5, p_mw=103, q_mvar=62, name='Load 5') + create_load(net_cigre_hv, bus6a, p_mw=435, q_mvar=296, name='Load 6a') # External grid - pp.create_ext_grid(net_cigre_hv, bus9, vm_pu=1.03, va_degree=0, name='Generator 9') + create_ext_grid(net_cigre_hv, bus9, vm_pu=1.03, va_degree=0, name='Generator 9') # Generators - pp.create_gen(net_cigre_hv, bus10, vm_pu=1.03, p_mw=500, name='Generator 10') - pp.create_gen(net_cigre_hv, bus11, vm_pu=1.03, p_mw=200, name='Generator 11') - pp.create_gen(net_cigre_hv, bus12, vm_pu=1.03, p_mw=300, name='Generator 12') + create_gen(net_cigre_hv, bus10, vm_pu=1.03, p_mw=500, name='Generator 10') + create_gen(net_cigre_hv, bus11, vm_pu=1.03, p_mw=200, name='Generator 11') + create_gen(net_cigre_hv, bus12, vm_pu=1.03, p_mw=300, name='Generator 12') # Shunts - pp.create_shunt(net_cigre_hv, bus4, p_mw=0.0, q_mvar=-160, name='Shunt 4') - pp.create_shunt(net_cigre_hv, bus5, p_mw=0.0, q_mvar=-80, name='Shunt 5') - pp.create_shunt(net_cigre_hv, bus6a, p_mw=0.0, q_mvar=-180, name='Shunt 6a') + create_shunt(net_cigre_hv, bus4, p_mw=0.0, q_mvar=-160, name='Shunt 4') + create_shunt(net_cigre_hv, bus5, p_mw=0.0, q_mvar=-80, name='Shunt 5') + create_shunt(net_cigre_hv, bus6a, p_mw=0.0, q_mvar=-180, name='Shunt 6a') # Bus geo data bus_geodata = list(map(lambda xy: f'{{"type":"Point", "coordinates":[{xy[0]}, {xy[1]}]}}', zip( @@ -155,135 +148,122 @@ def create_cigre_network_mv(with_der=False): if with_der not in [False, "pv_wind", "all"]: raise ValueError("'with_der' is unknown. It should be in [False, 'pv_wind', 'all'].") - net_cigre_mv = pp.create_empty_network() + net_cigre_mv = create_empty_network() # Linedata line_data = {'c_nf_per_km': 151.1749, 'r_ohm_per_km': 0.501, 'x_ohm_per_km': 0.716, 'max_i_ka': 0.145, 'type': 'cs'} - pp.create_std_type(net_cigre_mv, line_data, name='CABLE_CIGRE_MV', element='line') + create_std_type(net_cigre_mv, line_data, name='CABLE_CIGRE_MV', element='line') line_data = {'c_nf_per_km': 10.09679, 'r_ohm_per_km': 0.510, 'x_ohm_per_km': 0.366, 'max_i_ka': 0.195, 'type': 'ol'} - pp.create_std_type(net_cigre_mv, line_data, name='OHL_CIGRE_MV', element='line') + create_std_type(net_cigre_mv, line_data, name='OHL_CIGRE_MV', element='line') # Busses bus_geodata = list(zip([7., 4., 4., 4., 2.5, 1., 1., 8., 8., 6., 4., 4., 10., 10., 10.], [16., 15., 13., 11., 9., 7., 3., 3., 5., 5., 5., 7., 15., 11., 5.])) - bus0 = pp.create_bus(net_cigre_mv, name='Bus 0', vn_kv=110, type='b', zone='CIGRE_MV', geodata=bus_geodata[0]) - buses = pp.create_buses(net_cigre_mv, 14, name=['Bus %i' % i for i in range(1, 15)], vn_kv=20, - type='b', zone='CIGRE_MV', geodata=bus_geodata[1:]) + bus0 = create_bus(net_cigre_mv, name='Bus 0', vn_kv=110, type='b', zone='CIGRE_MV', geodata=bus_geodata[0]) + buses = create_buses(net_cigre_mv, 14, name=['Bus %i' % i for i in range(1, 15)], vn_kv=20, + type='b', zone='CIGRE_MV', geodata=bus_geodata[1:]) # Lines - pp.create_line(net_cigre_mv, buses[0], buses[1], length_km=2.82, - std_type='CABLE_CIGRE_MV', name='Line 1-2') - pp.create_line(net_cigre_mv, buses[1], buses[2], length_km=4.42, - std_type='CABLE_CIGRE_MV', name='Line 2-3') - pp.create_line(net_cigre_mv, buses[2], buses[3], length_km=0.61, - std_type='CABLE_CIGRE_MV', name='Line 3-4') - pp.create_line(net_cigre_mv, buses[3], buses[4], length_km=0.56, - std_type='CABLE_CIGRE_MV', name='Line 4-5') - pp.create_line(net_cigre_mv, buses[4], buses[5], length_km=1.54, - std_type='CABLE_CIGRE_MV', name='Line 5-6') - pp.create_line(net_cigre_mv, buses[6], buses[7], length_km=1.67, - std_type='CABLE_CIGRE_MV', name='Line 7-8') - pp.create_line(net_cigre_mv, buses[7], buses[8], length_km=0.32, - std_type='CABLE_CIGRE_MV', name='Line 8-9') - pp.create_line(net_cigre_mv, buses[8], buses[9], length_km=0.77, - std_type='CABLE_CIGRE_MV', name='Line 9-10') - pp.create_line(net_cigre_mv, buses[9], buses[10], length_km=0.33, - std_type='CABLE_CIGRE_MV', name='Line 10-11') - pp.create_line(net_cigre_mv, buses[2], buses[7], length_km=1.3, - std_type='CABLE_CIGRE_MV', name='Line 3-8') - pp.create_line(net_cigre_mv, buses[11], buses[12], length_km=4.89, - std_type='OHL_CIGRE_MV', name='Line 12-13') - pp.create_line(net_cigre_mv, buses[12], buses[13], length_km=2.99, - std_type='OHL_CIGRE_MV', name='Line 13-14') - - line6_7 = pp.create_line(net_cigre_mv, buses[5], buses[6], length_km=0.24, - std_type='CABLE_CIGRE_MV', name='Line 6-7') - line4_11 = pp.create_line(net_cigre_mv, buses[10], buses[3], length_km=0.49, - std_type='CABLE_CIGRE_MV', name='Line 11-4') - line8_14 = pp.create_line(net_cigre_mv, buses[13], buses[7], length_km=2., - std_type='OHL_CIGRE_MV', name='Line 14-8') + create_line(net_cigre_mv, buses[0], buses[1], length_km=2.82, std_type='CABLE_CIGRE_MV', name='Line 1-2') + create_line(net_cigre_mv, buses[1], buses[2], length_km=4.42, std_type='CABLE_CIGRE_MV', name='Line 2-3') + create_line(net_cigre_mv, buses[2], buses[3], length_km=0.61, std_type='CABLE_CIGRE_MV', name='Line 3-4') + create_line(net_cigre_mv, buses[3], buses[4], length_km=0.56, std_type='CABLE_CIGRE_MV', name='Line 4-5') + create_line(net_cigre_mv, buses[4], buses[5], length_km=1.54, std_type='CABLE_CIGRE_MV', name='Line 5-6') + create_line(net_cigre_mv, buses[6], buses[7], length_km=1.67, std_type='CABLE_CIGRE_MV', name='Line 7-8') + create_line(net_cigre_mv, buses[7], buses[8], length_km=0.32, std_type='CABLE_CIGRE_MV', name='Line 8-9') + create_line(net_cigre_mv, buses[8], buses[9], length_km=0.77, std_type='CABLE_CIGRE_MV', name='Line 9-10') + create_line(net_cigre_mv, buses[9], buses[10], length_km=0.33, std_type='CABLE_CIGRE_MV', name='Line 10-11') + create_line(net_cigre_mv, buses[2], buses[7], length_km=1.3, std_type='CABLE_CIGRE_MV', name='Line 3-8') + create_line(net_cigre_mv, buses[11], buses[12], length_km=4.89, std_type='OHL_CIGRE_MV', name='Line 12-13') + create_line(net_cigre_mv, buses[12], buses[13], length_km=2.99, std_type='OHL_CIGRE_MV', name='Line 13-14') + + line6_7 = create_line(net_cigre_mv, buses[5], buses[6], length_km=0.24, std_type='CABLE_CIGRE_MV', name='Line 6-7') + line4_11 = create_line(net_cigre_mv, buses[10], buses[3], length_km=0.49, std_type='CABLE_CIGRE_MV', + name='Line 11-4') + line8_14 = create_line(net_cigre_mv, buses[13], buses[7], length_km=2., std_type='OHL_CIGRE_MV', name='Line 14-8') # Ext-Grid - pp.create_ext_grid(net_cigre_mv, bus0, vm_pu=1.03, va_degree=0., - s_sc_max_mva=5000, s_sc_min_mva=5000, rx_max=0.1, rx_min=0.1) + create_ext_grid( + net_cigre_mv, bus0, vm_pu=1.03, va_degree=0., s_sc_max_mva=5000, s_sc_min_mva=5000, rx_max=0.1, rx_min=0.1 + ) # Trafos - trafo0 = pp.create_transformer_from_parameters(net_cigre_mv, bus0, buses[0], sn_mva=25, - vn_hv_kv=110, vn_lv_kv=20, vkr_percent=0.16, - vk_percent=12.00107, pfe_kw=0, i0_percent=0, - shift_degree=30.0, name='Trafo 0-1') - trafo1 = pp.create_transformer_from_parameters(net_cigre_mv, bus0, buses[11], sn_mva=25, - vn_hv_kv=110, vn_lv_kv=20, vkr_percent=0.16, - vk_percent=12.00107, pfe_kw=0, i0_percent=0, - shift_degree=30.0, name='Trafo 0-12') + trafo0 = create_transformer_from_parameters(net_cigre_mv, bus0, buses[0], sn_mva=25, + vn_hv_kv=110, vn_lv_kv=20, vkr_percent=0.16, + vk_percent=12.00107, pfe_kw=0, i0_percent=0, + shift_degree=30.0, name='Trafo 0-1') + trafo1 = create_transformer_from_parameters(net_cigre_mv, bus0, buses[11], sn_mva=25, + vn_hv_kv=110, vn_lv_kv=20, vkr_percent=0.16, + vk_percent=12.00107, pfe_kw=0, i0_percent=0, + shift_degree=30.0, name='Trafo 0-12') # Switches # S2 - pp.create_switch(net_cigre_mv, buses[5], line6_7, et='l', closed=True, type='LBS') - pp.create_switch(net_cigre_mv, buses[6], line6_7, et='l', closed=False, type='LBS', name='S2') + create_switch(net_cigre_mv, buses[5], line6_7, et='l', closed=True, type='LBS') + create_switch(net_cigre_mv, buses[6], line6_7, et='l', closed=False, type='LBS', name='S2') # S3 - pp.create_switch(net_cigre_mv, buses[3], line4_11, et='l', closed=False, type='LBS', name='S3') - pp.create_switch(net_cigre_mv, buses[10], line4_11, et='l', closed=True, type='LBS') + create_switch(net_cigre_mv, buses[3], line4_11, et='l', closed=False, type='LBS', name='S3') + create_switch(net_cigre_mv, buses[10], line4_11, et='l', closed=True, type='LBS') # S1 - pp.create_switch(net_cigre_mv, buses[7], line8_14, et='l', closed=False, type='LBS', name='S1') - pp.create_switch(net_cigre_mv, buses[13], line8_14, et='l', closed=True, type='LBS') + create_switch(net_cigre_mv, buses[7], line8_14, et='l', closed=False, type='LBS', name='S1') + create_switch(net_cigre_mv, buses[13], line8_14, et='l', closed=True, type='LBS') # trafos - pp.create_switch(net_cigre_mv, bus0, trafo0, et='t', closed=True, type='CB') - pp.create_switch(net_cigre_mv, bus0, trafo1, et='t', closed=True, type='CB') + create_switch(net_cigre_mv, bus0, trafo0, et='t', closed=True, type='CB') + create_switch(net_cigre_mv, bus0, trafo1, et='t', closed=True, type='CB') # Loads # Residential - pp.create_load_from_cosphi(net_cigre_mv, buses[0], 15.3, 0.98, "underexcited", name='Load R1') - pp.create_load_from_cosphi(net_cigre_mv, buses[2], 0.285, 0.97, "underexcited", name='Load R3') - pp.create_load_from_cosphi(net_cigre_mv, buses[3], 0.445, 0.97, "underexcited", name='Load R4') - pp.create_load_from_cosphi(net_cigre_mv, buses[4], 0.750, 0.97, "underexcited", name='Load R5') - pp.create_load_from_cosphi(net_cigre_mv, buses[5], 0.565, 0.97, "underexcited", name='Load R6') - pp.create_load_from_cosphi(net_cigre_mv, buses[7], 0.605, 0.97, "underexcited", name='Load R8') - pp.create_load_from_cosphi(net_cigre_mv, buses[9], 0.490, 0.97, "underexcited", name='Load R10') - pp.create_load_from_cosphi(net_cigre_mv, buses[10], 0.340, 0.97, "underexcited", name='Load R11') - pp.create_load_from_cosphi(net_cigre_mv, buses[11], 15.3, 0.98, "underexcited", name='Load R12') - pp.create_load_from_cosphi(net_cigre_mv, buses[13], 0.215, 0.97, "underexcited", name='Load R14') + create_load_from_cosphi(net_cigre_mv, buses[0], 15.3, 0.98, "underexcited", name='Load R1') + create_load_from_cosphi(net_cigre_mv, buses[2], 0.285, 0.97, "underexcited", name='Load R3') + create_load_from_cosphi(net_cigre_mv, buses[3], 0.445, 0.97, "underexcited", name='Load R4') + create_load_from_cosphi(net_cigre_mv, buses[4], 0.750, 0.97, "underexcited", name='Load R5') + create_load_from_cosphi(net_cigre_mv, buses[5], 0.565, 0.97, "underexcited", name='Load R6') + create_load_from_cosphi(net_cigre_mv, buses[7], 0.605, 0.97, "underexcited", name='Load R8') + create_load_from_cosphi(net_cigre_mv, buses[9], 0.490, 0.97, "underexcited", name='Load R10') + create_load_from_cosphi(net_cigre_mv, buses[10], 0.340, 0.97, "underexcited", name='Load R11') + create_load_from_cosphi(net_cigre_mv, buses[11], 15.3, 0.98, "underexcited", name='Load R12') + create_load_from_cosphi(net_cigre_mv, buses[13], 0.215, 0.97, "underexcited", name='Load R14') # Commercial / Industrial - pp.create_load_from_cosphi(net_cigre_mv, buses[0], 5.1, 0.95, "underexcited", name='Load CI1') - pp.create_load_from_cosphi(net_cigre_mv, buses[2], 0.265, 0.85, "underexcited", name='Load CI3') - pp.create_load_from_cosphi(net_cigre_mv, buses[6], 0.090, 0.85, "underexcited", name='Load CI7') - pp.create_load_from_cosphi(net_cigre_mv, buses[8], 0.675, 0.85, "underexcited", name='Load CI9') - pp.create_load_from_cosphi(net_cigre_mv, buses[9], 0.080, 0.85, "underexcited", name='Load CI10') - pp.create_load_from_cosphi(net_cigre_mv, buses[11], 5.28, 0.95, "underexcited", name='Load CI12') - pp.create_load_from_cosphi(net_cigre_mv, buses[12], 0.04, 0.85, "underexcited", name='Load CI13') - pp.create_load_from_cosphi(net_cigre_mv, buses[13], 0.390, 0.85, "underexcited", name='Load CI14') + create_load_from_cosphi(net_cigre_mv, buses[0], 5.1, 0.95, "underexcited", name='Load CI1') + create_load_from_cosphi(net_cigre_mv, buses[2], 0.265, 0.85, "underexcited", name='Load CI3') + create_load_from_cosphi(net_cigre_mv, buses[6], 0.090, 0.85, "underexcited", name='Load CI7') + create_load_from_cosphi(net_cigre_mv, buses[8], 0.675, 0.85, "underexcited", name='Load CI9') + create_load_from_cosphi(net_cigre_mv, buses[9], 0.080, 0.85, "underexcited", name='Load CI10') + create_load_from_cosphi(net_cigre_mv, buses[11], 5.28, 0.95, "underexcited", name='Load CI12') + create_load_from_cosphi(net_cigre_mv, buses[12], 0.04, 0.85, "underexcited", name='Load CI13') + create_load_from_cosphi(net_cigre_mv, buses[13], 0.390, 0.85, "underexcited", name='Load CI14') # Optional distributed energy recources if with_der in ["pv_wind", "all"]: - pp.create_sgen(net_cigre_mv, buses[2], 0.02, q_mvar=0, sn_mva=0.02, name='PV 3', type='PV') - pp.create_sgen(net_cigre_mv, buses[3], 0.020, q_mvar=0, sn_mva=0.02, name='PV 4', type='PV') - pp.create_sgen(net_cigre_mv, buses[4], 0.030, q_mvar=0, sn_mva=0.03, name='PV 5', type='PV') - pp.create_sgen(net_cigre_mv, buses[5], 0.030, q_mvar=0, sn_mva=0.03, name='PV 6', type='PV') - pp.create_sgen(net_cigre_mv, buses[7], 0.030, q_mvar=0, sn_mva=0.03, name='PV 8', type='PV') - pp.create_sgen(net_cigre_mv, buses[8], 0.030, q_mvar=0, sn_mva=0.03, name='PV 9', type='PV') - pp.create_sgen(net_cigre_mv, buses[9], 0.040, q_mvar=0, sn_mva=0.04, name='PV 10', type='PV') - pp.create_sgen(net_cigre_mv, buses[10], 0.010, q_mvar=0, sn_mva=0.01, name='PV 11', type='PV') - pp.create_sgen(net_cigre_mv, buses[6], 1.5, q_mvar=0, sn_mva=1.5, name='WKA 7', - type='WP') + create_sgen(net_cigre_mv, buses[2], 0.02, q_mvar=0, sn_mva=0.02, name='PV 3', type='PV') + create_sgen(net_cigre_mv, buses[3], 0.020, q_mvar=0, sn_mva=0.02, name='PV 4', type='PV') + create_sgen(net_cigre_mv, buses[4], 0.030, q_mvar=0, sn_mva=0.03, name='PV 5', type='PV') + create_sgen(net_cigre_mv, buses[5], 0.030, q_mvar=0, sn_mva=0.03, name='PV 6', type='PV') + create_sgen(net_cigre_mv, buses[7], 0.030, q_mvar=0, sn_mva=0.03, name='PV 8', type='PV') + create_sgen(net_cigre_mv, buses[8], 0.030, q_mvar=0, sn_mva=0.03, name='PV 9', type='PV') + create_sgen(net_cigre_mv, buses[9], 0.040, q_mvar=0, sn_mva=0.04, name='PV 10', type='PV') + create_sgen(net_cigre_mv, buses[10], 0.010, q_mvar=0, sn_mva=0.01, name='PV 11', type='PV') + create_sgen(net_cigre_mv, buses[6], 1.5, q_mvar=0, sn_mva=1.5, name='WKA 7', + type='WP') if with_der == "all": - pp.create_storage(net_cigre_mv, bus=buses[4], p_mw=0.6, max_e_mwh=nan, sn_mva=0.2, - name='Battery 1', type='Battery', max_p_mw=0.6, min_p_mw=-0.6) - pp.create_sgen(net_cigre_mv, bus=buses[4], p_mw=0.033, sn_mva=0.033, - name='Residential fuel cell 1', type='Residential fuel cell') - pp.create_sgen(net_cigre_mv, bus=buses[8], p_mw=0.310, sn_mva=0.31, name='CHP diesel 1', - type='CHP diesel') - pp.create_sgen(net_cigre_mv, bus=buses[8], p_mw=0.212, sn_mva=0.212, name='Fuel cell 1', - type='Fuel cell') - pp.create_storage(net_cigre_mv, bus=buses[9], p_mw=0.200, max_e_mwh=nan, sn_mva=0.2, - name='Battery 2', type='Battery', max_p_mw=0.2, min_p_mw=-0.2) - pp.create_sgen(net_cigre_mv, bus=buses[9], p_mw=0.014, sn_mva=.014, - name='Residential fuel cell 2', type='Residential fuel cell') + create_storage(net_cigre_mv, bus=buses[4], p_mw=0.6, max_e_mwh=nan, sn_mva=0.2, + name='Battery 1', type='Battery', max_p_mw=0.6, min_p_mw=-0.6) + create_sgen(net_cigre_mv, bus=buses[4], p_mw=0.033, sn_mva=0.033, + name='Residential fuel cell 1', type='Residential fuel cell') + create_sgen(net_cigre_mv, bus=buses[8], p_mw=0.310, sn_mva=0.31, name='CHP diesel 1', + type='CHP diesel') + create_sgen(net_cigre_mv, bus=buses[8], p_mw=0.212, sn_mva=0.212, name='Fuel cell 1', + type='Fuel cell') + create_storage(net_cigre_mv, bus=buses[9], p_mw=0.200, max_e_mwh=nan, sn_mva=0.2, + name='Battery 2', type='Battery', max_p_mw=0.2, min_p_mw=-0.2) + create_sgen(net_cigre_mv, bus=buses[9], p_mw=0.014, sn_mva=.014, + name='Residential fuel cell 2', type='Residential fuel cell') return net_cigre_mv @@ -296,212 +276,175 @@ def create_cigre_network_lv(): OUTPUT: **net** - The pandapower format network. """ - net_cigre_lv = pp.create_empty_network() + net_cigre_lv = create_empty_network() # Linedata # UG1 line_data = {'c_nf_per_km': 0.0, 'r_ohm_per_km': 0.162, 'x_ohm_per_km': 0.0832, 'max_i_ka': 1.0, 'type': 'cs'} - pp.create_std_type(net_cigre_lv, line_data, name='UG1', element='line') + create_std_type(net_cigre_lv, line_data, name='UG1', element='line') # UG2 line_data = {'c_nf_per_km': 0.0, 'r_ohm_per_km': 0.2647, 'x_ohm_per_km': 0.0823, 'max_i_ka': 1.0, 'type': 'cs'} - pp.create_std_type(net_cigre_lv, line_data, name='UG2', element='line') + create_std_type(net_cigre_lv, line_data, name='UG2', element='line') # UG3 line_data = {'c_nf_per_km': 0.0, 'r_ohm_per_km': 0.822, 'x_ohm_per_km': 0.0847, 'max_i_ka': 1.0, 'type': 'cs'} - pp.create_std_type(net_cigre_lv, line_data, name='UG3', element='line') + create_std_type(net_cigre_lv, line_data, name='UG3', element='line') # OH1 line_data = {'c_nf_per_km': 0.0, 'r_ohm_per_km': 0.4917, 'x_ohm_per_km': 0.2847, 'max_i_ka': 1.0, 'type': 'ol'} - pp.create_std_type(net_cigre_lv, line_data, name='OH1', element='line') + create_std_type(net_cigre_lv, line_data, name='OH1', element='line') # OH2 line_data = {'c_nf_per_km': 0.0, 'r_ohm_per_km': 1.3207, 'x_ohm_per_km': 0.321, 'max_i_ka': 1.0, 'type': 'ol'} - pp.create_std_type(net_cigre_lv, line_data, name='OH2', element='line') + create_std_type(net_cigre_lv, line_data, name='OH2', element='line') # OH3 line_data = {'c_nf_per_km': 0.0, 'r_ohm_per_km': 2.0167, 'x_ohm_per_km': 0.3343, 'max_i_ka': 1.0, 'type': 'ol'} - pp.create_std_type(net_cigre_lv, line_data, name='OH3', element='line') + create_std_type(net_cigre_lv, line_data, name='OH3', element='line') # Busses - bus0 = pp.create_bus(net_cigre_lv, name='Bus 0', vn_kv=20.0, type='b', zone='CIGRE_LV') - busR0 = pp.create_bus(net_cigre_lv, name='Bus R0', vn_kv=20.0, type='b', zone='CIGRE_LV') - busR1 = pp.create_bus(net_cigre_lv, name='Bus R1', vn_kv=0.4, type='b', zone='CIGRE_LV') - busR2 = pp.create_bus(net_cigre_lv, name='Bus R2', vn_kv=0.4, type='m', zone='CIGRE_LV') - busR3 = pp.create_bus(net_cigre_lv, name='Bus R3', vn_kv=0.4, type='m', zone='CIGRE_LV') - busR4 = pp.create_bus(net_cigre_lv, name='Bus R4', vn_kv=0.4, type='m', zone='CIGRE_LV') - busR5 = pp.create_bus(net_cigre_lv, name='Bus R5', vn_kv=0.4, type='m', zone='CIGRE_LV') - busR6 = pp.create_bus(net_cigre_lv, name='Bus R6', vn_kv=0.4, type='m', zone='CIGRE_LV') - busR7 = pp.create_bus(net_cigre_lv, name='Bus R7', vn_kv=0.4, type='m', zone='CIGRE_LV') - busR8 = pp.create_bus(net_cigre_lv, name='Bus R8', vn_kv=0.4, type='m', zone='CIGRE_LV') - busR9 = pp.create_bus(net_cigre_lv, name='Bus R9', vn_kv=0.4, type='m', zone='CIGRE_LV') - busR10 = pp.create_bus(net_cigre_lv, name='Bus R10', vn_kv=0.4, type='m', zone='CIGRE_LV') - busR11 = pp.create_bus(net_cigre_lv, name='Bus R11', vn_kv=0.4, type='m', zone='CIGRE_LV') - busR12 = pp.create_bus(net_cigre_lv, name='Bus R12', vn_kv=0.4, type='m', zone='CIGRE_LV') - busR13 = pp.create_bus(net_cigre_lv, name='Bus R13', vn_kv=0.4, type='m', zone='CIGRE_LV') - busR14 = pp.create_bus(net_cigre_lv, name='Bus R14', vn_kv=0.4, type='m', zone='CIGRE_LV') - busR15 = pp.create_bus(net_cigre_lv, name='Bus R15', vn_kv=0.4, type='m', zone='CIGRE_LV') - busR16 = pp.create_bus(net_cigre_lv, name='Bus R16', vn_kv=0.4, type='m', zone='CIGRE_LV') - busR17 = pp.create_bus(net_cigre_lv, name='Bus R17', vn_kv=0.4, type='m', zone='CIGRE_LV') - busR18 = pp.create_bus(net_cigre_lv, name='Bus R18', vn_kv=0.4, type='m', zone='CIGRE_LV') - - busI0 = pp.create_bus(net_cigre_lv, name='Bus I0', vn_kv=20.0, type='b', zone='CIGRE_LV') - busI1 = pp.create_bus(net_cigre_lv, name='Bus I1', vn_kv=0.4, type='b', zone='CIGRE_LV') - busI2 = pp.create_bus(net_cigre_lv, name='Bus I2', vn_kv=0.4, type='m', zone='CIGRE_LV') - - busC0 = pp.create_bus(net_cigre_lv, name='Bus C0', vn_kv=20.0, type='b', zone='CIGRE_LV') - busC1 = pp.create_bus(net_cigre_lv, name='Bus C1', vn_kv=0.4, type='b', zone='CIGRE_LV') - busC2 = pp.create_bus(net_cigre_lv, name='Bus C2', vn_kv=0.4, type='m', zone='CIGRE_LV') - busC3 = pp.create_bus(net_cigre_lv, name='Bus C3', vn_kv=0.4, type='m', zone='CIGRE_LV') - busC4 = pp.create_bus(net_cigre_lv, name='Bus C4', vn_kv=0.4, type='m', zone='CIGRE_LV') - busC5 = pp.create_bus(net_cigre_lv, name='Bus C5', vn_kv=0.4, type='m', zone='CIGRE_LV') - busC6 = pp.create_bus(net_cigre_lv, name='Bus C6', vn_kv=0.4, type='m', zone='CIGRE_LV') - busC7 = pp.create_bus(net_cigre_lv, name='Bus C7', vn_kv=0.4, type='m', zone='CIGRE_LV') - busC8 = pp.create_bus(net_cigre_lv, name='Bus C8', vn_kv=0.4, type='m', zone='CIGRE_LV') - busC9 = pp.create_bus(net_cigre_lv, name='Bus C9', vn_kv=0.4, type='m', zone='CIGRE_LV') - busC10 = pp.create_bus(net_cigre_lv, name='Bus C10', vn_kv=0.4, type='m', zone='CIGRE_LV') - busC11 = pp.create_bus(net_cigre_lv, name='Bus C11', vn_kv=0.4, type='m', zone='CIGRE_LV') - busC12 = pp.create_bus(net_cigre_lv, name='Bus C12', vn_kv=0.4, type='m', zone='CIGRE_LV') - busC13 = pp.create_bus(net_cigre_lv, name='Bus C13', vn_kv=0.4, type='m', zone='CIGRE_LV') - busC14 = pp.create_bus(net_cigre_lv, name='Bus C14', vn_kv=0.4, type='m', zone='CIGRE_LV') - busC15 = pp.create_bus(net_cigre_lv, name='Bus C15', vn_kv=0.4, type='m', zone='CIGRE_LV') - busC16 = pp.create_bus(net_cigre_lv, name='Bus C16', vn_kv=0.4, type='m', zone='CIGRE_LV') - busC17 = pp.create_bus(net_cigre_lv, name='Bus C17', vn_kv=0.4, type='m', zone='CIGRE_LV') - busC18 = pp.create_bus(net_cigre_lv, name='Bus C18', vn_kv=0.4, type='m', zone='CIGRE_LV') - busC19 = pp.create_bus(net_cigre_lv, name='Bus C19', vn_kv=0.4, type='m', zone='CIGRE_LV') - busC20 = pp.create_bus(net_cigre_lv, name='Bus C20', vn_kv=0.4, type='m', zone='CIGRE_LV') + bus0 = create_bus(net_cigre_lv, name='Bus 0', vn_kv=20.0, type='b', zone='CIGRE_LV') + busR0 = create_bus(net_cigre_lv, name='Bus R0', vn_kv=20.0, type='b', zone='CIGRE_LV') + busR1 = create_bus(net_cigre_lv, name='Bus R1', vn_kv=0.4, type='b', zone='CIGRE_LV') + busR2 = create_bus(net_cigre_lv, name='Bus R2', vn_kv=0.4, type='m', zone='CIGRE_LV') + busR3 = create_bus(net_cigre_lv, name='Bus R3', vn_kv=0.4, type='m', zone='CIGRE_LV') + busR4 = create_bus(net_cigre_lv, name='Bus R4', vn_kv=0.4, type='m', zone='CIGRE_LV') + busR5 = create_bus(net_cigre_lv, name='Bus R5', vn_kv=0.4, type='m', zone='CIGRE_LV') + busR6 = create_bus(net_cigre_lv, name='Bus R6', vn_kv=0.4, type='m', zone='CIGRE_LV') + busR7 = create_bus(net_cigre_lv, name='Bus R7', vn_kv=0.4, type='m', zone='CIGRE_LV') + busR8 = create_bus(net_cigre_lv, name='Bus R8', vn_kv=0.4, type='m', zone='CIGRE_LV') + busR9 = create_bus(net_cigre_lv, name='Bus R9', vn_kv=0.4, type='m', zone='CIGRE_LV') + busR10 = create_bus(net_cigre_lv, name='Bus R10', vn_kv=0.4, type='m', zone='CIGRE_LV') + busR11 = create_bus(net_cigre_lv, name='Bus R11', vn_kv=0.4, type='m', zone='CIGRE_LV') + busR12 = create_bus(net_cigre_lv, name='Bus R12', vn_kv=0.4, type='m', zone='CIGRE_LV') + busR13 = create_bus(net_cigre_lv, name='Bus R13', vn_kv=0.4, type='m', zone='CIGRE_LV') + busR14 = create_bus(net_cigre_lv, name='Bus R14', vn_kv=0.4, type='m', zone='CIGRE_LV') + busR15 = create_bus(net_cigre_lv, name='Bus R15', vn_kv=0.4, type='m', zone='CIGRE_LV') + busR16 = create_bus(net_cigre_lv, name='Bus R16', vn_kv=0.4, type='m', zone='CIGRE_LV') + busR17 = create_bus(net_cigre_lv, name='Bus R17', vn_kv=0.4, type='m', zone='CIGRE_LV') + busR18 = create_bus(net_cigre_lv, name='Bus R18', vn_kv=0.4, type='m', zone='CIGRE_LV') + + busI0 = create_bus(net_cigre_lv, name='Bus I0', vn_kv=20.0, type='b', zone='CIGRE_LV') + busI1 = create_bus(net_cigre_lv, name='Bus I1', vn_kv=0.4, type='b', zone='CIGRE_LV') + busI2 = create_bus(net_cigre_lv, name='Bus I2', vn_kv=0.4, type='m', zone='CIGRE_LV') + + busC0 = create_bus(net_cigre_lv, name='Bus C0', vn_kv=20.0, type='b', zone='CIGRE_LV') + busC1 = create_bus(net_cigre_lv, name='Bus C1', vn_kv=0.4, type='b', zone='CIGRE_LV') + busC2 = create_bus(net_cigre_lv, name='Bus C2', vn_kv=0.4, type='m', zone='CIGRE_LV') + busC3 = create_bus(net_cigre_lv, name='Bus C3', vn_kv=0.4, type='m', zone='CIGRE_LV') + busC4 = create_bus(net_cigre_lv, name='Bus C4', vn_kv=0.4, type='m', zone='CIGRE_LV') + busC5 = create_bus(net_cigre_lv, name='Bus C5', vn_kv=0.4, type='m', zone='CIGRE_LV') + busC6 = create_bus(net_cigre_lv, name='Bus C6', vn_kv=0.4, type='m', zone='CIGRE_LV') + busC7 = create_bus(net_cigre_lv, name='Bus C7', vn_kv=0.4, type='m', zone='CIGRE_LV') + busC8 = create_bus(net_cigre_lv, name='Bus C8', vn_kv=0.4, type='m', zone='CIGRE_LV') + busC9 = create_bus(net_cigre_lv, name='Bus C9', vn_kv=0.4, type='m', zone='CIGRE_LV') + busC10 = create_bus(net_cigre_lv, name='Bus C10', vn_kv=0.4, type='m', zone='CIGRE_LV') + busC11 = create_bus(net_cigre_lv, name='Bus C11', vn_kv=0.4, type='m', zone='CIGRE_LV') + busC12 = create_bus(net_cigre_lv, name='Bus C12', vn_kv=0.4, type='m', zone='CIGRE_LV') + busC13 = create_bus(net_cigre_lv, name='Bus C13', vn_kv=0.4, type='m', zone='CIGRE_LV') + busC14 = create_bus(net_cigre_lv, name='Bus C14', vn_kv=0.4, type='m', zone='CIGRE_LV') + busC15 = create_bus(net_cigre_lv, name='Bus C15', vn_kv=0.4, type='m', zone='CIGRE_LV') + busC16 = create_bus(net_cigre_lv, name='Bus C16', vn_kv=0.4, type='m', zone='CIGRE_LV') + busC17 = create_bus(net_cigre_lv, name='Bus C17', vn_kv=0.4, type='m', zone='CIGRE_LV') + busC18 = create_bus(net_cigre_lv, name='Bus C18', vn_kv=0.4, type='m', zone='CIGRE_LV') + busC19 = create_bus(net_cigre_lv, name='Bus C19', vn_kv=0.4, type='m', zone='CIGRE_LV') + busC20 = create_bus(net_cigre_lv, name='Bus C20', vn_kv=0.4, type='m', zone='CIGRE_LV') # Lines - pp.create_line(net_cigre_lv, busR1, busR2, length_km=0.035, std_type='UG1', - name='Line R1-R2') - pp.create_line(net_cigre_lv, busR2, busR3, length_km=0.035, std_type='UG1', - name='Line R2-R3') - pp.create_line(net_cigre_lv, busR3, busR4, length_km=0.035, std_type='UG1', - name='Line R3-R4') - pp.create_line(net_cigre_lv, busR4, busR5, length_km=0.035, std_type='UG1', - name='Line R4-R5') - pp.create_line(net_cigre_lv, busR5, busR6, length_km=0.035, std_type='UG1', - name='Line R5-R6') - pp.create_line(net_cigre_lv, busR6, busR7, length_km=0.035, std_type='UG1', - name='Line R6-R7') - pp.create_line(net_cigre_lv, busR7, busR8, length_km=0.035, std_type='UG1', - name='Line R7-R8') - pp.create_line(net_cigre_lv, busR8, busR9, length_km=0.035, std_type='UG1', - name='Line R8-R9') - pp.create_line(net_cigre_lv, busR9, busR10, length_km=0.035, std_type='UG1', - name='Line R9-R10') - pp.create_line(net_cigre_lv, busR3, busR11, length_km=0.030, std_type='UG3', - name='Line R3-R11') - pp.create_line(net_cigre_lv, busR4, busR12, length_km=0.035, std_type='UG3', - name='Line R4-R12') - pp.create_line(net_cigre_lv, busR12, busR13, length_km=0.035, std_type='UG3', - name='Line R12-R13') - pp.create_line(net_cigre_lv, busR13, busR14, length_km=0.035, std_type='UG3', - name='Line R13-R14') - pp.create_line(net_cigre_lv, busR14, busR15, length_km=0.030, std_type='UG3', - name='Line R14-R15') - pp.create_line(net_cigre_lv, busR6, busR16, length_km=0.030, std_type='UG3', - name='Line R6-R16') - pp.create_line(net_cigre_lv, busR9, busR17, length_km=0.030, std_type='UG3', - name='Line R9-R17') - pp.create_line(net_cigre_lv, busR10, busR18, length_km=0.030, std_type='UG3', - name='Line R10-R18') - - pp.create_line(net_cigre_lv, busI1, busI2, length_km=0.2, std_type='UG2', - name='Line I1-I2') - - pp.create_line(net_cigre_lv, busC1, busC2, length_km=0.030, std_type='OH1', - name='Line C1-C2') - pp.create_line(net_cigre_lv, busC2, busC3, length_km=0.030, std_type='OH1', - name='Line C2-C3') - pp.create_line(net_cigre_lv, busC3, busC4, length_km=0.030, std_type='OH1', - name='Line C3-C4') - pp.create_line(net_cigre_lv, busC4, busC5, length_km=0.030, std_type='OH1', - name='Line C4-C5') - pp.create_line(net_cigre_lv, busC5, busC6, length_km=0.030, std_type='OH1', - name='Line C5-C6') - pp.create_line(net_cigre_lv, busC6, busC7, length_km=0.030, std_type='OH1', - name='Line C6-C7') - pp.create_line(net_cigre_lv, busC7, busC8, length_km=0.030, std_type='OH1', - name='Line C7-C8') - pp.create_line(net_cigre_lv, busC8, busC9, length_km=0.030, std_type='OH1', - name='Line C8-C9') - pp.create_line(net_cigre_lv, busC3, busC10, length_km=0.030, std_type='OH2', - name='Line C3-C10') - pp.create_line(net_cigre_lv, busC10, busC11, length_km=0.030, std_type='OH2', - name='Line C10-C11') - pp.create_line(net_cigre_lv, busC11, busC12, length_km=0.030, std_type='OH3', - name='Line C11-C12') - pp.create_line(net_cigre_lv, busC11, busC13, length_km=0.030, std_type='OH3', - name='Line C11-C13') - pp.create_line(net_cigre_lv, busC10, busC14, length_km=0.030, std_type='OH3', - name='Line C10-C14') - pp.create_line(net_cigre_lv, busC5, busC15, length_km=0.030, std_type='OH2', - name='Line C5-C15') - pp.create_line(net_cigre_lv, busC15, busC16, length_km=0.030, std_type='OH2', - name='Line C15-C16') - pp.create_line(net_cigre_lv, busC15, busC17, length_km=0.030, std_type='OH3', - name='Line C15-C17') - pp.create_line(net_cigre_lv, busC16, busC18, length_km=0.030, std_type='OH3', - name='Line C16-C18') - pp.create_line(net_cigre_lv, busC8, busC19, length_km=0.030, std_type='OH3', - name='Line C8-C19') - pp.create_line(net_cigre_lv, busC9, busC20, length_km=0.030, std_type='OH3', - name='Line C9-C20') + create_line(net_cigre_lv, busR1, busR2, length_km=0.035, std_type='UG1', name='Line R1-R2') + create_line(net_cigre_lv, busR2, busR3, length_km=0.035, std_type='UG1', name='Line R2-R3') + create_line(net_cigre_lv, busR3, busR4, length_km=0.035, std_type='UG1', name='Line R3-R4') + create_line(net_cigre_lv, busR4, busR5, length_km=0.035, std_type='UG1', name='Line R4-R5') + create_line(net_cigre_lv, busR5, busR6, length_km=0.035, std_type='UG1', name='Line R5-R6') + create_line(net_cigre_lv, busR6, busR7, length_km=0.035, std_type='UG1', name='Line R6-R7') + create_line(net_cigre_lv, busR7, busR8, length_km=0.035, std_type='UG1', name='Line R7-R8') + create_line(net_cigre_lv, busR8, busR9, length_km=0.035, std_type='UG1', name='Line R8-R9') + create_line(net_cigre_lv, busR9, busR10, length_km=0.035, std_type='UG1', name='Line R9-R10') + create_line(net_cigre_lv, busR3, busR11, length_km=0.030, std_type='UG3', name='Line R3-R11') + create_line(net_cigre_lv, busR4, busR12, length_km=0.035, std_type='UG3', name='Line R4-R12') + create_line(net_cigre_lv, busR12, busR13, length_km=0.035, std_type='UG3', name='Line R12-R13') + create_line(net_cigre_lv, busR13, busR14, length_km=0.035, std_type='UG3', name='Line R13-R14') + create_line(net_cigre_lv, busR14, busR15, length_km=0.030, std_type='UG3', name='Line R14-R15') + create_line(net_cigre_lv, busR6, busR16, length_km=0.030, std_type='UG3', name='Line R6-R16') + create_line(net_cigre_lv, busR9, busR17, length_km=0.030, std_type='UG3', name='Line R9-R17') + create_line(net_cigre_lv, busR10, busR18, length_km=0.030, std_type='UG3', name='Line R10-R18') + + create_line(net_cigre_lv, busI1, busI2, length_km=0.2, std_type='UG2', name='Line I1-I2') + + create_line(net_cigre_lv, busC1, busC2, length_km=0.030, std_type='OH1', name='Line C1-C2') + create_line(net_cigre_lv, busC2, busC3, length_km=0.030, std_type='OH1', name='Line C2-C3') + create_line(net_cigre_lv, busC3, busC4, length_km=0.030, std_type='OH1', name='Line C3-C4') + create_line(net_cigre_lv, busC4, busC5, length_km=0.030, std_type='OH1', name='Line C4-C5') + create_line(net_cigre_lv, busC5, busC6, length_km=0.030, std_type='OH1', name='Line C5-C6') + create_line(net_cigre_lv, busC6, busC7, length_km=0.030, std_type='OH1', name='Line C6-C7') + create_line(net_cigre_lv, busC7, busC8, length_km=0.030, std_type='OH1', name='Line C7-C8') + create_line(net_cigre_lv, busC8, busC9, length_km=0.030, std_type='OH1', name='Line C8-C9') + create_line(net_cigre_lv, busC3, busC10, length_km=0.030, std_type='OH2', name='Line C3-C10') + create_line(net_cigre_lv, busC10, busC11, length_km=0.030, std_type='OH2', name='Line C10-C11') + create_line(net_cigre_lv, busC11, busC12, length_km=0.030, std_type='OH3', name='Line C11-C12') + create_line(net_cigre_lv, busC11, busC13, length_km=0.030, std_type='OH3', name='Line C11-C13') + create_line(net_cigre_lv, busC10, busC14, length_km=0.030, std_type='OH3', name='Line C10-C14') + create_line(net_cigre_lv, busC5, busC15, length_km=0.030, std_type='OH2', name='Line C5-C15') + create_line(net_cigre_lv, busC15, busC16, length_km=0.030, std_type='OH2', name='Line C15-C16') + create_line(net_cigre_lv, busC15, busC17, length_km=0.030, std_type='OH3', name='Line C15-C17') + create_line(net_cigre_lv, busC16, busC18, length_km=0.030, std_type='OH3', name='Line C16-C18') + create_line(net_cigre_lv, busC8, busC19, length_km=0.030, std_type='OH3', name='Line C8-C19') + create_line(net_cigre_lv, busC9, busC20, length_km=0.030, std_type='OH3', name='Line C9-C20') # Trafos - pp.create_transformer_from_parameters(net_cigre_lv, busR0, busR1, sn_mva=0.5, vn_hv_kv=20.0, - vn_lv_kv=0.4, vkr_percent=1.0, vk_percent=4.123106, - pfe_kw=0.0, i0_percent=0.0, shift_degree=30.0, - tap_pos=0.0, name='Trafo R0-R1') + create_transformer_from_parameters(net_cigre_lv, busR0, busR1, sn_mva=0.5, vn_hv_kv=20.0, + vn_lv_kv=0.4, vkr_percent=1.0, vk_percent=4.123106, + pfe_kw=0.0, i0_percent=0.0, shift_degree=30.0, + tap_pos=0.0, name='Trafo R0-R1') - pp.create_transformer_from_parameters(net_cigre_lv, busI0, busI1, sn_mva=0.15, vn_hv_kv=20.0, - vn_lv_kv=0.4, vkr_percent=1.003125, vk_percent=4.126896, - pfe_kw=0.0, i0_percent=0.0, shift_degree=30.0, - tap_pos=0.0, name='Trafo I0-I1') + create_transformer_from_parameters(net_cigre_lv, busI0, busI1, sn_mva=0.15, vn_hv_kv=20.0, + vn_lv_kv=0.4, vkr_percent=1.003125, vk_percent=4.126896, + pfe_kw=0.0, i0_percent=0.0, shift_degree=30.0, + tap_pos=0.0, name='Trafo I0-I1') - pp.create_transformer_from_parameters(net_cigre_lv, busC0, busC1, sn_mva=0.3, vn_hv_kv=20.0, - vn_lv_kv=0.4, vkr_percent=0.993750, vk_percent=4.115529, - pfe_kw=0.0, i0_percent=0.0, shift_degree=30.0, - tap_pos=0.0, name='Trafo C0-C1') + create_transformer_from_parameters(net_cigre_lv, busC0, busC1, sn_mva=0.3, vn_hv_kv=20.0, + vn_lv_kv=0.4, vkr_percent=0.993750, vk_percent=4.115529, + pfe_kw=0.0, i0_percent=0.0, shift_degree=30.0, + tap_pos=0.0, name='Trafo C0-C1') # External grid - pp.create_ext_grid(net_cigre_lv, bus0, vm_pu=1.0, va_degree=0.0, s_sc_max_mva=100.0, - s_sc_min_mva=100.0, rx_max=1.0, rx_min=1.0) + create_ext_grid(net_cigre_lv, bus0, vm_pu=1.0, va_degree=0.0, s_sc_max_mva=100.0, + s_sc_min_mva=100.0, rx_max=1.0, rx_min=1.0) # Loads - pp.create_load(net_cigre_lv, busR1, p_mw=0.19, q_mvar=0.062449980, name='Load R1') - pp.create_load(net_cigre_lv, busR11, p_mw=0.01425, q_mvar=0.004683748, name='Load R11') - pp.create_load(net_cigre_lv, busR15, p_mw=0.0494, q_mvar=0.016236995, name='Load R15') - pp.create_load(net_cigre_lv, busR16, p_mw=0.05225, q_mvar=0.017173744, name='Load R16') - pp.create_load(net_cigre_lv, busR17, p_mw=0.03325, q_mvar=0.010928746, name='Load R17') - pp.create_load(net_cigre_lv, busR18, p_mw=0.04465, q_mvar=0.014675745, name='Load R18') - pp.create_load(net_cigre_lv, busI2, p_mw=0.0850, q_mvar=0.052678269, name='Load I2') - pp.create_load(net_cigre_lv, busC1, p_mw=0.1080, q_mvar=0.052306787, name='Load C1') - pp.create_load(net_cigre_lv, busC12, p_mw=0.018, q_mvar=0.008717798, name='Load C12') - pp.create_load(net_cigre_lv, busC13, p_mw=0.018, q_mvar=0.008717798, name='Load C13') - pp.create_load(net_cigre_lv, busC14, p_mw=0.0225, q_mvar=0.010897247, name='Load C14') - pp.create_load(net_cigre_lv, busC17, p_mw=0.0225, q_mvar=0.010897247, name='Load C17') - pp.create_load(net_cigre_lv, busC18, p_mw=0.0072, q_mvar=0.003487119, name='Load C18') - pp.create_load(net_cigre_lv, busC19, p_mw=0.0144, q_mvar=0.006974238, name='Load C19') - pp.create_load(net_cigre_lv, busC20, p_mw=0.0072, q_mvar=0.003487119, name='Load C20') + create_load(net_cigre_lv, busR1, p_mw=0.19, q_mvar=0.062449980, name='Load R1') + create_load(net_cigre_lv, busR11, p_mw=0.01425, q_mvar=0.004683748, name='Load R11') + create_load(net_cigre_lv, busR15, p_mw=0.0494, q_mvar=0.016236995, name='Load R15') + create_load(net_cigre_lv, busR16, p_mw=0.05225, q_mvar=0.017173744, name='Load R16') + create_load(net_cigre_lv, busR17, p_mw=0.03325, q_mvar=0.010928746, name='Load R17') + create_load(net_cigre_lv, busR18, p_mw=0.04465, q_mvar=0.014675745, name='Load R18') + create_load(net_cigre_lv, busI2, p_mw=0.0850, q_mvar=0.052678269, name='Load I2') + create_load(net_cigre_lv, busC1, p_mw=0.1080, q_mvar=0.052306787, name='Load C1') + create_load(net_cigre_lv, busC12, p_mw=0.018, q_mvar=0.008717798, name='Load C12') + create_load(net_cigre_lv, busC13, p_mw=0.018, q_mvar=0.008717798, name='Load C13') + create_load(net_cigre_lv, busC14, p_mw=0.0225, q_mvar=0.010897247, name='Load C14') + create_load(net_cigre_lv, busC17, p_mw=0.0225, q_mvar=0.010897247, name='Load C17') + create_load(net_cigre_lv, busC18, p_mw=0.0072, q_mvar=0.003487119, name='Load C18') + create_load(net_cigre_lv, busC19, p_mw=0.0144, q_mvar=0.006974238, name='Load C19') + create_load(net_cigre_lv, busC20, p_mw=0.0072, q_mvar=0.003487119, name='Load C20') # Switches - pp.create_switch(net_cigre_lv, bus0, busR0, et='b', closed=True, type='CB', name='S1') - pp.create_switch(net_cigre_lv, bus0, busI0, et='b', closed=True, type='CB', name='S2') - pp.create_switch(net_cigre_lv, bus0, busC0, et='b', closed=True, type='CB', name='S3') + create_switch(net_cigre_lv, bus0, busR0, et='b', closed=True, type='CB', name='S1') + create_switch(net_cigre_lv, bus0, busI0, et='b', closed=True, type='CB', name='S2') + create_switch(net_cigre_lv, bus0, busC0, et='b', closed=True, type='CB', name='S3') # Bus geo data bus_geodata = list(map(lambda xy: f'{{"type":"Point", "coordinates":[{xy[0]}, {xy[1]}]}}', zip( @@ -518,7 +461,8 @@ def create_cigre_network_lv(): net_cigre_lv.bus["geo"] = bus_geodata return net_cigre_lv + if __name__ == "__main__": net = create_cigre_network_lv() net = create_cigre_network_mv() - net = create_cigre_network_hv() \ No newline at end of file + net = create_cigre_network_hv() diff --git a/pandapower/networks/create_examples.py b/pandapower/networks/create_examples.py index 699ed7a89..61edcb8a7 100644 --- a/pandapower/networks/create_examples.py +++ b/pandapower/networks/create_examples.py @@ -6,7 +6,11 @@ import pandas as pd -import pandapower as pp +from pandapower.create import create_switch, create_empty_network, create_bus, create_ext_grid, create_load, \ + create_gen, create_sgen, create_line, create_shunt, create_transformer, create_transformer_from_parameters, \ + create_transformer3w_from_parameters, create_impedance, create_xward +from pandapower.run import runpp +from pandapower.toolbox.element_selection import get_element_index def example_simple(): @@ -17,62 +21,61 @@ def example_simple(): net - simple example network EXAMPLE: - - >>> import pandapower.networks - >>> net = pandapower.networks.example_simple() + >>> from pandapower.networks.create_examples import example_simple + >>> net = example_simple() """ - net = pp.create_empty_network() + net = create_empty_network() # create buses - bus1 = pp.create_bus(net, name="HV Busbar", vn_kv=110., type="b") - bus2 = pp.create_bus(net, name="HV Busbar 2", vn_kv=110., type="b") - bus3 = pp.create_bus(net, name="HV Transformer Bus", vn_kv=110., type="n") - bus4 = pp.create_bus(net, name="MV Transformer Bus", vn_kv=20., type="n") - bus5 = pp.create_bus(net, name="MV Main Bus", vn_kv=20., type="b") - bus6 = pp.create_bus(net, name="MV Bus 1", vn_kv=20., type="b") - bus7 = pp.create_bus(net, name="MV Bus 2", vn_kv=20., type="b") + bus1 = create_bus(net, name="HV Busbar", vn_kv=110., type="b") + bus2 = create_bus(net, name="HV Busbar 2", vn_kv=110., type="b") + bus3 = create_bus(net, name="HV Transformer Bus", vn_kv=110., type="n") + bus4 = create_bus(net, name="MV Transformer Bus", vn_kv=20., type="n") + bus5 = create_bus(net, name="MV Main Bus", vn_kv=20., type="b") + bus6 = create_bus(net, name="MV Bus 1", vn_kv=20., type="b") + bus7 = create_bus(net, name="MV Bus 2", vn_kv=20., type="b") # create external grid - pp.create_ext_grid(net, bus1, vm_pu=1.02, va_degree=50) + create_ext_grid(net, bus1, vm_pu=1.02, va_degree=50) # create transformer - pp.create_transformer(net, bus3, bus4, name="110kV/20kV transformer", - std_type="25 MVA 110/20 kV") + create_transformer(net, bus3, bus4, name="110kV/20kV transformer", + std_type="25 MVA 110/20 kV") # create lines - pp.create_line(net, bus1, bus2, length_km=10, - std_type="N2XS(FL)2Y 1x300 RM/35 64/110 kV", name="Line 1") - line2 = pp.create_line(net, bus5, bus6, length_km=2.0, - std_type="NA2XS2Y 1x240 RM/25 12/20 kV", name="Line 2") - line3 = pp.create_line(net, bus6, bus7, length_km=3.5, - std_type="48-AL1/8-ST1A 20.0", name="Line 3") - line4 = pp.create_line(net, bus7, bus5, length_km=2.5, - std_type="NA2XS2Y 1x240 RM/25 12/20 kV", name="Line 4") + create_line(net, bus1, bus2, length_km=10, + std_type="N2XS(FL)2Y 1x300 RM/35 64/110 kV", name="Line 1") + line2 = create_line(net, bus5, bus6, length_km=2.0, + std_type="NA2XS2Y 1x240 RM/25 12/20 kV", name="Line 2") + line3 = create_line(net, bus6, bus7, length_km=3.5, + std_type="48-AL1/8-ST1A 20.0", name="Line 3") + line4 = create_line(net, bus7, bus5, length_km=2.5, + std_type="NA2XS2Y 1x240 RM/25 12/20 kV", name="Line 4") # create bus-bus switches - pp.create_switch(net, bus2, bus3, et="b", type="CB") - pp.create_switch(net, bus4, bus5, et="b", type="CB") + create_switch(net, bus2, bus3, et="b", type="CB") + create_switch(net, bus4, bus5, et="b", type="CB") # create bus-line switches - pp.create_switch(net, bus5, line2, et="l", type="LBS", closed=True) - pp.create_switch(net, bus6, line2, et="l", type="LBS", closed=True) - pp.create_switch(net, bus6, line3, et="l", type="LBS", closed=True) - pp.create_switch(net, bus7, line3, et="l", type="LBS", closed=False) - pp.create_switch(net, bus7, line4, et="l", type="LBS", closed=True) - pp.create_switch(net, bus5, line4, et="l", type="LBS", closed=True) + create_switch(net, bus5, line2, et="l", type="LBS", closed=True) + create_switch(net, bus6, line2, et="l", type="LBS", closed=True) + create_switch(net, bus6, line3, et="l", type="LBS", closed=True) + create_switch(net, bus7, line3, et="l", type="LBS", closed=False) + create_switch(net, bus7, line4, et="l", type="LBS", closed=True) + create_switch(net, bus5, line4, et="l", type="LBS", closed=True) # create load - pp.create_load(net, bus7, p_mw=2, q_mvar=4, scaling=0.6, name="load") + create_load(net, bus7, p_mw=2, q_mvar=4, scaling=0.6, name="load") # create generator - pp.create_gen(net, bus6, p_mw=6, max_q_mvar=3, min_q_mvar=-3, vm_pu=1.03, - name="generator") + create_gen(net, bus6, p_mw=6, max_q_mvar=3, min_q_mvar=-3, vm_pu=1.03, + name="generator") # create static generator - pp.create_sgen(net, bus7, p_mw=2, q_mvar=-0.5, name="static generator") + create_sgen(net, bus7, p_mw=2, q_mvar=-0.5, name="static generator") # create shunt - pp.create_shunt(net, bus3, q_mvar=-0.96, p_mw=0, name='Shunt') + create_shunt(net, bus3, q_mvar=-0.96, p_mw=0, name='Shunt') return net @@ -85,57 +88,56 @@ def example_multivoltage(): net - multivoltage example network EXAMPLE: - - >>> import pandapower.networks - >>> net = pandapower.networks.example_multivoltage() + >>> from pandapower.networks.create_examples import example_multivoltage + >>> net = example_multivoltage() """ - net = pp.create_empty_network() + net = create_empty_network() # --- Busses # HV # 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') + create_bus(net, name='Double Busbar 1', vn_kv=380, type='b') + 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') + 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') + 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') + 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') + 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') + create_bus(net, name='Bus SB T%s.%s' % (i, j), vn_kv=110, type='n') # Remaining for i in range(1, 5): - pp.create_bus(net, name='Bus HV%s' % i, vn_kv=110, type='n') + create_bus(net, name='Bus HV%s' % i, vn_kv=110, type='n') # MV - pp.create_bus(net, name='Bus MV0 20kV', vn_kv=20, type='n') + 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') + create_bus(net, name='Bus MV%s' % i, vn_kv=10, type='n') # LV - pp.create_bus(net, name='Bus LV0', vn_kv=0.4, type='n') + 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') + 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') + 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') + create_bus(net, name='Bus LV2.2.1', vn_kv=0.4, type='m') + create_bus(net, name='Bus LV2.2.2', vn_kv=0.4, type='m') # --- Lines @@ -149,10 +151,10 @@ def example_multivoltage(): hv_lines['parallel'] = [1, 1, 1, 1, 1, 2] 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) + from_bus = get_element_index(net, "bus", hv_line.from_bus) + to_bus = get_element_index(net, "bus", hv_line.to_bus) + 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) # MV mv_lines = pd.DataFrame() @@ -163,10 +165,10 @@ def example_multivoltage(): mv_lines['std_type'] = 'NA2XS2Y 1x185 RM/25 12/20 kV' 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) + from_bus = get_element_index(net, "bus", mv_line.from_bus) + to_bus = get_element_index(net, "bus", mv_line.to_bus) + create_line(net, from_bus, to_bus, length_km=mv_line.length, + std_type=mv_line.std_type, name=mv_line.line_name) # LV lv_lines = pd.DataFrame() @@ -176,55 +178,55 @@ def example_multivoltage(): lv_lines['from_bus'] = ['Bus LV%s' % i for i in lv_line_idx] lv_line_idx = ['1.1', '1.2', '1.3', '1.4', '1.5', '2.1', '2.2', '2.3', '2.4', '2.2.1', '2.2.2'] lv_lines['to_bus'] = ['Bus LV%s' % i for i in lv_line_idx] - lv_lines['length'] = [0.08]*5 + [0.12]*6 - lv_lines['std_type'] = ['NAYY 4x120 SE']*7 + ['15-AL1/3-ST1A 0.4']*4 + lv_lines['length'] = [0.08] * 5 + [0.12] * 6 + lv_lines['std_type'] = ['NAYY 4x120 SE'] * 7 + ['15-AL1/3-ST1A 0.4'] * 4 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) + from_bus = get_element_index(net, "bus", lv_line.from_bus) + to_bus = get_element_index(net, "bus", lv_line.to_bus) + create_line(net, from_bus, to_bus, length_km=lv_line.length, + std_type=lv_line.std_type, name=lv_line.line_name) # --- Transformer - 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_mva=300, vn_hv_kv=380, vn_lv_kv=110, - vkr_percent=0.06, vk_percent=8, pfe_kw=0, - i0_percent=0, tap_pos=0, shift_degree=0, - name='EHV-HV-Trafo') - - 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_mva=0.4, vn_hv_kv=10, vn_lv_kv=0.4, - vkr_percent=1.325, vk_percent=4, - pfe_kw=0.95, i0_percent=0.2375, tap_side="hv", - tap_neutral=0, tap_min=-2, tap_max=2, - tap_step_percent=2.5, tap_pos=0, - shift_degree=150, name='MV-LV-Trafo') + hv_bus = get_element_index(net, "bus", "Bus DB 2") + lv_bus = get_element_index(net, "bus", "Bus SB 1") + create_transformer_from_parameters(net, hv_bus, lv_bus, + sn_mva=300, vn_hv_kv=380, vn_lv_kv=110, + vkr_percent=0.06, vk_percent=8, pfe_kw=0, + i0_percent=0, tap_pos=0, shift_degree=0, + name='EHV-HV-Trafo') + + hv_bus = get_element_index(net, "bus", "Bus MV4") + lv_bus = get_element_index(net, "bus", "Bus LV0") + create_transformer_from_parameters(net, hv_bus, lv_bus, + sn_mva=0.4, vn_hv_kv=10, vn_lv_kv=0.4, + vkr_percent=1.325, vk_percent=4, + pfe_kw=0.95, i0_percent=0.2375, tap_side="hv", + tap_neutral=0, tap_min=-2, tap_max=2, + tap_step_percent=2.5, tap_pos=0, + shift_degree=150, name='MV-LV-Trafo') # Trafo3w - 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_mva=40, sn_mv_mva=15, sn_lv_mva=25, - vk_hv_percent=10.1, vk_mv_percent=10.1, - vk_lv_percent=10.1, vkr_hv_percent=0.266667, - vkr_mv_percent=0.033333, vkr_lv_percent=0.04, - pfe_kw=0, i0_percent=0, shift_mv_degree=30, - shift_lv_degree=30, tap_side="hv", tap_neutral=0, - tap_min=-8, tap_max=8, tap_step_percent=1.25, - tap_pos=0, name='HV-MV-MV-Trafo') + hv_bus = get_element_index(net, "bus", "Bus HV2") + mv_bus = get_element_index(net, "bus", "Bus MV0 20kV") + lv_bus = get_element_index(net, "bus", "Bus MV0") + 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_mva=40, sn_mv_mva=15, sn_lv_mva=25, + vk_hv_percent=10.1, vk_mv_percent=10.1, + vk_lv_percent=10.1, vkr_hv_percent=0.266667, + vkr_mv_percent=0.033333, vkr_lv_percent=0.04, + pfe_kw=0, i0_percent=0, shift_mv_degree=30, + shift_lv_degree=30, tap_side="hv", tap_neutral=0, + tap_min=-8, tap_max=8, tap_step_percent=1.25, + tap_pos=0, name='HV-MV-MV-Trafo') # --- Static generators # HV - pp.create_sgen(net, pp.get_element_index(net, "bus", 'Bus SB 5'), p_mw=20, - q_mvar=4, sn_mva=45, type='WP', name='Wind Park') + create_sgen(net, get_element_index(net, "bus", 'Bus SB 5'), p_mw=20, + q_mvar=4, sn_mva=45, type='WP', name='Wind Park') # MV mv_sgens = pd.DataFrame() @@ -237,9 +239,9 @@ def example_multivoltage(): mv_sgens['type'] = ['SGEN', 'SGEN', 'SGEN', 'PV'] for _, sgen in mv_sgens.iterrows(): - bus_idx = pp.get_element_index(net, "bus", sgen.bus) - pp.create_sgen(net, bus_idx, p_mw=sgen.p, q_mvar=sgen.q, sn_mva=sgen.sn, - type=sgen.type, name=sgen.sgen_name) + bus_idx = get_element_index(net, "bus", sgen.bus) + create_sgen(net, bus_idx, p_mw=sgen.p, q_mvar=sgen.q, sn_mva=sgen.sn, + type=sgen.type, name=sgen.sgen_name) # LV lv_sgens = pd.DataFrame() @@ -251,9 +253,9 @@ def example_multivoltage(): lv_sgens['type'] = 'PV' for _, sgen in lv_sgens.iterrows(): - bus_idx = pp.get_element_index(net, "bus", sgen.bus) - pp.create_sgen(net, bus_idx, p_mw=sgen.p, q_mvar=sgen.q, sn_mva=sgen.sn, - type=sgen.type, name=sgen.sgen_name) + bus_idx = get_element_index(net, "bus", sgen.bus) + create_sgen(net, bus_idx, p_mw=sgen.p, q_mvar=sgen.q, sn_mva=sgen.sn, + type=sgen.type, name=sgen.sgen_name) # --- Loads @@ -265,8 +267,8 @@ def example_multivoltage(): hv_loads['q'] = 6 for _, load in hv_loads.iterrows(): - bus_idx = pp.get_element_index(net, "bus", load.bus) - pp.create_load(net, bus_idx, p_mw=load.p, q_mvar=load.q, name=load.load_name) + bus_idx = get_element_index(net, "bus", load.bus) + create_load(net, bus_idx, p_mw=load.p, q_mvar=load.q, name=load.load_name) # MV mv_loads = pd.DataFrame() @@ -277,8 +279,8 @@ def example_multivoltage(): mv_loads['q'] = [2, 4, 0.1, 0.06, 0.06, 0.06, 0.06, 0.06] for _, load in mv_loads.iterrows(): - bus_idx = pp.get_element_index(net, "bus", load.bus) - pp.create_load(net, bus_idx, p_mw=load.p, q_mvar=load.q, name=load.load_name) + bus_idx = get_element_index(net, "bus", load.bus) + create_load(net, bus_idx, p_mw=load.p, q_mvar=load.q, name=load.load_name) # LV lv_loads = pd.DataFrame() @@ -286,40 +288,40 @@ def example_multivoltage(): lv_loads['load_name'] = ['Further LV-Feeders Load'] + [ 'Residential Load%s' % i for i in idx[0:5]] + ['Rural Load%s' % i for i in idx[0:6]] lv_loads['bus'] = ['Bus LV%s' % i for i in ['0', '1.1', '1.2', '1.3', '1.4', '1.5', '2.1', - '2.2', '2.3', '2.4', '2.2.1', '2.2.2']] - lv_loads['p'] = [0.1] + [0.01]*11 - lv_loads['q'] = [0.01] + [0.03]*11 + '2.2', '2.3', '2.4', '2.2.1', '2.2.2']] + lv_loads['p'] = [0.1] + [0.01] * 11 + lv_loads['q'] = [0.01] + [0.03] * 11 for _, load in lv_loads.iterrows(): - bus_idx = pp.get_element_index(net, "bus", load.bus) - pp.create_load(net, bus_idx, p_mw=load.p, q_mvar=load.q, name=load.load_name) + bus_idx = get_element_index(net, "bus", load.bus) + create_load(net, bus_idx, p_mw=load.p, q_mvar=load.q, name=load.load_name) # --- Other # Shunt - pp.create_shunt(net, pp.get_element_index(net, "bus", 'Bus HV1'), p_mw=0, q_mvar=-0.96, - name='Shunt') + create_shunt(net, get_element_index(net, "bus", 'Bus HV1'), p_mw=0, q_mvar=-0.96, + name='Shunt') # ExtGrids - 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) + create_ext_grid(net, 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) # Gen - pp.create_gen(net, pp.get_element_index(net, "bus", 'Bus HV4'), vm_pu=1.03, p_mw=100, - name='Gas turbine') + create_gen(net, get_element_index(net, "bus", 'Bus HV4'), vm_pu=1.03, p_mw=100, + name='Gas turbine') # 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_mva=100, name='Impedance') + create_impedance(net, get_element_index(net, "bus", 'Bus HV3'), + get_element_index(net, "bus", 'Bus HV1'), rft_pu=0.074873, + xft_pu=0.198872, sn_mva=100, name='Impedance') # xwards - pp.create_xward(net, pp.get_element_index(net, "bus", 'Bus HV3'), ps_mw=23.942, - qs_mvar=-12.24187, pz_mw=2.814571, qz_mvar=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_mw=3.776, - qs_mvar=-7.769979, pz_mw=9.174917, qz_mvar=0, r_ohm=0, x_ohm=50.56217, - vm_pu=1.024001, name='XWard 2') + create_xward(net, get_element_index(net, "bus", 'Bus HV3'), ps_mw=23.942, + qs_mvar=-12.24187, pz_mw=2.814571, qz_mvar=0, r_ohm=0, x_ohm=12.18951, + vm_pu=1.02616, name='XWard 1') + create_xward(net, get_element_index(net, "bus", 'Bus HV1'), ps_mw=3.776, + qs_mvar=-7.769979, pz_mw=9.174917, qz_mvar=0, r_ohm=0, x_ohm=50.56217, + vm_pu=1.024001, name='XWard 2') # --- Switches @@ -342,24 +344,24 @@ def example_multivoltage(): ['Bus SB %s' % i for i in ['1', 'T1.2', '2', 'T2.2', '3', 'T3.2', '4', 'T4.2', '5', 'T5.2']] + \ ['Bus SB T%s.1' % i for i in range(1, 6)] - hv_bus_sw['type'] = ['DS']*14 + ['CB']*5 + ['DS']*10 + ['CB']*5 + hv_bus_sw['type'] = ['DS'] * 14 + ['CB'] * 5 + ['DS'] * 10 + ['CB'] * 5 hv_bus_sw['et'] = 'b' hv_bus_sw['closed'] = [bool(i) for i in [1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, - 1] + [1]*15] + 1] + [1] * 15] 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) + from_bus = get_element_index(net, "bus", switch.from_bus) + to_bus = get_element_index(net, "bus", switch.to_bus) + 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(): for bus in [line.from_bus, line.to_bus]: - pp.create_switch(net, bus, line.name, et='l', closed=True, type='LBS', - name='Switch %s - %s' % (net.bus.name.at[bus], line['name'])) + create_switch(net, bus, line.name, et='l', closed=True, type='LBS', + name='Switch %s - %s' % (net.bus.name.at[bus], line['name'])) # MV # Bus-line switches @@ -367,8 +369,8 @@ def example_multivoltage(): mv_ls = net.line[(net.line.from_bus.isin(mv_buses)) & (net.line.to_bus.isin(mv_buses))] for _, line in mv_ls.iterrows(): for bus in [line.from_bus, line.to_bus]: - pp.create_switch(net, bus, line.name, et='l', closed=True, type='LBS', - name='Switch %s - %s' % (net.bus.name.at[bus], line['name'])) + create_switch(net, bus, line.name, et='l', closed=True, type='LBS', + name='Switch %s - %s' % (net.bus.name.at[bus], line['name'])) open_switch_id = net.switch[(net.switch.name == 'Switch Bus MV5 - MV Line5')].index net.switch.loc[open_switch_id, "closed"] = False @@ -379,28 +381,28 @@ def example_multivoltage(): lv_ls = net.line[(net.line.from_bus.isin(lv_buses)) & (net.line.to_bus.isin(lv_buses))] for _, line in lv_ls.iterrows(): for bus in [line.from_bus, line.to_bus]: - pp.create_switch(net, bus, line.name, et='l', closed=True, type='LBS', - name='Switch %s - %s' % (net.bus.name.at[bus], line['name'])) + create_switch(net, bus, line.name, et='l', closed=True, type='LBS', + name='Switch %s - %s' % (net.bus.name.at[bus], line['name'])) # Trafoswitches # HV - 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') + create_switch(net, get_element_index(net, "bus", 'Bus DB 2'), + get_element_index(net, "trafo", 'EHV-HV-Trafo'), et='t', closed=True, + type='LBS', name='Switch DB2 - EHV-HV-Trafo') + create_switch(net, get_element_index(net, "bus", 'Bus SB 1'), + get_element_index(net, "trafo", 'EHV-HV-Trafo'), et='t', closed=True, + type='LBS', name='Switch SB1 - EHV-HV-Trafo') # LV - 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') + create_switch(net, get_element_index(net, "bus", 'Bus MV4'), + get_element_index(net, "trafo", 'MV-LV-Trafo'), et='t', closed=True, + type='LBS', name='Switch MV4 - MV-LV-Trafo') + create_switch(net, get_element_index(net, "bus", 'Bus LV0'), + get_element_index(net, "trafo", 'MV-LV-Trafo'), et='t', closed=True, + type='LBS', name='Switch LV0 - MV-LV-Trafo') # --- Powerflow # run power flow and generate result tables - pp.runpp(net, init='dc', calculate_voltage_angles=True, Numba=False) + runpp(net, init='dc', calculate_voltage_angles=True, Numba=False) return net diff --git a/pandapower/networks/dickert_lv_networks.py b/pandapower/networks/dickert_lv_networks.py index de6b42929..caf3ec35f 100644 --- a/pandapower/networks/dickert_lv_networks.py +++ b/pandapower/networks/dickert_lv_networks.py @@ -1,25 +1,31 @@ -import pandapower as pp -from numpy import append, ceil from copy import deepcopy +from numpy import append, ceil + +from pandapower.create import create_load, create_buses, create_line, create_empty_network, create_bus, \ + create_ext_grid, create_transformer +from pandapower.std_types import change_std_type, create_std_type +from pandapower.toolbox.element_selection import get_connected_elements +from pandapower.toolbox.power_factor import pq_from_cosphi + def _change_to_ohl(net, idx_busbar, new_lines, n_cable): """ This function changes line types from cable to ohl beginning at the end of the feeders in a \ way, that the tapped line has the most portions of overhead-lines. """ - con_lines = pp.get_connected_elements(net, "line", idx_busbar) & new_lines + con_lines = get_connected_elements(net, "line", idx_busbar) & new_lines cable_lines = con_lines last_con_lines = list(con_lines) while len(cable_lines) < n_cable: - con_lines = sorted(pp.get_connected_elements( - net, "line", net.line.to_bus.loc[last_con_lines]) & new_lines - cable_lines) + con_lines = sorted(get_connected_elements( + net, "line", net.line.to_bus.loc[last_con_lines]) & new_lines - cable_lines) last_con_lines = deepcopy(con_lines) while len(con_lines) > 0: cable_lines.add(con_lines.pop(0)) for idx_line in list(new_lines - cable_lines): - pp.change_std_type(net, idx_line, 'NFA2X 4x70', element="line") + change_std_type(net, idx_line, 'NFA2X 4x70', element="line") def _create_loads_with_coincidence(net, buses): @@ -36,13 +42,13 @@ def _create_loads_with_coincidence(net, buses): # calculations n_buses = len(buses) - c = c_inf + (1 - c_inf) * n_buses**(-1/2) + c = c_inf + (1 - c_inf) * n_buses ** (-1 / 2) p_mw = c * P_max1 - p_mw, q_mvar = pp.pq_from_cosphi(p_mw, powerfactor, qmode='underexcited', pmode="load") + p_mw, q_mvar = pq_from_cosphi(p_mw, powerfactor, qmode='underexcited', pmode="load") # create loads for i in buses: - pp.create_load(net, i, p_mw=p_mw, q_mvar=q_mvar, sn_mva=P_max1) + create_load(net, i, p_mw=p_mw, q_mvar=q_mvar, sn_mva=P_max1) def _create_feeder(net, net_data, branching, idx_busbar, linetype, lv_vn_kv): @@ -53,65 +59,65 @@ def _create_feeder(net, net_data, branching, idx_busbar, linetype, lv_vn_kv): """ n_DP = net_data[1] d_DP = net_data[0] - buses = pp.create_buses(net, int(n_DP), lv_vn_kv, zone='Feeder B' + str(branching), - type='m') + buses = create_buses(net, int(n_DP), lv_vn_kv, zone='Feeder B' + str(branching), + type='m') from_bus = append(idx_busbar, buses[:-1]) # branch consideration if branching == 1: n_LS = int(ceil(n_DP / 3)) - idx_B1 = 2*n_LS - if n_LS*3 - n_DP == 2: + idx_B1 = 2 * n_LS + if n_LS * 3 - n_DP == 2: idx_B1 -= 1 - from_bus[idx_B1] = buses[n_LS-1] + from_bus[idx_B1] = buses[n_LS - 1] elif branching == 2: n_LS = int(ceil(n_DP / 6)) - idx_B1 = 3*n_LS - idx_B2 = 4*n_LS - if n_LS*6 - n_DP >= 1: + idx_B1 = 3 * n_LS + idx_B2 = 4 * n_LS + if n_LS * 6 - n_DP >= 1: idx_B2 -= 1 - if n_LS*6 - n_DP >= 4: + if n_LS * 6 - n_DP >= 4: idx_B1 -= 1 idx_B2 -= 1 - if n_LS*6 - n_DP == 5: + if n_LS * 6 - n_DP == 5: idx_B2 -= 1 - from_bus[idx_B1] = buses[2*n_LS-1] - from_bus[idx_B2] = buses[n_LS-1] + from_bus[idx_B1] = buses[2 * n_LS - 1] + from_bus[idx_B2] = buses[n_LS - 1] elif branching == 3: n_LS = int(ceil(n_DP / 10)) - idx_B1 = 4*n_LS - idx_B2 = 5*n_LS - idx_B3 = 7*n_LS - if n_LS*10 - n_DP >= 1: + idx_B1 = 4 * n_LS + idx_B2 = 5 * n_LS + idx_B3 = 7 * n_LS + if n_LS * 10 - n_DP >= 1: idx_B2 -= 1 idx_B3 -= 1 - if n_LS*10 - n_DP >= 2: + if n_LS * 10 - n_DP >= 2: idx_B3 -= 1 - if n_LS*10 - n_DP >= 3: + if n_LS * 10 - n_DP >= 3: idx_B3 -= 1 - if n_LS*10 - n_DP >= 7: + if n_LS * 10 - n_DP >= 7: idx_B1 -= 1 idx_B2 -= 1 idx_B3 -= 1 - if n_LS*10 - n_DP >= 8: + if n_LS * 10 - n_DP >= 8: idx_B2 -= 1 idx_B3 -= 1 - if n_LS*10 - n_DP == 9: + if n_LS * 10 - n_DP == 9: idx_B3 -= 1 - from_bus[idx_B1] = buses[3*n_LS-1] - from_bus[idx_B2] = buses[2*n_LS-1] - from_bus[idx_B3] = buses[n_LS-1] + from_bus[idx_B1] = buses[3 * n_LS - 1] + from_bus[idx_B2] = buses[2 * n_LS - 1] + from_bus[idx_B3] = buses[n_LS - 1] elif branching != 0: raise ValueError("branching must be in (0, 1, 2, 3), but is %s" % str(branching)) # create lines new_lines = set() for i, f_bus in enumerate(from_bus): - new_lines.add(pp.create_line(net, f_bus, buses[i], length_km=d_DP*1e-3, - std_type='NAYY 4x150 SE')) + new_lines.add(create_line(net, f_bus, buses[i], length_km=d_DP * 1e-3, + std_type='NAYY 4x150 SE')) # line type consideration if linetype == 'C&OHL': - _change_to_ohl(net, idx_busbar, new_lines, round(len(new_lines)*0.4)) + _change_to_ohl(net, idx_busbar, new_lines, round(len(new_lines) * 0.4)) # create loads _create_loads_with_coincidence(net, buses) @@ -151,12 +157,9 @@ def create_dickert_lv_feeders(net, busbar_index, feeders_range='short', linetype **case** (str, 'good') - case of supply mission, which can be ('good', 'average', 'worse') EXAMPLE: - - import pandapower.networks as pn - - net = pn.create_dickert_lv_network() - - pn.create_dickert_lv_feeders(net, busbar_index=1, customer='multiple') + >>> from pandapower.networks.dickert_lv_networks import create_dickert_lv_feeders, create_dickert_lv_networks + >>> net = create_dickert_lv_network() + >>> create_dickert_lv_feeders(net, busbar_index=1, customer='multiple') """ # --- paper data - TABLE III and IV parameters = {'short': {'cable': {'single': {'good': [60, 1, False, False, False], @@ -187,9 +190,9 @@ def create_dickert_lv_feeders(net, busbar_index, feeders_range='short', linetype # add missing line types if 'NFA2X 4x70' not in net.std_types['line'].keys(): - pp.create_std_type(net, {"c_nf_per_km": 12.8, "r_ohm_per_km": 0.443, "x_ohm_per_km": 0.07, - "max_i_ka": 0.205, "type": "ol"}, name='NFA2X 4x70', - element="line") + create_std_type(net, {"c_nf_per_km": 12.8, "r_ohm_per_km": 0.443, "x_ohm_per_km": 0.07, + "max_i_ka": 0.205, "type": "ol"}, name='NFA2X 4x70', + element="line") # determine low voltage vn_kv lv_vn_kv = net.bus.vn_kv.at[busbar_index] @@ -252,26 +255,24 @@ def create_dickert_lv_network(feeders_range='short', linetype='cable', customer= **net** (pandapowerNet) - Returns the required dickert lv network EXAMPLE: - - import pandapower.networks as pn - - net = pn.create_dickert_lv_network() + >>> from pandapower.networks.dickert_lv_networks import create_dickert_lv_network + >>> net = create_dickert_lv_network() """ # --- create network - net = pp.create_empty_network(name='dickert_lv_network with' + feeders_range + - '-range feeders, ' + linetype + 'and ' + customer + - 'customers in ' + case + 'case') + net = create_empty_network(name='dickert_lv_network with' + feeders_range + + '-range feeders, ' + linetype + 'and ' + customer + + 'customers in ' + case + 'case') # assumptions mv_vn_kv = 20 lv_vn_kv = 0.4 # create mv connection - mv_bus = pp.create_bus(net, mv_vn_kv, name='mv bus') - busbar_index = pp.create_bus(net, lv_vn_kv, name='busbar') - pp.create_ext_grid(net, mv_bus) + mv_bus = create_bus(net, mv_vn_kv, name='mv bus') + busbar_index = create_bus(net, lv_vn_kv, name='busbar') + create_ext_grid(net, mv_bus) if trafo_type_name not in net.std_types['trafo'].keys(): - pp.create_std_type(net, trafo_type_data, name=trafo_type_name, element="trafo") - pp.create_transformer(net, mv_bus, busbar_index, std_type=trafo_type_name) + create_std_type(net, trafo_type_data, name=trafo_type_name, element="trafo") + create_transformer(net, mv_bus, busbar_index, std_type=trafo_type_name) # create feeders create_dickert_lv_feeders(net=net, busbar_index=busbar_index, feeders_range=feeders_range, @@ -279,6 +280,7 @@ def create_dickert_lv_network(feeders_range='short', linetype='cable', customer= return net + if __name__ == "__main__": if 0: feeders_range = 'middle' @@ -292,6 +294,7 @@ def create_dickert_lv_network(feeders_range='short', linetype='cable', customer= trafo_type_name=trafo_type_name, trafo_type_data=trafo_type_data) from pandapower.plotting import simple_plot + simple_plot(net) else: pass diff --git a/pandapower/networks/ieee_europen_lv_asymmetric.py b/pandapower/networks/ieee_europen_lv_asymmetric.py index 24a9f996d..0b34a3ca7 100644 --- a/pandapower/networks/ieee_europen_lv_asymmetric.py +++ b/pandapower/networks/ieee_europen_lv_asymmetric.py @@ -4,8 +4,9 @@ # and Energy System Technology (IEE), Kassel. All rights reserved. import os -import pandapower as pp + from pandapower.__init__ import pp_dir +from pandapower.file_io import from_json def ieee_european_lv_asymmetric(scenario="on_peak_566", **kwargs): @@ -34,19 +35,18 @@ def ieee_european_lv_asymmetric(scenario="on_peak_566", **kwargs): **net** - pandapower network EXAMPLE: - - import pandapower.networks - net = pandapower.networks.ieee_european_lv_asymmetric("off_start") + >>> from pandapower.networks import ieee_european_lv_asymmetric + >>> net = ieee_european_lv_asymmetric("off_start") """ if scenario == "off_peak_1": - net = pp.from_json(os.path.join(pp_dir, "networks", "IEEE_European_LV_Off_Peak_1.json"), - **kwargs) + net = from_json(os.path.join(pp_dir, "networks", "IEEE_European_LV_Off_Peak_1.json"), + **kwargs) elif scenario == "on_peak_566": - net = pp.from_json(os.path.join(pp_dir, "networks", "IEEE_European_LV_On_Peak_566.json"), - **kwargs) + net = from_json(os.path.join(pp_dir, "networks", "IEEE_European_LV_On_Peak_566.json"), + **kwargs) elif scenario == "off_peak_1440": - net = pp.from_json(os.path.join(pp_dir, "networks", "IEEE_European_LV_Off_Peak_1440.json"), - **kwargs) + net = from_json(os.path.join(pp_dir, "networks", "IEEE_European_LV_Off_Peak_1440.json"), + **kwargs) else: raise ValueError("Unknown scenario %s - chose 'on_peak_566' or " % scenario + "'off_peak_1' or 'off_peak_1440'") diff --git a/pandapower/networks/kerber_networks.py b/pandapower/networks/kerber_networks.py index 8b4c68158..9bf00e4ee 100644 --- a/pandapower/networks/kerber_networks.py +++ b/pandapower/networks/kerber_networks.py @@ -6,7 +6,9 @@ import random as rd -import pandapower as pp +from pandapower.create import create_empty_network, create_bus, create_ext_grid, create_line, create_load, \ + create_transformer +from pandapower.std_types import create_std_type # --- support functions @@ -19,7 +21,7 @@ def _create_empty_network_with_transformer(trafotype, V_OS=10., V_US=0.4): The voltage levels can be set manually and the transformer parameter can \ be set with "ti" """ - pd_net = pp.create_empty_network() + pd_net = create_empty_network() NFA2X4x70 = {"c_nf_per_km": 0, "r_ohm_per_km": 0.443, "x_ohm_per_km": 0.069, "max_i_ka": 0.270, "type": "ol", "q_mm2": 70} NAYY4x50 = {"c_nf_per_km": 670, "r_ohm_per_km": 0.6417, "x_ohm_per_km": 0.084823, @@ -30,24 +32,24 @@ def _create_empty_network_with_transformer(trafotype, V_OS=10., V_US=0.4): "max_i_ka": 0.313, "type": "cs", "q_mm2": 185} NYY4x35 = {"c_nf_per_km": 0, "r_ohm_per_km": 0.5240284, "x_ohm_per_km": 0.08513716, "max_i_ka": 0.156, "type": "cs", "q_mm2": 35} - pp.create_std_type(net=pd_net, data=NFA2X4x70, name="NFA2X 4x70", element="line") - pp.create_std_type(net=pd_net, data=NAYY4x50, name="NAYY 4x50", element="line") - pp.create_std_type(net=pd_net, data=NAYY4x150, name="NAYY 4x150", element="line") - pp.create_std_type(net=pd_net, data=NAYY4x185, name="NAYY 4x185", element="line") - pp.create_std_type(net=pd_net, data=NYY4x35, name="NYY 4x35", element="line") + create_std_type(net=pd_net, data=NFA2X4x70, name="NFA2X 4x70", element="line") + create_std_type(net=pd_net, data=NAYY4x50, name="NAYY 4x50", element="line") + create_std_type(net=pd_net, data=NAYY4x150, name="NAYY 4x150", element="line") + create_std_type(net=pd_net, data=NAYY4x185, name="NAYY 4x185", element="line") + create_std_type(net=pd_net, data=NYY4x35, name="NYY 4x35", element="line") T100kVA = {"sn_mva": 0.100, "vn_hv_kv": 10, "vn_lv_kv": 0.4, "vk_percent": 4, "vkr_percent": 1.2, "pfe_kw": 0.45, "i0_percent": 0.25, "shift_degree": 150, "vector_group": "Dyn5"} T160kVA = {"sn_mva": 0.160, "vn_hv_kv": 10, "vn_lv_kv": 0.4, "vk_percent": 4, "vkr_percent": 1.2, "pfe_kw": 0.38, "i0_percent": 0.26, "shift_degree": 150, "vector_group": "Dyn5"} - pp.create_std_type(net=pd_net, data=T100kVA, name="0.1 MVA 10/0.4 kV", element="trafo") - pp.create_std_type(net=pd_net, data=T160kVA, name="0.16 MVA 10/0.4 kV", element="trafo") + create_std_type(net=pd_net, data=T100kVA, name="0.1 MVA 10/0.4 kV", element="trafo") + create_std_type(net=pd_net, data=T160kVA, name="0.16 MVA 10/0.4 kV", element="trafo") - busnr1 = pp.create_bus(pd_net, name="Trafostation_OS", vn_kv=V_OS) - pp.create_ext_grid(pd_net, bus=busnr1) - main_busbar_nr = pp.create_bus(pd_net, name="main_busbar", vn_kv=V_US, type="b") - pp.create_transformer(pd_net, hv_bus=busnr1, lv_bus=main_busbar_nr, std_type=trafotype, + busnr1 = create_bus(pd_net, name="Trafostation_OS", vn_kv=V_OS) + create_ext_grid(pd_net, bus=busnr1) + main_busbar_nr = create_bus(pd_net, name="main_busbar", vn_kv=V_US, type="b") + create_transformer(pd_net, hv_bus=busnr1, lv_bus=main_busbar_nr, std_type=trafotype, name="trafo 1") return pd_net, main_busbar_nr @@ -73,13 +75,13 @@ def _add_lines_and_loads(pd_net, n_lines, startbusnr, length_per_line, for i in list(range(n_lines)): buscounter = startpoint_bus + i linecounter = startpoint_line + i - created_bus_nr = pp.create_bus(pd_net, name="bus_%d_%d" % (branchnr, buscounter), vn_kv=.4) + created_bus_nr = create_bus(pd_net, name="bus_%d_%d" % (branchnr, buscounter), vn_kv=.4) - pp.create_line(pd_net, bus_before, created_bus_nr, length_km=length_per_line, + create_line(pd_net, bus_before, created_bus_nr, length_km=length_per_line, name="line_%d_%d" % (branchnr, linecounter), std_type=std_type) if p_load_mw or q_load_mvar: - pp.create_load(pd_net, created_bus_nr, p_mw=p_load_mw, q_mvar=q_load_mvar) + create_load(pd_net, created_bus_nr, p_mw=p_load_mw, q_mvar=q_load_mvar) bus_before = created_bus_nr # rueckgefuehrter Wert in der Schleife @@ -128,22 +130,22 @@ def _add_lines_with_branched_loads(net, n_lines, startbus, length_per_line, for i in range(n_lines): buscounter = startpoint_bus + i linecounter = startpoint_line + i - created_bus_nr = pp.create_bus(net, name="%s_%d_%d" % (bustype, branchnr, buscounter), + created_bus_nr = create_bus(net, name="%s_%d_%d" % (bustype, branchnr, buscounter), type="b" if bustype == "KV" else "n", vn_kv=.4) - pp.create_line(net, bus_before, created_bus_nr, + create_line(net, bus_before, created_bus_nr, length_km=length_per_line, name="line_%d_%d" % (branchnr, linecounter), std_type=std_type) - loadbusnr = pp.create_bus(net, name="loadbus_%d_%d" % (branchnr, buscounter), vn_kv=.4) + loadbusnr = create_bus(net, name="loadbus_%d_%d" % (branchnr, buscounter), vn_kv=.4) - pp.create_line(net, created_bus_nr, loadbusnr, + create_line(net, created_bus_nr, loadbusnr, length_km=length_branchout_line, name="branchout_line_%d_%d" % (branchnr, linecounter), std_type=std_type_branchout_line) if p_load_mw or q_load_mvar: - pp.create_load(net, loadbusnr, + create_load(net, loadbusnr, p_mw=p_load_mw, q_mvar=q_load_mvar) bus_before = created_bus_nr # rueckgefuehrter Wert in der Schleife diff --git a/pandapower/networks/lv_schutterwald.py b/pandapower/networks/lv_schutterwald.py index 01839e84c..8ef8727cc 100644 --- a/pandapower/networks/lv_schutterwald.py +++ b/pandapower/networks/lv_schutterwald.py @@ -6,10 +6,12 @@ import os -import pandapower as pp -import pandapower.topology as top -import pandapower.plotting.geo as geo from pandapower.__init__ import pp_dir +from pandapower.file_io import from_json +from pandapower.run import runpp +from pandapower.toolbox.grid_modification import drop_elements, select_subnet +from pandapower.topology.create_graph import create_nxgraph +from pandapower.topology.graph_searches import connected_components def lv_schutterwald(separation_by_sub=False, include_heat_pumps=False, **kwargs): @@ -36,43 +38,42 @@ def lv_schutterwald(separation_by_sub=False, include_heat_pumps=False, **kwargs) EXAMPLE: - ``import pandapower.networks`` - - ``net = pandapower.networks.lv_schutterwald()`` + >>> from pandapower.networks import lv_schutterwald + >>> net = lv_schutterwald() or with separation - ``net_list = pandapower.networks.lv_schutterwald(separation_by_sub=True)`` + >>> net_list = lv_schutterwald(separation_by_sub=True) """ - net = pp.from_json(os.path.join(pp_dir, "networks", "lv_schutterwald.json"), **kwargs) + net = from_json(os.path.join(pp_dir, "networks", "lv_schutterwald.json"), **kwargs) # modifications on the original file # geo.convert_crs(net, epsg_out=4326, epsg_in=31467) # geo.convert_geodata_to_geojson(net, lonlat=False) - # pp.drop_inactive_elements(net) + # drop_inactive_elements(net) # net.load.replace({"type": "WP"}, "HP", inplace=True) # net.load.replace({"type": "HA"}, "HH", inplace=True) # net.load.name = net.load.name.str.replace("H", "HH", regex=False) # net.load.name = net.load.name.str.replace("WP", "HP", regex=False) if not include_heat_pumps: - pp.drop_elements(net, "load", net.load.loc[net.load.type == "HP"].index) + drop_elements(net, "load", net.load.loc[net.load.type == "HP"].index) subnets = list() if separation_by_sub: # creating multigraph - mg = top.create_nxgraph(net) + mg = create_nxgraph(net) # clustering connected buses - zones = [list(area) for area in top.connected_components(mg)] + zones = [list(area) for area in connected_components(mg)] for i, zone in enumerate(zones): - net1 = pp.select_subnet(net, buses=zone, include_switch_buses=False, - include_results=True, keep_everything_else=True) - pp.runpp(net1) + net1 = select_subnet(net, buses=zone, include_switch_buses=False, + include_results=True, keep_everything_else=True) + runpp(net1) net1.name = f'LV Schutterwald {i}' subnets.append(net1) return subnets - pp.runpp(net) + runpp(net) net.name = 'LV Schutterwald' return net diff --git a/pandapower/networks/mv_oberrhein.py b/pandapower/networks/mv_oberrhein.py index c43abe314..1ba989edd 100644 --- a/pandapower/networks/mv_oberrhein.py +++ b/pandapower/networks/mv_oberrhein.py @@ -8,9 +8,12 @@ import numpy as np -import pandapower as pp -import pandapower.topology as top from pandapower.__init__ import pp_dir +from pandapower.file_io import from_json +from pandapower.run import runpp +from pandapower.toolbox.grid_modification import select_subnet +from pandapower.topology.create_graph import create_nxgraph +from pandapower.topology.graph_searches import connected_components def mv_oberrhein(scenario="load", cosphi_load=0.98, cosphi_pv=1.0, include_substations=False, @@ -52,20 +55,19 @@ def mv_oberrhein(scenario="load", cosphi_load=0.98, cosphi_pv=1.0, include_subst EXAMPLE: - ``import pandapower.networks`` - - ``net = pandapower.networks.mv_oberrhein("generation")`` + >>> from pandapower.networks.mv_oberrhein import mv_oberrhein + >>> net = mv_oberrhein("generation") or with separation - ``net0, net1 = pandapower.networks.mv_oberrhein(separation_by_sub=True)`` - """ + >>> net0, net1 = pandapower.networks.mv_oberrhein(separation_by_sub=True) + """ if include_substations: - net = pp.from_json(os.path.join(pp_dir, "networks", "mv_oberrhein_substations.json"), **kwargs) + net = from_json(os.path.join(pp_dir, "networks", "mv_oberrhein_substations.json"), **kwargs) # geo.convert_epsg_bus_geodata(net, epsg_out=4326, epsg_in=31467) # geo.convert_geodata_to_geojson(net, lonlat=False) else: - net = pp.from_json(os.path.join(pp_dir, "networks", "mv_oberrhein.json"), **kwargs) + net = from_json(os.path.join(pp_dir, "networks", "mv_oberrhein.json"), **kwargs) # geo.convert_epsg_bus_geodata(net, epsg_out=4326, epsg_in=31467) # geo.convert_geodata_to_geojson(net, lonlat=False) net.load.q_mvar = np.tan(np.arccos(cosphi_load)) * net.load.p_mw @@ -86,16 +88,16 @@ def mv_oberrhein(scenario="load", cosphi_load=0.98, cosphi_pv=1.0, include_subst if separation_by_sub: # creating multigraph - mg = top.create_nxgraph(net) + mg = create_nxgraph(net) # clustering connected buses - zones = [list(area) for area in top.connected_components(mg)] - net1 = pp.select_subnet(net, buses=zones[0], include_switch_buses=False, - include_results=True, keep_everything_else=True) - net0 = pp.select_subnet(net, buses=zones[1], include_switch_buses=False, - include_results=True, keep_everything_else=True) - - pp.runpp(net0) - pp.runpp(net1) + zones = [list(area) for area in connected_components(mg)] + net1 = select_subnet(net, buses=zones[0], include_switch_buses=False, + include_results=True, keep_everything_else=True) + net0 = select_subnet(net, buses=zones[1], include_switch_buses=False, + include_results=True, keep_everything_else=True) + + runpp(net0) + runpp(net1) net0.name = 'MV Oberrhein 0' net1.name = 'MV Oberrhein 1' # TODO: this should be added to the initial data not converted here. @@ -103,7 +105,7 @@ def mv_oberrhein(scenario="load", cosphi_load=0.98, cosphi_pv=1.0, include_subst # geo.convert_geodata_to_geojson(net1) return net0, net1 - pp.runpp(net) + runpp(net) net.name = 'MV Oberrhein' # geo.convert_geodata_to_geojson(net) return net diff --git a/pandapower/networks/power_system_test_cases.py b/pandapower/networks/power_system_test_cases.py index 596ea0381..414d79c83 100644 --- a/pandapower/networks/power_system_test_cases.py +++ b/pandapower/networks/power_system_test_cases.py @@ -6,11 +6,11 @@ import os -import pandapower as pp -import pandapower.toolbox -from pandapower.file_io import from_json from pandapower.__init__ import pp_dir -import pandapower.plotting.geo as geo +from pandapower.create import create_gen, create_ext_grid, create_sgen +from pandapower.file_io import from_json +from pandapower.plotting.geo import convert_geodata_to_geojson +from pandapower.toolbox.element_selection import pp_elements def _get_cases_path(filename=None): @@ -42,28 +42,28 @@ def _change_ref_bus(net, ref_bus_idx, ext_grid_p=0): for i in ext_grid_idx: ext_grid_data = net.ext_grid.loc[i] net.ext_grid = net.ext_grid.drop(i) - pp.create_gen(net, ext_grid_data.bus, ext_grid_p[j], - vm_pu=ext_grid_data.vm_pu, controllable=True, - min_q_mvar=ext_grid_data.min_q_mvar, max_q_mvar=ext_grid_data.max_q_mvar, - min_p_mw=ext_grid_data.min_p_mw, max_p_mw=ext_grid_data.max_p_mw) + create_gen(net, ext_grid_data.bus, ext_grid_p[j], + vm_pu=ext_grid_data.vm_pu, controllable=True, + min_q_mvar=ext_grid_data.min_q_mvar, max_q_mvar=ext_grid_data.max_q_mvar, + min_p_mw=ext_grid_data.min_p_mw, max_p_mw=ext_grid_data.max_p_mw) j += 1 # old gen at ref_bus -> ext_grid (and sgen) for i in gen_idx: gen_data = net.gen.loc[i] net.gen = net.gen.drop(i) if gen_data.bus not in net.ext_grid.bus.values: - pp.create_ext_grid(net, gen_data.bus, vm_pu=gen_data.vm_pu, va_degree=0., - min_q_mvar=gen_data.min_q_mvar, max_q_mvar=gen_data.max_q_mvar, - min_p_mw=gen_data.min_p_mw, max_p_mw=gen_data.max_p_mw) + create_ext_grid(net, gen_data.bus, vm_pu=gen_data.vm_pu, va_degree=0., + min_q_mvar=gen_data.min_q_mvar, max_q_mvar=gen_data.max_q_mvar, + min_p_mw=gen_data.min_p_mw, max_p_mw=gen_data.max_p_mw) else: - pp.create_sgen(net, gen_data.bus, p_mw=gen_data.p_mw, - min_q_mvar=gen_data.min_q_mvar, max_q_mvar=gen_data.max_q_mvar, - min_p_mw=gen_data.min_p_mw, max_p_mw=gen_data.max_p_mw) + create_sgen(net, gen_data.bus, p_mw=gen_data.p_mw, + min_q_mvar=gen_data.min_q_mvar, max_q_mvar=gen_data.max_q_mvar, + min_p_mw=gen_data.min_p_mw, max_p_mw=gen_data.max_p_mw) def sorted_from_json(path, **kwargs): net = from_json(path, **kwargs) - for elm in pandapower.toolbox.pp_elements(): + for elm in pp_elements(): net[elm].sort_index(inplace=True) return net @@ -71,16 +71,15 @@ def sorted_from_json(path, **kwargs): def case4gs(**kwargs): """ This is the 4 bus example from J. J. Grainger and W. D. Stevenson, Power system analysis. \ - McGraw-Hill, 1994. pp. 337-338. Its data origin is \ + McGraw-Hill, 1994. 337-338. Its data origin is \ `PYPOWER `_. OUTPUT: **net** - Returns the required ieee network case4gs EXAMPLE: - import pandapower.networks as pn - - net = pn.case4gs() + >>> from pandapower.networks.power_system_test_cases import case4gs + >>> net = case4gs() """ case4gs = sorted_from_json(_get_cases_path("case4gs.json"), **kwargs) return case4gs @@ -95,9 +94,8 @@ def case5(**kwargs): **net** - Returns the required ieee network case5 EXAMPLE: - import pandapower.networks as pn - - net = pn.case5() + >>> from pandapower.networks.power_system_test_cases import case5 + >>> net = case5() """ case5 = sorted_from_json(_get_cases_path("case5.json", **kwargs)) return case5 @@ -106,7 +104,7 @@ def case5(**kwargs): def case6ww(**kwargs): """ Calls the json file case6ww.json which data origin is \ - `PYPOWER `_. It represents the 6 bus example from pp. \ + `PYPOWER `_. It represents the 6 bus example from \ 104, 112, 119, 123-124, 549 from A. J. Wood and B. F. Wollenberg, Power generation, operation, \ and control. John Wiley & Sons, 2012.. @@ -114,9 +112,8 @@ def case6ww(**kwargs): **net** - Returns the required ieee network case6ww EXAMPLE: - import pandapower.networks as pn - - net = pn.case6ww() + >>> from pandapower.networks.power_system_test_cases import case6ww + >>> net = case6ww() """ case6ww = sorted_from_json(_get_cases_path("case6ww.json", **kwargs)) return case6ww @@ -133,13 +130,12 @@ def case9(**kwargs): **net** - Returns the required ieee network case9 EXAMPLE: - import pandapower.networks as pn - - net = pn.case9() + >>> from pandapower.networks.power_system_test_cases import case9 + >>> net = case9() """ case9 = sorted_from_json(_get_cases_path("case9.json", **kwargs)) # TODO: add converted net to the json and remove this conversion step. - geo.convert_geodata_to_geojson(case9) + convert_geodata_to_geojson(case9) return case9 @@ -161,9 +157,8 @@ def case11_iwamoto(**kwargs): **net** - Returns the required network case11_iwamoto EXAMPLE: - import pandapower.networks as pn - - net = pn.case11_iwamoto() + >>> from pandapower.networks.power_system_test_cases import case11_iwamoto + >>> net = case11_iwamoto() """ case11 = sorted_from_json(_get_cases_path("case11_iwamoto.json", **kwargs)) return case11 @@ -182,9 +177,8 @@ def case14(**kwargs): **net** - Returns the required ieee network case14 EXAMPLE: - import pandapower.networks as pn - - net = pn.case14() + >>> from pandapower.networks.power_system_test_cases import case14 + >>> net = case14() """ case14 = sorted_from_json(_get_cases_path("case14.json", **kwargs)) return case14 @@ -202,9 +196,8 @@ def case24_ieee_rts(**kwargs): **net** - Returns the required ieee network case24 EXAMPLE: - import pandapower.networks as pn - - net = pn.case24_ieee_rts() + >>> from pandapower.networks.power_system_test_cases import case24_ieee_rts + >>> net = case24_ieee_rts() """ case24 = sorted_from_json(_get_cases_path("case24_ieee_rts.json", **kwargs)) return case24 @@ -220,13 +213,12 @@ def case30(**kwargs): **net** - Returns the required ieee network case30 EXAMPLE: - import pandapower.networks as pn - - net = pn.case30() + >>> from pandapower.networks.power_system_test_cases import case30 + >>> net = case30() """ case30 = sorted_from_json(_get_cases_path("case30.json", **kwargs)) # TODO: add converted net to the json and remove this conversion step. - geo.convert_geodata_to_geojson(case30) + convert_geodata_to_geojson(case30) return case30 @@ -241,9 +233,8 @@ def case_ieee30(**kwargs): **net** - Returns the required ieee network case30 EXAMPLE: - import pandapower.networks as pn - - net = pn.case_ieee30() + >>> from pandapower.networks.power_system_test_cases import case_ieee30 + >>> net = case_ieee30() """ case_ieee30 = sorted_from_json(_get_cases_path("case_ieee30.json", **kwargs)) return case_ieee30 @@ -261,9 +252,8 @@ def case33bw(**kwargs): **net** - Returns the required ieee network case33bw EXAMPLE: - import pandapower.networks as pn - - net = pn.case33bw() + >>> from pandapower.networks.power_system_test_cases import case33bw + >>> net = case33bw() """ case33bw = sorted_from_json(_get_cases_path("case33bw.json", **kwargs)) return case33bw @@ -284,13 +274,12 @@ def case39(**kwargs): **net** - Returns the required ieee network case39 EXAMPLE: - import pandapower.networks as pn - - net = pn.case39() + >>> from pandapower.networks.power_system_test_cases import case39 + >>> net = case39() """ case39 = sorted_from_json(_get_cases_path("case39.json", **kwargs)) # TODO: add converted net to the json and remove this conversion step. - geo.convert_geodata_to_geojson(case39) + convert_geodata_to_geojson(case39) return case39 @@ -315,9 +304,8 @@ def case57(vn_kv_area1=115, vn_kv_area2=500, vn_kv_area3=138, vn_kv_area4=345, v **net** - Returns the required ieee network case57 EXAMPLE: - import pandapower.networks as pn - - net = pn.case57() + >>> from pandapower.networks.power_system_test_cases import case57 + >>> net = pn.case57() """ case57 = sorted_from_json(_get_cases_path("case57.json", **kwargs)) Idx_area1 = case57.bus[case57.bus.vn_kv == 110].index @@ -344,15 +332,14 @@ def case89pegase(**kwargs): PEGASE `_, 2016 and S. Fliscounakis, P. Panciatici, \ F. Capitanescu, and L. Wehenkel, Contingency ranking with respect to overloads in very large \ power systems taking into account uncertainty, preventive, and corrective actions, \ - IEEE Transactions on Power Systems, vol. 28, no. 4, pp. 4909-4917, Nov 2013.. + IEEE Transactions on Power Systems, vol. 28, no. 4, 4909-4917, Nov 2013.. OUTPUT: **net** - Returns the required ieee network case89pegase EXAMPLE: - import pandapower.networks as pn - - net = pn.case89pegase() + >>> from pandapower.networks.power_system_test_cases import case89pegase + >>> net = case89pegase() """ case89pegase = sorted_from_json(_get_cases_path("case89pegase.json", **kwargs)) return case89pegase @@ -371,13 +358,12 @@ def case118(**kwargs): **net** - Returns the required ieee network case118 EXAMPLE: - import pandapower.networks as pn - - net = pn.case118() + >>> from pandapower.networks.power_system_test_cases import case118 + >>> net = case118() """ case118 = sorted_from_json(_get_cases_path("case118.json", **kwargs)) # TODO: add converted net to the json and remove this conversion step. - geo.convert_geodata_to_geojson(case118) + convert_geodata_to_geojson(case118) return case118 @@ -391,9 +377,8 @@ def case145(**kwargs): **net** - Returns the required ieee network case145 EXAMPLE: - import pandapower.networks as pn - - net = pn.case145() + >>> from pandapower.networks.power_system_test_cases import case145 + >>> net = case145() """ case145 = sorted_from_json(_get_cases_path("case145.json", **kwargs)) return case145 @@ -410,9 +395,8 @@ def case_illinois200(**kwargs): **net** - Returns the required ieee network case30 EXAMPLE: - import pandapower.networks as pn - - net = pn.case_illinois200() + >>> from pandapower.networks.power_system_test_cases import case_illinois200 + >>> net = case_illinois200() """ case_illinois200 = sorted_from_json(_get_cases_path("case_illinois200.json", **kwargs)) return case_illinois200 @@ -430,9 +414,8 @@ def case300(**kwargs): **net** - Returns the required ieee network case300 EXAMPLE: - import pandapower.networks as pn - - net = pn.case300() + >>> from pandapower.networks.power_system_test_cases import case300 + >>> net = case300() """ case300 = sorted_from_json(_get_cases_path("case300.json", **kwargs)) return case300 @@ -447,15 +430,14 @@ def case1354pegase(**kwargs): `_, 2016 and S. Fliscounakis, P. Panciatici, F. Capitanescu, \ and L. Wehenkel, Contingency ranking with respect to overloads in very large power systems \ taking into account uncertainty, preventive, and corrective actions, IEEE Transactions on \ - Power Systems, vol. 28, no. 4, pp. 4909-4917, Nov 2013.. + Power Systems, vol. 28, no. 4, 4909-4917, Nov 2013.. OUTPUT: **net** - Returns the required ieee network case1354pegase EXAMPLE: - import pandapower.networks as pn - - net = pn.case1354pegase() + >>> from pandapower.networks.power_system_test_cases import case1354pegase + >>> net = case1354pegase() """ case1354pegase = sorted_from_json(_get_cases_path("case1354pegase.json", **kwargs)) return case1354pegase @@ -483,12 +465,11 @@ def case1888rte(ref_bus_idx=1246, **kwargs): **net** - Returns the required ieee network case1888rte EXAMPLE: - import pandapower.networks as pn - - net = pn.case1888rte() + >>> from pandapower.networks.power_system_test_cases import case1888rte + >>> net = case1888rte() """ case1888rte = sorted_from_json(_get_cases_path("case1888rte.json", **kwargs)) - case1888rte.ext_grid.loc[0, ['min_p_mw', 'max_p_mw', 'min_q_mvar', 'max_q_mvar']] *= 2 + case1888rte.ext_grid.loc[0, ['min_p_mw', 'max_p_mw', 'min_q_mvar', 'max_q_mvar']] *= 2 if ref_bus_idx != 1246: # change reference bus _change_ref_bus(case1888rte, ref_bus_idx, ext_grid_p=[-89.5]) @@ -517,9 +498,8 @@ def case2848rte(ref_bus_idx=271, **kwargs): **net** - Returns the required ieee network case2848rte EXAMPLE: - import pandapower.networks as pn - - net = pn.case2848rte() + >>> from pandapower.networks.power_system_test_cases import case2848rte + >>> net = case2848rte() """ case2848rte = sorted_from_json(_get_cases_path("case2848rte.json", **kwargs)) if ref_bus_idx != 271: # change reference bus @@ -536,15 +516,14 @@ def case2869pegase(**kwargs): `_, 2016 and S. Fliscounakis, P. Panciatici, F. Capitanescu, \ and L. Wehenkel, Contingency ranking with respect to overloads in very large power systems \ taking into account uncertainty, preventive, and corrective actions, IEEE Transactions on \ - Power Systems, vol. 28, no. 4, pp. 4909-4917, Nov 2013.. + Power Systems, vol. 28, no. 4, 4909-4917, Nov 2013.. OUTPUT: **net** - Returns the required ieee network case2869pegase EXAMPLE: - import pandapower.networks as pn - - net = pn.case2869pegase() + >>> from pandapower.networks.power_system_test_cases import case2869pegase + >>> net = case2869pegase() """ case2869pegase = sorted_from_json(_get_cases_path("case2869pegase.json", **kwargs)) return case2869pegase @@ -560,9 +539,8 @@ def case3120sp(**kwargs): **net** - Returns the required ieee network case3120sp EXAMPLE: - import pandapower.networks as pn - - net = pn.case3120sp() + >>> from pandapower.networks.power_system_test_cases import case3120sp + >>> net = case3120sp() """ case3120sp = sorted_from_json(_get_cases_path("case3120sp.json", **kwargs)) return case3120sp @@ -590,12 +568,11 @@ def case6470rte(ref_bus_idx=5988, **kwargs): **net** - Returns the required ieee network case6470rte EXAMPLE: - import pandapower.networks as pn - - net = pn.case6470rte() + >>> from pandapower.networks.power_system_test_cases import case6470rte + >>> net = case6470rte() """ case6470rte = sorted_from_json(_get_cases_path("case6470rte.json", **kwargs)) - case6470rte.ext_grid.loc[0, ['min_p_mw', 'max_p_mw', 'min_q_mvar', 'max_q_mvar']] *= 2 + case6470rte.ext_grid.loc[0, ['min_p_mw', 'max_p_mw', 'min_q_mvar', 'max_q_mvar']] *= 2 if ref_bus_idx != 5988: # change reference bus _change_ref_bus(case6470rte, ref_bus_idx, ext_grid_p=[-169.41]) return case6470rte @@ -624,9 +601,8 @@ def case6495rte(ref_bus_idx=None, **kwargs): **net** - Returns the required ieee network case6495rte EXAMPLE: - import pandapower.networks as pn - - net = pn.case6495rte() + >>> from pandapower.networks.power_system_test_cases import case6495rte + >>> net = case6495rte() """ ref_bus_idx = ref_bus_idx or [6077, 6161, 6305, 6306, 6307, 6308] case6495rte = sorted_from_json(_get_cases_path("case6495rte.json", **kwargs)) @@ -658,9 +634,8 @@ def case6515rte(ref_bus_idx=6171, **kwargs): **net** - Returns the required ieee network case6515rte EXAMPLE: - import pandapower.networks as pn - - net = pn.case6515rte() + >>> from pandapower.networks.power_system_test_cases import case6515rte + >>> net = case6515rte() """ case6515rte = sorted_from_json(_get_cases_path("case6515rte.json", **kwargs)) if ref_bus_idx != 6171: # change reference bus @@ -677,15 +652,15 @@ def case9241pegase(**kwargs): `_, 2016 and S. Fliscounakis, P. Panciatici, F. Capitanescu, \ and L. Wehenkel, Contingency ranking with respect to overloads in very large power systems \ taking into account uncertainty, preventive, and corrective actions, IEEE Transactions on \ - Power Systems, vol. 28, no. 4, pp. 4909-4917, Nov 2013.. + Power Systems, vol. 28, no. 4, 4909-4917, Nov 2013.. OUTPUT: **net** - Returns the required ieee network case9241pegase EXAMPLE: - import pandapower.networks as pn - net = pn.case9241pegase() + >>> from pandapower.networks.power_system_test_cases import case9241pegase + >>> net = case9241pegase() """ case9241pegase = sorted_from_json(_get_cases_path("case9241pegase.json", **kwargs)) return case9241pegase @@ -703,9 +678,8 @@ def GBreducednetwork(**kwargs): **net** - Returns the required ieee network GBreducednetwork EXAMPLE: - import pandapower.networks as pn - - net = pn.GBreducednetwork() + >>> from pandapower.networks.power_system_test_cases import GBreducednetwork + >>> net = GBreducednetwork() """ GBreducednetwork = sorted_from_json(_get_cases_path("GBreducednetwork.json", **kwargs)) return GBreducednetwork @@ -725,9 +699,8 @@ def GBnetwork(**kwargs): **net** - Returns the required ieee network GBreducednetwork EXAMPLE: - import pandapower.networks as pn - - net = pn.GBnetwork() + >>> from pandapower.networks.power_system_test_cases import GBnetwork + >>> net = GBnetwork() """ GBnetwork = sorted_from_json(_get_cases_path("GBnetwork.json", **kwargs)) return GBnetwork @@ -746,9 +719,8 @@ def iceland(**kwargs): **net** - Returns the required ieee network iceland EXAMPLE: - import pandapower.networks as pn - - net = pn.iceland() + >>> from pandapower.networks.power_system_test_cases import iceland + >>> net = iceland() """ iceland = sorted_from_json(_get_cases_path("iceland.json", **kwargs)) return iceland diff --git a/pandapower/networks/simple_pandapower_test_networks.py b/pandapower/networks/simple_pandapower_test_networks.py index b76b53785..77c6165fb 100644 --- a/pandapower/networks/simple_pandapower_test_networks.py +++ b/pandapower/networks/simple_pandapower_test_networks.py @@ -3,8 +3,8 @@ # Copyright (c) 2016-2024 by University of Kassel and Fraunhofer Institute for Energy Economics # and Energy System Technology (IEE), Kassel. All rights reserved. - -import pandapower as pp +from pandapower.create import create_bus, create_ext_grid, create_line, create_load, create_switch, create_sgen, \ + create_transformer, create_empty_network def panda_four_load_branch(): @@ -16,36 +16,35 @@ def panda_four_load_branch(): **net** - Returns the required four load system EXAMPLE: - import pandapower.networks as pn - - net_four_load = pn.panda_four_load_branch() + >>> from pandapower.networks.simple_pandapower_test_networks import panda_four_load_branch + >>> net_four_load = panda_four_load_branch() """ - net = pp.create_empty_network() - - busnr1 = pp.create_bus(net, name="bus1", vn_kv=10., geodata=(0, 0)) - busnr2 = pp.create_bus(net, name="bus2", vn_kv=.4, geodata=(0, -1)) - busnr3 = pp.create_bus(net, name="bus3", vn_kv=.4, geodata=(0, -2)) - busnr4 = pp.create_bus(net, name="bus4", vn_kv=.4, geodata=(0, -3)) - busnr5 = pp.create_bus(net, name="bus5", vn_kv=.4, geodata=(0, -4)) - busnr6 = pp.create_bus(net, name="bus6", vn_kv=.4, geodata=(0, -5)) - - pp.create_ext_grid(net, busnr1) - - pp.create_transformer(net, busnr1, busnr2, std_type="0.25 MVA 10/0.4 kV") - - pp.create_line(net, busnr2, busnr3, name="line1", length_km=0.05, - std_type="NAYY 4x120 SE") - pp.create_line(net, busnr3, busnr4, name="line2", length_km=0.05, - std_type="NAYY 4x120 SE") - pp.create_line(net, busnr4, busnr5, name="line3", length_km=0.05, - std_type="NAYY 4x120 SE") - pp.create_line(net, busnr5, busnr6, name="line4", length_km=0.05, - std_type="NAYY 4x120 SE") - - pp.create_load(net, busnr3, 0.030, 0.010) - pp.create_load(net, busnr4, 0.030, 0.010) - pp.create_load(net, busnr5, 0.030, 0.010) - pp.create_load(net, busnr6, 0.030, 0.010) + net = create_empty_network() + + busnr1 = create_bus(net, name="bus1", vn_kv=10., geodata=(0, 0)) + busnr2 = create_bus(net, name="bus2", vn_kv=.4, geodata=(0, -1)) + busnr3 = create_bus(net, name="bus3", vn_kv=.4, geodata=(0, -2)) + busnr4 = create_bus(net, name="bus4", vn_kv=.4, geodata=(0, -3)) + busnr5 = create_bus(net, name="bus5", vn_kv=.4, geodata=(0, -4)) + busnr6 = create_bus(net, name="bus6", vn_kv=.4, geodata=(0, -5)) + + create_ext_grid(net, busnr1) + + create_transformer(net, busnr1, busnr2, std_type="0.25 MVA 10/0.4 kV") + + create_line(net, busnr2, busnr3, name="line1", length_km=0.05, + std_type="NAYY 4x120 SE") + create_line(net, busnr3, busnr4, name="line2", length_km=0.05, + std_type="NAYY 4x120 SE") + create_line(net, busnr4, busnr5, name="line3", length_km=0.05, + std_type="NAYY 4x120 SE") + create_line(net, busnr5, busnr6, name="line4", length_km=0.05, + std_type="NAYY 4x120 SE") + + create_load(net, busnr3, 0.030, 0.010) + create_load(net, busnr4, 0.030, 0.010) + create_load(net, busnr5, 0.030, 0.010) + create_load(net, busnr6, 0.030, 0.010) return net @@ -59,45 +58,44 @@ def four_loads_with_branches_out(): **net** - Returns the required four load system with branches EXAMPLE: - import pandapower.networks as pn - - net_four_load_with_branches = pn.four_loads_with_branches_out() + >>> from pandapower.networks.simple_pandapower_test_networks import four_loads_with_branches_out + >>> net_four_load_with_branches = four_loads_with_branches_out() """ - net = pp.create_empty_network() - - busnr1 = pp.create_bus(net, name="bus1ref", vn_kv=10., geodata=(0, 0)) - pp.create_ext_grid(net, busnr1) - busnr2 = pp.create_bus(net, name="bus2", vn_kv=.4, geodata=(0, -1)) - pp.create_transformer(net, busnr1, busnr2, std_type="0.25 MVA 10/0.4 kV") - busnr3 = pp.create_bus(net, name="bus3", vn_kv=.4, geodata=(0, -2)) - pp.create_line(net, busnr2, busnr3, name="line1", length_km=0.05, - std_type="NAYY 4x120 SE") - busnr4 = pp.create_bus(net, name="bus4", vn_kv=.4, geodata=(0, -3)) - pp.create_line(net, busnr3, busnr4, name="line2", length_km=0.05, - std_type="NAYY 4x120 SE") - busnr5 = pp.create_bus(net, name="bus5", vn_kv=.4, geodata=(0, -4)) - pp.create_line(net, busnr4, busnr5, name="line3", length_km=0.05, - std_type="NAYY 4x120 SE") - busnr6 = pp.create_bus(net, name="bus6", vn_kv=.4, geodata=(0, -5)) - pp.create_line(net, busnr5, busnr6, name="line4", length_km=0.05, - std_type="NAYY 4x120 SE") - busnr7 = pp.create_bus(net, name="bus7", vn_kv=.4, geodata=(1, -3)) - pp.create_line(net, busnr3, busnr7, name="line5", length_km=0.05, - std_type="NAYY 4x120 SE") - busnr8 = pp.create_bus(net, name="bus8", vn_kv=.4, geodata=(1, -4)) - pp.create_line(net, busnr4, busnr8, name="line6", length_km=0.05, - std_type="NAYY 4x120 SE") - busnr9 = pp.create_bus(net, name="bus9", vn_kv=.4, geodata=(1, -5)) - pp.create_line(net, busnr5, busnr9, name="line7", length_km=0.05, - std_type="NAYY 4x120 SE") - busnr10 = pp.create_bus(net, name="bus10", vn_kv=.4, geodata=(1, -6)) - pp.create_line(net, busnr6, busnr10, name="line8", length_km=0.05, - std_type="NAYY 4x120 SE") - - pp.create_load(net, busnr7, p_mw=0.030, q_mvar=0.010) - pp.create_load(net, busnr8, p_mw=0.030, q_mvar=0.010) - pp.create_load(net, busnr9, p_mw=0.030, q_mvar=0.010) - pp.create_load(net, busnr10, p_mw=0.030, q_mvar=0.010) + net = create_empty_network() + + busnr1 = create_bus(net, name="bus1ref", vn_kv=10., geodata=(0, 0)) + create_ext_grid(net, busnr1) + busnr2 = create_bus(net, name="bus2", vn_kv=.4, geodata=(0, -1)) + create_transformer(net, busnr1, busnr2, std_type="0.25 MVA 10/0.4 kV") + busnr3 = create_bus(net, name="bus3", vn_kv=.4, geodata=(0, -2)) + create_line(net, busnr2, busnr3, name="line1", length_km=0.05, + std_type="NAYY 4x120 SE") + busnr4 = create_bus(net, name="bus4", vn_kv=.4, geodata=(0, -3)) + create_line(net, busnr3, busnr4, name="line2", length_km=0.05, + std_type="NAYY 4x120 SE") + busnr5 = create_bus(net, name="bus5", vn_kv=.4, geodata=(0, -4)) + create_line(net, busnr4, busnr5, name="line3", length_km=0.05, + std_type="NAYY 4x120 SE") + busnr6 = create_bus(net, name="bus6", vn_kv=.4, geodata=(0, -5)) + create_line(net, busnr5, busnr6, name="line4", length_km=0.05, + std_type="NAYY 4x120 SE") + busnr7 = create_bus(net, name="bus7", vn_kv=.4, geodata=(1, -3)) + create_line(net, busnr3, busnr7, name="line5", length_km=0.05, + std_type="NAYY 4x120 SE") + busnr8 = create_bus(net, name="bus8", vn_kv=.4, geodata=(1, -4)) + create_line(net, busnr4, busnr8, name="line6", length_km=0.05, + std_type="NAYY 4x120 SE") + busnr9 = create_bus(net, name="bus9", vn_kv=.4, geodata=(1, -5)) + create_line(net, busnr5, busnr9, name="line7", length_km=0.05, + std_type="NAYY 4x120 SE") + busnr10 = create_bus(net, name="bus10", vn_kv=.4, geodata=(1, -6)) + create_line(net, busnr6, busnr10, name="line8", length_km=0.05, + std_type="NAYY 4x120 SE") + + create_load(net, busnr7, p_mw=0.030, q_mvar=0.010) + create_load(net, busnr8, p_mw=0.030, q_mvar=0.010) + create_load(net, busnr9, p_mw=0.030, q_mvar=0.010) + create_load(net, busnr10, p_mw=0.030, q_mvar=0.010) return net @@ -111,23 +109,22 @@ def simple_four_bus_system(): **net** - Returns the required four bus system EXAMPLE: - import pandapower.networks as pn - - net_simple_four_bus = pn.simple_four_bus_system() + >>> from pandapower.networks.simple_pandapower_test_networks import simple_four_bus_system + >>> net_simple_four_bus = simple_four_bus_system() """ - net = pp.create_empty_network() - busnr1 = pp.create_bus(net, name="bus1ref", vn_kv=10, geodata=(0, 0)) - pp.create_ext_grid(net, busnr1) - busnr2 = pp.create_bus(net, name="bus2", vn_kv=.4, geodata=(0, -1)) - pp.create_transformer(net, busnr1, busnr2, name="transformer", std_type="0.25 MVA 10/0.4 kV") - busnr3 = pp.create_bus(net, name="bus3", vn_kv=.4, geodata=(0, -2)) - pp.create_line(net, busnr2, busnr3, name="line1", length_km=0.50000, std_type="NAYY 4x50 SE") - busnr4 = pp.create_bus(net, name="bus4", vn_kv=.4, geodata=(0, -3)) - pp.create_line(net, busnr3, busnr4, name="line2", length_km=0.50000, std_type="NAYY 4x50 SE") - pp.create_load(net, busnr3, 0.030, 0.010, name="load1") - pp.create_load(net, busnr4, 0.030, 0.010, name="load2") - pp.create_sgen(net, busnr3, p_mw=0.020, q_mvar=0.005, name="pv1", sn_mva=0.03) - pp.create_sgen(net, busnr4, p_mw=0.015, q_mvar=0.002, name="pv2", sn_mva=0.02) + net = create_empty_network() + busnr1 = create_bus(net, name="bus1ref", vn_kv=10, geodata=(0, 0)) + create_ext_grid(net, busnr1) + busnr2 = create_bus(net, name="bus2", vn_kv=.4, geodata=(0, -1)) + create_transformer(net, busnr1, busnr2, name="transformer", std_type="0.25 MVA 10/0.4 kV") + busnr3 = create_bus(net, name="bus3", vn_kv=.4, geodata=(0, -2)) + create_line(net, busnr2, busnr3, name="line1", length_km=0.50000, std_type="NAYY 4x50 SE") + busnr4 = create_bus(net, name="bus4", vn_kv=.4, geodata=(0, -3)) + create_line(net, busnr3, busnr4, name="line2", length_km=0.50000, std_type="NAYY 4x50 SE") + create_load(net, busnr3, 0.030, 0.010, name="load1") + create_load(net, busnr4, 0.030, 0.010, name="load2") + create_sgen(net, busnr3, p_mw=0.020, q_mvar=0.005, name="pv1", sn_mva=0.03) + create_sgen(net, busnr4, p_mw=0.015, q_mvar=0.002, name="pv2", sn_mva=0.02) return net @@ -141,54 +138,53 @@ def simple_mv_open_ring_net(): **net** - Returns the required simple medium voltage open ring network EXAMPLE: - import pandapower.networks as pn - - net_simple_open_ring = pn.simple_mv_open_ring_net() + >>> from pandapower.networks.simple_pandapower_test_networks import simple_mv_open_ring_net + >>> net_simple_open_ring = simple_mv_open_ring_net() """ - net = pp.create_empty_network() - - pp.create_bus(net, name="110 kV bar", vn_kv=110, type='b', geodata=(0, 0)) - pp.create_bus(net, name="20 kV bar", vn_kv=20, type='b', geodata=(0, -1)) - pp.create_bus(net, name="bus 2", vn_kv=20, type='b', geodata=(-0.5, -2)) - pp.create_bus(net, name="bus 3", vn_kv=20, type='b', geodata=(-0.5, -3)) - pp.create_bus(net, name="bus 4", vn_kv=20, type='b', geodata=(-0.5, -4)) - pp.create_bus(net, name="bus 5", vn_kv=20, type='b', geodata=(0.5, -4)) - pp.create_bus(net, name="bus 6", vn_kv=20, type='b', geodata=(0.5, -3)) - - pp.create_ext_grid(net, 0, vm_pu=1) - - pp.create_line(net, name="line 0", from_bus=1, to_bus=2, length_km=1, - std_type="NA2XS2Y 1x185 RM/25 12/20 kV") - pp.create_line(net, name="line 1", from_bus=2, to_bus=3, length_km=1, - std_type="NA2XS2Y 1x185 RM/25 12/20 kV") - pp.create_line(net, name="line 2", from_bus=3, to_bus=4, length_km=1, - std_type="NA2XS2Y 1x185 RM/25 12/20 kV") - pp.create_line(net, name="line 3", from_bus=4, to_bus=5, length_km=1, - std_type="NA2XS2Y 1x185 RM/25 12/20 kV") - pp.create_line(net, name="line 4", from_bus=5, to_bus=6, length_km=1, - std_type="NA2XS2Y 1x185 RM/25 12/20 kV") - pp.create_line(net, name="line 5", from_bus=6, to_bus=1, length_km=1, - std_type="NA2XS2Y 1x185 RM/25 12/20 kV") - - pp.create_transformer(net, hv_bus=0, lv_bus=1, std_type="25 MVA 110/20 kV") - - pp.create_load(net, 2, p_mw=1, q_mvar=0.200, name="load 0") - pp.create_load(net, 3, p_mw=1, q_mvar=0.200, name="load 1") - pp.create_load(net, 4, p_mw=1, q_mvar=0.200, name="load 2") - pp.create_load(net, 5, p_mw=1, q_mvar=0.200, name="load 3") - pp.create_load(net, 6, p_mw=1, q_mvar=0.200, name="load 4") - - pp.create_switch(net, bus=1, element=0, et='l') - pp.create_switch(net, bus=2, element=0, et='l') - pp.create_switch(net, bus=2, element=1, et='l') - pp.create_switch(net, bus=3, element=1, et='l') - pp.create_switch(net, bus=3, element=2, et='l') - pp.create_switch(net, bus=4, element=2, et='l') - pp.create_switch(net, bus=4, element=3, et='l', closed=0) - pp.create_switch(net, bus=5, element=3, et='l') - pp.create_switch(net, bus=5, element=4, et='l') - pp.create_switch(net, bus=6, element=4, et='l') - pp.create_switch(net, bus=6, element=5, et='l') - pp.create_switch(net, bus=1, element=5, et='l') + net = create_empty_network() + + create_bus(net, name="110 kV bar", vn_kv=110, type='b', geodata=(0, 0)) + create_bus(net, name="20 kV bar", vn_kv=20, type='b', geodata=(0, -1)) + create_bus(net, name="bus 2", vn_kv=20, type='b', geodata=(-0.5, -2)) + create_bus(net, name="bus 3", vn_kv=20, type='b', geodata=(-0.5, -3)) + create_bus(net, name="bus 4", vn_kv=20, type='b', geodata=(-0.5, -4)) + create_bus(net, name="bus 5", vn_kv=20, type='b', geodata=(0.5, -4)) + create_bus(net, name="bus 6", vn_kv=20, type='b', geodata=(0.5, -3)) + + create_ext_grid(net, 0, vm_pu=1) + + create_line(net, name="line 0", from_bus=1, to_bus=2, length_km=1, + std_type="NA2XS2Y 1x185 RM/25 12/20 kV") + create_line(net, name="line 1", from_bus=2, to_bus=3, length_km=1, + std_type="NA2XS2Y 1x185 RM/25 12/20 kV") + create_line(net, name="line 2", from_bus=3, to_bus=4, length_km=1, + std_type="NA2XS2Y 1x185 RM/25 12/20 kV") + create_line(net, name="line 3", from_bus=4, to_bus=5, length_km=1, + std_type="NA2XS2Y 1x185 RM/25 12/20 kV") + create_line(net, name="line 4", from_bus=5, to_bus=6, length_km=1, + std_type="NA2XS2Y 1x185 RM/25 12/20 kV") + create_line(net, name="line 5", from_bus=6, to_bus=1, length_km=1, + std_type="NA2XS2Y 1x185 RM/25 12/20 kV") + + create_transformer(net, hv_bus=0, lv_bus=1, std_type="25 MVA 110/20 kV") + + create_load(net, 2, p_mw=1, q_mvar=0.200, name="load 0") + create_load(net, 3, p_mw=1, q_mvar=0.200, name="load 1") + create_load(net, 4, p_mw=1, q_mvar=0.200, name="load 2") + create_load(net, 5, p_mw=1, q_mvar=0.200, name="load 3") + create_load(net, 6, p_mw=1, q_mvar=0.200, name="load 4") + + create_switch(net, bus=1, element=0, et='l') + create_switch(net, bus=2, element=0, et='l') + create_switch(net, bus=2, element=1, et='l') + create_switch(net, bus=3, element=1, et='l') + create_switch(net, bus=3, element=2, et='l') + create_switch(net, bus=4, element=2, et='l') + create_switch(net, bus=4, element=3, et='l', closed=0) + create_switch(net, bus=5, element=3, et='l') + create_switch(net, bus=5, element=4, et='l') + create_switch(net, bus=6, element=4, et='l') + create_switch(net, bus=6, element=5, et='l') + create_switch(net, bus=1, element=5, et='l') return net diff --git a/pandapower/networks/synthetic_voltage_control_lv_networks.py b/pandapower/networks/synthetic_voltage_control_lv_networks.py index c1b7edb71..213d207d1 100644 --- a/pandapower/networks/synthetic_voltage_control_lv_networks.py +++ b/pandapower/networks/synthetic_voltage_control_lv_networks.py @@ -3,10 +3,13 @@ # Copyright (c) 2016-2024 by University of Kassel and Fraunhofer Institute for Energy Economics # and Energy System Technology (IEE), Kassel. All rights reserved. -import pandapower as pp import pandas as pd -from numpy import nan, append from geojson import Point, dumps +from numpy import nan, append + +from pandapower.create import create_empty_network, create_bus, create_ext_grid, create_transformer, create_buses, \ + create_line, create_load, create_sgen +from pandapower.std_types import create_std_type def create_synthetic_voltage_control_lv_network(network_class="rural_1"): @@ -34,10 +37,8 @@ def create_synthetic_voltage_control_lv_network(network_class="rural_1"): **net** - returns the required synthetic voltage control lv network EXAMPLE: - - import pandapower.networks as pn - - net = pn.create_synthetic_voltage_control_lv_network() + >>> from pandapower.networks.synthetic_voltage_control_lv_networks import create_synthetic_voltage_control_lv_network + >>> net = create_synthetic_voltage_control_lv_network() """ # process network choosing input data if network_class not in ['rural_1', 'rural_2', 'village_1', 'village_2', 'suburb_1']: @@ -49,16 +50,16 @@ def create_synthetic_voltage_control_lv_network(network_class="rural_1"): 'village_1': [0.053, 0.034, 0.08, 0.04], 'village_2': [0.021, 0.033, 0.023, 0.052], 'suburb_1': [0.041, 0.017, 0.056, 0.018, 0.035, 0.103, 0.046, 0.019, 0.065, 0.026, 0.031]} - line_types = {'rural_1': ['NAYY 4x150 SE']*2 + [('NAYY 4x150 SE', 'NAYY 4x120 SE')], - 'rural_2': ['NAYY 4x35'] + ['NF 4x70']*3, - 'village_1': ['NAYY 4x150 SE']*4, + line_types = {'rural_1': ['NAYY 4x150 SE'] * 2 + [('NAYY 4x150 SE', 'NAYY 4x120 SE')], + 'rural_2': ['NAYY 4x35'] + ['NF 4x70'] * 3, + 'village_1': ['NAYY 4x150 SE'] * 4, 'village_2': [('NAYY 4x70', 'NF 4x50'), ('NAYY 4x120 SE', 'NF 4x95'), ('NAYY 4x95', 'NF 4x70'), ('NAYY 4x150 SE', 'NF 4x120')], - 'suburb_1': [('NAYY 4x150 SE', 'NAYY 4x120 SE')]*3 + + 'suburb_1': [('NAYY 4x150 SE', 'NAYY 4x120 SE')] * 3 + [('NAYY 4x120 SE', 'NAYY 4x95'), 'NAYY 4x150 SE', 'NAYY 4x95'] + - ['NAYY 4x150 SE']*5} - line_type_change_at = {'rural_1': [nan]*2 + [5], 'rural_2': [nan]*4, 'village_1': [nan]*4, - 'village_2': [8, 3, 4, 5], 'suburb_1': [5, 10, 3, 6] + [nan]*7} + ['NAYY 4x150 SE'] * 5} + line_type_change_at = {'rural_1': [nan] * 2 + [5], 'rural_2': [nan] * 4, 'village_1': [nan] * 4, + 'village_2': [8, 3, 4, 5], 'suburb_1': [5, 10, 3, 6] + [nan] * 7} trafo_type = {'rural_1': '0.16 MVA 20/0.4 kV vc', 'rural_2': '0.25 MVA 20/0.4 kV vc', 'village_1': '0.25 MVA 20/0.4 kV vc', 'village_2': '0.4 MVA 20/0.4 kV vc', 'suburb_1': '0.4 MVA 20/0.4 kV vc'} @@ -69,37 +70,37 @@ def create_synthetic_voltage_control_lv_network(network_class="rural_1"): 'suburb_1': 'NAYY 4x35'} # create network - net = pp.create_empty_network(name='synthetic_voltage_control_lv_network: ' + network_class) + net = create_empty_network(name='synthetic_voltage_control_lv_network: ' + network_class) # create std_types # cable data (r, x, i_max) from www.faberkabel.de if network_class in ["rural_2", "village_2", "suburb_1"]: - pp.create_std_type(net, { - "c_nf_per_km": 202, "r_ohm_per_km": 0.869, "x_ohm_per_km": 0.085, - "max_i_ka": 0.123, "type": "cs", "q_mm2": 35}, name="NAYY 4x35", element="line") + create_std_type(net, { + "c_nf_per_km": 202, "r_ohm_per_km": 0.869, "x_ohm_per_km": 0.085, + "max_i_ka": 0.123, "type": "cs", "q_mm2": 35}, name="NAYY 4x35", element="line") if network_class != "suburb_1": - pp.create_std_type(net, { - "c_nf_per_km": 17.8, "r_ohm_per_km": 0.439, "x_ohm_per_km": 0.295, - "max_i_ka": 0.28, "type": "ol", "q_mm2": 70}, name="NF 4x70", element="line") + create_std_type(net, { + "c_nf_per_km": 17.8, "r_ohm_per_km": 0.439, "x_ohm_per_km": 0.295, + "max_i_ka": 0.28, "type": "ol", "q_mm2": 70}, name="NF 4x70", element="line") if network_class == "village_2": - pp.create_std_type(net, { - "c_nf_per_km": 230, "r_ohm_per_km": 0.443, "x_ohm_per_km": 0.0823, - "max_i_ka": 0.179, "type": "cs", "q_mm2": 70}, name="NAYY 4x70", - element="line") + create_std_type(net, { + "c_nf_per_km": 230, "r_ohm_per_km": 0.443, "x_ohm_per_km": 0.0823, + "max_i_ka": 0.179, "type": "cs", "q_mm2": 70}, name="NAYY 4x70", + element="line") data = net.std_types['line']['48-AL1/8-ST1A 0.4'] data['q_mm2'] = 50 - pp.create_std_type(net, data, name="NF 4x50", element="line") + create_std_type(net, data, name="NF 4x50", element="line") data = net.std_types['line']['94-AL1/15-ST1A 0.4'] data['q_mm2'] = 95 - pp.create_std_type(net, data, name="NF 4x95", element="line") - pp.create_std_type(net, { - "c_nf_per_km": 16.2, "r_ohm_per_km": 0.274, "x_ohm_per_km": 0.31, - "max_i_ka": 0.4, "type": "ol", "q_mm2": 120}, name="NF 4x120", - element="line") + create_std_type(net, data, name="NF 4x95", element="line") + create_std_type(net, { + "c_nf_per_km": 16.2, "r_ohm_per_km": 0.274, "x_ohm_per_km": 0.31, + "max_i_ka": 0.4, "type": "ol", "q_mm2": 120}, name="NF 4x120", + element="line") if network_class != "rural_2": - pp.create_std_type(net, { - "c_nf_per_km": 240, "r_ohm_per_km": 0.32, "x_ohm_per_km": 0.082, - "max_i_ka": 0.215, "type": "cs", "q_mm2": 95}, name="NAYY 4x95", element="line") + create_std_type(net, { + "c_nf_per_km": 240, "r_ohm_per_km": 0.32, "x_ohm_per_km": 0.082, + "max_i_ka": 0.215, "type": "cs", "q_mm2": 95}, name="NAYY 4x95", element="line") # trafos if network_class == "rural_1": data = net.std_types['trafo']['0.25 MVA 20/0.4 kV'] @@ -108,23 +109,23 @@ def create_synthetic_voltage_control_lv_network(network_class="rural_1"): data['i0_percent'] = 0.31 data['vkr_percent'] = data['vkr_percent'] * 4 / data['vk_percent'] data['vk_percent'] = 4 - pp.create_std_type(net, data, name=trafo_type[network_class], element="trafo") + create_std_type(net, data, name=trafo_type[network_class], element="trafo") elif network_class in ["rural_2", "village_1"]: data = net.std_types['trafo']['0.25 MVA 20/0.4 kV'] data['vkr_percent'] = data['vkr_percent'] * 4 / data['vk_percent'] data['vk_percent'] = 4 - pp.create_std_type(net, data, name=trafo_type[network_class], element="trafo") + create_std_type(net, data, name=trafo_type[network_class], element="trafo") elif network_class in ["suburb_1", "village_2"]: data = net.std_types['trafo']['0.4 MVA 20/0.4 kV'] data['vkr_percent'] = data['vkr_percent'] * 4 / data['vk_percent'] data['vk_percent'] = 4 - pp.create_std_type(net, data, name=trafo_type[network_class], element="trafo") + create_std_type(net, data, name=trafo_type[network_class], element="trafo") # create mv connection - mv_bus = pp.create_bus(net, 20, name='mv bus') - bb = pp.create_bus(net, 0.4, name='busbar') - pp.create_ext_grid(net, mv_bus) - pp.create_transformer(net, mv_bus, bb, std_type=trafo_type[network_class]) + mv_bus = create_bus(net, 20, name='mv bus') + bb = create_bus(net, 0.4, name='busbar') + create_ext_grid(net, mv_bus) + create_transformer(net, mv_bus, bb, std_type=trafo_type[network_class]) # create lv network idx_feeder = range(len(n_feeder[network_class])) @@ -132,32 +133,32 @@ def create_synthetic_voltage_control_lv_network(network_class="rural_1"): house_buses = {} for i in idx_feeder: # buses - lv_buses[i] = pp.create_buses(net, n_feeder[network_class][i], 0.4, zone='Feeder'+str(i+1), - type='m') - house_buses[i] = pp.create_buses(net, n_feeder[network_class][i], 0.4, - zone='Feeder'+str(i+1), type='n') + lv_buses[i] = create_buses(net, n_feeder[network_class][i], 0.4, zone='Feeder' + str(i + 1), + type='m') + house_buses[i] = create_buses(net, n_feeder[network_class][i], 0.4, + zone='Feeder' + str(i + 1), type='n') # lines lines = pd.DataFrame() lines['from_bus'] = append(bb, append(lv_buses[i][:-1], lv_buses[i])) lines['to_bus'] = append(lv_buses[i], house_buses[i]) if line_type_change_at[network_class][i] is nan: - lines['std_type'] = [line_types[network_class][i]]*n_feeder[network_class][i] + \ - [house_connection_type[network_class]]*n_feeder[network_class][i] + lines['std_type'] = [line_types[network_class][i]] * n_feeder[network_class][i] + \ + [house_connection_type[network_class]] * n_feeder[network_class][i] else: lines['std_type'] = \ - [line_types[network_class][i][0]]*line_type_change_at[network_class][i] + \ - [line_types[network_class][i][1]]*(n_feeder[network_class][i] - - line_type_change_at[network_class][i]) + \ - [house_connection_type[network_class]]*n_feeder[network_class][i] - lines['length'] = [l_lines[network_class][i]]*n_feeder[network_class][i] + \ - [house_connection_length[network_class]]*n_feeder[network_class][i] + [line_types[network_class][i][0]] * line_type_change_at[network_class][i] + \ + [line_types[network_class][i][1]] * (n_feeder[network_class][i] - + line_type_change_at[network_class][i]) + \ + [house_connection_type[network_class]] * n_feeder[network_class][i] + lines['length'] = [l_lines[network_class][i]] * n_feeder[network_class][i] + \ + [house_connection_length[network_class]] * n_feeder[network_class][i] for _, lines in lines.iterrows(): - pp.create_line(net, lines.from_bus, lines.to_bus, length_km=lines.length, - std_type=lines.std_type) + create_line(net, lines.from_bus, lines.to_bus, length_km=lines.length, + std_type=lines.std_type) # load for i in house_buses[i]: - pp.create_load(net, i, p_mw=5.1e-3) + create_load(net, i, p_mw=5.1e-3) # direct loads and DEA if network_class == "rural_1": @@ -181,9 +182,9 @@ def create_synthetic_voltage_control_lv_network(network_class="rural_1"): DER = [(1, 1, 9.36), (1, 2, 79.12), (7, 7, 30), (8, 7, 18.47), (8, 15, 9.54), (10, 10, 14.4)] for i in special_load: - pp.create_load(net, lv_buses[i[0]-1][i[1]-1], p_mw=7.9e-3) + create_load(net, lv_buses[i[0] - 1][i[1] - 1], p_mw=7.9e-3) for i in DER: - pp.create_sgen(net, house_buses[i[0]-1][i[1]-1], p_mw=i[2]*1e-3) + create_sgen(net, house_buses[i[0] - 1][i[1] - 1], p_mw=i[2] * 1e-3) # set bus geo data bus_geo = { diff --git a/pandapower/pd2ppc.py b/pandapower/pd2ppc.py index dc0045944..162cc21bd 100644 --- a/pandapower/pd2ppc.py +++ b/pandapower/pd2ppc.py @@ -4,7 +4,8 @@ # and Energy System Technology (IEE), Kassel. All rights reserved. import numpy as np -import pandapower.auxiliary as aux +from pandapower.auxiliary import _select_is_elements_numba, _check_connectivity_opf, _check_connectivity, \ + _set_isolated_buses_out_of_service, _replace_nans_with_default_limits, _write_lookup_to_net from pandapower.build_branch import _switch_branches, _branches_with_oos_buses, \ _build_branch_ppc, _build_tcsc_ppc, _build_branch_dc_ppc from pandapower.build_bus import _build_bus_ppc, _calc_pq_elements_and_add_on_ppc, \ @@ -29,7 +30,7 @@ def _pd2ppc_recycle(net, sequence, recycle): - # todo for FACTS and DC elements: SVC, TCSC, SSC, VSC + # TODO: for FACTS and DC elements: SVC, TCSC, SSC, VSC key = "_ppc" if sequence is None else "_ppc%d" % sequence if not recycle or not net.get(key, None): return _pd2ppc(net, sequence=sequence) @@ -77,7 +78,8 @@ def _check_vsc_different_ac_control_modes_at_same_bus(ppci): ac_vm_pu_buses = ppci["vsc"][ppci["vsc"][:, VSC_MODE_AC] == VSC_MODE_AC_V, VSC_BUS] ac_q_mvar_buses = ppci["vsc"][ppci["vsc"][:, VSC_MODE_AC] == VSC_MODE_AC_Q, VSC_BUS] ac_slack_buses = ppci["vsc"][ppci["vsc"][:, VSC_MODE_AC] == VSC_MODE_AC_SL, VSC_BUS] - ac_bus_intersection = np.hstack([np.intersect1d(a, b) for a, b in combinations([ac_vm_pu_buses, ac_q_mvar_buses, ac_slack_buses], r=2)]) + ac_bus_intersection = np.hstack( + [np.intersect1d(a, b) for a, b in combinations([ac_vm_pu_buses, ac_q_mvar_buses, ac_slack_buses], r=2)]) if len(ac_bus_intersection) != 0: raise NotImplementedError("Found multiple VSC converters that share the same AC bus and have " "different AC control modes - not implemented. VSC converters can only " @@ -134,7 +136,7 @@ def _pd2ppc(net, sequence=None, **kwargs): """ # select elements in service (time consuming, so we do it once) - net["_is_elements"] = aux._select_is_elements_numba(net, sequence=sequence) + net["_is_elements"] = _select_is_elements_numba(net, sequence=sequence) # Gets network configurations mode = net["_options"]["mode"] @@ -188,18 +190,18 @@ def _pd2ppc(net, sequence=None, **kwargs): if sequence in [None, 1, 2]: # sets islands (multiple isolated nodes) out of service if mode == "opf": - net["_isolated_buses"], _, _ = aux._check_connectivity_opf(ppc) + net["_isolated_buses"], _, _ = _check_connectivity_opf(ppc) net["_isolated_buses_dc"] = np.array([], dtype=np.int64) else: - net["_isolated_buses"], _, _, net["_isolated_buses_dc"], _, _ = aux._check_connectivity(ppc) - net["_is_elements_final"] = aux._select_is_elements_numba(net, net._isolated_buses, - net._isolated_buses_dc, sequence) + net["_isolated_buses"], _, _, net["_isolated_buses_dc"], _, _ = _check_connectivity(ppc) + net["_is_elements_final"] = _select_is_elements_numba(net, net._isolated_buses, + net._isolated_buses_dc, sequence) else: ppc["bus"][net._isolated_buses, BUS_TYPE] = NONE net["_is_elements"] = net["_is_elements_final"] else: # sets buses out of service, which aren't connected to branches / REF buses - aux._set_isolated_buses_out_of_service(net, ppc) + _set_isolated_buses_out_of_service(net, ppc) # we need to check this after checking connectivity (isolated vsc as DC slack cause change of DC_REF to DC_P) if "pf" in mode or "se" in mode: @@ -207,7 +209,7 @@ def _pd2ppc(net, sequence=None, **kwargs): _build_gen_ppc(net, ppc) - aux._replace_nans_with_default_limits(net, ppc) + _replace_nans_with_default_limits(net, ppc) # generates "internal" ppci format (for powerflow calc) # from "external" ppc format and updates the bus lookup @@ -233,28 +235,29 @@ def _pd2ppc(net, sequence=None, **kwargs): def _init_ppc(net, mode="pf", sequence=None): # init empty ppc - ppc = {"baseMVA": net.sn_mva, - "version": 2, - "bus": np.array([], dtype=float), - "bus_dc": np.array([], dtype=np.float64), - "branch": np.array([], dtype=np.complex128), - "branch_dc": np.array([], dtype=np.float64), - "tcsc": np.array([], dtype=np.complex128), - "svc": np.array([], dtype=np.complex128), - "ssc": np.array([], dtype=np.complex128), - "vsc": np.array([], dtype=np.float64), - "gen": np.array([], dtype=float), - "internal": { - "Ybus": np.array([], dtype=np.complex128), - "Yf": np.array([], dtype=np.complex128), - "Yt": np.array([], dtype=np.complex128), - "branch_is": np.array([], dtype=bool), - "branch_dc_is": np.array([], dtype=bool), - "gen_is": np.array([], dtype=bool), - "DLF": np.array([], dtype=np.complex128), - "buses_ord_bfs_nets": np.array([], dtype=float) - } - } + ppc = { + "baseMVA": net.sn_mva, + "version": 2, + "bus": np.array([], dtype=float), + "bus_dc": np.array([], dtype=np.float64), + "branch": np.array([], dtype=np.complex128), + "branch_dc": np.array([], dtype=np.float64), + "tcsc": np.array([], dtype=np.complex128), + "svc": np.array([], dtype=np.complex128), + "ssc": np.array([], dtype=np.complex128), + "vsc": np.array([], dtype=np.float64), + "gen": np.array([], dtype=float), + "internal": { + "Ybus": np.array([], dtype=np.complex128), + "Yf": np.array([], dtype=np.complex128), + "Yt": np.array([], dtype=np.complex128), + "branch_is": np.array([], dtype=bool), + "branch_dc_is": np.array([], dtype=bool), + "gen_is": np.array([], dtype=bool), + "DLF": np.array([], dtype=np.complex128), + "buses_ord_bfs_nets": np.array([], dtype=float) + } + } if mode == "opf": # additional fields in ppc ppc["gencost"] = np.array([], dtype=float) @@ -292,13 +295,13 @@ def _ppc2ppci(ppc, net, ppci=None): # get bus_lookup bus_lookup = net["_pd2ppc_lookups"]["bus"] bus_dc_lookup = net["_pd2ppc_lookups"]["bus_dc"] - # get OOS busses and place them at the end of the bus array + # get OOS buses and place them at the end of the bus array # (there are no OOS busses in the ppci) oos_buses = ppc['bus'][:, BUS_TYPE] == NONE oos_buses_dc = ppc['bus_dc'][:, BUS_TYPE] == DC_NONE ppci['bus'] = ppc['bus'][~oos_buses] ppci['bus_dc'] = ppc['bus_dc'][~oos_buses_dc] - # in ppc the OOS busses are included and at the end of the array + # in ppc the OOS buses are included and at the end of the array ppc['bus'] = np.vstack([ppc['bus'][~oos_buses], ppc['bus'][oos_buses]]) ppc['bus_dc'] = np.vstack([ppc['bus_dc'][~oos_buses_dc], ppc['bus_dc'][oos_buses_dc]]) @@ -383,19 +386,19 @@ def _ppc2ppci(ppc, net, ppci=None): ppci["internal"]["gen_is"] = gs svcs = ((ppc["svc"][:, SVC_STATUS] > 0) & # gen status - bs[n2i[np.real(ppc["svc"][:, SVC_BUS]).astype(np.int64)]]) + bs[n2i[np.real(ppc["svc"][:, SVC_BUS]).astype(np.int64)]]) ppci["internal"]["svc_is"] = svcs sscs = ((ppc["ssc"][:, SSC_STATUS] > 0) & # ssc status - bs[n2i[np.real(ppc["ssc"][:, SSC_BUS]).astype(np.int64)]] & - bs[n2i[np.real(ppc["ssc"][:, SSC_INTERNAL_BUS]).astype(np.int64)]]) + bs[n2i[np.real(ppc["ssc"][:, SSC_BUS]).astype(np.int64)]] & + bs[n2i[np.real(ppc["ssc"][:, SSC_INTERNAL_BUS]).astype(np.int64)]]) ppci["internal"]["ssc_is"] = sscs vscs = ((ppc["vsc"][:, VSC_STATUS] > 0) & # vsc status - bs[n2i[np.real(ppc["vsc"][:, VSC_BUS]).astype(np.int64)]] & - bs[n2i[np.real(ppc["vsc"][:, VSC_INTERNAL_BUS]).astype(np.int64)]] & - bs_dc[n2i_dc[np.real(ppc["vsc"][:, VSC_BUS_DC]).astype(np.int64)]] & - bs_dc[n2i_dc[np.real(ppc["vsc"][:, VSC_INTERNAL_BUS_DC]).astype(np.int64)]]) + bs[n2i[np.real(ppc["vsc"][:, VSC_BUS]).astype(np.int64)]] & + bs[n2i[np.real(ppc["vsc"][:, VSC_INTERNAL_BUS]).astype(np.int64)]] & + bs_dc[n2i_dc[np.real(ppc["vsc"][:, VSC_BUS_DC]).astype(np.int64)]] & + bs_dc[n2i_dc[np.real(ppc["vsc"][:, VSC_INTERNAL_BUS_DC]).astype(np.int64)]]) ppci["internal"]["vsc_is"] = vscs brs = (np.real(ppc["branch"][:, BR_STATUS]).astype(np.int64) & # branch status @@ -404,8 +407,8 @@ def _ppc2ppci(ppc, net, ppci=None): ppci["internal"]["branch_is"] = brs brs_dc = (np.real(ppc["branch_dc"][:, DC_BR_STATUS]).astype(np.int64) & # branch status - bs_dc[n2i_dc[np.real(ppc["branch_dc"][:, DC_F_BUS]).astype(np.int64)]] & - bs_dc[n2i_dc[np.real(ppc["branch_dc"][:, DC_T_BUS]).astype(np.int64)]]).astype(bool) + bs_dc[n2i_dc[np.real(ppc["branch_dc"][:, DC_F_BUS]).astype(np.int64)]] & + bs_dc[n2i_dc[np.real(ppc["branch_dc"][:, DC_T_BUS]).astype(np.int64)]]).astype(bool) ppci["internal"]["branch_dc_is"] = brs_dc trs = (np.real(ppc["tcsc"][:, TCSC_STATUS]).astype(np.int64) & # branch status @@ -450,7 +453,7 @@ def _update_lookup_entries(net, lookup, e2i, element): valid_bus_lookup_entries = lookup >= 0 # update entries lookup[valid_bus_lookup_entries] = e2i[lookup[valid_bus_lookup_entries]] - aux._write_lookup_to_net(net, element, lookup) + _write_lookup_to_net(net, element, lookup) def _build_gen_lookups(net, element, f, t): @@ -471,4 +474,4 @@ def _init_lookup(net, lookup_name, pandapower_index, ppc_index): # update lookup lookup[pandapower_index] = ppc_index - aux._write_lookup_to_net(net, lookup_name, lookup) + _write_lookup_to_net(net, lookup_name, lookup) diff --git a/pandapower/pd2ppc_zero.py b/pandapower/pd2ppc_zero.py index e34ce4f90..09cc544c6 100644 --- a/pandapower/pd2ppc_zero.py +++ b/pandapower/pd2ppc_zero.py @@ -10,11 +10,10 @@ import numpy as np from itertools import product -import pandapower.auxiliary as aux +from pandapower.auxiliary import _select_is_elements_numba, _sum_by_group from pandapower.pypower.idx_bus_dc import DC_NONE, DC_BUS_TYPE from pandapower.build_bus import _build_bus_ppc, _build_svc_ppc, _build_ssc_ppc, _build_vsc_ppc, _build_bus_dc_ppc from pandapower.build_gen import _build_gen_ppc -# from pandapower.pd2ppc import _ppc2ppci, _init_ppc from pandapower.pypower.idx_brch import BR_G, BR_B, BR_R, BR_X, F_BUS, T_BUS, branch_cols, BR_STATUS, SHIFT, TAP, BR_R_ASYM, \ BR_X_ASYM, BR_G_ASYM, BR_B_ASYM from pandapower.pypower.idx_bus import BASE_KV, BS, GS, BUS_TYPE, NONE @@ -36,7 +35,7 @@ def _pd2ppc_zero(net, k_st, sequence=0): For short-circuit calculation, the short-circuit impedance of external grids is also considered. """ # select elements in service (time consuming, so we do it once) - net["_is_elements"] = aux._select_is_elements_numba(net, sequence=sequence) + net["_is_elements"] = _select_is_elements_numba(net, sequence=sequence) ppc = _init_ppc(net, sequence) @@ -366,7 +365,7 @@ def _add_trafo_sc_impedance_zero(net, ppc, trafo_df=None, k_st=None): raise ValueError("Transformer vector group %s is unknown " "/ not implemented for three phase load flow" % vector_group) - buses, gs, bs = aux._sum_by_group(buses_all, gs_all, bs_all) + buses, gs, bs = _sum_by_group(buses_all, gs_all, bs_all) ppc["bus"][buses, GS] += gs ppc["bus"][buses, BS] += bs del net.trafo["_ppc_idx"] @@ -431,7 +430,7 @@ def _add_ext_grid_sc_impedance_zero(net, ppc): r0_grid = net.ext_grid[is_egs]["r0x0_%s" % case].values * x0_grid y0_grid = 1 / (r0_grid + x0_grid*1j) - buses, gs, bs = aux._sum_by_group(eg_buses_ppc, y0_grid.real, y0_grid.imag) + buses, gs, bs = _sum_by_group(eg_buses_ppc, y0_grid.real, y0_grid.imag) ppc["bus"][buses, GS] = gs ppc["bus"][buses, BS] = bs diff --git a/pandapower/plotting/collections.py b/pandapower/plotting/collections.py index e060c1d2c..0f4b0cc2a 100644 --- a/pandapower/plotting/collections.py +++ b/pandapower/plotting/collections.py @@ -3,14 +3,14 @@ # Copyright (c) 2016-2023 by University of Kassel and Fraunhofer Institute for Energy Economics # and Energy System Technology (IEE), Kassel. All rights reserved. -import re import ast -import sys import copy import inspect -import geojson +import re +import sys from typing import Callable, TYPE_CHECKING +import geojson import pandas as pd if TYPE_CHECKING: @@ -28,6 +28,7 @@ from matplotlib.patches import Circle, Rectangle, PathPatch from matplotlib.textpath import TextPath from matplotlib.transforms import Affine2D + MATPLOTLIB_INSTALLED = True except ImportError: MATPLOTLIB_INSTALLED = False @@ -117,7 +118,7 @@ def create_annotation_collection(texts, coords, size, prop=None, **kwargs): **kwargs** - Any other keyword-arguments will be passed to the PatchCollection. """ if not MATPLOTLIB_INSTALLED: - soft_dependency_error(str(sys._getframe().f_code.co_name)+"()", "matplotlib") + soft_dependency_error(str(sys._getframe().f_code.co_name) + "()", "matplotlib") tp = [] # we convert TextPaths to PathPatches to create a PatchCollection if hasattr(size, "__iter__"): @@ -152,7 +153,7 @@ def add_cmap_to_collection(collection, cmap, norm, z, cbar_title, plot_colormap= :return: collection - the given collection with added colormap (no copy!) """ if not MATPLOTLIB_INSTALLED: - soft_dependency_error(str(sys._getframe().f_code.co_name)+"()", "matplotlib") + soft_dependency_error(str(sys._getframe().f_code.co_name) + "()", "matplotlib") collection.set_cmap(cmap) collection.set_norm(norm) collection.set_array(np.ma.masked_invalid(z)) @@ -192,7 +193,7 @@ def _create_node_collection(nodes, coords, size=5, patch_type="circle", color=No :return: pc - patch collection for the nodes """ if not MATPLOTLIB_INSTALLED: - soft_dependency_error(str(sys._getframe().f_code.co_name)+"()", "matplotlib") + soft_dependency_error(str(sys._getframe().f_code.co_name) + "()", "matplotlib") if len(coords) == 0: return None @@ -237,7 +238,7 @@ def _create_line2d_collection(coords, indices, infos=None, picker=False, **kwarg :return: lc - line collection for the given coordinates """ if not MATPLOTLIB_INSTALLED: - soft_dependency_error(str(sys._getframe().f_code.co_name)+"()", "matplotlib") + soft_dependency_error(str(sys._getframe().f_code.co_name) + "()", "matplotlib") # This would be done anyway by matplotlib - doing it explicitly makes it clear and # prevents unexpected behavior when observing colors being "none" lc = LineCollection(coords, picker=picker, **kwargs) @@ -287,7 +288,7 @@ def _create_node_element_collection(node_coords, patch_maker, size=1., infos=Non """ if not MATPLOTLIB_INSTALLED: - soft_dependency_error(str(sys._getframe().f_code.co_name)+"()", "matplotlib") + soft_dependency_error(str(sys._getframe().f_code.co_name) + "()", "matplotlib") angles = orientation if hasattr(orientation, '__iter__') else [orientation] * len(node_coords) assert len(node_coords) == len(angles), \ "The length of coordinates does not match the length of the orientation angles!" @@ -356,7 +357,7 @@ def _create_complex_branch_collection(coords, patch_maker, size=1, infos=None, r - line_coll - line collection connecting the patches with the nodes """ if not MATPLOTLIB_INSTALLED: - soft_dependency_error(str(sys._getframe().f_code.co_name)+"()", "matplotlib") + soft_dependency_error(str(sys._getframe().f_code.co_name) + "()", "matplotlib") if infos is None: infos_pc = [] infos_lc = [] @@ -436,7 +437,7 @@ def create_bus_collection(net, buses=None, size=5, patch_type="circle", color=No raise NotImplementedError(f"bus table {bus_table} not implemented!") if not MATPLOTLIB_INSTALLED: - soft_dependency_error(str(sys._getframe().f_code.co_name)+"()", "matplotlib") + soft_dependency_error(str(sys._getframe().f_code.co_name) + "()", "matplotlib") buses = get_index_array(buses, net[bus_table].index) if len(buses) == 0: return None @@ -452,7 +453,7 @@ def create_bus_collection(net, buses=None, size=5, patch_type="circle", color=No buses_with_geo = buses[np.isin(buses, bus_geodata.index.values)] if len(buses_with_geo) < len(buses): logger.warning( - f"The following buses cannot be displayed as there is on geodata available: {set(buses)-set(buses_with_geo)}" + f"The following buses cannot be displayed as there is on geodata available: {set(buses) - set(buses_with_geo)}" ) coords = bus_geodata.loc[buses_with_geo].values @@ -528,9 +529,10 @@ def create_line_collection(net: pandapowerNet, lines=None, raise NotImplementedError(f"line table {line_table} not implemented!") if not MATPLOTLIB_INSTALLED: - soft_dependency_error(str(sys._getframe().f_code.co_name)+"()", "matplotlib") + soft_dependency_error(str(sys._getframe().f_code.co_name) + "()", "matplotlib") - if not use_bus_geodata and line_geodata is None and ("geo" not in net[line_table].columns or net[line_table].geo.empty): + if not use_bus_geodata and line_geodata is None and ( + "geo" not in net[line_table].columns or net[line_table].geo.empty): # if bus geodata is available, but no line geodata logger.warning("use_bus_geodata is automatically set to True, since net.line.geo is empty.") use_bus_geodata = True @@ -613,7 +615,7 @@ def create_dcline_collection(net, dclines=None, line_geodata=None, infofunc=None **lc** - line collection """ if not MATPLOTLIB_INSTALLED: - soft_dependency_error(str(sys._getframe().f_code.co_name)+"()", "matplotlib") + soft_dependency_error(str(sys._getframe().f_code.co_name) + "()", "matplotlib") use_bus_geodata = True @@ -669,7 +671,7 @@ def create_impedance_collection(net, impedances=None, bus_geodata=None, infofunc **lc** - line collection """ if not MATPLOTLIB_INSTALLED: - soft_dependency_error(str(sys._getframe().f_code.co_name)+"()", "matplotlib") + soft_dependency_error(str(sys._getframe().f_code.co_name) + "()", "matplotlib") impedances = get_index_array(impedances, net.impedance.index) if len(impedances) == 0: @@ -728,7 +730,7 @@ def create_trafo_connection_collection(net, trafos=None, bus_geodata=None, infof **lc** - line collection """ if not MATPLOTLIB_INSTALLED: - soft_dependency_error(str(sys._getframe().f_code.co_name)+"()", "matplotlib") + soft_dependency_error(str(sys._getframe().f_code.co_name) + "()", "matplotlib") trafos = get_index_array(trafos, net.trafo.index) @@ -740,8 +742,10 @@ def create_trafo_connection_collection(net, trafos=None, bus_geodata=None, infof trafos = trafos[in_geodata] trafo_table = net.trafo.loc[trafos] - hv_geo = bus_geodata.loc[trafo_table["hv_bus"]].apply(geojson.loads).apply(geojson.utils.coords).apply(next).to_list() # using next works because bus only has one coordinate pair - lv_geo = bus_geodata.loc[trafo_table["lv_bus"]].apply(geojson.loads).apply(geojson.utils.coords).apply(next).to_list() + hv_geo = bus_geodata.loc[trafo_table["hv_bus"]].apply(geojson.loads).apply(geojson.utils.coords).apply( + next).to_list() # using next works because bus only has one coordinate pair + lv_geo = bus_geodata.loc[trafo_table["lv_bus"]].apply(geojson.loads).apply(geojson.utils.coords).apply( + next).to_list() tg = list(zip(hv_geo, lv_geo)) info = [infofunc(tr) for tr in trafos] if infofunc is not None else [] @@ -780,7 +784,7 @@ def create_trafo3w_connection_collection(net, trafos=None, bus_geodata=None, inf **lc** - line collection """ if not MATPLOTLIB_INSTALLED: - soft_dependency_error(str(sys._getframe().f_code.co_name)+"()", "matplotlib") + soft_dependency_error(str(sys._getframe().f_code.co_name) + "()", "matplotlib") trafos = get_index_array(trafos, net.trafo3w.index) if bus_geodata is None: @@ -838,7 +842,7 @@ def create_trafo_collection(net, trafos=None, picker=False, size=None, infofunc= **pc** - patch collection """ if not MATPLOTLIB_INSTALLED: - soft_dependency_error(str(sys._getframe().f_code.co_name)+"()", "matplotlib") + soft_dependency_error(str(sys._getframe().f_code.co_name) + "()", "matplotlib") trafos = get_index_array(trafos, net.trafo.index) @@ -903,7 +907,7 @@ def create_trafo3w_collection(net, trafo3ws=None, picker=False, infofunc=None, c **pc** - patch collection """ if not MATPLOTLIB_INSTALLED: - soft_dependency_error(str(sys._getframe().f_code.co_name)+"()", "matplotlib") + soft_dependency_error(str(sys._getframe().f_code.co_name) + "()", "matplotlib") trafo3ws = get_index_array(trafo3ws, net.trafo3w.index) @@ -977,6 +981,7 @@ def create_trafo3w_collection(net, trafo3ws=None, picker=False, infofunc=None, c lc.cbar_title = cbar_title return lc, pc + # todo geojson def create_vsc_collection(net, vscs=None, picker=False, size=None, infofunc=None, cmap=None, norm=None, z=None, clim=None, cbar_title="VSC power", @@ -1006,7 +1011,7 @@ def create_vsc_collection(net, vscs=None, picker=False, size=None, infofunc=None **pc** - patch collection """ if not MATPLOTLIB_INSTALLED: - soft_dependency_error(str(sys._getframe().f_code.co_name)+"()", "matplotlib") + soft_dependency_error(str(sys._getframe().f_code.co_name) + "()", "matplotlib") vscs = get_index_array(vscs, net.vsc.index) @@ -1049,6 +1054,7 @@ def create_vsc_collection(net, vscs=None, picker=False, size=None, infofunc=None add_cmap_to_collection(lc, cmap, norm, z_duplicated, cbar_title, plot_colormap, clim) return lc, pc + # todo geojson def create_vsc_connection_collection(net, vscs=None, bus_geodata=None, bus_dc_geodata=None, infofunc=None, cmap=None, clim=None, norm=None, z=None, @@ -1090,7 +1096,7 @@ def create_vsc_connection_collection(net, vscs=None, bus_geodata=None, bus_dc_ge **lc** - line collection """ if not MATPLOTLIB_INSTALLED: - soft_dependency_error(str(sys._getframe().f_code.co_name)+"()", "matplotlib") + soft_dependency_error(str(sys._getframe().f_code.co_name) + "()", "matplotlib") vscs = get_index_array(vscs, net.vsc.index) @@ -1209,7 +1215,8 @@ def create_load_collection(net, loads=None, size=1., infofunc=None, orientation= """ loads = get_index_array(loads, net.load.index) infos = [infofunc(i) for i in range(len(loads))] if infofunc is not None else [] - node_coords = net.bus.loc[net.load.loc[loads, "bus"].values, "geo"].apply(geojson.loads).apply(geojson.utils.coords).apply(next).to_list() + node_coords = net.bus.loc[net.load.loc[loads, "bus"].values, "geo"].apply(geojson.loads).apply( + geojson.utils.coords).apply(next).to_list() color = kwargs.pop("color", "k") @@ -1248,7 +1255,8 @@ def create_gen_collection(net, gens=None, size=1., infofunc=None, orientation=np """ gens = get_index_array(gens, net.gen.index) infos = [infofunc(i) for i in range(len(gens))] if infofunc is not None else [] - node_coords = net.bus.loc[net.gen.loc[gens, "bus"].values, "geo"].apply(geojson.loads).apply(geojson.utils.coords).apply(next).to_list() + node_coords = net.bus.loc[net.gen.loc[gens, "bus"].values, "geo"].apply(geojson.loads).apply( + geojson.utils.coords).apply(next).to_list() color = kwargs.pop("color", "k") @@ -1287,7 +1295,8 @@ def create_sgen_collection(net, sgens=None, size=1., infofunc=None, orientation= """ sgens = get_index_array(sgens, net.sgen.index) infos = [infofunc(i) for i in range(len(sgens))] if infofunc is not None else [] - node_coords = net.bus.loc[net.sgen.loc[sgens, "bus"].values, "geo"].apply(geojson.loads).apply(geojson.utils.coords).apply(next).to_list() + node_coords = net.bus.loc[net.sgen.loc[sgens, "bus"].values, "geo"].apply(geojson.loads).apply( + geojson.utils.coords).apply(next).to_list() color = kwargs.pop("color", "k") @@ -1326,7 +1335,8 @@ def create_storage_collection(net, storages=None, size=1., infofunc=None, orient **storage_lc** - line collection """ infos = [infofunc(i) for i in range(len(storages))] if infofunc is not None else [] - node_coords = net.bus.loc[net.storage.loc[storages, "bus"].values, "geo"].apply(geojson.loads).apply(geojson.utils.coords).apply(next).to_list() + node_coords = net.bus.loc[net.storage.loc[storages, "bus"].values, "geo"].apply(geojson.loads).apply( + geojson.utils.coords).apply(next).to_list() color = kwargs.pop("color", "k") @@ -1374,7 +1384,8 @@ def create_ext_grid_collection(net, ext_grids=None, size=1., infofunc=None, orie infos = [infofunc(ext_grid_idx) for ext_grid_idx in ext_grids] if infofunc is not None else [] # This code does not support bus bars. It would require the format here to be a bit different. - node_coords = net.bus.geo.loc[ext_grid_buses].apply(geojson.loads).apply(geojson.utils.coords).apply(next).values.tolist() + node_coords = net.bus.geo.loc[ext_grid_buses].apply(geojson.loads).apply(geojson.utils.coords).apply( + next).values.tolist() color = kwargs.pop("color", "k") @@ -1411,10 +1422,10 @@ def create_line_switch_collection(net, switches=None, size=1, distance_to_bus=3, **switches** - patch collection """ if not MATPLOTLIB_INSTALLED: - soft_dependency_error(str(sys._getframe().f_code.co_name)+"()", "matplotlib") + soft_dependency_error(str(sys._getframe().f_code.co_name) + "()", "matplotlib") if switches is None: - switches = net.switch.index[net.switch.et == "l"] # only line switches + switches = net.switch.index[net.switch.et == "l"] # only line switches color = kwargs.pop("color", "k") @@ -1513,7 +1524,7 @@ def create_bus_bus_switch_collection(net, size=1., helper_line_style=':', helper **switches**, **helper_lines** - tuple of patch collections """ if not MATPLOTLIB_INSTALLED: - soft_dependency_error(str(sys._getframe().f_code.co_name)+"()", "matplotlib") + soft_dependency_error(str(sys._getframe().f_code.co_name) + "()", "matplotlib") if switches is None: switches = net.switch.index.to_list() lbs_switches = net.switch.index[(net.switch.et == "b") & (net.switch.index.isin(switches))] @@ -1523,7 +1534,7 @@ def create_bus_bus_switch_collection(net, size=1., helper_line_style=':', helper for switch in lbs_switches: switch_bus = net.switch.bus.loc[switch] target_bus = net.switch.element.loc[switch] - if switch_bus not in net.bus.index or target_bus not in net.bus.index\ + if switch_bus not in net.bus.index or target_bus not in net.bus.index \ or pd.isnull(net.bus.loc[switch_bus, "geo"]) or pd.isnull(net.bus.loc[target_bus, "geo"]): logger.warning("Bus coordinates for switch %s not found, skipped switch!" % switch) continue @@ -1590,13 +1601,14 @@ def create_ward_collection(net, wards=None, ward_buses=None, size=5., bus_geodat assert len(wards) == len(ward_buses), \ "Length mismatch between chosen xwards and xward_buses." infos = [infofunc(i) for i in range(len(wards))] if infofunc is not None else [] - node_coords = net.bus.geo.loc[ward_buses].apply(geojson.loads).apply(geojson.utils.coords).apply(next).values.tolist() + node_coords = net.bus.geo.loc[ward_buses].apply(geojson.loads).apply(geojson.utils.coords).apply( + next).values.tolist() color = kwargs.pop("color", "k") ward_pc, ward_lc = _create_node_element_collection( node_coords, ward_patches, size=size, infos=infos, orientation=orientation, - picker=picker, line_color=color, **kwargs) # patch_facecolor=color, patch_edgecolor=color + picker=picker, line_color=color, **kwargs) # patch_facecolor=color, patch_edgecolor=color return ward_pc, ward_lc @@ -1638,7 +1650,8 @@ def create_xward_collection(net, xwards=None, xward_buses=None, size=5., bus_geo assert len(xwards) == len(xward_buses), \ "Length mismatch between chosen xwards and xward_buses." infos = [infofunc(i) for i in range(len(xwards))] if infofunc is not None else [] - node_coords = net.bus.geo.loc[xward_buses].apply(geojson.loads).apply(geojson.utils.coords).apply(next).values.tolist() + node_coords = net.bus.geo.loc[xward_buses].apply(geojson.loads).apply(geojson.utils.coords).apply( + next).values.tolist() color = kwargs.pop("color", "w") @@ -1673,7 +1686,7 @@ def draw_collections(collections, figsize=(10, 8), ax=None, plot_colorbars=True, **ax** - matplotlib axes """ if not MATPLOTLIB_INSTALLED: - soft_dependency_error(str(sys._getframe().f_code.co_name)+"()", "matplotlib") + soft_dependency_error(str(sys._getframe().f_code.co_name) + "()", "matplotlib") if ax is None: plt.figure(facecolor="white", figsize=figsize) plt.subplots_adjust(left=0.01, right=0.99, top=0.99, bottom=0.05, @@ -1730,21 +1743,22 @@ def add_collections_to_axes(ax, collections, plot_colorbars=True, copy_collectio if __name__ == "__main__": # if 0: - # import pandapower as pp + # from pandapower.create import create_empty_network, create_bus, create_gen, create_load, create_ext_grid, / + # create_transformer # # ntw = pp.create_empty_network() - # b1 = pp.create_bus(ntw, 10, geodata=(5, 10)) - # b2 = pp.create_bus(ntw, 0.4, geodata=(5, 15)) - # b3 = pp.create_bus(ntw, 0.4, geodata=(0, 22)) - # b4 = pp.create_bus(ntw, 0.4, geodata=(8, 20)) - # pp.create_gen(ntw, b1, p_mw=0.1) - # pp.create_load(ntw, b3, p_mw=0.1) - # pp.create_ext_grid(ntw, b4) + # b1 = create_bus(ntw, 10, geodata=(5, 10)) + # b2 = create_bus(ntw, 0.4, geodata=(5, 15)) + # b3 = create_bus(ntw, 0.4, geodata=(0, 22)) + # b4 = create_bus(ntw, 0.4, geodata=(8, 20)) + # create_gen(ntw, b1, p_mw=0.1) + # create_load(ntw, b3, p_mw=0.1) + # create_ext_grid(ntw, b4) # - # pp.create_line(ntw, b2, b3, 2.0, std_type="NAYY 4x50 SE") - # pp.create_line(ntw, b2, b4, 2.0, std_type="NAYY 4x50 SE") - # pp.create_transformer(ntw, b1, b2, std_type="0.63 MVA 10/0.4 kV") - # pp.create_transformer(ntw, b3, b4, std_type="0.63 MVA 10/0.4 kV") + # create_line(ntw, b2, b3, 2.0, std_type="NAYY 4x50 SE") + # create_line(ntw, b2, b4, 2.0, std_type="NAYY 4x50 SE") + # create_transformer(ntw, b1, b2, std_type="0.63 MVA 10/0.4 kV") + # create_transformer(ntw, b3, b4, std_type="0.63 MVA 10/0.4 kV") # # bus_col = create_bus_collection(ntw, size=0.2, color="k") # line_col = create_line_collection(ntw, use_line_geodata=False, color="k", linewidth=3.) diff --git a/pandapower/plotting/generic_geodata.py b/pandapower/plotting/generic_geodata.py index f452bcf94..6e391a1e7 100644 --- a/pandapower/plotting/generic_geodata.py +++ b/pandapower/plotting/generic_geodata.py @@ -12,7 +12,8 @@ import numpy as np from pandapower.auxiliary import soft_dependency_error -import pandapower.topology as top +from pandapower.topology.create_graph import create_nxgraph +from pandapower.topology.graph_searches import connected_components try: import igraph @@ -218,7 +219,7 @@ def create_generic_coordinates(net, mg=None, library="igraph", coords = coords_from_igraph(graph, roots, meshed) elif library == "networkx": if mg is None: - nxg = top.create_nxgraph(net, respect_switches=respect_switches, + nxg = create_nxgraph(net, respect_switches=respect_switches, include_out_of_service=True, trafo_length_km=trafo_length_km, switch_length_km=switch_length_km) else: @@ -246,9 +247,9 @@ def _prepare_geodata_table(net, geodata_table, overwrite): net[geodata_table] = pd.DataFrame(columns=["geo"]) def fuse_geodata(net): - mg = top.create_nxgraph(net, include_lines=False, include_impedances=False, respect_switches=False) + mg = create_nxgraph(net, include_lines=False, include_impedances=False, respect_switches=False) geocoords = set(net.bus.dropna(subset=['geo']).index) - for area in top.connected_components(mg): + for area in connected_components(mg): if len(area & geocoords) > 1: geo = net.bus.loc[list(area & geocoords), 'geo'].apply(geojson.loads) for bus in area: diff --git a/pandapower/plotting/geo.py b/pandapower/plotting/geo.py index 52926f3d1..b9fba15e3 100644 --- a/pandapower/plotting/geo.py +++ b/pandapower/plotting/geo.py @@ -17,7 +17,6 @@ import pandas as pd from numpy import array -import pandapower from pandapower.auxiliary import soft_dependency_error, pandapowerNet # get logger (same as in simple_plot) diff --git a/pandapower/plotting/plotly/mapbox_plot.py b/pandapower/plotting/plotly/mapbox_plot.py index cdec01449..a6ff1464b 100644 --- a/pandapower/plotting/plotly/mapbox_plot.py +++ b/pandapower/plotting/plotly/mapbox_plot.py @@ -8,7 +8,7 @@ from typing_extensions import deprecated -from pandapower.plotting import geo +from pandapower.plotting.geo import convert_crs try: import pandaplan.core.pplog as logging @@ -58,7 +58,7 @@ def geo_data_to_latlong(net, projection): - "epsg:2032" - NAD27(CGQ77) / UTM zone 18N - "epsg:2190" - Azores Oriental 1940 / UTM zone 26N """ - geo.convert_crs(net, epsg_in=projection.split(':')[1], epsg_out=4326) + convert_crs(net, epsg_in=projection.split(':')[1], epsg_out=4326) def set_mapbox_token(token): diff --git a/pandapower/plotting/powerflow_results.py b/pandapower/plotting/powerflow_results.py index d08b47d2b..ef3afd575 100644 --- a/pandapower/plotting/powerflow_results.py +++ b/pandapower/plotting/powerflow_results.py @@ -17,7 +17,8 @@ MATPLOTLIB_INSTALLED = False from pandapower.auxiliary import soft_dependency_error, warn_and_fix_parameter_renaming -import pandapower.topology as top +from pandapower.topology.create_graph import create_nxgraph +from pandapower.topology.graph_searches import calc_distance_to_bus def plot_voltage_profile(net, ax=None, plot_transformers=True, xlabel="Distance from Slack [km]", @@ -81,7 +82,7 @@ def plot_voltage_profile(net, ax=None, plot_transformers=True, xlabel="Distance net.ext_grid.loc[net.ext_grid.in_service, "bus"].values, net.gen.loc[net.gen.slack & net.gen.in_service, "bus"].values) for eg in sl_buses: - d = top.calc_distance_to_bus(net, eg) + d = calc_distance_to_bus(net, eg) for lix, line in net.line[net.line.in_service & net.line.index.isin(lines)].iterrows(): if line.from_bus not in d.index: continue @@ -200,7 +201,7 @@ def voltage_profile_to_bus_geodata(net, voltages=None, root_bus=None): raise ValueError("no results in this pandapower network") voltages = net.res_bus.vm_pu - mg = top.create_nxgraph(net, respect_switches=True) + mg = create_nxgraph(net, respect_switches=True) sl_buses = np.r_[ net.ext_grid.loc[net.ext_grid.in_service, "bus"].values, net.gen.loc[net.gen.slack & net.gen.in_service, "bus"].values] @@ -216,11 +217,11 @@ def voltage_profile_to_bus_geodata(net, voltages=None, root_bus=None): if __name__ == "__main__": - import pandapower as pp - import pandapower.networks as nw + from pandapower.run import runpp + from pandapower.networks.mv_oberrhein import mv_oberrhein - net = nw.mv_oberrhein() - pp.runpp(net) + net = mv_oberrhein() + runpp(net) fig, axs = plt.subplots(ncols=2, figsize=(8, 5), gridspec_kw={"width_ratios": [4, 1]}) plot_voltage_profile(net, ax=axs[0]) diff --git a/pandapower/plotting/simple_plot.py b/pandapower/plotting/simple_plot.py index 4aa4d1793..f0118c869 100644 --- a/pandapower/plotting/simple_plot.py +++ b/pandapower/plotting/simple_plot.py @@ -221,9 +221,11 @@ def simple_plot(net, respect_switches=False, line_width=1.0, bus_size=1.0, ext_g if __name__ == "__main__": - import pandapower.networks as nw + from pandapower.networks.power_system_test_cases import case145 + # from pandapower.networks.cigre_networks import create_cigre_network_mv + # from pandapower.networks.mv_oberrhein import mv_oberrhein - net = nw.case145() + net = case145() # net = nw.create_cigre_network_mv() # net = nw.mv_oberrhein() simple_plot(net, bus_size=0.4) diff --git a/pandapower/protection/basic_protection_device.py b/pandapower/protection/basic_protection_device.py index f333b783a..79c5480ef 100644 --- a/pandapower/protection/basic_protection_device.py +++ b/pandapower/protection/basic_protection_device.py @@ -65,7 +65,7 @@ def __setstate__(self, state): if __name__ == "__main__": - import pandapower as pp + from pandapower.create import create_empty_network - net = pp.create_empty_network() + net = create_empty_network() ProtectionDevice(net) diff --git a/pandapower/protection/example_grids.py b/pandapower/protection/example_grids.py index 07acfe8da..1c95ba718 100644 --- a/pandapower/protection/example_grids.py +++ b/pandapower/protection/example_grids.py @@ -4,131 +4,126 @@ """ import pandas as pd -import pandapower as pp -import numpy as np + +from pandapower.create import create_empty_network, create_buses, create_ext_grid, create_lines, create_switches, \ + create_loads + pd.Series(dtype='float64') + def three_radial_bus_net(): - - import pandapower as pp - net = pp.create_empty_network() # create an empty network - pp.create_buses(net, nr_buses=16, vn_kv=20, index=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15], name=None, type="n", - geodata=[(0,0), (0, -1), (0, -2), (-2, -3), (-2, -4), (-2, -5), (0, -6), - (0, -4.5), (0, -5), (0, -6), (0, -7), (0, -8), (2, -8), (2, -9), (2, -10), (2, -12)]) + net = create_empty_network() # create an empty network + create_buses(net, nr_buses=16, vn_kv=20, index=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], name=None, + type="n", + geodata=[(0, 0), (0, -1), (0, -2), (-2, -3), (-2, -4), (-2, -5), (0, -6), + (0, -4.5), (0, -5), (0, -6), (0, -7), (0, -8), (2, -8), (2, -9), (2, -10), (2, -12)]) + + # external grids + create_ext_grid(net, 0, vm_pu=1.0, va_degree=0, s_sc_max_mva=100, s_sc_min_mva=50, rx_max=0.1, rx_min=0.1) - # external grids - pp.create_ext_grid(net, 0, vm_pu=1.0, va_degree=0, s_sc_max_mva=100, s_sc_min_mva=50, rx_max=0.1, rx_min=0.1) - - pp.create_lines(net, from_buses=[0,1,2,3,4,5,2,7,8,9,10,9,12,13,14], to_buses=[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15], length_km=[5,4,4,0.5,0.5,1,2,4,4,5,6,5,3,2,1],std_type="NAYY 4x50 SE", - name=None, index=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14], df=1., parallel=1) + create_lines(net, from_buses=[0, 1, 2, 3, 4, 5, 2, 7, 8, 9, 10, 9, 12, 13, 14], + to_buses=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], + length_km=[5, 4, 4, 0.5, 0.5, 1, 2, 4, 4, 5, 6, 5, 3, 2, 1], std_type="NAYY 4x50 SE", + name=None, index=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], df=1., parallel=1) - net.line["endtemp_degree"] = 250 - - pp.create_switches(net, buses = [0,1,2,3,4,5,2,7,8,9,10,9,12,13,14], elements = - [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14], et = 'l', type ="CB_IDTOC") + net.line["endtemp_degree"] = 250 + create_switches(net, buses=[0, 1, 2, 3, 4, 5, 2, 7, 8, 9, 10, 9, 12, 13, 14], elements= + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], et='l', type="CB_IDTOC") - # Define load - pp.create_loads(net, buses=[5,11,15], p_mw=[5,5,4], q_mvar=[1,1,1], const_z_percent=0, const_i_percent=0, sn_mva=None, - name=None, scaling=1., index=[0,1,2]) + # Define load + create_loads(net, buses=[5, 11, 15], p_mw=[5, 5, 4], q_mvar=[1, 1, 1], const_z_percent=0, const_i_percent=0, + sn_mva=None, + name=None, scaling=1., index=[0, 1, 2]) + return net - return net - def dtoc_relay_net(open_loop=True): - net = pp.create_empty_network() # create an empty network - - #create buses - pp.create_buses(net, nr_buses=7, vn_kv=20, index=[0,1,2,3,4,5,6], name=None, type="n", - geodata=[(0,0), (0, -1), (-2, -2), (-2, -4), (2, -2), (2, -3), (2, -4)]) + net = create_empty_network() # create an empty network + + # create buses + create_buses(net, nr_buses=7, vn_kv=20, index=[0, 1, 2, 3, 4, 5, 6], name=None, type="n", + geodata=[(0, 0), (0, -1), (-2, -2), (-2, -4), (2, -2), (2, -3), (2, -4)]) # external grids - pp.create_ext_grid(net, 0, vm_pu=1.0, va_degree=0, s_sc_max_mva=100, s_sc_min_mva=50, rx_max=0.1, rx_min=0.1) - - pp.create_lines(net, from_buses=[0,1,2,1,4,5,3], to_buses=[1,2,3,4,5,6,6], length_km=[2,5,4,4,0.5,0.5,1],std_type="NAYY 4x50 SE", - name=None, index=[0,1,2,3,4,5,6], df=1., parallel=1) + create_ext_grid(net, 0, vm_pu=1.0, va_degree=0, s_sc_max_mva=100, s_sc_min_mva=50, rx_max=0.1, rx_min=0.1) + + create_lines(net, from_buses=[0, 1, 2, 1, 4, 5, 3], to_buses=[1, 2, 3, 4, 5, 6, 6], + length_km=[2, 5, 4, 4, 0.5, 0.5, 1], std_type="NAYY 4x50 SE", + name=None, index=[0, 1, 2, 3, 4, 5, 6], df=1., parallel=1) net.line["endtemp_degree"] = 250 - - pp.create_switches(net, buses = [0,1,2,3,4,5], elements = - [0,1,2,3,4,5], et = 'l', type ="CB_DTOC") + + create_switches(net, buses=[0, 1, 2, 3, 4, 5], elements=[0, 1, 2, 3, 4, 5], et='l', type="CB_DTOC") + # Define switches - if open_loop: - - pp.create_switches(net, buses = [3,6], elements = - [6,6], et = 'l', type ="CB_DTOC",closed=False) + create_switches(net, buses=[3, 6], elements=[6, 6], et='l', type="CB_DTOC", closed=False) else: - pp.create_switches(net, buses = [3,6], elements = - [6,6], et = 'l', type ="CB_DTOC",closed=True) - - - #define load - pp.create_loads(net, buses=[3,6], p_mw=[5,2], q_mvar=[1,1], const_z_percent=0, const_i_percent=0, sn_mva=None, - name=None, scaling=1., index=[0,1]) + create_switches(net, buses=[3, 6], elements=[6, 6], et='l', type="CB_DTOC", closed=True) + #define load + create_loads(net, buses=[3, 6], p_mw=[5, 2], q_mvar=[1, 1], const_z_percent=0, const_i_percent=0, sn_mva=None, + name=None, scaling=1., index=[0, 1]) return net + def idmt_relay_net(open_loop=True): - net = pp.create_empty_network() # create an empty network - + net = create_empty_network() # create an empty network + #create buses - pp.create_buses(net, nr_buses=7, vn_kv=20, index=[0,1,2,3,4,5,6], name=None, type="n", - geodata=[(0,0), (0, -1), (-2, -2), (-2, -4), (2, -2), (2, -3), (2, -4)]) + create_buses(net, nr_buses=7, vn_kv=20, index=[0, 1, 2, 3, 4, 5, 6], name=None, type="n", + geodata=[(0, 0), (0, -1), (-2, -2), (-2, -4), (2, -2), (2, -3), (2, -4)]) # external grids - pp.create_ext_grid(net, 0, vm_pu=1.0, va_degree=0, s_sc_max_mva=100, s_sc_min_mva=50, rx_max=0.1, rx_min=0.1) - - pp.create_lines(net, from_buses=[0,1,2,1,4,5,3], to_buses=[1,2,3,4,5,6,6], length_km=[2,5,4,4,0.5,0.5,1],std_type="NAYY 4x50 SE", - name=None, index=[0,1,2,3,4,5,6], df=1., parallel=1) + create_ext_grid(net, 0, vm_pu=1.0, va_degree=0, s_sc_max_mva=100, s_sc_min_mva=50, rx_max=0.1, rx_min=0.1) + + create_lines(net, from_buses=[0, 1, 2, 1, 4, 5, 3], to_buses=[1, 2, 3, 4, 5, 6, 6], + length_km=[2, 5, 4, 4, 0.5, 0.5, 1], std_type="NAYY 4x50 SE", + name=None, index=[0, 1, 2, 3, 4, 5, 6], df=1., parallel=1) net.line["endtemp_degree"] = 250 - - pp.create_switches(net, buses = [0,1,2,3,4,5], elements = - [0,1,2,3,4,5], et = 'l', type ="CB_IDMT") + + create_switches(net, buses=[0, 1, 2, 3, 4, 5], elements=[0, 1, 2, 3, 4, 5], et='l', type="CB_IDMT") + # Define switches if open_loop: - - pp.create_switches(net, buses = [3,6], elements = - [6,6], et = 'l', type ="CB_IDMT",closed=False) + create_switches(net, buses=[3, 6], elements=[6, 6], et='l', type="CB_IDMT", closed=False) else: - pp.create_switches(net, buses = [3,6], elements = - [6,6], et = 'l', type ="CB_IDMT",closed=True) - - #define load - - pp.create_loads(net, buses=[3,6], p_mw=[5,2], q_mvar=[1,1], const_z_percent=0, const_i_percent=0, sn_mva=None, - name=None, scaling=1., index=[0,1]) + create_switches(net, buses=[3, 6], elements=[6, 6], et='l', type="CB_IDMT", closed=True) + + # define load + create_loads(net, buses=[3, 6], p_mw=[5, 2], q_mvar=[1, 1], const_z_percent=0, const_i_percent=0, sn_mva=None, + name=None, scaling=1., index=[0, 1]) return net + def idtoc_relay_net(open_loop=True): - net = pp.create_empty_network() # create an empty network - - #create buses - pp.create_buses(net, nr_buses=7, vn_kv=20, index=[0,1,2,3,4,5,6], name=None, type="n", - geodata=[(0,0), (0, -1), (-2, -2), (-2, -4), (2, -2), (2, -3), (2, -4)]) + net = create_empty_network() # create an empty network + + # create buses + create_buses(net, nr_buses=7, vn_kv=20, index=[0, 1, 2, 3, 4, 5, 6], name=None, type="n", + geodata=[(0, 0), (0, -1), (-2, -2), (-2, -4), (2, -2), (2, -3), (2, -4)]) # external grids - pp.create_ext_grid(net, 0, vm_pu=1.0, va_degree=0, s_sc_max_mva=100, s_sc_min_mva=50, rx_max=0.1, rx_min=0.1) - - pp.create_lines(net, from_buses=[0,1,2,1,4,5,3], to_buses=[1,2,3,4,5,6,6], length_km=[2,5,4,4,0.5,0.5,1],std_type="NAYY 4x50 SE", - name=None, index=[0,1,2,3,4,5,6], df=1., parallel=1) + create_ext_grid(net, 0, vm_pu=1.0, va_degree=0, s_sc_max_mva=100, s_sc_min_mva=50, rx_max=0.1, rx_min=0.1) + + create_lines(net, from_buses=[0, 1, 2, 1, 4, 5, 3], to_buses=[1, 2, 3, 4, 5, 6, 6], + length_km=[2, 5, 4, 4, 0.5, 0.5, 1], std_type="NAYY 4x50 SE", + name=None, index=[0, 1, 2, 3, 4, 5, 6], df=1., parallel=1) net.line["endtemp_degree"] = 250 - - pp.create_switches(net, buses = [0,1,2,3,4,5], elements = - [0,1,2,3,4,5], et = 'l', type ="CB_IDTOC") + + create_switches(net, buses=[0, 1, 2, 3, 4, 5], elements=[0, 1, 2, 3, 4, 5], et='l', type="CB_IDTOC") + # Define switches - if open_loop: - - pp.create_switches(net, buses = [3,6], elements = - [6,6], et = 'l', type ="CB_IDTOC",closed=False) + create_switches(net, buses=[3, 6], elements=[6, 6], et='l', type="CB_IDTOC", closed=False) else: - pp.create_switches(net, buses = [3,6], elements = - [6,6], et = 'l', type ="CB_IDTOC",closed=True) - #define load - pp.create_loads(net, buses=[3,6], p_mw=[5,2], q_mvar=[1,1], const_z_percent=0, const_i_percent=0, sn_mva=None, - name=None, scaling=1., index=[0,1]) - return net \ No newline at end of file + create_switches(net, buses=[3, 6], elements=[6, 6], et='l', type="CB_IDTOC", closed=True) + + # define load + create_loads(net, buses=[3, 6], p_mw=[5, 2], q_mvar=[1, 1], const_z_percent=0, const_i_percent=0, sn_mva=None, + name=None, scaling=1., index=[0, 1]) + return net diff --git a/pandapower/protection/protection_devices/ocrelay.py b/pandapower/protection/protection_devices/ocrelay.py index 31bdbef7e..e1b357545 100644 --- a/pandapower/protection/protection_devices/ocrelay.py +++ b/pandapower/protection/protection_devices/ocrelay.py @@ -1,11 +1,10 @@ import copy import numpy as np import pandas as pd + from pandapower.protection.basic_protection_device import ProtectionDevice -import pandapower.shortcircuit as sc -#from pandapower.protection.oc_relay_model import time_grading from pandapower.protection.utility_functions import create_sc_bus,bus_path_multiple_ext_bus,get_line_path,parallel_lines - +from pandapower.shortcircuit.calc_sc import calc_sc try: import matplotlib.pyplot as plt @@ -130,7 +129,7 @@ def create_protection_function(self, net): else: raise ValueError("OC Relay must be connected to line or transformer element") - sc.calc_sc(net_sc, bus=bus_idx, branch_results=True) + calc_sc(net_sc, bus=bus_idx, branch_results=True) if self.oc_relay_type == 'DTOC': if self.pickup_current_manual is None: diff --git a/pandapower/protection/run_protection.py b/pandapower/protection/run_protection.py index 8d15d618b..08e926e83 100644 --- a/pandapower/protection/run_protection.py +++ b/pandapower/protection/run_protection.py @@ -1,7 +1,5 @@ -import pandapower.shortcircuit as sc import pandas as pd - def calculate_protection_times(net, scenario="sc"): """ Calculate protection times for short-circuit and power-flow scenarios diff --git a/pandapower/protection/utility_functions.py b/pandapower/protection/utility_functions.py index b1f3ad034..ab87b524c 100644 --- a/pandapower/protection/utility_functions.py +++ b/pandapower/protection/utility_functions.py @@ -15,10 +15,16 @@ import networkx as nx import logging as log -import pandapower as pp -import pandapower.plotting as plot -from pandapower import pandapowerNet +from pandapower.auxiliary import pandapowerNet from pandapower.topology.create_graph import create_nxgraph +from pandapower.create import create_bus, create_line_from_parameters +from pandapower.plotting.collections import create_annotation_collection, create_line_collection, \ + create_bus_collection, create_line_switch_collection, draw_collections, create_trafo_collection, \ + create_trafo_connection_collection, create_load_collection, create_bus_bus_switch_collection +from pandapower.toolbox.grid_modification import fuse_buses +from pandapower.toolbox.element_selection import get_connected_buses_at_element, get_connected_elements, next_bus +from pandapower.run import runpp +from pandapower.shortcircuit.calc_sc import calc_sc import warnings @@ -42,7 +48,7 @@ warnings.filterwarnings('ignore') -def _get_coords_from_bus_idx(net: pp.pandapowerNet, bus_idx: pd.Index) -> List[Tuple[float, float]]: +def _get_coords_from_bus_idx(net: pandapowerNet, bus_idx: pd.Index) -> List[Tuple[float, float]]: try: bl = net.bus.dropna(subset=["geo"]).loc[bus_idx, 'geo'] if isinstance(bl, pd.Series): @@ -54,7 +60,7 @@ def _get_coords_from_bus_idx(net: pp.pandapowerNet, bus_idx: pd.Index) -> List[T return [] -def _get_coords_from_line_idx(net: pp.pandapowerNet, line_idx: pd.Index) -> List[Tuple[float, float]]: +def _get_coords_from_line_idx(net: pandapowerNet, line_idx: pd.Index) -> List[Tuple[float, float]]: try: ll = net.line.dropna(subset=["geo"]).loc[line_idx, 'geo'] if isinstance(ll, pd.Series): @@ -82,7 +88,7 @@ def create_sc_bus(net_copy, sc_line_id, sc_fraction): bus_vn_kv = net.bus.vn_kv.at[aux_line.from_bus] # set new virtual short circuit bus with give line and location - bus_sc = pp.create_bus(net, name="Bus_SC", vn_kv=bus_vn_kv, type="b", index=max_idx_bus + 1) + bus_sc = create_bus(net, name="Bus_SC", vn_kv=bus_vn_kv, type="b", index=max_idx_bus + 1) # sim bench grids if 's_sc_max_mva' not in net.ext_grid: @@ -100,7 +106,7 @@ def create_sc_bus(net_copy, sc_line_id, sc_fraction): net.line.at[sc_line1, 'to_bus'] = bus_sc net.line.at[sc_line1, 'length_km'] *= sc_fraction - sc_line2 = pp.create_line_from_parameters(net, bus_sc, aux_line.to_bus, + sc_line2 = create_line_from_parameters(net, bus_sc, aux_line.to_bus, length_km=aux_line.length_km * (1 - sc_fraction), index=max_idx_line + 1, r_ohm_per_km=aux_line.r_ohm_per_km, x_ohm_per_km=aux_line.x_ohm_per_km, c_nf_per_km=aux_line.c_nf_per_km, @@ -131,7 +137,6 @@ def create_sc_bus(net_copy, sc_line_id, sc_fraction): def calc_faults_at_full_line(net, line, location_step_size=0.01, start_location=0.01, end_location=1, sc_case="min"): # functon to create sc at full line - import pandapower.shortcircuit as sc i = 0 fault_currents = [] @@ -139,7 +144,7 @@ def calc_faults_at_full_line(net, line, location_step_size=0.01, start_location= location = start_location while location < end_location: net_sc = create_sc_bus(net, line, location) - sc.calc_sc(net_sc, case=sc_case) + calc_sc(net_sc, case=sc_case) fault_currents.append(net_sc.res_bus_sc.ikss_ka.at[max_bus_idx + 1]) @@ -224,7 +229,7 @@ def fuse_bus_switches(net, bus_switches): bus1 = net.switch.bus.at[bus_switch] bus2 = net.switch.element.at[bus_switch] - pp.fuse_buses(net, bus1, bus2) + fuse_buses(net, bus1, bus2) return net @@ -237,7 +242,7 @@ def get_fault_annotation(net: pandapowerNet, fault_current: float = .0, font_siz fault_geo_x_y = (fault_geo_x_y[0], fault_geo_x_y[1] - font_size_bus + 0.02) # list of new geo data for line (half position of switch) - fault_annotate: PatchCollection = plot.create_annotation_collection( + fault_annotate: PatchCollection = create_annotation_collection( texts=[fault_text], coords=[fault_geo_x_y], size=font_size_bus, @@ -255,7 +260,7 @@ def get_sc_location_annotation(net: pandapowerNet, sc_location: float, font_size sc_geo_x_y = next(geojson.utils.coords(geojson.loads(net.bus.geo.at[max_bus_idx]))) sc_geo_x_y = (sc_geo_x_y[0], sc_geo_x_y[1] + 0.02) - sc_annotate: PatchCollection = plot.create_annotation_collection( + sc_annotate: PatchCollection = create_annotation_collection( texts=[sc_text], coords=[sc_geo_x_y], size=font_size_bus, @@ -275,14 +280,14 @@ def plot_tripped_grid(net, trip_decisions, sc_location, bus_size=0.055, plot_ann ext_grid_busses = net.ext_grid.bus.values fault_location = [max(net.bus.index)] - lc = plot.create_line_collection(net, lines=net.line.index, zorder=0) + lc = create_line_collection(net, lines=net.line.index, zorder=0) - bc_extgrid = plot.create_bus_collection(net, buses=ext_grid_busses, zorder=1, size=bus_size, patch_type="rect") + bc_extgrid = create_bus_collection(net, buses=ext_grid_busses, zorder=1, size=bus_size, patch_type="rect") - bc = plot.create_bus_collection(net, buses=set(net.bus.index) - set(ext_grid_busses) - set(fault_location), + bc = create_bus_collection(net, buses=set(net.bus.index) - set(ext_grid_busses) - set(fault_location), zorder=2, color="black", size=bus_size) - bc_fault_location = plot.create_bus_collection(net, buses=set(fault_location), zorder=3, color="red", size=bus_size, + bc_fault_location = create_bus_collection(net, buses=set(fault_location), zorder=3, color="red", size=bus_size, patch_type="circle") collection = [lc, bc_extgrid, bc, bc_fault_location] @@ -320,20 +325,20 @@ def plot_tripped_grid(net, trip_decisions, sc_location, bus_size=0.055, plot_ann # Inst relay trip, red colour if len(inst_trip_switches) > 0: - sc_inst = plot.create_line_switch_collection(net, size=bus_size, distance_to_bus=dist_to_bus, color="red", + sc_inst = create_line_switch_collection(net, size=bus_size, distance_to_bus=dist_to_bus, color="red", switches=inst_trip_switches) collection.append(sc_inst) # backup relay based on time grade (yellow colour) if len(backup_trip_switches) > 0: - sc_backup = plot.create_line_switch_collection(net, size=bus_size, distance_to_bus=dist_to_bus, color="yellow", + sc_backup = create_line_switch_collection(net, size=bus_size, distance_to_bus=dist_to_bus, color="yellow", switches=backup_trip_switches) collection.append(sc_backup) # orange colour for inst_backup relay if len(inst_backup_switches) > 0: - instant_sc_backup = plot.create_line_switch_collection(net, size=bus_size, distance_to_bus=dist_to_bus, + instant_sc_backup = create_line_switch_collection(net, size=bus_size, distance_to_bus=dist_to_bus, color="orange", switches=inst_backup_switches) collection.append(instant_sc_backup) @@ -342,7 +347,7 @@ def plot_tripped_grid(net, trip_decisions, sc_location, bus_size=0.055, plot_ann if len_sc != 0: # closed switch-black - sc = plot.create_line_switch_collection(net, size=bus_size, distance_to_bus=dist_to_bus, color="black", + sc = create_line_switch_collection(net, size=bus_size, distance_to_bus=dist_to_bus, color="black", switches=set(net.switch.index) - set(inst_trip_switches) - set( backup_trip_switches)) collection.append(sc) @@ -365,7 +370,7 @@ def plot_tripped_grid(net, trip_decisions, sc_location, bus_size=0.055, plot_ann text_line = r" line_" + str(line) # + ",sw_"+str(Switch_index) # get bus_index from the line (from switch) - get_bus_index = pp.get_connected_buses_at_element(net, element_index=line, element_type='l', + get_bus_index = get_connected_buses_at_element(net, element_index=line, element_type='l', respect_in_service=False) bus_list = list(get_bus_index) @@ -374,7 +379,7 @@ def plot_tripped_grid(net, trip_decisions, sc_location, bus_size=0.055, plot_ann ] # TODO: - # place annotations on middle of the line + # place annotations on middle of the line line_geo_x = (bus_coords[0][0] + bus_coords[1][0]) / 2 line_geo_y = ((bus_coords[0][1] + bus_coords[1][1]) / 2) + 0.05 @@ -389,7 +394,7 @@ def plot_tripped_grid(net, trip_decisions, sc_location, bus_size=0.055, plot_ann line_text.append(text_line) # line annotations to collections for plotting - line_annotate = plot.create_annotation_collection(texts=line_text, coords=line_geodata, size=0.06, prop=None) + line_annotate = create_annotation_collection(texts=line_text, coords=line_geodata, size=0.06, prop=None) collection.append(line_annotate) # Bus Annotatations @@ -407,7 +412,7 @@ def plot_tripped_grid(net, trip_decisions, sc_location, bus_size=0.055, plot_ann bus_index = [(x[0] - 0.11, x[1] + 0.095) for x in bus_geodata] # TODO: - bus_annotate = plot.create_annotation_collection(texts=bus_text, coords=bus_index, size=0.06, prop=None) + bus_annotate = create_annotation_collection(texts=bus_text, coords=bus_index, size=0.06, prop=None) collection.append(bus_annotate) # Short circuit annotations @@ -431,10 +436,10 @@ def plot_tripped_grid(net, trip_decisions, sc_location, bus_size=0.055, plot_ann switch_geodata[i]['x'] = switch_geodata[i]['x'] - 0.085 # scale the value if annotations overlap switch_geodata[i]['y'] = switch_geodata[i]['y'] + 0.055 # scale the value if annotations overlap i = i + 1 - switch_annotate = plot.create_annotation_collection(texts=switch_text, coords=switch_geodata, size=0.06, + switch_annotate = create_annotation_collection(texts=switch_text, coords=switch_geodata, size=0.06, prop=None) collection.append(switch_annotate) - plot.draw_collections(collection) + draw_collections(collection) def plot_tripped_grid_protection_device(net, trip_decisions, sc_location, sc_bus, bus_size=0.055, @@ -448,14 +453,14 @@ def plot_tripped_grid_protection_device(net, trip_decisions, sc_location, sc_bus ext_grid_busses = net.ext_grid.bus.values fault_location = [max(net.bus.index)] - lc = plot.create_line_collection(net, lines=net.line.index, zorder=0) + lc = create_line_collection(net, lines=net.line.index, zorder=0) - bc_extgrid = plot.create_bus_collection(net, buses=ext_grid_busses, zorder=1, size=bus_size, patch_type="rect") + bc_extgrid = create_bus_collection(net, buses=ext_grid_busses, zorder=1, size=bus_size, patch_type="rect") - bc = plot.create_bus_collection(net, buses=set(net.bus.index) - set(ext_grid_busses) - set(fault_location), + bc = create_bus_collection(net, buses=set(net.bus.index) - set(ext_grid_busses) - set(fault_location), zorder=2, color="black", size=bus_size) - bc_fault_location = plot.create_bus_collection(net, buses=set(fault_location), zorder=3, color="red", size=bus_size, + bc_fault_location = create_bus_collection(net, buses=set(fault_location), zorder=3, color="red", size=bus_size, patch_type="circle") collection = [lc, bc_extgrid, bc, bc_fault_location] @@ -479,13 +484,13 @@ def plot_tripped_grid_protection_device(net, trip_decisions, sc_location, sc_bus # add trafo to collection if len(net.trafo) > 0: - trafo_collection = plot.create_trafo_collection(net, size=2 * bus_size) - trafo_conn_collection = plot.create_trafo_connection_collection(net) + trafo_collection = create_trafo_collection(net, size=2 * bus_size) + trafo_conn_collection = create_trafo_connection_collection(net) collection.append(trafo_collection) collection.append(trafo_conn_collection) # add load to collection if len(net.load) > 0: - load_collection = plot.create_load_collection(net, size=2 * bus_size) + load_collection = create_load_collection(net, size=2 * bus_size) collection.append(load_collection) for trip_idx in range(len(trip_decisions)): @@ -507,35 +512,35 @@ def plot_tripped_grid_protection_device(net, trip_decisions, sc_location, sc_bus # Inst relay trip, red colour if len(inst_trip_switches) > 0: - sc_inst = plot.create_line_switch_collection(net, size=bus_size, distance_to_bus=dist_to_bus, color="red", + sc_inst = create_line_switch_collection(net, size=bus_size, distance_to_bus=dist_to_bus, color="red", switches=set(inst_trip_switches) - set(bus_bus_switches)) - bb_inst = plot.create_bus_bus_switch_collection(net, size=bus_size, helper_line_color="red") + bb_inst = create_bus_bus_switch_collection(net, size=bus_size, helper_line_color="red") collection.append(sc_inst) collection.append(bb_inst) # backup relay based on time grade (yellow colour) if len(backup_trip_switches) > 0: - sc_backup = plot.create_line_switch_collection(net, size=bus_size, distance_to_bus=dist_to_bus, color="yellow", + sc_backup = create_line_switch_collection(net, size=bus_size, distance_to_bus=dist_to_bus, color="yellow", switches=backup_trip_switches) - bb_backup = plot.create_bus_bus_switch_collection(net, size=bus_size, helper_line_color="yellow") + bb_backup = create_bus_bus_switch_collection(net, size=bus_size, helper_line_color="yellow") collection.append(sc_backup) collection.append(bb_backup) # orange colour for inst_backup relay if len(inst_backup_switches) > 0: - instant_sc_backup = plot.create_line_switch_collection(net, size=bus_size, distance_to_bus=dist_to_bus, + instant_sc_backup = create_line_switch_collection(net, size=bus_size, distance_to_bus=dist_to_bus, color="orange", switches=inst_backup_switches) - instant_bb_backup = plot.create_bus_bus_switch_collection(net, size=bus_size, helper_line_color="orange") + instant_bb_backup = create_bus_bus_switch_collection(net, size=bus_size, helper_line_color="orange") collection.append(instant_sc_backup) len_sc = len(set(net.switch.index) - set(inst_trip_switches) - set(backup_trip_switches)) if len_sc != 0: # closed switch-black - sc = plot.create_line_switch_collection(net, size=bus_size, distance_to_bus=dist_to_bus, color="black", + sc = create_line_switch_collection(net, size=bus_size, distance_to_bus=dist_to_bus, color="black", switches=set(net.switch.index) - set(inst_trip_switches) - set( backup_trip_switches) - set(bus_bus_switches)) - bb = plot.create_bus_bus_switch_collection(net, size=bus_size, helper_line_color="black") + bb = create_bus_bus_switch_collection(net, size=bus_size, helper_line_color="black") collection.append(sc) collection.append(bb) @@ -558,7 +563,7 @@ def plot_tripped_grid_protection_device(net, trip_decisions, sc_location, sc_bus text_line = r" line_" + str(line) # + ",sw_"+str(Switch_index) # get bus_index from the line (from switch) - get_bus_index = pp.get_connected_buses_at_element(net, element_index=line, element_type='l', + get_bus_index = get_connected_buses_at_element(net, element_index=line, element_type='l', respect_in_service=False) bus_list = list(get_bus_index) @@ -578,7 +583,7 @@ def plot_tripped_grid_protection_device(net, trip_decisions, sc_location, sc_bus line_text.append(text_line) # line annotations to collections for plotting - line_annotate = plot.create_annotation_collection(texts=line_text, coords=line_geodata, size=0.06, prop=None) + line_annotate = create_annotation_collection(texts=line_text, coords=line_geodata, size=0.06, prop=None) collection.append(line_annotate) # Bus Annotations @@ -594,7 +599,7 @@ def plot_tripped_grid_protection_device(net, trip_decisions, sc_location, sc_bus # placing bus bus_geodata = [(x[0] - 0.11, x[1] + 0.095) for x in bus_geodata] - bus_annotate = plot.create_annotation_collection(texts=bus_text, coords=bus_geodata, size=0.06, prop=None) + bus_annotate = create_annotation_collection(texts=bus_text, coords=bus_geodata, size=0.06, prop=None) collection.append(bus_annotate) max_bus_idx = max(net.bus.dropna(subset=['geo']).index) @@ -615,14 +620,14 @@ def plot_tripped_grid_protection_device(net, trip_decisions, sc_location, sc_bus switch_geodata = switch_geodatas(net, size=bus_size, distance_to_bus=3.25 * bus_size) for i, (x, y) in enumerate(switch_geodata): switch_geodata[i] = (x - 0.085, y + 0.055) - switch_annotate = plot.create_annotation_collection( + switch_annotate = create_annotation_collection( texts=switch_text, coords=switch_geodata, size=0.06, prop=None ) collection.append(switch_annotate) - plot.draw_collections(collection) + draw_collections(collection) def calc_line_intersection(m1, b1, m2, b2): @@ -634,22 +639,22 @@ def calc_line_intersection(m1, b1, m2, b2): # get connected lines using bus id @deprecated("Use pandapower.get_connected_elements(net, 'line', bus_idx) instead!") def get_connected_lines(net, bus_idx): - return pp.get_connected_elements(net, "line", bus_idx) + return get_connected_elements(net, "line", bus_idx) # Returns the index of the second bus an element is connected to, given a # first one. E.g. the from_bus given the to_bus of a line. @deprecated("Use pandapower.next_bus(net, bus, element_id instead!") def next_buses(net, bus, element_id): - return pp.next_bus(net, bus, element_id) + return next_bus(net, bus, element_id) # get the connected bus listr from start to end bus def source_to_end_path(net, start_bus, bus_list, bus_order): - connected_lines = pp.get_connected_elements(net, 'line', start_bus) + connected_lines = get_connected_elements(net, 'line', start_bus) flag = 0 for line in connected_lines: - next_connected_bus = pp.next_bus(net, bus=start_bus, element_id=line) + next_connected_bus = next_bus(net, bus=start_bus, element_id=line) bus_order_1 = bus_order.copy() if next_connected_bus in bus_order: continue @@ -668,7 +673,7 @@ def source_to_end_path(net, start_bus, bus_list, bus_order): # get connected switches with bus @deprecated("Use pandapower.get_connected_switches(net, buses, consider='l', status='closed') instead!") def get_connected_switches(net, buses): - return pp.get_connected_switches(net, buses, consider='l', status="closed") + return get_connected_switches(net, buses, consider='l', status="closed") # get connected buses with a oven element @@ -676,7 +681,7 @@ def get_connected_switches(net, buses): "Use pandapower.get_connected_buses_at_element(net, element, element_type='l', respect_in_service=False) instead!" ) def connected_bus_in_line(net, element): - return pp.get_connected_buses_at_element(net, element, element_type='l', respect_in_service=False) + return get_connected_buses_at_element(net, element, element_type='l', respect_in_service=False) @deprecated("Use networkx topological search instead! See pandapower docs.") @@ -787,13 +792,13 @@ def power_flow_end_points(net): """function calculate end point from meshed grid and the start point from the radial grid to ext grid""" pf_net = copy.deepcopy(net) - pp.runpp(pf_net) + runpp(pf_net) pf_loop_end_buses = [] pf_radial_end_buses = [] for bus in pf_net.bus.index: - lines = pp.get_connected_elements(pf_net, element_type='l', buses=bus) + lines = get_connected_elements(pf_net, element_type='l', buses=bus) if len(lines) == 1: pf_radial_end_buses.append(bus) @@ -847,7 +852,7 @@ def get_switches_in_path(net, paths): lines_at_path: set = set() for bus in path: - lines_at_path.update(pp.get_connected_elements(net, "l", bus)) + lines_at_path.update(get_connected_elements(net, "l", bus)) lines_at_paths = [ line for line in lines_at_path @@ -872,7 +877,7 @@ def get_vi_angle(net: pandapowerNet, switch_id: int, **kwargs) -> float: "The powerflow_results argument is deprecated and will be removed in the future." ) - pp.runpp(net) + runpp(net) line_idx = net.switch.element.at[switch_id] if get_from_bus_info_switch(net, switch_id): diff --git a/pandapower/shortcircuit/calc_sc.py b/pandapower/shortcircuit/calc_sc.py index 06dc18d87..f1d76567f 100644 --- a/pandapower/shortcircuit/calc_sc.py +++ b/pandapower/shortcircuit/calc_sc.py @@ -3,31 +3,29 @@ # Copyright (c) 2016-2023 by University of Kassel and Fraunhofer Institute for Energy Economics # and Energy System Technology (IEE), Kassel. All rights reserved. - -try: - import pandaplan.core.pplog as logging -except ImportError: - import logging - -logger = logging.getLogger(__name__) +from numbers import Number import numpy as np from scipy.sparse.linalg import factorized -from numbers import Number from pandapower.auxiliary import _clean_up, _add_ppc_options, _add_sc_options, _add_auxiliary_elements -from pandapower.pd2ppc import _pd2ppc from pandapower.pd2ppc_zero import _pd2ppc_zero +from pandapower.pypower.idx_brch_sc import K_ST from pandapower.results import _copy_results_ppci_to_ppc - +from pandapower.results import init_results from pandapower.shortcircuit.currents import _calc_ikss, \ _calc_ikss_1ph, _calc_ip, _calc_ith, _calc_branch_currents, _calc_branch_currents_complex from pandapower.shortcircuit.impedance import _calc_zbus, _calc_ybus, _calc_rx -from pandapower.shortcircuit.ppc_conversion import _init_ppc, _create_k_updated_ppci, _get_is_ppci_bus from pandapower.shortcircuit.kappa import _add_kappa_to_ppc +from pandapower.shortcircuit.ppc_conversion import _init_ppc, _create_k_updated_ppci, _get_is_ppci_bus from pandapower.shortcircuit.results import _extract_results, _copy_result_to_ppci_orig -from pandapower.results import init_results -from pandapower.pypower.idx_brch_sc import K_ST + +try: + import pandaplan.core.pplog as logging +except ImportError: + import logging + +logger = logging.getLogger(__name__) def calc_sc(net, bus=None, @@ -35,7 +33,6 @@ def calc_sc(net, bus=None, ith=False, tk_s=1., kappa_method="C", r_fault_ohm=0., x_fault_ohm=0., branch_results=False, check_connectivity=True, return_all_currents=False, inverse_y=True, use_pre_fault_voltage=False): - """ Calculates minimal or maximal symmetrical short-circuit currents. The calculation is based on the method of the equivalent voltage source @@ -51,7 +48,8 @@ def calc_sc(net, bus=None, INPUT: **net** (pandapowerNet) pandapower Network - **bus** (int, list, np.array, None) defines if short-circuit calculations should only be calculated for defined bus + **bus** (int, list, np.array, None) defines if short-circuit calculations should only be calculated for + defined bus ***fault** (str, 3ph) type of fault @@ -96,9 +94,11 @@ def calc_sc(net, bus=None, **return_all_currents** (bool, False) applies only if branch_results=True, if True short-circuit currents for each (branch, bus) tuple is returned otherwise only the max/min is returned - **inverse_y** (bool, True) defines if complete inverse should be used instead of LU factorization, factorization version is in experiment which should be faster and memory efficienter + **inverse_y** (bool, True) defines if complete inverse should be used instead of LU factorization, + factorization version is in experiment which should be faster and memory efficienter - **use_pre_fault_voltage** (bool, False) whether to consider the pre-fault grid state (superposition method, "Type C") + **use_pre_fault_voltage** (bool, False) whether to consider the pre-fault grid state (superposition method, + "Type C") OUTPUT: @@ -130,7 +130,7 @@ def calc_sc(net, bus=None, if use_pre_fault_voltage: init_vm_pu = init_va_degree = "results" - trafo_model = net._options["trafo_model"] # trafo model for SC must match the trafo model for PF calculation + trafo_model = net._options["trafo_model"] # trafo model for SC must match the trafo model for PF calculation if not isinstance(bus, Number) and len(net.sgen.query("in_service")) > 0: raise NotImplementedError("Short-circuit with Type C method and sgen is only implemented for a single bus") else: @@ -168,13 +168,13 @@ def _calc_current(net, ppci_orig, bus): ppci_bus = _get_is_ppci_bus(net, bus) # update ppci - non_ps_gen_ppci_bus, non_ps_gen_ppci, ps_gen_bus_ppci_dict =\ + non_ps_gen_ppci_bus, non_ps_gen_ppci, ps_gen_bus_ppci_dict = \ _create_k_updated_ppci(net, ppci_orig, ppci_bus=ppci_bus) # For each ps_gen_bus one unique ppci is required ps_gen_ppci_bus = list(ps_gen_bus_ppci_dict.keys()) - for calc_bus in ps_gen_ppci_bus+[non_ps_gen_ppci_bus]: + for calc_bus in ps_gen_ppci_bus + [non_ps_gen_ppci_bus]: if isinstance(calc_bus, np.ndarray): # Use ppci for general bus this_ppci, this_ppci_bus = non_ps_gen_ppci, calc_bus diff --git a/pandapower/shortcircuit/toolbox.py b/pandapower/shortcircuit/toolbox.py index 47529d50d..7966d38d9 100644 --- a/pandapower/shortcircuit/toolbox.py +++ b/pandapower/shortcircuit/toolbox.py @@ -15,11 +15,11 @@ import pandas as pd import networkx as nx from copy import deepcopy -from scipy.sparse import csr_matrix as sparse -import pandapower as pp -import pandapower.topology as top -import pandapower.shortcircuit as sc +from pandapower.create import create_bus +from pandapower.run import rundcpp +from pandapower.topology.graph_searches import connected_component +from pandapower.shortcircuit.calc_sc import calc_sc from pandapower.create import _get_index_with_check from pandapower.topology import create_nxgraph from pandapower.pypower.idx_bus import BUS_I @@ -101,7 +101,7 @@ def _create_aux_net(net, line_ix, distance_to_bus0): aux_net = deepcopy(net) # Create auxiliary bus - aux_bus = pp.create_bus(aux_net, vn_kv=aux_net.bus.at[aux_net.line.at[line_ix, "from_bus"], "vn_kv"], + aux_bus = create_bus(aux_net, vn_kv=aux_net.bus.at[aux_net.line.at[line_ix, "from_bus"], "vn_kv"], name="aux_bus_sc_calc") # Create auxiliary line, while preserve the original index @@ -150,8 +150,8 @@ def calc_sc_on_line(net, line_ix, distance_to_bus0, **kwargs): # Update network aux_net, aux_bus = _create_aux_net(net, line_ix, distance_to_bus0) - pp.rundcpp(aux_net) - sc.calc_sc(aux_net, bus=aux_bus, **kwargs) + rundcpp(aux_net) + calc_sc(aux_net, bus=aux_bus, **kwargs) # Return the new net and the aux bus return aux_net, aux_bus @@ -181,14 +181,14 @@ def adjust_V0_for_trafo_tap(ppci, V0, bus_idx): lv_buses = branch[tap_branch_idx, T_BUS].real.astype(np.int64) for bh, bl, t in zip(hv_buses, lv_buses, tap[tap_branch_idx]): - c = top.connected_component(mg, bh, notravbuses={bl}) + c = connected_component(mg, bh, notravbuses={bl}) c = [cc for cc in c if cc != bl] if not np.intersect1d(c, bus_idx): for b in c: V0[b] = (Zbus[:, b] / Zbus[b, b] * V0[b] * t)[b] else: - c = top.connected_component(mg, bl, notravbuses={bh}) + c = connected_component(mg, bl, notravbuses={bh}) c = [cc for cc in c if cc != bh] if not np.intersect1d(c, bus_idx): for b in c: diff --git a/pandapower/std_types.py b/pandapower/std_types.py index 3687b94e7..5ee81cbfe 100644 --- a/pandapower/std_types.py +++ b/pandapower/std_types.py @@ -247,11 +247,12 @@ def parameter_from_std_type(net, parameter, element="line",fill=None): type does not have a value for the parameter EXAMPLE: - import pandapower as pp - import pandapower.networks as pn - net = pn.simple_mv_open_ring_net() - pp.parameter_from_std_type(net, "q_mm2") + >>> from pandapower import parameter_from_std_type + >>> from pandapower.networks import simple_mv_open_ring_net + >>> + >>> net = simple_mv_open_ring_net() + >>> parameter_from_std_type(net, "q_mm2") """ if parameter not in net[element]: net[element][parameter] = fill diff --git a/pandapower/test/api/test_auxiliary.py b/pandapower/test/api/test_auxiliary.py index 33e532bf3..d096eca0a 100644 --- a/pandapower/test/api/test_auxiliary.py +++ b/pandapower/test/api/test_auxiliary.py @@ -10,8 +10,6 @@ import numpy as np import pandas as pd -from pandapower.control import SplineCharacteristic -from pandapower.control.util.characteristic import LogSplineCharacteristic try: import geopandas as gpd @@ -20,12 +18,13 @@ except ImportError: GEOPANDAS_INSTALLED = False -from pandapower.auxiliary import get_indices - -import pandapower as pp -import pandapower.networks -import pandapower.control -import pandapower.timeseries +from pandapower import get_gc_objects_dict, create_empty_network, from_json_string, to_json, create_bus, create_lines, \ + create_line +from pandapower.auxiliary import get_indices, pandapowerNet +from pandapower.networks import example_simple, example_multivoltage, mv_oberrhein +from pandapower.timeseries import DFData +from pandapower.control import SplineCharacteristic, ContinuousTapControl, ConstControl, create_trafo_characteristics +from pandapower.control.util.characteristic import LogSplineCharacteristic class MemoryLeakDemo: @@ -88,13 +87,13 @@ def test_get_indices(): def test_net_deepcopy(): - net = pp.networks.example_simple() + net = example_simple() net.line.at[0, 'geo'] = geojson.LineString([(0., 1.), (1., 2.)]) net.bus.at[0, 'geo'] = geojson.Point((0., 1.)) - pp.control.ContinuousTapControl(net, element_index=0, vm_set_pu=1) - ds = pp.timeseries.DFData(pd.DataFrame(data=[[0, 1, 2], [3, 4, 5]])) - pp.control.ConstControl(net, element='load', variable='p_mw', element_index=[0], + ContinuousTapControl(net, element_index=0, vm_set_pu=1) + ds = DFData(pd.DataFrame(data=[[0, 1, 2], [3, 4, 5]])) + ConstControl(net, element='load', variable='p_mw', element_index=[0], profile_name=[0], data_source=ds) net1 = copy.deepcopy(net) @@ -114,29 +113,29 @@ def test_net_deepcopy(): def test_memory_leaks(): - net = pp.networks.example_simple() + net = example_simple() # first, test to check that there are no memory leaks - types_dict1 = pp.get_gc_objects_dict() + types_dict1 = get_gc_objects_dict() num = 3 for _ in range(num): net_copy = copy.deepcopy(net) # In each net copy it has only one controller - pp.control.ContinuousTapControl(net_copy, element_index=0, vm_set_pu=1) + ContinuousTapControl(net_copy, element_index=0, vm_set_pu=1) gc.collect() - types_dict2 = pp.get_gc_objects_dict() + types_dict2 = get_gc_objects_dict() - assert types_dict2[pandapower.auxiliary.pandapowerNet] - types_dict1[pandapower.auxiliary.pandapowerNet] == 1 - assert types_dict2[pandapower.control.ContinuousTapControl] - types_dict1.get( - pandapower.control.ContinuousTapControl, 0) == 1 + assert types_dict2[pandapowerNet] - types_dict1[pandapowerNet] == 1 + assert types_dict2[ContinuousTapControl] - types_dict1.get( + ContinuousTapControl, 0) == 1 def test_memory_leaks_demo(): - net = pp.networks.example_simple() + net = example_simple() # first, test to check that there are no memory leaks - types_dict1 = pp.get_gc_objects_dict() + types_dict1 = get_gc_objects_dict() # now, demonstrate how a memory leak occurs # emulates the earlier behavior before the fix with weakref num = 3 @@ -146,71 +145,71 @@ def test_memory_leaks_demo(): # demonstrate how the garbage collector doesn't remove the objects even if called explicitly gc.collect() - types_dict2 = pp.get_gc_objects_dict() - assert types_dict2[pandapower.auxiliary.pandapowerNet] - types_dict1[pandapower.auxiliary.pandapowerNet] == num + types_dict2 = get_gc_objects_dict() + assert types_dict2[pandapowerNet] - types_dict1[pandapowerNet] == num assert types_dict2[MemoryLeakDemo] - types_dict1.get(MemoryLeakDemo, 0) == num def test_memory_leaks_no_copy(): - types_dict0 = pp.get_gc_objects_dict() + types_dict0 = get_gc_objects_dict() num = 3 for _ in range(num): - net = pp.create_empty_network() + net = create_empty_network() # In each net copy it has only one controller - pp.control.ConstControl(net, 'sgen', 'p_mw', 0) + ConstControl(net, 'sgen', 'p_mw', 0) gc.collect() - types_dict1 = pp.get_gc_objects_dict() - assert types_dict1[pandapower.control.ConstControl] - types_dict0.get(pandapower.control.ConstControl, 0) == 1 - assert types_dict1[pandapower.auxiliary.pandapowerNet] - types_dict0.get(pandapower.auxiliary.pandapowerNet, 0) <= 1 + types_dict1 = get_gc_objects_dict() + assert types_dict1[ConstControl] - types_dict0.get(ConstControl, 0) == 1 + assert types_dict1[pandapowerNet] - types_dict0.get(pandapowerNet, 0) <= 1 def test_memory_leak_no_copy_demo(): - types_dict1 = pp.get_gc_objects_dict() + types_dict1 = get_gc_objects_dict() # now, demonstrate how a memory leak occurs # emulates the earlier behavior before the fix with weakref num = 3 for _ in range(num): - net = pp.networks.example_simple() + net = example_simple() MemoryLeakDemo(net) # demonstrate how the garbage collector doesn't remove the objects even if called explicitly gc.collect() - types_dict2 = pp.get_gc_objects_dict() - assert types_dict2[pandapower.auxiliary.pandapowerNet] - \ - types_dict1.get(pandapower.auxiliary.pandapowerNet, 0) >= num-1 + types_dict2 = get_gc_objects_dict() + assert types_dict2[pandapowerNet] - \ + types_dict1.get(pandapowerNet, 0) >= num-1 assert types_dict2[MemoryLeakDemo] - types_dict1.get(MemoryLeakDemo, 0) == num def test_memory_leak_df(): - types_dict1 = pp.get_gc_objects_dict() + types_dict1 = get_gc_objects_dict() num = 3 for _ in range(num): df = pd.DataFrame() MemoryLeakDemoDF(df) gc.collect() - types_dict2 = pp.get_gc_objects_dict() + types_dict2 = get_gc_objects_dict() assert types_dict2[MemoryLeakDemoDF] - types_dict1.get(MemoryLeakDemoDF, 0) == num def test_memory_leak_dict(): - types_dict1 = pp.get_gc_objects_dict() + types_dict1 = get_gc_objects_dict() num = 3 for _ in range(num): d = dict() MemoryLeakDemoDict(d) gc.collect() - types_dict2 = pp.get_gc_objects_dict() + types_dict2 = get_gc_objects_dict() assert types_dict2[MemoryLeakDemoDict] - types_dict1.get(MemoryLeakDemoDict, 0) <= 1 def test_create_trafo_characteristics(): - net = pp.networks.example_multivoltage() + net = example_multivoltage() # test 2 modes, multiple index and single index, for 2w trafo - pp.control.create_trafo_characteristics(net, "trafo", [1], 'vk_percent', [[-2,-1,0,1,2]], [[2,3,4,5,6]]) + create_trafo_characteristics(net, "trafo", [1], 'vk_percent', [[-2,-1,0,1,2]], [[2,3,4,5,6]]) assert "characteristic" in net assert "tap_dependent_impedance" in net.trafo.columns assert net.trafo.tap_dependent_impedance.dtype == np.bool_ @@ -222,18 +221,18 @@ def test_create_trafo_characteristics(): assert net.trafo.vk_percent_characteristic.dtype == pd.Int64Dtype() assert "vkr_percent_characteristic" not in net.trafo.columns - pp.control.create_trafo_characteristics(net, "trafo", 1, 'vkr_percent', [-2,-1,0,1,2], [1.323,1.324,1.325,1.326,1.327]) + create_trafo_characteristics(net, "trafo", 1, 'vkr_percent', [-2,-1,0,1,2], [1.323,1.324,1.325,1.326,1.327]) assert len(net.characteristic) == 2 assert "vkr_percent_characteristic" in net.trafo.columns assert net.trafo.at[1, 'vkr_percent_characteristic'] == 1 assert pd.isnull(net.trafo.at[0, 'vkr_percent_characteristic']) assert net.trafo.vkr_percent_characteristic.dtype == pd.Int64Dtype() - assert isinstance(net.characteristic.object.at[0], pp.control.SplineCharacteristic) - assert isinstance(net.characteristic.object.at[1], pp.control.SplineCharacteristic) + assert isinstance(net.characteristic.object.at[0], SplineCharacteristic) + assert isinstance(net.characteristic.object.at[1], SplineCharacteristic) # test for 3w trafo - pp.control.create_trafo_characteristics(net, "trafo3w", 0, 'vk_hv_percent', [-8, -4, 0, 4, 8], [8.1, 9.1, 10.1, 11.1, 12.1]) + create_trafo_characteristics(net, "trafo3w", 0, 'vk_hv_percent', [-8, -4, 0, 4, 8], [8.1, 9.1, 10.1, 11.1, 12.1]) assert "tap_dependent_impedance" in net.trafo3w.columns assert net.trafo3w.tap_dependent_impedance.dtype == np.bool_ assert net.trafo3w.tap_dependent_impedance.at[0] @@ -243,7 +242,7 @@ def test_create_trafo_characteristics(): assert "vkr_hv_percent_characteristic" not in net.trafo3w.columns assert "vk_mv_percent_characteristic" not in net.trafo3w.columns - pp.control.create_trafo_characteristics(net, "trafo3w", 0, 'vk_mv_percent', [-8, -4, 0, 4, 8], [8.1, 9.1, 10.1, 11.1, 12.1]) + create_trafo_characteristics(net, "trafo3w", 0, 'vk_mv_percent', [-8, -4, 0, 4, 8], [8.1, 9.1, 10.1, 11.1, 12.1]) assert net.trafo3w.tap_dependent_impedance.dtype == np.bool_ assert net.trafo3w.tap_dependent_impedance.at[0] assert "vk_mv_percent_characteristic" in net.trafo3w.columns @@ -258,38 +257,38 @@ def test_create_trafo_characteristics(): # invalid variable with pytest.raises(UserWarning): - pp.control.create_trafo_characteristics(net, "trafo3w", 0, 'vk_percent', + create_trafo_characteristics(net, "trafo3w", 0, 'vk_percent', [-8, -4, 0, 4, 8], [8.1, 9.1, 10.1, 11.1, 12.1]) # invalid shapes with pytest.raises(UserWarning): - pp.control.create_trafo_characteristics(net, "trafo3w", 0, 'vk_hv_percent', + create_trafo_characteristics(net, "trafo3w", 0, 'vk_hv_percent', [-8, -4, 0, 4, 8], [8.1, 9.1, 10.1, 11.1]) with pytest.raises(UserWarning): - pp.control.create_trafo_characteristics(net, "trafo3w", [0], 'vk_hv_percent', + create_trafo_characteristics(net, "trafo3w", [0], 'vk_hv_percent', [-8, -4, 0, 4, 8], [8.1, 9.1, 10.1, 11.1, 12.1]) with pytest.raises(UserWarning): - pp.control.create_trafo_characteristics(net, "trafo3w", [0, 1], 'vk_hv_percent', + create_trafo_characteristics(net, "trafo3w", [0, 1], 'vk_hv_percent', [[-8, -4, 0, 4, 8]], [[8.1, 9.1, 10.1, 11.1, 12.1]]) with pytest.raises(UserWarning): - pp.control.create_trafo_characteristics(net, "trafo3w", [0, 1], 'vk_hv_percent', + create_trafo_characteristics(net, "trafo3w", [0, 1], 'vk_hv_percent', [[-8, -4, 0, 4, 8], [-8, -4, 0, 4, 8]], [[8.1, 9.1, 10.1, 11.1, 12.1]]) @pytest.mark.parametrize("file_io", (False, True), ids=("Without JSON I/O", "With JSON I/O")) def test_characteristic(file_io): - net = pp.create_empty_network() + net = create_empty_network() c1 = SplineCharacteristic(net, [0,1,2], [0, 1, 4], fill_value=(0, 4)) c2 = SplineCharacteristic(net, [0,1,2], [0, 1, 4], interpolator_kind="Pchip", extrapolate=False) c3 = SplineCharacteristic(net, [0,1,2], [0, 1, 4], interpolator_kind="hello") c4 = LogSplineCharacteristic(net, [0,1,2], [0, 1, 4], interpolator_kind="Pchip", extrapolate=False) if file_io: - net_copy = pp.from_json_string(pp.to_json(net)) + net_copy = from_json_string(to_json(net)) c1, c2, c3, c4 = net_copy.characteristic.object.values assert np.allclose(c1([-1]), [0], rtol=0, atol=1e-6) @@ -305,17 +304,17 @@ def test_characteristic(file_io): def test_log_characteristic_property(): - net = pp.create_empty_network() + net = create_empty_network() c = LogSplineCharacteristic(net, [10, 1000, 10000], [1000, 0.1, 0.001], interpolator_kind="Pchip", extrapolate=False) c._x_vals c([2]) def test_geo_accessor_geojson(): - net = pp.create_empty_network() - b1 = pp.create_bus(net, 10, geodata=(1, 1)) - b2 = pp.create_bus(net, 10, geodata=(2, 2)) - l = pp.create_lines( + net = create_empty_network() + b1 = create_bus(net, 10, geodata=(1, 1)) + b2 = create_bus(net, 10, geodata=(2, 2)) + l = create_lines( net, [b1, b1], [b2, b2], @@ -323,7 +322,7 @@ def test_geo_accessor_geojson(): std_type="48-AL1/8-ST1A 10.0", geodata=[[(1, 1), (2, 2), (3, 3)], [(1, 1), (1, 2)]], ) - pp.create_line(net, b1, b2, 1.5, std_type="48-AL1/8-ST1A 10.0") + create_line(net, b1, b2, 1.5, std_type="48-AL1/8-ST1A 10.0") assert len(net.line.geo.geojson._coords) == 2 assert np.array_equal(net.line.geo.geojson._coords.at[l[0]], [[1, 1], [2, 2], [3, 3]]) @@ -342,7 +341,7 @@ def test_geo_accessor_geojson(): @pytest.mark.skipif(not GEOPANDAS_INSTALLED, reason="geopandas is not installed") def test_geo_accessor_geopandas(): - net = pp.networks.mv_oberrhein() + net = mv_oberrhein() reference_point = (7.781067, 48.389774) radius_m = 2200 circle_polygon = gpd.GeoSeries([shapely.geometry.Point(reference_point)], diff --git a/pandapower/test/api/test_convert_format.py b/pandapower/test/api/test_convert_format.py index 5851a0b60..ec770ef85 100644 --- a/pandapower/test/api/test_convert_format.py +++ b/pandapower/test/api/test_convert_format.py @@ -4,13 +4,14 @@ # and Energy System Technology (IEE), Kassel. All rights reserved. -import pandapower as pp import numpy as np import os import pytest from packaging import version as vs -folder = os.path.join(pp.pp_dir, "test", "test_files", "old_versions") +from pandapower import pp_dir, from_json, convert_format, runpp + +folder = os.path.join(pp_dir, "test", "test_files", "old_versions") found_versions = [file.split("_")[1].split(".json")[0] for _, _, files in os.walk(folder) for file in files] @@ -22,15 +23,15 @@ def test_convert_format(version): if not os.path.isfile(filename): raise ValueError("File for version %s does not exist" % version) try: - net = pp.from_json(filename, convert=False) + net = from_json(filename, convert=False) if ('version' in net) and (vs.parse(str(net.version)) > vs.parse('2.0.1')): - _ = pp.from_json(filename, elements_to_deserialize=['bus', 'load']) + _ = from_json(filename, elements_to_deserialize=['bus', 'load']) except: raise UserWarning("Can not load network saved in pandapower version %s" % version) vm_pu_old = net.res_bus.vm_pu.copy() - pp.convert_format(net) + convert_format(net) try: - pp.runpp(net, run_control="controller" in net and len(net.controller) > 0) + runpp(net, run_control="controller" in net and len(net.controller) > 0) except: raise UserWarning("Can not run power flow in network " "saved with pandapower version %s" % version) @@ -40,27 +41,27 @@ def test_convert_format(version): def test_convert_format_pq_bus_meas(): - net = pp.from_json(os.path.join(folder, "example_2.3.1.json"), convert=False) - net = pp.convert_format(net) - pp.runpp(net) + net = from_json(os.path.join(folder, "example_2.3.1.json"), convert=False) + net = convert_format(net) + runpp(net) bus_p_meas = net.measurement.query("element_type=='bus' and measurement_type=='p'").set_index("element", drop=True) assert np.allclose(net.res_bus.p_mw, bus_p_meas["value"]) def test_convert_format_controller(): - net = pp.from_json(os.path.join(folder, "example_2.3.0.json"), convert=True) + net = from_json(os.path.join(folder, "example_2.3.0.json"), convert=True) controller = net.controller.object.iloc[0] assert not hasattr(controller, "net") def test_convert_format_characteristics(): - net = pp.from_json(os.path.join(folder, "example_2.13.0.1.json"), convert=True) + net = from_json(os.path.join(folder, "example_2.13.0.1.json"), convert=True) assert hasattr(net.characteristic.at[0, "object"], "interpolator_kind") assert hasattr(net.characteristic.at[0, "object"], "kwargs") assert not hasattr(net.characteristic.at[0, "object"], "kind") assert not hasattr(net.characteristic.at[0, "object"], "fill_value") - pp.runpp(net) + runpp(net) if __name__ == '__main__': diff --git a/pandapower/test/api/test_create.py b/pandapower/test/api/test_create.py index 0aaa51f43..43137df6f 100644 --- a/pandapower/test/api/test_create.py +++ b/pandapower/test/api/test_create.py @@ -10,7 +10,14 @@ import pandas as pd import pytest -import pandapower as pp +from pandapower import create_empty_network, create_bus, create_ext_grid, create_line_from_parameters, \ + create_load_from_cosphi, runpp, create_shunt_as_capacitor, create_sgen_from_cosphi, \ + create_series_reactor_as_impedance, create_transformer_from_parameters, create_load, create_sgen, create_dcline, \ + create_gen, create_ward, create_xward, create_shunt, create_line, create_transformer, create_transformer3w, \ + create_transformer3w_from_parameters, create_impedance, create_switch, create_gens, load_std_type, \ + create_std_type, create_buses, create_lines, create_lines_from_parameters, create_transformers_from_parameters, \ + create_transformers3w_from_parameters, create_switches, create_loads, create_storage, create_storages, nets_equal, \ + create_wards, create_sgens pd.set_option("display.max_rows", 500) pd.set_option("display.max_columns", 500) @@ -18,12 +25,12 @@ def test_convenience_create_functions(): - net = pp.create_empty_network() - b1 = pp.create_bus(net, 110.0) - b2 = pp.create_bus(net, 110.0) - b3 = pp.create_bus(net, 20) - pp.create_ext_grid(net, b1) - pp.create_line_from_parameters( + net = create_empty_network() + b1 = create_bus(net, 110.0) + b2 = create_bus(net, 110.0) + b3 = create_bus(net, 20) + create_ext_grid(net, b1) + create_line_from_parameters( net, b1, b2, @@ -34,10 +41,10 @@ def test_convenience_create_functions(): max_i_ka=0.664, ) - l0 = pp.create_load_from_cosphi( + l0 = create_load_from_cosphi( net, b2, 10, 0.95, "underexcited", name="load", test_kwargs="dummy_string" ) - pp.runpp(net, init="flat") + runpp(net, init="flat") assert net.load.p_mw.at[l0] == 9.5 assert net.load.q_mvar.at[l0] > 0 @@ -46,20 +53,20 @@ def test_convenience_create_functions(): assert net.load.name.at[l0] == "load" assert net.load.test_kwargs.at[l0] == "dummy_string" - sh0 = pp.create_shunt_as_capacitor( + sh0 = create_shunt_as_capacitor( net, b2, 10, loss_factor=0.01, name="shunt", test_kwargs="dummy_string" ) - pp.runpp(net, init="flat") + runpp(net, init="flat") assert np.isclose(net.res_shunt.q_mvar.at[sh0], -10.043934174) assert np.isclose(net.res_shunt.p_mw.at[sh0], 0.10043933665) assert np.isclose(net.res_bus.vm_pu.at[b2], 1.0021942964) assert net.shunt.name.at[sh0] == "shunt" assert net.shunt.test_kwargs.at[sh0] == "dummy_string" - sg0 = pp.create_sgen_from_cosphi( + sg0 = create_sgen_from_cosphi( net, b2, 5, 0.95, "overexcited", name="sgen", test_kwargs="dummy_string" ) - pp.runpp(net, init="flat") + runpp(net, init="flat") assert np.sqrt(net.sgen.p_mw.at[sg0] ** 2 + net.sgen.q_mvar.at[sg0] ** 2) == 5 assert net.sgen.p_mw.at[sg0] == 4.75 assert net.sgen.q_mvar.at[sg0] > 0 @@ -69,14 +76,14 @@ def test_convenience_create_functions(): tol = 1e-6 base_z = 110 ** 2 / 100 - sind = pp.create_series_reactor_as_impedance( + sind = create_series_reactor_as_impedance( net, b1, b2, r_ohm=100, x_ohm=200, sn_mva=100, test_kwargs="dummy_string" ) assert net.impedance.at[sind, "rft_pu"] - 100 / base_z < tol assert net.impedance.at[sind, "xft_pu"] - 200 / base_z < tol assert net.impedance.test_kwargs.at[sind] == "dummy_string" - tid = pp.create_transformer_from_parameters( + tid = create_transformer_from_parameters( net, hv_bus=b2, lv_bus=b3, @@ -89,29 +96,29 @@ def test_convenience_create_functions(): i0_percent=1, test_kwargs="dummy_string", ) - pp.create_load(net, b3, 0.1) + create_load(net, b3, 0.1) assert net.trafo.at[tid, "df"] == 1 - pp.runpp(net) + runpp(net) tr_l = net.res_trafo.at[tid, "loading_percent"] net.trafo.at[tid, "df"] = 2 - pp.runpp(net) + runpp(net) tr_l_2 = net.res_trafo.at[tid, "loading_percent"] assert tr_l == tr_l_2 * 2 net.trafo.at[tid, "df"] = 0 with pytest.raises(UserWarning): - pp.runpp(net) + runpp(net) assert net.trafo.test_kwargs.at[tid] == "dummy_string" def test_nonexistent_bus(): from functools import partial - net = pp.create_empty_network() + net = create_empty_network() create_functions = [ - partial(pp.create_load, net=net, p_mw=0, q_mvar=0, bus=0, index=0), - partial(pp.create_sgen, net=net, p_mw=0, q_mvar=0, bus=0, index=0), + partial(create_load, net=net, p_mw=0, q_mvar=0, bus=0, index=0), + partial(create_sgen, net=net, p_mw=0, q_mvar=0, bus=0, index=0), partial( - pp.create_dcline, + create_dcline, net, from_bus=0, to_bus=1, @@ -122,13 +129,13 @@ def test_nonexistent_bus(): vm_to_pu=1.0, index=0, ), - partial(pp.create_gen, net=net, p_mw=0, bus=0, index=0), - partial(pp.create_ward, net, 0, 0, 0, 0, 0, index=0), - partial(pp.create_xward, net, 0, 0, 0, 0, 0, 1, 1, 1, index=0), - partial(pp.create_shunt, net=net, q_mvar=0, bus=0, index=0), - partial(pp.create_ext_grid, net=net, bus=1, index=0), + partial(create_gen, net=net, p_mw=0, bus=0, index=0), + partial(create_ward, net, 0, 0, 0, 0, 0, index=0), + partial(create_xward, net, 0, 0, 0, 0, 0, 1, 1, 1, index=0), + partial(create_shunt, net=net, q_mvar=0, bus=0, index=0), + partial(create_ext_grid, net=net, bus=1, index=0), partial( - pp.create_line, + create_line, net=net, from_bus=0, to_bus=1, @@ -137,7 +144,7 @@ def test_nonexistent_bus(): index=0, ), partial( - pp.create_line_from_parameters, + create_line_from_parameters, net=net, from_bus=0, to_bus=1, @@ -149,7 +156,7 @@ def test_nonexistent_bus(): index=1, ), partial( - pp.create_transformer, + create_transformer, net=net, hv_bus=0, lv_bus=1, @@ -157,7 +164,7 @@ def test_nonexistent_bus(): index=0, ), partial( - pp.create_transformer3w, + create_transformer3w, net=net, hv_bus=0, lv_bus=1, @@ -166,7 +173,7 @@ def test_nonexistent_bus(): index=0, ), partial( - pp.create_transformer3w_from_parameters, + create_transformer3w_from_parameters, net=net, hv_bus=0, lv_bus=1, @@ -188,7 +195,7 @@ def test_nonexistent_bus(): index=1, ), partial( - pp.create_transformer_from_parameters, + create_transformer_from_parameters, net=net, hv_bus=0, lv_bus=1, @@ -202,7 +209,7 @@ def test_nonexistent_bus(): index=1, ), partial( - pp.create_impedance, + create_impedance, net=net, from_bus=0, to_bus=1, @@ -211,16 +218,16 @@ def test_nonexistent_bus(): sn_mva=0.6, index=0, ), - partial(pp.create_switch, net, bus=0, element=1, et="b", index=0), + partial(create_switch, net, bus=0, element=1, et="b", index=0), ] for func in create_functions: with pytest.raises( Exception ): # exception has to be raised since bus doesn't exist func() - pp.create_bus(net, 0.4) - pp.create_bus(net, 0.4) - pp.create_bus(net, 0.4) + create_bus(net, 0.4) + create_bus(net, 0.4) + create_bus(net, 0.4) for func in create_functions: func() # buses exist, element can be created with pytest.raises( @@ -231,23 +238,23 @@ def test_nonexistent_bus(): def test_tap_phase_shifter_default(): expected_default = False - net = pp.create_empty_network() - pp.create_bus(net, 110) - pp.create_bus(net, 20) - data = pp.load_std_type(net, "25 MVA 110/20 kV", "trafo") + net = create_empty_network() + create_bus(net, 110) + create_bus(net, 20) + data = load_std_type(net, "25 MVA 110/20 kV", "trafo") if "tap_phase_shifter" in data: del data["tap_phase_shifter"] - pp.create_std_type(net, data, "without_tap_shifter_info", "trafo") - pp.create_transformer_from_parameters(net, 0, 1, 25e3, 110, 20, 0.4, 12, 20, 0.07) - pp.create_transformer(net, 0, 1, "without_tap_shifter_info") + create_std_type(net, data, "without_tap_shifter_info", "trafo") + create_transformer_from_parameters(net, 0, 1, 25e3, 110, 20, 0.4, 12, 20, 0.07) + create_transformer(net, 0, 1, "without_tap_shifter_info") assert (net.trafo.tap_phase_shifter == expected_default).all() def test_create_line_conductance(): - net = pp.create_empty_network() - pp.create_bus(net, 20) - pp.create_bus(net, 20) - pp.create_std_type( + net = create_empty_network() + create_bus(net, 20) + create_bus(net, 20) + create_std_type( net, { "c_nf_per_km": 210, @@ -261,20 +268,20 @@ def test_create_line_conductance(): "test_conductance", ) - l = pp.create_line(net, 0, 1, 1.0, "test_conductance", test_kwargs="dummy_string") + l = create_line(net, 0, 1, 1.0, "test_conductance", test_kwargs="dummy_string") assert net.line.g_us_per_km.at[l] == 1 assert net.line.test_kwargs.at[l] == "dummy_string" def test_create_buses(): - net = pp.create_empty_network() + net = create_empty_network() # standard - b1 = pp.create_buses(net, 3, 110, test_kwargs="dummy_string") + b1 = create_buses(net, 3, 110, test_kwargs="dummy_string") # with geodata - b2 = pp.create_buses(net, 3, 110, geodata=(10, 20)) + b2 = create_buses(net, 3, 110, geodata=(10, 20)) # with geodata as array geodata = [(10, 20), (20, 30), (30, 40)] - b3 = pp.create_buses(net, 3, 110, geodata=geodata) + b3 = create_buses(net, 3, 110, geodata=geodata) assert len(net.bus) == 9 assert net.bus.test_kwargs.at[b1[0]] == "dummy_string" @@ -286,10 +293,10 @@ def test_create_buses(): def test_create_lines(): # standard - net = pp.create_empty_network() - b1 = pp.create_bus(net, 10) - b2 = pp.create_bus(net, 10) - l = pp.create_lines( + net = create_empty_network() + b1 = create_bus(net, 10) + b2 = create_bus(net, 10) + l = create_lines( net, [b1, b1], [b2, b2], @@ -302,10 +309,10 @@ def test_create_lines(): assert len(set(net.line.r_ohm_per_km)) == 1 assert all(net.line.test_kwargs == "dummy_string") - net = pp.create_empty_network() - b1 = pp.create_bus(net, 10) - b2 = pp.create_bus(net, 10) - l = pp.create_lines( + net = create_empty_network() + b1 = create_bus(net, 10) + b2 = create_bus(net, 10) + l = create_lines( net, [b1, b1], [b2, b2], @@ -317,10 +324,10 @@ def test_create_lines(): assert sum(net.line.std_type == "NA2XS2Y 1x240 RM/25 6/10 kV") == 1 # with geodata - net = pp.create_empty_network() - b1 = pp.create_bus(net, 10) - b2 = pp.create_bus(net, 10) - l = pp.create_lines( + net = create_empty_network() + b1 = create_bus(net, 10) + b2 = create_bus(net, 10) + l = create_lines( net, [b1, b1], [b2, b2], @@ -334,10 +341,10 @@ def test_create_lines(): assert net.line.at[l[1], "geo"] == geojson.dumps(geojson.LineString([(1, 1), (1, 2)]), sort_keys=True) # setting params as single value - net = pp.create_empty_network() - b1 = pp.create_bus(net, 10) - b2 = pp.create_bus(net, 10) - l = pp.create_lines( + net = create_empty_network() + b1 = create_bus(net, 10) + b2 = create_bus(net, 10) + l = create_lines( net, [b1, b1], [b2, b2], @@ -367,10 +374,10 @@ def test_create_lines(): assert net.line.at[l[1], "parallel"] == 1 # setting params as array - net = pp.create_empty_network() - b1 = pp.create_bus(net, 10) - b2 = pp.create_bus(net, 10) - l = pp.create_lines( + net = create_empty_network() + b1 = create_bus(net, 10) + b2 = create_bus(net, 10) + l = create_lines( net, [b1, b1], [b2, b2], @@ -402,10 +409,10 @@ def test_create_lines(): def test_create_lines_from_parameters(): # standard - net = pp.create_empty_network() - b1 = pp.create_bus(net, 10) - b2 = pp.create_bus(net, 10) - l = pp.create_lines_from_parameters( + net = create_empty_network() + b1 = create_bus(net, 10) + b2 = create_bus(net, 10) + l = create_lines_from_parameters( net, [b1, b1], [b2, b2], @@ -425,10 +432,10 @@ def test_create_lines_from_parameters(): assert net.line.test_kwargs.at[l[0]] == "dummy_string" # with geodata - net = pp.create_empty_network() - b1 = pp.create_bus(net, 10) - b2 = pp.create_bus(net, 10) - l = pp.create_lines_from_parameters( + net = create_empty_network() + b1 = create_bus(net, 10) + b2 = create_bus(net, 10) + l = create_lines_from_parameters( net, [b1, b1], [b2, b2], @@ -445,10 +452,10 @@ def test_create_lines_from_parameters(): assert net.line.at[l[1], "geo"] == geojson.dumps(geojson.LineString([(1, 1), (1, 2)]), sort_keys=True) # setting params as single value - net = pp.create_empty_network() - b1 = pp.create_bus(net, 10) - b2 = pp.create_bus(net, 10) - l = pp.create_lines_from_parameters( + net = create_empty_network() + b1 = create_bus(net, 10) + b2 = create_bus(net, 10) + l = create_lines_from_parameters( net, [b1, b1], [b2, b2], @@ -491,10 +498,10 @@ def test_create_lines_from_parameters(): assert all(net.line.test_kwargs == "dummy_string") # setting params as array - net = pp.create_empty_network() - b1 = pp.create_bus(net, 10) - b2 = pp.create_bus(net, 10) - l = pp.create_lines_from_parameters( + net = create_empty_network() + b1 = create_bus(net, 10) + b2 = create_bus(net, 10) + l = create_lines_from_parameters( net, [b1, b1], [b2, b2], @@ -547,10 +554,10 @@ def test_create_lines_from_parameters(): def test_create_lines_raise_errorexcept(): # standard - net = pp.create_empty_network() - b1 = pp.create_bus(net, 10) - b2 = pp.create_bus(net, 10) - pp.create_lines_from_parameters( + net = create_empty_network() + b1 = create_bus(net, 10) + b2 = create_bus(net, 10) + create_lines_from_parameters( net, [b1, b1], [b2, b2], @@ -562,7 +569,7 @@ def test_create_lines_raise_errorexcept(): ) with pytest.raises(UserWarning, match="Lines trying to attach .*"): - pp.create_lines_from_parameters( + create_lines_from_parameters( net, [b1, 2], [2, b2], @@ -573,7 +580,7 @@ def test_create_lines_raise_errorexcept(): max_i_ka=[100, 100], ) with pytest.raises(UserWarning, match="Lines with indexes .*"): - pp.create_lines_from_parameters( + create_lines_from_parameters( net, [b1, b1], [b2, b2], @@ -586,7 +593,7 @@ def test_create_lines_raise_errorexcept(): ) with pytest.raises(UserWarning, match="Passed indexes"): - pp.create_lines_from_parameters( + create_lines_from_parameters( net, [b1, b1], [b2, b2], @@ -601,40 +608,40 @@ def test_create_lines_raise_errorexcept(): def test_create_lines_optional_columns(): # - net = pp.create_empty_network() - pp.create_buses(net, 5, 110) - pp.create_line(net, 0, 1, 10, "48-AL1/8-ST1A 10.0") - pp.create_line_from_parameters(net, 3, 4, 10, 1, 1, 1, 100) - pp.create_lines(net, [0, 1], [1, 0], 10, "48-AL1/8-ST1A 10.0") - pp.create_lines_from_parameters(net, [3, 4], [4, 3], [10, 11], 1, 1, 1, 100) + net = create_empty_network() + create_buses(net, 5, 110) + create_line(net, 0, 1, 10, "48-AL1/8-ST1A 10.0") + create_line_from_parameters(net, 3, 4, 10, 1, 1, 1, 100) + create_lines(net, [0, 1], [1, 0], 10, "48-AL1/8-ST1A 10.0") + create_lines_from_parameters(net, [3, 4], [4, 3], [10, 11], 1, 1, 1, 100) assert "max_loading_percent" not in net.line.columns v = None - pp.create_line(net, 0, 1, 10, "48-AL1/8-ST1A 10.0", max_loading_percent=v) - pp.create_line_from_parameters(net, 3, 4, 10, 1, 1, 1, 100, max_loading_percent=v) - pp.create_lines(net, [0, 1], [1, 0], 10, "48-AL1/8-ST1A 10.0", max_loading_percent=v) - # pp.create_lines(net, [0, 1], [1, 0], 10, "48-AL1/8-ST1A 10.0", max_loading_percent=[v, v]) # would be added - pp.create_lines_from_parameters(net, [3, 4], [4, 3], [10, 11], 1, 1, 1, 100, max_loading_percent=v) - # pp.create_lines_from_parameters(net, [3, 4], [4, 3], [10, 11], 1, 1, 1, 100, max_loading_percent=[v, v]) # would be added + create_line(net, 0, 1, 10, "48-AL1/8-ST1A 10.0", max_loading_percent=v) + create_line_from_parameters(net, 3, 4, 10, 1, 1, 1, 100, max_loading_percent=v) + create_lines(net, [0, 1], [1, 0], 10, "48-AL1/8-ST1A 10.0", max_loading_percent=v) + # create_lines(net, [0, 1], [1, 0], 10, "48-AL1/8-ST1A 10.0", max_loading_percent=[v, v]) # would be added + create_lines_from_parameters(net, [3, 4], [4, 3], [10, 11], 1, 1, 1, 100, max_loading_percent=v) + # create_lines_from_parameters(net, [3, 4], [4, 3], [10, 11], 1, 1, 1, 100, max_loading_percent=[v, v]) # would be added assert "max_loading_percent" not in net.line.columns v = np.nan - pp.create_line(net, 0, 1, 10, "48-AL1/8-ST1A 10.0", max_loading_percent=v) - pp.create_line_from_parameters(net, 3, 4, 10, 1, 1, 1, 100, max_loading_percent=v) + create_line(net, 0, 1, 10, "48-AL1/8-ST1A 10.0", max_loading_percent=v) + create_line_from_parameters(net, 3, 4, 10, 1, 1, 1, 100, max_loading_percent=v) # np.nan is not None: - # pp.create_lines(net, [0, 1], [1, 0], 10, "48-AL1/8-ST1A 10.0", max_loading_percent=v) - # pp.create_lines(net, [0, 1], [1, 0], 10, "48-AL1/8-ST1A 10.0", max_loading_percent=[v, v]) # would be added - # pp.create_lines_from_parameters(net, [3, 4], [4, 3], [10, 11], 1, 1, 1, 100, max_loading_percent=v) - # pp.create_lines_from_parameters(net, [3, 4], [4, 3], [10, 11], 1, 1, 1, 100, max_loading_percent=[v, v]) + # create_lines(net, [0, 1], [1, 0], 10, "48-AL1/8-ST1A 10.0", max_loading_percent=v) + # create_lines(net, [0, 1], [1, 0], 10, "48-AL1/8-ST1A 10.0", max_loading_percent=[v, v]) # would be added + # create_lines_from_parameters(net, [3, 4], [4, 3], [10, 11], 1, 1, 1, 100, max_loading_percent=v) + # create_lines_from_parameters(net, [3, 4], [4, 3], [10, 11], 1, 1, 1, 100, max_loading_percent=[v, v]) assert "max_loading_percent" not in net.line.columns def test_create_line_alpha_temperature(): - net = pp.create_empty_network() - b = pp.create_buses(net, 5, 110) + net = create_empty_network() + b = create_buses(net, 5, 110) - l1 = pp.create_line(net, 0, 1, 10, "48-AL1/8-ST1A 10.0") - l2 = pp.create_line( + l1 = create_line(net, 0, 1, 10, "48-AL1/8-ST1A 10.0") + l2 = create_line( net, 1, 2, @@ -643,9 +650,9 @@ def test_create_line_alpha_temperature(): alpha=4.03e-3, temperature_degree_celsius=80, ) - l3 = pp.create_line(net, 2, 3, 10, "48-AL1/8-ST1A 10.0") - l4 = pp.create_line_from_parameters(net, 3, 4, 10, 1, 1, 1, 100) - l5 = pp.create_line_from_parameters(net, 3, 4, 10, 1, 1, 1, 100, alpha=4.03e-3) + l3 = create_line(net, 2, 3, 10, "48-AL1/8-ST1A 10.0") + l4 = create_line_from_parameters(net, 3, 4, 10, 1, 1, 1, 100) + l5 = create_line_from_parameters(net, 3, 4, 10, 1, 1, 1, 100, alpha=4.03e-3) assert "alpha" in net.line.columns assert all(net.line.loc[[l2, l3, l5], "alpha"] == 4.03e-3) @@ -654,19 +661,19 @@ def test_create_line_alpha_temperature(): assert all(net.line.loc[[l1, l3, l4, l5], "temperature_degree_celsius"].isnull()) # make sure optional columns are not created if None or np.nan: - pp.create_line(net, 2, 3, 10, "48-AL1/8-ST1A 10.0", wind_speed_m_per_s=None) - pp.create_lines(net, [2], [3], 10, "48-AL1/8-ST1A 10.0", wind_speed_m_per_s=None) - pp.create_line_from_parameters(net, 3, 4, 10, 1, 1, 1, 100, wind_speed_m_per_s=None) - pp.create_line_from_parameters(net, 3, 4, 10, 1, 1, 1, 100, alpha=4.03e-3, wind_speed_m_per_s=np.nan) + create_line(net, 2, 3, 10, "48-AL1/8-ST1A 10.0", wind_speed_m_per_s=None) + create_lines(net, [2], [3], 10, "48-AL1/8-ST1A 10.0", wind_speed_m_per_s=None) + create_line_from_parameters(net, 3, 4, 10, 1, 1, 1, 100, wind_speed_m_per_s=None) + create_line_from_parameters(net, 3, 4, 10, 1, 1, 1, 100, alpha=4.03e-3, wind_speed_m_per_s=np.nan) assert "wind_speed_m_per_s" not in net.line.columns def test_create_transformers_from_parameters(): # standard - net = pp.create_empty_network() - b1 = pp.create_bus(net, 15) - b2 = pp.create_bus(net, 0.4) - index = pp.create_transformers_from_parameters( + net = create_empty_network() + b1 = create_bus(net, 15) + b2 = create_bus(net, 0.4) + index = create_transformers_from_parameters( net, [b1, b1], [b2, b2], @@ -680,7 +687,7 @@ def test_create_transformers_from_parameters(): foo=2, ) with pytest.raises(UserWarning): - pp.create_transformers_from_parameters( + create_transformers_from_parameters( net, [b1, b1], [b2, b2], @@ -703,10 +710,10 @@ def test_create_transformers_from_parameters(): assert len(net.trafo.foo) == 2 # setting params as single value - net = pp.create_empty_network() - b1 = pp.create_bus(net, 15) - b2 = pp.create_bus(net, 0.4) - pp.create_transformers_from_parameters( + net = create_empty_network() + b1 = create_bus(net, 15) + b2 = create_bus(net, 0.4) + create_transformers_from_parameters( net, hv_buses=[b1, b1], lv_buses=[b2, b2], @@ -748,10 +755,10 @@ def test_create_transformers_from_parameters(): assert all(net.trafo.test_kwargs == "dummy_string") # setting params as array - net = pp.create_empty_network() - b1 = pp.create_bus(net, 10) - b2 = pp.create_bus(net, 10) - t = pp.create_transformers_from_parameters( + net = create_empty_network() + b1 = create_bus(net, 10) + b2 = create_bus(net, 10) + t = create_transformers_from_parameters( net, hv_buses=[b1, b1], lv_buses=[b2, b2], @@ -792,10 +799,10 @@ def test_create_transformers_from_parameters(): def test_create_transformers_raise_errorexcept(): # standard - net = pp.create_empty_network() - b1 = pp.create_bus(net, 10) - b2 = pp.create_bus(net, 10) - pp.create_transformers_from_parameters( + net = create_empty_network() + b1 = create_bus(net, 10) + b2 = create_bus(net, 10) + create_transformers_from_parameters( net, [b1, b1], [b2, b2], @@ -810,7 +817,7 @@ def test_create_transformers_raise_errorexcept(): ) with pytest.raises(UserWarning, match=r"Trafos with indexes \[1\] already exist."): - pp.create_transformers_from_parameters( + create_transformers_from_parameters( net, [b1, b1], [b2, b2], @@ -823,10 +830,10 @@ def test_create_transformers_raise_errorexcept(): i0_percent=0.3, index=[2, 1], ) - net = pp.create_empty_network() - b1 = pp.create_bus(net, 10) - b2 = pp.create_bus(net, 10) - pp.create_transformers_from_parameters( + net = create_empty_network() + b1 = create_bus(net, 10) + b2 = create_bus(net, 10) + create_transformers_from_parameters( net, [b1, b1], [b2, b2], @@ -842,7 +849,7 @@ def test_create_transformers_raise_errorexcept(): with pytest.raises( UserWarning, match=r"Transformers trying to attach to non existing buses \{2\}" ): - pp.create_transformers_from_parameters( + create_transformers_from_parameters( net, [b1, 2], [b2, b2], @@ -858,7 +865,7 @@ def test_create_transformers_raise_errorexcept(): with pytest.raises( UserWarning, match=r"Transformers trying to attach to non existing buses \{3\}" ): - pp.create_transformers_from_parameters( + create_transformers_from_parameters( net, [b1, b1], [b2, 3], @@ -874,10 +881,10 @@ def test_create_transformers_raise_errorexcept(): def test_trafo_2_tap_changers(): - net = pp.create_empty_network() - b1 = pp.create_bus(net, 110) - b2 = pp.create_bus(net, 20) - pp.create_transformer(net, b1, b2, "40 MVA 110/20 kV") + net = create_empty_network() + b1 = create_bus(net, 110) + b2 = create_bus(net, 20) + create_transformer(net, b1, b2, "40 MVA 110/20 kV") tap2_data = {"tap2_side": "hv", "tap2_neutral": 0, @@ -890,11 +897,11 @@ def test_trafo_2_tap_changers(): for c in tap2_data.keys(): assert c not in net.trafo.columns - std_type = pp.load_std_type(net, "40 MVA 110/20 kV", "trafo") + std_type = load_std_type(net, "40 MVA 110/20 kV", "trafo") - pp.create_std_type(net, {**std_type, **tap2_data}, "test_trafo_type", "trafo") + create_std_type(net, {**std_type, **tap2_data}, "test_trafo_type", "trafo") - t = pp.create_transformer(net, b1, b2, "test_trafo_type") + t = create_transformer(net, b1, b2, "test_trafo_type") for c in tap2_data.keys(): assert c in net.trafo.columns @@ -902,11 +909,11 @@ def test_trafo_2_tap_changers(): def test_trafo_2_tap_changers_parameters(): - net = pp.create_empty_network() - b1 = pp.create_bus(net, 110) - b2 = pp.create_bus(net, 20) + net = create_empty_network() + b1 = create_bus(net, 110) + b2 = create_bus(net, 20) - std_type = pp.load_std_type(net, "40 MVA 110/20 kV", "trafo") + std_type = load_std_type(net, "40 MVA 110/20 kV", "trafo") tap2_data = {"tap2_side": "hv", "tap2_neutral": 0, "tap2_max": 10, @@ -915,12 +922,12 @@ def test_trafo_2_tap_changers_parameters(): "tap2_step_degree": 0, "tap2_phase_shifter": False} - pp.create_transformer_from_parameters(net, b1, b2, **std_type) + create_transformer_from_parameters(net, b1, b2, **std_type) for c in tap2_data.keys(): assert c not in net.trafo.columns - t = pp.create_transformer_from_parameters(net, b1, b2, **std_type, **tap2_data) + t = create_transformer_from_parameters(net, b1, b2, **std_type, **tap2_data) for c in tap2_data.keys(): assert c in net.trafo.columns @@ -928,11 +935,11 @@ def test_trafo_2_tap_changers_parameters(): def test_trafos_2_tap_changers_parameters(): - net = pp.create_empty_network() - b1 = pp.create_bus(net, 110) - b2 = pp.create_bus(net, 20) + net = create_empty_network() + b1 = create_bus(net, 110) + b2 = create_bus(net, 20) - std_type = pp.load_std_type(net, "40 MVA 110/20 kV", "trafo") + std_type = load_std_type(net, "40 MVA 110/20 kV", "trafo") tap2_data = {"tap2_side": "hv", "tap2_neutral": 0, "tap2_max": 10, @@ -943,12 +950,12 @@ def test_trafos_2_tap_changers_parameters(): std_type_p = {k: np.array([v, v]) if not isinstance(v, str) else v for k, v in std_type.items()} - pp.create_transformers_from_parameters(net, [b1, b1], [b2, b2], **std_type_p) + create_transformers_from_parameters(net, [b1, b1], [b2, b2], **std_type_p) for c in tap2_data.keys(): assert c not in net.trafo.columns - t = pp.create_transformer_from_parameters(net, b1, b2, **std_type, **tap2_data) + t = create_transformer_from_parameters(net, b1, b2, **std_type, **tap2_data) for c in tap2_data.keys(): assert c in net.trafo.columns @@ -957,11 +964,11 @@ def test_trafos_2_tap_changers_parameters(): def test_create_transformers3w_from_parameters(): # setting params as single value - net = pp.create_empty_network() - b1 = pp.create_bus(net, 15) - b2 = pp.create_bus(net, 0.4) - b3 = pp.create_bus(net, 0.9) - pp.create_transformers3w_from_parameters( + net = create_empty_network() + b1 = create_bus(net, 15) + b2 = create_bus(net, 0.4) + b3 = create_bus(net, 0.9) + create_transformers3w_from_parameters( net, hv_buses=[b1, b1], mv_buses=[b3, b3], @@ -1010,11 +1017,11 @@ def test_create_transformers3w_from_parameters(): assert all(net.trafo3w.test_kwargs == "dummy_string") # setting params as array - net = pp.create_empty_network() - b1 = pp.create_bus(net, 10) - b2 = pp.create_bus(net, 0.4) - b3 = pp.create_bus(net, 0.9) - pp.create_transformers3w_from_parameters( + net = create_empty_network() + b1 = create_bus(net, 10) + b2 = create_bus(net, 0.4) + b3 = create_bus(net, 0.9) + create_transformers3w_from_parameters( net, hv_buses=[b1, b1], mv_buses=[b3, b3], @@ -1064,11 +1071,11 @@ def test_create_transformers3w_from_parameters(): def test_create_transformers3w_raise_errorexcept(): # standard - net = pp.create_empty_network() - b1 = pp.create_bus(net, 15) - b2 = pp.create_bus(net, 0.4) - b3 = pp.create_bus(net, 0.9) - pp.create_transformers3w_from_parameters( + net = create_empty_network() + b1 = create_bus(net, 15) + b2 = create_bus(net, 0.4) + b3 = create_bus(net, 0.9) + create_transformers3w_from_parameters( net, hv_buses=[b1, b1], mv_buses=[b3, b3], @@ -1096,7 +1103,7 @@ def test_create_transformers3w_raise_errorexcept(): UserWarning, match=r"Three winding transformers with indexes \[1\] already exist.", ): - pp.create_transformers3w_from_parameters( + create_transformers3w_from_parameters( net, hv_buses=[b1, b1], mv_buses=[b3, b3], @@ -1120,14 +1127,14 @@ def test_create_transformers3w_raise_errorexcept(): mag0_percent=0.3, index=[2, 1], ) - net = pp.create_empty_network() - b1 = pp.create_bus(net, 15) - b2 = pp.create_bus(net, 0.4) - b3 = pp.create_bus(net, 0.9) + net = create_empty_network() + b1 = create_bus(net, 15) + b2 = create_bus(net, 0.4) + b3 = create_bus(net, 0.9) with pytest.raises( UserWarning, match=r"Transformers trying to attach to non existing buses \{6\}" ): - pp.create_transformers3w_from_parameters( + create_transformers3w_from_parameters( net, hv_buses=[6, b1], mv_buses=[b3, b3], @@ -1154,7 +1161,7 @@ def test_create_transformers3w_raise_errorexcept(): with pytest.raises( UserWarning, match=r"Transformers trying to attach to non existing buses \{3\}" ): - pp.create_transformers3w_from_parameters( + create_transformers3w_from_parameters( net, hv_buses=[b1, b1], mv_buses=[b3, 3], @@ -1181,7 +1188,7 @@ def test_create_transformers3w_raise_errorexcept(): UserWarning, match=r"Transformers trying to attach to non existing buses \{3, 4\}", ): - pp.create_transformers3w_from_parameters( + create_transformers3w_from_parameters( net, hv_buses=[b1, b1], mv_buses=[b3, b3], @@ -1207,16 +1214,16 @@ def test_create_transformers3w_raise_errorexcept(): def test_create_switches(): - net = pp.create_empty_network() + net = create_empty_network() # standard - b1 = pp.create_bus(net, 110) - b2 = pp.create_bus(net, 110) - b3 = pp.create_bus(net, 15) - b4 = pp.create_bus(net, 15) - l1 = pp.create_line(net, b1, b2, length_km=1, std_type="48-AL1/8-ST1A 10.0") - t1 = pp.create_transformer(net, b2, b3, std_type="160 MVA 380/110 kV") - - sw = pp.create_switches( + b1 = create_bus(net, 110) + b2 = create_bus(net, 110) + b3 = create_bus(net, 15) + b4 = create_bus(net, 15) + l1 = create_line(net, b1, b2, length_km=1, std_type="48-AL1/8-ST1A 10.0") + t1 = create_transformer(net, b2, b3, std_type="160 MVA 380/110 kV") + + sw = create_switches( net, buses=[b1, b2, b3], elements=[l1, t1, b4], @@ -1243,17 +1250,17 @@ def test_create_switches(): def test_create_switches_raise_errorexcept(): - net = pp.create_empty_network() + net = create_empty_network() # standard - b1 = pp.create_bus(net, 110) - b2 = pp.create_bus(net, 110) - b3 = pp.create_bus(net, 15) - b4 = pp.create_bus(net, 15) - b5 = pp.create_bus(net, 0.9) - b6 = pp.create_bus(net, 0.4) - l1 = pp.create_line(net, b1, b2, length_km=1, std_type="48-AL1/8-ST1A 10.0") - t1 = pp.create_transformer(net, b2, b3, std_type="160 MVA 380/110 kV") - t3w1 = pp.create_transformer3w_from_parameters( + b1 = create_bus(net, 110) + b2 = create_bus(net, 110) + b3 = create_bus(net, 15) + b4 = create_bus(net, 15) + b5 = create_bus(net, 0.9) + b6 = create_bus(net, 0.4) + l1 = create_line(net, b1, b2, length_km=1, std_type="48-AL1/8-ST1A 10.0") + t1 = create_transformer(net, b2, b3, std_type="160 MVA 380/110 kV") + t3w1 = create_transformer3w_from_parameters( net, hv_bus=b4, mv_bus=b5, @@ -1274,11 +1281,11 @@ def test_create_switches_raise_errorexcept(): i0_percent=0.3, tap_neutral=0.0, ) - sw = pp.create_switch(net, bus=b1, element=l1, et="l", z_ohm=0.0) + sw = create_switch(net, bus=b1, element=l1, et="l", z_ohm=0.0) with pytest.raises( UserWarning, match=r"Switches with indexes \[0\] already exist." ): - pp.create_switches( + create_switches( net, buses=[b1, b2, b3], elements=[l1, t1, b4], @@ -1289,15 +1296,15 @@ def test_create_switches_raise_errorexcept(): with pytest.raises( UserWarning, match=r"Cannot attach to buses \{6\}, they do not exist" ): - pp.create_switches( + create_switches( net, buses=[6, b2, b3], elements=[l1, t1, b4], et=["l", "t", "b"], z_ohm=0.0 ) with pytest.raises(UserWarning, match=r"Line buses do not exist: \[1\]"): - pp.create_switches( + create_switches( net, buses=[b1, b2, b3], elements=[1, t1, b4], et=["l", "t", "b"], z_ohm=0.0 ) - with pytest.raises(UserWarning, match=r"Line not connected \(line element, bus\): \[\(%s, %s\)\]" % (b3, l1)): - pp.create_switches( + with pytest.raises(UserWarning, match=rf"Line not connected \(line element, bus\): \[\({b3}, {l1}\)\]"): + create_switches( net, buses=[b3, b2, b3], elements=[l1, t1, b4], @@ -1305,13 +1312,13 @@ def test_create_switches_raise_errorexcept(): z_ohm=0.0, ) with pytest.raises(UserWarning, match=r"Trafo buses do not exist: \[1\]"): - pp.create_switches( + create_switches( net, buses=[b1, b2, b3], elements=[l1, 1, b4], et=["l", "t", "b"], z_ohm=0.0 ) with pytest.raises( UserWarning, match=r"Trafo not connected \(trafo element, bus\): \[\(%s, %s\)\]" % (b1, t1) ): - pp.create_switches( + create_switches( net, buses=[b1, b1, b3], elements=[l1, t1, b4], @@ -1321,11 +1328,11 @@ def test_create_switches_raise_errorexcept(): with pytest.raises( UserWarning, match=r"Cannot attach to elements \{6\}, they do not exist" ): - pp.create_switches( + create_switches( net, buses=[b1, b2, b3], elements=[l1, t1, 6], et=["l", "t", "b"], z_ohm=0.0 ) with pytest.raises(UserWarning, match=r"Trafo3w buses do not exist: \[1\]"): - pp.create_switches( + create_switches( net, buses=[b1, b2, b3], elements=[l1, t1, 1], @@ -1335,7 +1342,7 @@ def test_create_switches_raise_errorexcept(): with pytest.raises( UserWarning, match=r"Trafo3w not connected \(trafo3w element, bus\): \[\(%s, %s\)\]" % (b3, t3w1) ): - pp.create_switches( + create_switches( net, buses=[b1, b2, b3], elements=[l1, t1, t3w1], @@ -1345,7 +1352,7 @@ def test_create_switches_raise_errorexcept(): with pytest.raises( UserWarning, match=r"Cannot attach to elements \{12398\}, they do not exist" ): - pp.create_switches( + create_switches( net, buses=[b1, b2], elements=[b3, 12398], @@ -1355,7 +1362,7 @@ def test_create_switches_raise_errorexcept(): with pytest.raises( UserWarning, match=r"Cannot attach to buses \{13098\}, they do not exist" ): - pp.create_switches( + create_switches( net, buses=[b1, 13098], elements=[b2, b3], @@ -1365,12 +1372,12 @@ def test_create_switches_raise_errorexcept(): def test_create_loads(): - net = pp.create_empty_network() + net = create_empty_network() # standard - b1 = pp.create_bus(net, 110) - b2 = pp.create_bus(net, 110) - b3 = pp.create_bus(net, 110) - pp.create_loads( + b1 = create_bus(net, 110) + b2 = create_bus(net, 110) + b3 = create_bus(net, 110) + create_loads( net, buses=[b1, b2, b3], p_mw=[0, 0, 1], @@ -1407,16 +1414,16 @@ def test_create_loads(): def test_create_loads_raise_errorexcept(): - net = pp.create_empty_network() + net = create_empty_network() # standard - b1 = pp.create_bus(net, 110) - b2 = pp.create_bus(net, 110) - b3 = pp.create_bus(net, 110) + b1 = create_bus(net, 110) + b2 = create_bus(net, 110) + b3 = create_bus(net, 110) with pytest.raises( UserWarning, match=r"Cannot attach to buses \{3, 4, 5\}, they do not exist" ): - pp.create_loads( + create_loads( net, buses=[3, 4, 5], p_mw=[0, 0, 1], @@ -1427,7 +1434,7 @@ def test_create_loads_raise_errorexcept(): max_q_mvar=0.2, min_q_mvar=[0, 0.1, 0], ) - l = pp.create_loads( + l = create_loads( net, buses=[b1, b2, b3], p_mw=[0, 0, 1], @@ -1441,7 +1448,7 @@ def test_create_loads_raise_errorexcept(): with pytest.raises( UserWarning, match=r"Loads with indexes \[0 1 2\] already exist" ): - pp.create_loads( + create_loads( net, buses=[b1, b2, b3], p_mw=[0, 0, 1], @@ -1456,20 +1463,20 @@ def test_create_loads_raise_errorexcept(): def test_create_storages(): - net = pp.create_empty_network() - b1 = pp.create_bus(net, 110) - b2 = pp.create_bus(net, 110) - b3 = pp.create_bus(net, 110) + net = create_empty_network() + b1 = create_bus(net, 110) + b2 = create_bus(net, 110) + b3 = create_bus(net, 110) net_bulk = deepcopy(net) - pp.create_storage(net, b1, 0, 3, 0.5, controllable=True, max_p_mw=0.2, min_p_mw=0, + create_storage(net, b1, 0, 3, 0.5, controllable=True, max_p_mw=0.2, min_p_mw=0, max_q_mvar=0.2, min_q_mvar=0, test_kwargs="dummy_string_1") - pp.create_storage(net, b2, 0, 5, 0.5, controllable=False, max_p_mw=0.2, min_p_mw=0.1, + create_storage(net, b2, 0, 5, 0.5, controllable=False, max_p_mw=0.2, min_p_mw=0.1, max_q_mvar=0.2, min_q_mvar=0.1, test_kwargs="dummy_string_2") - pp.create_storage(net, b3, 1, 7, 0.5, max_p_mw=0.2, min_p_mw=0, + create_storage(net, b3, 1, 7, 0.5, max_p_mw=0.2, min_p_mw=0, max_q_mvar=0.2, min_q_mvar=0, test_kwargs="dummy_string_3") - pp.create_storages( + create_storages( net_bulk, buses=[b1, b2, b3], p_mw=[0, 0, 1], @@ -1509,22 +1516,22 @@ def test_create_storages(): ) for col in ["name", "type"]: net.storage.loc[net.storage[col].isnull(), col] = "" - assert pp.nets_equal(net, net_bulk) + assert nets_equal(net, net_bulk) def test_create_wards(): - net = pp.create_empty_network() - b1 = pp.create_bus(net, 110) - b2 = pp.create_bus(net, 110) - b3 = pp.create_bus(net, 110) + net = create_empty_network() + b1 = create_bus(net, 110) + b2 = create_bus(net, 110) + b3 = create_bus(net, 110) net_bulk = deepcopy(net) vals = np.c_[[b1, b2, b3], np.reshape(np.arange(12), (3, 4)), ["asd", None, "123"], [True, False, False]] - pp.create_ward(net, *vals[0, :]) - pp.create_ward(net, *vals[1, :]) - pp.create_ward(net, *vals[2, :]) + create_ward(net, *vals[0, :]) + create_ward(net, *vals[1, :]) + create_ward(net, *vals[2, :]) - pp.create_wards(net_bulk, vals[:, 0], vals[:, 1], vals[:, 2], vals[:, 3], vals[:, 4], + create_wards(net_bulk, vals[:, 0], vals[:, 1], vals[:, 2], vals[:, 3], vals[:, 4], vals[:, 5], vals[:, 6]) assert net.ward.bus.at[0] == b1 @@ -1548,16 +1555,16 @@ def test_create_wards(): assert net.ward.in_service.at[0] assert not net.ward.in_service.at[1] assert not net.ward.in_service.at[2] - assert pp.nets_equal(net, net_bulk) + assert nets_equal(net, net_bulk) def test_create_sgens(): - net = pp.create_empty_network() + net = create_empty_network() # standard - b1 = pp.create_bus(net, 110) - b2 = pp.create_bus(net, 110) - b3 = pp.create_bus(net, 110) - pp.create_sgens( + b1 = create_bus(net, 110) + b2 = create_bus(net, 110) + b3 = create_bus(net, 110) + create_sgens( net, buses=[b1, b2, b3], p_mw=[0, 0, 1], @@ -1597,16 +1604,16 @@ def test_create_sgens(): def test_create_sgens_raise_errorexcept(): - net = pp.create_empty_network() + net = create_empty_network() # standard - b1 = pp.create_bus(net, 110) - b2 = pp.create_bus(net, 110) - b3 = pp.create_bus(net, 110) + b1 = create_bus(net, 110) + b2 = create_bus(net, 110) + b3 = create_bus(net, 110) with pytest.raises( UserWarning, match=r"Cannot attach to buses \{3, 4, 5\}, they do not exist" ): - pp.create_sgens( + create_sgens( net, buses=[3, 4, 5], p_mw=[0, 0, 1], @@ -1620,7 +1627,7 @@ def test_create_sgens_raise_errorexcept(): rx=0.4, current_source=True, ) - sg = pp.create_sgens( + sg = create_sgens( net, buses=[b1, b2, b3], p_mw=[0, 0, 1], @@ -1637,7 +1644,7 @@ def test_create_sgens_raise_errorexcept(): with pytest.raises( UserWarning, match=r"Sgens with indexes \[0 1 2\] already exist" ): - pp.create_sgens( + create_sgens( net, buses=[b1, b2, b3], p_mw=[0, 0, 1], @@ -1655,12 +1662,12 @@ def test_create_sgens_raise_errorexcept(): def test_create_gens(): - net = pp.create_empty_network() + net = create_empty_network() # standard - b1 = pp.create_bus(net, 110) - b2 = pp.create_bus(net, 110) - b3 = pp.create_bus(net, 110) - pp.create_gens( + b1 = create_bus(net, 110) + b2 = create_bus(net, 110) + b3 = create_bus(net, 110) + create_gens( net, buses=[b1, b2, b3], p_mw=[0, 0, 1], @@ -1702,16 +1709,16 @@ def test_create_gens(): def test_create_gens_raise_errorexcept(): - net = pp.create_empty_network() + net = create_empty_network() # standard - b1 = pp.create_bus(net, 110) - b2 = pp.create_bus(net, 110) - b3 = pp.create_bus(net, 110) + b1 = create_bus(net, 110) + b2 = create_bus(net, 110) + b3 = create_bus(net, 110) with pytest.raises( UserWarning, match=r"Cannot attach to buses \{3, 4, 5\}, they do not exist" ): - pp.create_gens( + create_gens( net, buses=[3, 4, 5], p_mw=[0, 0, 1], @@ -1728,7 +1735,7 @@ def test_create_gens_raise_errorexcept(): rdss_pu=0.1, cos_phi=1.0, ) - g = pp.create_gens( + g = create_gens( net, buses=[b1, b2, b3], p_mw=[0, 0, 1], @@ -1747,7 +1754,7 @@ def test_create_gens_raise_errorexcept(): ) with pytest.raises(UserWarning, match=r"Gens with indexes \[0 1 2\] already exist"): - pp.create_gens( + create_gens( net, buses=[b1, b2, b3], p_mw=[0, 0, 1], diff --git a/pandapower/test/api/test_diagnostic.py b/pandapower/test/api/test_diagnostic.py index 19cc69a1d..453e8c1ef 100644 --- a/pandapower/test/api/test_diagnostic.py +++ b/pandapower/test/api/test_diagnostic.py @@ -5,65 +5,75 @@ import copy + import pytest + pytestmark = pytest.mark.filterwarnings("ignore") import numpy as np import pytest -import pandapower as pp -import pandapower.networks as nw +from pandapower import diagnostic, invalid_values, no_ext_grid, create_ext_grid, \ + multiple_voltage_controlling_elements_per_bus, parallel_switches, create_switch, overload, \ + wrong_switch_configuration, different_voltage_levels_connected, implausible_impedance_values, \ + nominal_voltages_dont_match, wrong_reference_system, drop_trafos, disconnected_elements, change_std_type, \ + deviation_from_std_type, numba_comparison, missing_bus_indices +from pandapower.networks import example_multivoltage, example_simple from pandapower.diagnostic_reports import DiagnosticReports try: import numba + numba_installed = True except ImportError: numba_installed = False + @pytest.fixture(scope='function') def diag_errors(): return {} + @pytest.fixture(scope='function') def diag_params(): return { - "overload_scaling_factor": 0.001, - "min_r_ohm":0.001, - "min_x_ohm":0.001, - "min_r_pu":1e-05, - "min_x_pu":1e-05, - "nom_voltage_tolerance": 0.3, - "numba_tolerance": 1e-8} + "overload_scaling_factor": 0.001, + "min_r_ohm": 0.001, + "min_x_ohm": 0.001, + "min_r_pu": 1e-05, + "min_x_pu": 1e-05, + "nom_voltage_tolerance": 0.3, + "numba_tolerance": 1e-8} + @pytest.fixture(scope='module') def test_net(): - net = nw.example_multivoltage() + net = example_multivoltage() return net + @pytest.fixture(scope='module') def report_methods(): return { - "missing_bus_indices": "diag_report.report_missing_bus_indices()", - "disconnected_elements": "diag_report.report_disconnected_elements()", - "different_voltage_levels_connected": "diag_report.report_different_voltage_levels_connected()", - "impedance_values_close_to_zero": "diag_report.report_impedance_values_close_to_zero()", - "nominal_voltages_dont_match": "diag_report.report_nominal_voltages_dont_match()", - "invalid_values": "diag_report.report_invalid_values()", - "overload": "diag_report.report_overload()", - "multiple_voltage_controlling_elements_per_bus" : "diag_report.report_multiple_voltage_controlling_elements_per_bus()", - "wrong_switch_configuration": "diag_report.report_wrong_switch_configuration()", - "no_ext_grid": "diag_report.report_no_ext_grid()", - "wrong_reference_system": "diag_report.report_wrong_reference_system()", - "deviation_from_std_type": "diag_report.report_deviation_from_std_type()", - "numba_comparison": "diag_report.report_numba_comparison()", - "parallel_switches": "diag_report.report_parallel_switches()"} - + "missing_bus_indices": "diag_report.report_missing_bus_indices()", + "disconnected_elements": "diag_report.report_disconnected_elements()", + "different_voltage_levels_connected": "diag_report.report_different_voltage_levels_connected()", + "impedance_values_close_to_zero": "diag_report.report_impedance_values_close_to_zero()", + "nominal_voltages_dont_match": "diag_report.report_nominal_voltages_dont_match()", + "invalid_values": "diag_report.report_invalid_values()", + "overload": "diag_report.report_overload()", + "multiple_voltage_controlling_elements_per_bus": "diag_report.report_multiple_voltage_controlling_elements_per_bus()", + "wrong_switch_configuration": "diag_report.report_wrong_switch_configuration()", + "no_ext_grid": "diag_report.report_no_ext_grid()", + "wrong_reference_system": "diag_report.report_wrong_reference_system()", + "deviation_from_std_type": "diag_report.report_deviation_from_std_type()", + "numba_comparison": "diag_report.report_numba_comparison()", + "parallel_switches": "diag_report.report_parallel_switches()"} def test_no_issues(diag_params, diag_errors, report_methods): - net = nw.example_simple() - diag_results = pp.diagnostic(net, report_style=None) + net = example_simple() + diag_results = diagnostic(net, report_style=None) assert diag_results == {} for bool_value in [True, False]: for check_function in report_methods.keys(): @@ -99,28 +109,28 @@ def test_greater_zero(self, test_net, diag_params, diag_errors, report_methods): net.trafo3w.loc[0, 'vn_lv_kv'] = False net.ext_grid.loc[0, 'vm_pu'] = True - check_result = pp.invalid_values(net) + check_result = invalid_values(net) if check_result: diag_results = {check_function: check_result} else: diag_results = {} assert diag_results[check_function] == \ - {'bus': [(42, 'vn_kv', '-1', '>0')], - 'ext_grid': [(0, 'vm_pu', True, '>0')], - 'line': [(7, 'length_km', -1.0, '>0'), - (8, 'max_i_ka', 0.0, '>0')], - 'trafo': [(0, 'sn_mva', 'nan', '>0'), - (0, 'vn_hv_kv', -1.5, '>0'), - (0, 'vn_lv_kv', False, '>0'), - (0, 'vk_percent', 0.0, '>0')], - 'trafo3w': [(0, 'sn_mv_mva', 'a', '>0'), - (0, 'vn_hv_kv', -1.5, '>0'), - (0, 'vn_mv_kv', -1.5, '>0'), - (0, 'vn_lv_kv', False, '>0'), - (0, 'vk_mv_percent', 'nan', '>0'), - (0, 'vk_lv_percent', 0.0, '>0'), - (0, 'vk_mv_percent', 'nan', '<15')]} + {'bus': [(42, 'vn_kv', '-1', '>0')], + 'ext_grid': [(0, 'vm_pu', True, '>0')], + 'line': [(7, 'length_km', -1.0, '>0'), + (8, 'max_i_ka', 0.0, '>0')], + 'trafo': [(0, 'sn_mva', 'nan', '>0'), + (0, 'vn_hv_kv', -1.5, '>0'), + (0, 'vn_lv_kv', False, '>0'), + (0, 'vk_percent', 0.0, '>0')], + 'trafo3w': [(0, 'sn_mv_mva', 'a', '>0'), + (0, 'vn_hv_kv', -1.5, '>0'), + (0, 'vn_mv_kv', -1.5, '>0'), + (0, 'vn_lv_kv', False, '>0'), + (0, 'vk_mv_percent', 'nan', '>0'), + (0, 'vk_lv_percent', 0.0, '>0'), + (0, 'vk_mv_percent', 'nan', '<15')]} for bool_value in [True, False]: diag_report = DiagnosticReports(net, diag_results, diag_errors, diag_params, compact_report=bool_value) @@ -132,7 +142,6 @@ def test_greater_zero(self, test_net, diag_params, diag_errors, report_methods): report_check = False assert report_check - def test_greater_equal_zero(self, test_net, diag_params, diag_errors, report_methods): net = copy.deepcopy(test_net) check_function = 'invalid_values' @@ -154,28 +163,28 @@ def test_greater_equal_zero(self, test_net, diag_params, diag_errors, report_met net.gen.loc[0, 'scaling'] = None net.sgen.loc[0, 'scaling'] = False - check_result = pp.invalid_values(net) + check_result = invalid_values(net) if check_result: diag_results = {check_function: check_result} else: diag_results = {} assert diag_results[check_function] == \ - {'line': [(7, 'r_ohm_per_km', -1.0, '>=0'), - (8, 'x_ohm_per_km', 'nan', '>=0'), - (8, 'c_nf_per_km', '0', '>=0')], - 'trafo': [(0, 'vkr_percent', '-1', '>=0'), - (0, 'vkr_percent', '-1', '<15'), - (0, 'pfe_kw', -1.5, '>=0'), - (0, 'i0_percent', -0.001, '>=0')], - 'trafo3w': [(0, 'vkr_hv_percent', True, '>=0'), - (0, 'vkr_mv_percent', False, '>=0'), - (0, 'vkr_hv_percent', True, '<15'), - (0, 'vkr_mv_percent', False, '<15'), - (0, 'pfe_kw', '2', '>=0')], - 'gen': [(0, 'scaling', 'nan', '>=0')], - 'load': [(0, 'scaling', -0.1, '>=0'), - (3, 'scaling', '1', '>=0')], - 'sgen': [(0, 'scaling', False, '>=0')]} + {'line': [(7, 'r_ohm_per_km', -1.0, '>=0'), + (8, 'x_ohm_per_km', 'nan', '>=0'), + (8, 'c_nf_per_km', '0', '>=0')], + 'trafo': [(0, 'vkr_percent', '-1', '>=0'), + (0, 'vkr_percent', '-1', '<15'), + (0, 'pfe_kw', -1.5, '>=0'), + (0, 'i0_percent', -0.001, '>=0')], + 'trafo3w': [(0, 'vkr_hv_percent', True, '>=0'), + (0, 'vkr_mv_percent', False, '>=0'), + (0, 'vkr_hv_percent', True, '<15'), + (0, 'vkr_mv_percent', False, '<15'), + (0, 'pfe_kw', '2', '>=0')], + 'gen': [(0, 'scaling', 'nan', '>=0')], + 'load': [(0, 'scaling', -0.1, '>=0'), + (3, 'scaling', '1', '>=0')], + 'sgen': [(0, 'scaling', False, '>=0')]} for bool_value in [True, False]: diag_report = DiagnosticReports(net, diag_results, diag_errors, diag_params, compact_report=bool_value) @@ -186,15 +195,16 @@ def test_greater_equal_zero(self, test_net, diag_params, diag_errors, report_met except: report_check = False assert report_check -# -# -# #def test_smaller_zero(self, net): # check_smaller_zero currently not in use -# #pass -# -# #def test_smaller_equal_zero(self, net): # check_smaller_equal_zero currently not in use -# #pass -# -# + + # + # + # #def test_smaller_zero(self, net): # check_smaller_zero currently not in use + # #pass + # + # #def test_smaller_equal_zero(self, net): # check_smaller_equal_zero currently not in use + # #pass + # + # def test_boolean(self, test_net, diag_params, diag_errors, report_methods): net = copy.deepcopy(test_net) check_function = 'invalid_values' @@ -216,24 +226,24 @@ def test_boolean(self, test_net, diag_params, diag_errors, report_methods): net.switch.loc[4, 'closed'] = None net.switch.loc[5, 'closed'] = '10' - check_result = pp.invalid_values(net) + check_result = invalid_values(net) if check_result: diag_results = {check_function: check_result} else: diag_results = {} assert diag_results[check_function] == \ - {'bus': [(0, 'in_service', 'no', 'boolean')], - 'gen': [(0, 'in_service', '1', 'boolean')], - 'line': [(0, 'in_service', '-1', 'boolean')], - 'load': [(0, 'in_service', '10', 'boolean')], - 'sgen': [(2, 'in_service', '0', 'boolean'), - (3, 'in_service', '0.0', 'boolean')], - 'switch': [(1, 'closed', 'False', 'boolean'), - (3, 'closed', 'False', 'boolean'), - (4, 'closed', 'None', 'boolean'), - (5, 'closed', '10', 'boolean')], - 'trafo': [(0, 'in_service', 'True', 'boolean')], - 'trafo3w': [(0, 'in_service', 'nan', 'boolean')]} + {'bus': [(0, 'in_service', 'no', 'boolean')], + 'gen': [(0, 'in_service', '1', 'boolean')], + 'line': [(0, 'in_service', '-1', 'boolean')], + 'load': [(0, 'in_service', '10', 'boolean')], + 'sgen': [(2, 'in_service', '0', 'boolean'), + (3, 'in_service', '0.0', 'boolean')], + 'switch': [(1, 'closed', 'False', 'boolean'), + (3, 'closed', 'False', 'boolean'), + (4, 'closed', 'None', 'boolean'), + (5, 'closed', '10', 'boolean')], + 'trafo': [(0, 'in_service', 'True', 'boolean')], + 'trafo3w': [(0, 'in_service', 'nan', 'boolean')]} for bool_value in [True, False]: diag_report = DiagnosticReports(net, diag_results, diag_errors, diag_params, compact_report=bool_value) @@ -245,7 +255,6 @@ def test_boolean(self, test_net, diag_params, diag_errors, report_methods): report_check = False assert report_check - def test_pos_int(self, test_net, diag_params, diag_errors, report_methods): net = copy.deepcopy(test_net) check_function = 'invalid_values' @@ -265,23 +274,23 @@ def test_pos_int(self, test_net, diag_params, diag_errors, report_methods): net.switch.loc[0, 'bus'] = None net.switch.loc[0, 'element'] = -1.5 - check_result = pp.invalid_values(net) + check_result = invalid_values(net) if check_result: diag_results = {check_function: check_result} else: diag_results = {} assert diag_results[check_function] == \ - {'ext_grid': [(0, 'bus', -2.5, 'positive_integer')], - 'gen': [(0, 'bus', 'nan', 'positive_integer')], - 'line': [(8, 'to_bus', '2', 'positive_integer')], - 'load': [(0, 'bus', True, 'positive_integer')], - 'sgen': [(0, 'bus', 1.5, 'positive_integer')], - 'switch': [(0, 'bus', 'nan', 'positive_integer'), - (0, 'element', -1.5, 'positive_integer')], - 'trafo': [(0, 'hv_bus', False, 'positive_integer'), - (0, 'lv_bus', 'nan', 'positive_integer')], - 'trafo3w': [(0, 'hv_bus', False, 'positive_integer'), - (0, 'mv_bus', 0.5, 'positive_integer')]} + {'ext_grid': [(0, 'bus', -2.5, 'positive_integer')], + 'gen': [(0, 'bus', 'nan', 'positive_integer')], + 'line': [(8, 'to_bus', '2', 'positive_integer')], + 'load': [(0, 'bus', True, 'positive_integer')], + 'sgen': [(0, 'bus', 1.5, 'positive_integer')], + 'switch': [(0, 'bus', 'nan', 'positive_integer'), + (0, 'element', -1.5, 'positive_integer')], + 'trafo': [(0, 'hv_bus', False, 'positive_integer'), + (0, 'lv_bus', 'nan', 'positive_integer')], + 'trafo3w': [(0, 'hv_bus', False, 'positive_integer'), + (0, 'mv_bus', 0.5, 'positive_integer')]} for bool_value in [True, False]: diag_report = DiagnosticReports(net, diag_results, diag_errors, diag_params, compact_report=bool_value) @@ -293,7 +302,6 @@ def test_pos_int(self, test_net, diag_params, diag_errors, report_methods): report_check = False assert report_check - def test_number(self, test_net, diag_params, diag_errors, report_methods): net = copy.deepcopy(test_net) check_function = 'invalid_values' @@ -306,15 +314,15 @@ def test_number(self, test_net, diag_params, diag_errors, report_methods): net.sgen.loc[1, 'q_mvar'] = np.nan net.ext_grid.loc[0, 'va_degree'] = 13.55 - check_result = pp.invalid_values(net) + check_result = invalid_values(net) if check_result: diag_results = {check_function: check_result} else: diag_results = {} assert diag_results[check_function] == \ - {'gen': [(0, 'p_mw', False, 'number')], - 'load': [(0, 'p_mw', '1000', 'number'), (1, 'q_mvar', 'nan', 'number')], - 'sgen': [(1, 'q_mvar', 'nan', 'number')]} + {'gen': [(0, 'p_mw', False, 'number')], + 'load': [(0, 'p_mw', '1000', 'number'), (1, 'q_mvar', 'nan', 'number')], + 'sgen': [(1, 'q_mvar', 'nan', 'number')]} for bool_value in [True, False]: diag_report = DiagnosticReports(net, diag_results, diag_errors, diag_params, compact_report=bool_value) @@ -326,7 +334,6 @@ def test_number(self, test_net, diag_params, diag_errors, report_methods): report_check = False assert report_check - def test_between_zero_and_one(self, test_net, diag_params, diag_errors, report_methods): net = copy.deepcopy(test_net) check_function = 'invalid_values' @@ -334,13 +341,13 @@ def test_between_zero_and_one(self, test_net, diag_params, diag_errors, report_m report_methods = copy.deepcopy(report_methods) net.line.loc[0, 'df'] = 1.5 - check_result = pp.invalid_values(net) + check_result = invalid_values(net) if check_result: diag_results = {check_function: check_result} else: diag_results = {} assert diag_results[check_function] == \ - {'line': [(0, 'df', 1.5, '0 0: @@ -82,17 +78,17 @@ def assert_postgresql_roundtrip(net_in, **kwargs): convert_geodata_to_geojson(net) include_results = kwargs.pop("include_results", False) if not include_results: - pp.reset_results(net) + reset_results(net) else: - pp.runpp(net) + runpp(net) connection_data, schema = get_postgresql_connection_data() - grid_id = pp.to_postgresql(net, schema=schema, include_results=include_results, **connection_data, **kwargs) + grid_id = to_postgresql(net, schema=schema, include_results=include_results, **connection_data, **kwargs) - net_out = pp.from_postgresql(grid_id=grid_id, schema=schema, **connection_data, **kwargs) + net_out = from_postgresql(grid_id=grid_id, schema=schema, **connection_data, **kwargs) if not include_results: - pp.runpp(net) - pp.runpp(net_out) + runpp(net) + runpp(net_out) assert_res_equal(net, net_out) @@ -111,7 +107,7 @@ def assert_postgresql_roundtrip(net_in, **kwargs): pdt.assert_frame_equal(table_in, table_out, check_dtype=False) # clean-up - pp.delete_postgresql_net(grid_id=grid_id, schema=schema, **connection_data) + delete_postgresql_net(grid_id=grid_id, schema=schema, **connection_data) POSTGRESQL_AVAILABLE = PSYCOPG2_INSTALLED and postgresql_listening(**get_postgresql_connection_data()[0]) @@ -127,13 +123,13 @@ def test_postgresql(net_in): @pytest.mark.skipif(not POSTGRESQL_AVAILABLE, reason="testing happens on GitHub Actions where we create a temporary instance of PostgreSQL") def test_unique(): - net = pp.networks.case9() + net = case9() connection_data, schema = get_postgresql_connection_data() - grid_id = pp.to_postgresql(net, **connection_data, schema=schema) + grid_id = to_postgresql(net, **connection_data, schema=schema) with pytest.raises(UserWarning): - pp.to_postgresql(net, **connection_data, schema=schema, grid_id=grid_id) + to_postgresql(net, **connection_data, schema=schema, grid_id=grid_id) # clean-up: - pp.delete_postgresql_net(grid_id=grid_id, schema=schema, **connection_data) + delete_postgresql_net(grid_id=grid_id, schema=schema, **connection_data) @pytest.mark.skipif(not POSTGRESQL_AVAILABLE, @@ -142,14 +138,14 @@ def test_delete(): connection_data, schema = get_postgresql_connection_data() # cannot delete if the net does not exist with pytest.raises(UserWarning): - pp.delete_postgresql_net(grid_id=int(time.time()), schema=schema, **connection_data) + delete_postgresql_net(grid_id=int(time.time()), schema=schema, **connection_data) # check that net is deleted - net = pp.networks.case9() - grid_id = pp.to_postgresql(net, **connection_data, schema=schema) - pp.delete_postgresql_net(grid_id=grid_id, schema=schema, **connection_data) + net = case9() + grid_id = to_postgresql(net, **connection_data, schema=schema) + delete_postgresql_net(grid_id=grid_id, schema=schema, **connection_data) with pytest.raises(UserWarning): - _ = pp.from_postgresql(grid_id=grid_id, schema=schema, **connection_data) + _ = from_postgresql(grid_id=grid_id, schema=schema, **connection_data) # check that it is not only deleted from the grid catalogue conn = psycopg2.connect(**connection_data) diff --git a/pandapower/test/api/test_std_types.py b/pandapower/test/api/test_std_types.py index aedcceb6a..cc7548beb 100644 --- a/pandapower/test/api/test_std_types.py +++ b/pandapower/test/api/test_std_types.py @@ -6,12 +6,14 @@ import pytest -import pandapower as pp -import pandapower.networks as nw +from pandapower.networks import simple_mv_open_ring_net +from pandapower import create_empty_network, create_std_type, load_std_type, create_std_types, \ + find_std_type_by_parameter, find_std_type_alternative, create_bus, create_line, change_std_type, \ + create_line_from_parameters, parameter_from_std_type, add_temperature_coefficient, copy_std_types, std_type_exists def test_create_and_load_std_type_line(): - net = pp.create_empty_network() + net = create_empty_network() c = 40 r = 0.01 x = 0.02 @@ -20,29 +22,29 @@ def test_create_and_load_std_type_line(): typdata = {} with pytest.raises(UserWarning): - pp.create_std_type(net, name=name, data=typdata, element="line") + create_std_type(net, name=name, data=typdata, element="line") typdata = {"c_nf_per_km": c} with pytest.raises(UserWarning): - pp.create_std_type(net, name=name, data=typdata, element="line") + create_std_type(net, name=name, data=typdata, element="line") typdata = {"c_nf_per_km": c, "r_ohm_per_km": r} with pytest.raises(UserWarning): - pp.create_std_type(net, name=name, data=typdata, element="line") + create_std_type(net, name=name, data=typdata, element="line") typdata = {"c_nf_per_km": c, "r_ohm_per_km": r, "x_ohm_per_km": x} with pytest.raises(UserWarning): - pp.create_std_type(net, name=name, data=typdata, element="line") + create_std_type(net, name=name, data=typdata, element="line") typdata = {"c_nf_per_km": c, "r_ohm_per_km": r, "x_ohm_per_km": x, "max_i_ka": i} - pp.create_std_type(net, name=name, data=typdata, element="line") + create_std_type(net, name=name, data=typdata, element="line") assert net.std_types["line"][name] == typdata - loaded_type = pp.load_std_type(net, name) + loaded_type = load_std_type(net, name) assert loaded_type == typdata def test_create_std_types_line(): - net = pp.create_empty_network() + net = create_empty_network() c = 40 r = 0.01 x = 0.02 @@ -51,13 +53,13 @@ def test_create_std_types_line(): typdata = {"c_nf_per_km": c, "r_ohm_per_km": r, "x_ohm_per_km": x, "max_i_ka": i} typdatas = {"typ1": typdata, "typ2": typdata} - pp.create_std_types(net, data=typdatas, element="line") + create_std_types(net, data=typdatas, element="line") assert net.std_types["line"]["typ1"] == typdata assert net.std_types["line"]["typ1"] == typdata def test_create_std_types_from_net_line(): - net1 = pp.create_empty_network() - net2 = pp.create_empty_network() + net1 = create_empty_network() + net2 = create_empty_network() c = 40 r = 0.01 @@ -66,12 +68,12 @@ def test_create_std_types_from_net_line(): typdata = {"c_nf_per_km": c, "r_ohm_per_km": r, "x_ohm_per_km": x, "max_i_ka": i, "additional": 8} - pp.create_std_type(net1, typdata, "test_copy") - pp.copy_std_types(net2, net1, element="line") - assert pp.std_type_exists(net2, "test_copy") + create_std_type(net1, typdata, "test_copy") + copy_std_types(net2, net1, element="line") + assert std_type_exists(net2, "test_copy") def test_create_and_load_std_type_trafo(): - net = pp.create_empty_network() + net = create_empty_network() sn_mva = 40 vn_hv_kv = 110 vn_lv_kv = 20 @@ -84,45 +86,45 @@ def test_create_and_load_std_type_trafo(): typdata = {"sn_mva": sn_mva} with pytest.raises(UserWarning): - pp.create_std_type(net, name=name, data=typdata, element="trafo") + create_std_type(net, name=name, data=typdata, element="trafo") typdata = {"sn_mva": sn_mva, "vn_hv_kv": vn_hv_kv} with pytest.raises(UserWarning): - pp.create_std_type(net, name=name, data=typdata, element="trafo") + create_std_type(net, name=name, data=typdata, element="trafo") typdata = {"sn_mva": sn_mva, "vn_hv_kv": vn_hv_kv, "vn_lv_kv": vn_lv_kv} with pytest.raises(UserWarning): - pp.create_std_type(net, name=name, data=typdata, element="trafo") + create_std_type(net, name=name, data=typdata, element="trafo") typdata = {"sn_mva": sn_mva, "vn_hv_kv": vn_hv_kv, "vn_lv_kv": vn_lv_kv, "vk_percent": vk_percent} with pytest.raises(UserWarning): - pp.create_std_type(net, name=name, data=typdata, element="trafo") + create_std_type(net, name=name, data=typdata, element="trafo") typdata = {"sn_mva": sn_mva, "vn_hv_kv": vn_hv_kv, "vn_lv_kv": vn_lv_kv, "vk_percent": vk_percent, "vkr_percent": vkr_percent} with pytest.raises(UserWarning): - pp.create_std_type(net, name=name, data=typdata, element="trafo") + create_std_type(net, name=name, data=typdata, element="trafo") typdata = {"sn_mva": sn_mva, "vn_hv_kv": vn_hv_kv, "vn_lv_kv": vn_lv_kv, "vk_percent": vk_percent, "vkr_percent": vkr_percent, "pfe_kw": pfe_kw} with pytest.raises(UserWarning): - pp.create_std_type(net, name=name, data=typdata, element="trafo") + create_std_type(net, name=name, data=typdata, element="trafo") typdata = {"sn_mva": sn_mva, "vn_hv_kv": vn_hv_kv, "vn_lv_kv": vn_lv_kv, "vk_percent": vk_percent, "vkr_percent": vkr_percent, "pfe_kw": pfe_kw, "i0_percent": i0_percent} with pytest.raises(UserWarning): - pp.create_std_type(net, name=name, data=typdata, element="trafo") + create_std_type(net, name=name, data=typdata, element="trafo") typdata = {"sn_mva": sn_mva, "vn_hv_kv": vn_hv_kv, "vn_lv_kv": vn_lv_kv, "vk_percent": vk_percent, "vkr_percent": vkr_percent, "pfe_kw": pfe_kw, "i0_percent": i0_percent, "shift_degree": shift_degree} - pp.create_std_type(net, name=name, data=typdata, element="trafo") + create_std_type(net, name=name, data=typdata, element="trafo") assert net.std_types["trafo"][name] == typdata - loaded_type = pp.load_std_type(net, name, element="trafo") + loaded_type = load_std_type(net, name, element="trafo") assert loaded_type == typdata def test_create_and_load_std_type_trafo3w(): - net = pp.create_empty_network() + net = create_empty_network() sn_hv_mva = 40; sn_mv_mva = 20; sn_lv_mva = 20 vn_hv_kv = 110; vn_mv_kv = 50; vn_lv_kv = 20 vk_hv_percent = 5.; vk_mv_percent = 5.; vk_lv_percent = 5. @@ -134,52 +136,52 @@ def test_create_and_load_std_type_trafo3w(): typdata = {"sn_hv_mva": sn_hv_mva} with pytest.raises(UserWarning): - pp.create_std_type(net, name=name, data=typdata, element="trafo3w") + create_std_type(net, name=name, data=typdata, element="trafo3w") typdata = {"sn_mv_mva": sn_mv_mva, "vn_hv_kv": vn_hv_kv} with pytest.raises(UserWarning): - pp.create_std_type(net, name=name, data=typdata, element="trafo3w") + create_std_type(net, name=name, data=typdata, element="trafo3w") typdata = {"sn_lv_mva": sn_lv_mva, "vn_mv_kv": vn_mv_kv, "vn_lv_kv": vn_lv_kv} with pytest.raises(UserWarning): - pp.create_std_type(net, name=name, data=typdata, element="trafo3w") + create_std_type(net, name=name, data=typdata, element="trafo3w") typdata = {"sn_mv_mva": sn_mv_mva, "vn_hv_kv": vn_hv_kv, "vn_lv_kv": vn_lv_kv, "vk_hv_percent": vk_hv_percent} with pytest.raises(UserWarning): - pp.create_std_type(net, name=name, data=typdata, element="trafo3w") + create_std_type(net, name=name, data=typdata, element="trafo3w") typdata = {"sn_hv_mva": sn_hv_mva, "vn_hv_kv": vn_hv_kv, "vn_lv_kv": vn_lv_kv, "vk_mv_percent": vk_mv_percent, "vkr_hv_percent": vkr_hv_percent} with pytest.raises(UserWarning): - pp.create_std_type(net, name=name, data=typdata, element="trafo3w") + create_std_type(net, name=name, data=typdata, element="trafo3w") typdata = {"sn_hv_mva": sn_hv_mva, "vn_hv_kv": vn_hv_kv, "vn_lv_kv": vn_lv_kv, "vk_lv_percent": vk_lv_percent, "vkr_mv_percent": vkr_mv_percent, "pfe_kw": pfe_kw} with pytest.raises(UserWarning): - pp.create_std_type(net, name=name, data=typdata, element="trafo3w") + create_std_type(net, name=name, data=typdata, element="trafo3w") typdata = {"sn_hv_mva": sn_hv_mva, "vn_hv_kv": vn_hv_kv, "vn_lv_kv": vn_lv_kv, "vk_hv_percent": vk_hv_percent, "vkr_lv_percent": vkr_lv_percent, "pfe_kw": pfe_kw, "i0_percent": i0_percent} with pytest.raises(UserWarning): - pp.create_std_type(net, name=name, data=typdata, element="trafo3w") + create_std_type(net, name=name, data=typdata, element="trafo3w") typdata = {"sn_hv_mva": sn_hv_mva, "vn_hv_kv": vn_hv_kv, "vn_lv_kv": vn_lv_kv, "vk_hv_percent": vk_hv_percent, "vkr_hv_percent": vkr_hv_percent, "pfe_kw": pfe_kw, "i0_percent": i0_percent, "shift_mv_degree": shift_mv_degree} with pytest.raises(UserWarning): - pp.create_std_type(net, name=name, data=typdata, element="trafo3w") + create_std_type(net, name=name, data=typdata, element="trafo3w") typdata = {"vn_hv_kv": vn_hv_kv, "vn_mv_kv": vn_mv_kv, "vn_lv_kv": vn_lv_kv, "sn_hv_mva": sn_hv_mva, "sn_mv_mva": sn_mv_mva, "sn_lv_mva": sn_lv_mva, "vk_hv_percent": vk_hv_percent, "vk_mv_percent": vk_mv_percent, "vk_lv_percent": vk_lv_percent, "vkr_hv_percent": vkr_hv_percent, "vkr_mv_percent": vkr_mv_percent, "vkr_lv_percent": vkr_lv_percent, "pfe_kw": pfe_kw, "i0_percent": i0_percent, "shift_mv_degree":shift_mv_degree, "shift_lv_degree": shift_lv_degree} - pp.create_std_type(net, name=name, data=typdata, element="trafo3w") + create_std_type(net, name=name, data=typdata, element="trafo3w") assert net.std_types["trafo3w"][name] == typdata - loaded_type = pp.load_std_type(net, name, element="trafo3w") + loaded_type = load_std_type(net, name, element="trafo3w") assert loaded_type == typdata def test_create_std_types_trafo(): - net = pp.create_empty_network() + net = create_empty_network() sn_mva = 40 vn_hv_kv = 110 vn_lv_kv = 20 @@ -193,12 +195,12 @@ def test_create_std_types_trafo(): "vkr_percent": vkr_percent, "pfe_kw": pfe_kw, "i0_percent": i0_percent, "shift_degree": shift_degree} typdatas = {"typ1": typdata, "typ2": typdata} - pp.create_std_types(net, data=typdatas, element="trafo") + create_std_types(net, data=typdatas, element="trafo") assert net.std_types["trafo"]["typ1"] == typdata assert net.std_types["trafo"]["typ2"] == typdata def test_create_std_types_trafo3w(): - net = pp.create_empty_network() + net = create_empty_network() sn_hv_mva = 40; sn_mv_mva = 20; sn_lv_mva = 20 vn_hv_kv = 110; vn_mv_kv = 50; vn_lv_kv = 20 vk_hv_percent = 5.; vk_mv_percent = 5.; vk_lv_percent = 5. @@ -214,30 +216,30 @@ def test_create_std_types_trafo3w(): "shift_mv_degree":shift_mv_degree, "shift_lv_degree": shift_lv_degree} typdatas = {"typ1": typdata, "typ2": typdata} - pp.create_std_types(net, data=typdatas, element="trafo3w") + create_std_types(net, data=typdatas, element="trafo3w") assert net.std_types["trafo3w"]["typ1"] == typdata assert net.std_types["trafo3w"]["typ2"] == typdata def test_find_line_type(): - net = pp.create_empty_network() + net = create_empty_network() c = 40000 r = 1.5 x = 2.0 i = 10 name = "test_line1" typdata = {"c_nf_per_km": c, "r_ohm_per_km": r, "x_ohm_per_km": x, "max_i_ka": i} - pp.create_std_type(net, data=typdata, name=name, element="line") + create_std_type(net, data=typdata, name=name, element="line") - fitting_type = pp.find_std_type_by_parameter(net, typdata) + fitting_type = find_std_type_by_parameter(net, typdata) assert len(fitting_type) == 1 assert fitting_type[0] == name - fitting_type = pp.find_std_type_by_parameter(net, {"r_ohm_per_km":r+0.05}, epsilon=.06) + fitting_type = find_std_type_by_parameter(net, {"r_ohm_per_km":r+0.05}, epsilon=.06) assert len(fitting_type) == 1 assert fitting_type[0] == name def test_find_std_alternative(): - net = pp.create_empty_network() + net = create_empty_network() c = 210 r = 0.642 x = 0.083 @@ -247,25 +249,25 @@ def test_find_std_alternative(): # Assuming we are looking for the cable NAYY 4X50 SE with a maximum ampacity of 0.142 A name ='NAYY 4x50 SE' typdata = {"c_nf_per_km": c, "r_ohm_per_km": r, "x_ohm_per_km": x, "max_i_ka": i, "voltage_rating": vr} - fitting_type = pp.find_std_type_alternative(net, {"r_ohm_per_km":r+0.05}, voltage_rating ="LV", epsilon=0.06) + fitting_type = find_std_type_alternative(net, {"r_ohm_per_km":r+0.05}, voltage_rating ="LV", epsilon=0.06) assert len(fitting_type) == 1 assert fitting_type[0] == name - fitting_type = pp.find_std_type_alternative(net, {"r_ohm_per_km":r+0.07}, voltage_rating ="LV", epsilon=0.06) + fitting_type = find_std_type_alternative(net, {"r_ohm_per_km":r+0.07}, voltage_rating ="LV", epsilon=0.06) assert len(fitting_type) == 0 - fitting_type = pp.find_std_type_alternative(net, {"r_ohm_per_km":r+0.07}, voltage_rating ="MV", epsilon=0.06) + fitting_type = find_std_type_alternative(net, {"r_ohm_per_km":r+0.07}, voltage_rating ="MV", epsilon=0.06) assert len(fitting_type) == 0 def test_change_type_line(): - net = pp.create_empty_network() + net = create_empty_network() r1 = 0.01 x1 = 0.02 c1 = 40 i1 = 0.2 name1 = "test_line1" typ1 = {"c_nf_per_km": c1, "r_ohm_per_km": r1, "x_ohm_per_km": x1, "max_i_ka": i1} - pp.create_std_type(net, data=typ1, name=name1, element="line") + create_std_type(net, data=typ1, name=name1, element="line") r2 = 0.02 x2 = 0.04 @@ -273,18 +275,18 @@ def test_change_type_line(): i2 = 0.4 name2 = "test_line2" typ2 = {"c_nf_per_km": c2, "r_ohm_per_km": r2, "x_ohm_per_km": x2, "max_i_ka": i2} - pp.create_std_type(net, data=typ2, name=name2, element="line") + create_std_type(net, data=typ2, name=name2, element="line") - b1 = pp.create_bus(net, vn_kv=0.4) - b2 = pp.create_bus(net, vn_kv=0.4) - lid = pp.create_line(net, b1, b2, 1., std_type=name1) + b1 = create_bus(net, vn_kv=0.4) + b2 = create_bus(net, vn_kv=0.4) + lid = create_line(net, b1, b2, 1., std_type=name1) assert net.line.r_ohm_per_km.at[lid] == r1 assert net.line.x_ohm_per_km.at[lid] == x1 assert net.line.c_nf_per_km.at[lid] == c1 assert net.line.max_i_ka.at[lid] == i1 assert net.line.std_type.at[lid] == name1 - pp.change_std_type(net, lid, name2) + change_std_type(net, lid, name2) assert net.line.r_ohm_per_km.at[lid] == r2 assert net.line.x_ohm_per_km.at[lid] == x2 @@ -294,14 +296,14 @@ def test_change_type_line(): def test_parameter_from_std_type_line(): - net = pp.create_empty_network() + net = create_empty_network() r1 = 0.01 x1 = 0.02 c1 = 40 i1 = 0.2 name1 = "test_line1" typ1 = {"c_nf_per_km": c1, "r_ohm_per_km": r1, "x_ohm_per_km": x1, "max_i_ka": i1} - pp.create_std_type(net, data=typ1, name=name1, element="line") + create_std_type(net, data=typ1, name=name1, element="line") r2 = 0.02 x2 = 0.04 @@ -314,28 +316,28 @@ def test_parameter_from_std_type_line(): name2 = "test_line2" typ2 = {"c_nf_per_km": c2, "r_ohm_per_km": r2, "x_ohm_per_km": x2, "max_i_ka": i2, "endtemp_degree": endtemp2} - pp.create_std_type(net, data=typ2, name=name2, element="line") + create_std_type(net, data=typ2, name=name2, element="line") - b1 = pp.create_bus(net, vn_kv=0.4) - b2 = pp.create_bus(net, vn_kv=0.4) - lid1 = pp.create_line(net, b1, b2, 1., std_type=name1) - lid2 = pp.create_line(net, b1, b2, 1., std_type=name2) - lid3 = pp.create_line_from_parameters(net, b1, b2, 1., r_ohm_per_km=0.03, x_ohm_per_km=0.04, + b1 = create_bus(net, vn_kv=0.4) + b2 = create_bus(net, vn_kv=0.4) + lid1 = create_line(net, b1, b2, 1., std_type=name1) + lid2 = create_line(net, b1, b2, 1., std_type=name2) + lid3 = create_line_from_parameters(net, b1, b2, 1., r_ohm_per_km=0.03, x_ohm_per_km=0.04, c_nf_per_km=20, max_i_ka=0.3) - pp.parameter_from_std_type(net, "endtemp_degree", fill=endtemp_fill) + parameter_from_std_type(net, "endtemp_degree", fill=endtemp_fill) assert net.line.endtemp_degree.at[lid1] == endtemp_fill #type1 one has not specified an endtemp assert net.line.endtemp_degree.at[lid2] == endtemp2 #type2 has specified endtemp assert net.line.endtemp_degree.at[lid3] == endtemp_fill #line3 has no standard type net.line.at[lid3, "endtemp_degree"] = 10 - pp.parameter_from_std_type(net, "endtemp_degree", fill=endtemp_fill) + parameter_from_std_type(net, "endtemp_degree", fill=endtemp_fill) assert net.line.endtemp_degree.at[lid3] == 10 #check that existing values arent overwritten def test_add_temperature_coefficient(): - net = nw.simple_mv_open_ring_net() - pp.add_temperature_coefficient(net) + net = simple_mv_open_ring_net() + add_temperature_coefficient(net) assert "alpha" in net.line.columns assert all(net.line.alpha == 4.03e-3) diff --git a/pandapower/test/conftest.py b/pandapower/test/conftest.py index e076c4dad..9a59514d9 100644 --- a/pandapower/test/conftest.py +++ b/pandapower/test/conftest.py @@ -7,39 +7,42 @@ import numpy as np import pytest -import pandapower as pp +from pandapower import create_empty_network, create_bus, create_ext_grid, create_transformer, create_line, create_load, \ + create_gen, create_sgen from pandapower.test.loadflow.result_test_network_generator import result_test_network_generator @pytest.fixture(scope="session") def simple_network(): - net = pp.create_empty_network() - b1 = pp.create_bus(net, name="bus1", vn_kv=10.) - pp.create_ext_grid(net, b1) - b2 = pp.create_bus(net, name="bus2", geodata=(1, 2)) - b3 = pp.create_bus(net, name="bus3", geodata=(1, 3)) - b4 = pp.create_bus(net, name="bus4", vn_kv=10.) - pp.create_transformer(net, b4, b2, + net = create_empty_network() + b1 = create_bus(net, name="bus1", vn_kv=10.) + create_ext_grid(net, b1) + b2 = create_bus(net, name="bus2", geodata=(1, 2)) + b3 = create_bus(net, name="bus3", geodata=(1, 3)) + b4 = create_bus(net, name="bus4", vn_kv=10.) + create_transformer(net, b4, b2, std_type="0.25 MVA 10/0.4 kV", name=None, in_service=True, index=None) - pp.create_line(net, b2, b3, 1, name="line1", + create_line(net, b2, b3, 1, name="line1", std_type="NAYY 4x150 SE", geodata=np.array([[1, 2], [3, 4]])) - pp.create_line(net, b1, b4, 1, name="line2", + create_line(net, b1, b4, 1, name="line2", std_type="NAYY 4x150 SE") - pp.create_load(net, b2, p_mw=0.01, q_mvar=0, name="load1") - pp.create_load(net, b3, p_mw=0.04, q_mvar=0.002, name="load2") - pp.create_gen(net, 3, q_mvar=0.020, vm_pu=1.0) - pp.create_sgen(net, 2, p_mw=0.050, sn_mva=0.1) + create_load(net, b2, p_mw=0.01, q_mvar=0, name="load1") + create_load(net, b3, p_mw=0.04, q_mvar=0.002, name="load2") + create_gen(net, 3, q_mvar=0.020, vm_pu=1.0) + create_sgen(net, 2, p_mw=0.050, sn_mva=0.1) return net @pytest.fixture(scope="session") def result_test_network(): + from pandapower import runpp + for net in result_test_network_generator(): pass - pp.runpp(net, trafo_model="t", trafo_loading="current") + runpp(net, trafo_model="t", trafo_loading="current") return net if __name__ == '__main__': diff --git a/pandapower/test/consistency_checks.py b/pandapower/test/consistency_checks.py index 10f4e76f4..afd2c532a 100644 --- a/pandapower/test/consistency_checks.py +++ b/pandapower/test/consistency_checks.py @@ -6,13 +6,14 @@ import pandas as pd from numpy import allclose, isclose + +from pandapower import runpp, rundcpp, runpp_pgm from pandapower.pf.runpp_3ph import runpp_3ph from pandapower.results import get_relevant_elements -import pandapower as pp def runpp_with_consistency_checks(net, **kwargs): - pp.runpp(net, **kwargs) + runpp(net, **kwargs) consistency_checks(net) return True @@ -22,17 +23,17 @@ def runpp_3ph_with_consistency_checks(net, **kwargs): return True def rundcpp_with_consistency_checks(net, **kwargs): - pp.rundcpp(net, **kwargs) + rundcpp(net, **kwargs) consistency_checks(net, test_q=False) return True def runpp_pgm_with_consistency_checks(net): - pp.runpp_pgm(net, error_tolerance_vm_pu=1e-11, symmetric=True) + runpp_pgm(net, error_tolerance_vm_pu=1e-11, symmetric=True) consistency_checks(net) return True def runpp_pgm_3ph_with_consistency_checks(net): - pp.runpp_pgm(net, error_tolerance_vm_pu=1e-11, symmetric=False) + runpp_pgm(net, error_tolerance_vm_pu=1e-11, symmetric=False) consistency_checks_3ph(net) return True diff --git a/pandapower/test/contingency/__init__.py b/pandapower/test/contingency/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/pandapower/test/contingency/test_contingency.py b/pandapower/test/contingency/test_contingency.py index a2a07fe2e..5aa55b1c0 100644 --- a/pandapower/test/contingency/test_contingency.py +++ b/pandapower/test/contingency/test_contingency.py @@ -9,13 +9,21 @@ import pandas as pd from pandas.testing import assert_frame_equal -import pandapower as pp -import pandapower.networks -import pandapower.control -import pandapower.timeseries -import pandapower.contingency import pytest -from pandapower.contingency.contingency import _convert_trafo_phase_shifter + +from pandapower.control import ConstControl +from pandapower.run import set_user_pf_options, runpp +from pandapower.toolbox.grid_modification import replace_ext_grid_by_gen +from pandapower.toolbox.data_modification import reindex_elements, create_continuous_bus_index +from pandapower.contingency.contingency import _convert_trafo_phase_shifter, get_element_limits, run_contingency, \ + report_contingency_results, check_elements_within_limits, run_contingency_ls2g +from pandapower.networks.power_system_test_cases import case9, case118, case14 +from pandapower.create import create_empty_network, create_buses, create_ext_grid, create_lines, \ + create_transformer_from_parameters, create_load, create_lines_from_parameters, create_transformers_from_parameters, \ + create_gen +from pandapower.timeseries.output_writer import OutputWriter +from pandapower.timeseries.run_time_series import run_timeseries +from pandapower.timeseries.data_sources.frame_data import DFData try: import lightsim2grid @@ -33,43 +41,43 @@ def test_contingency(): - net = pp.networks.case9() + net = case9() - element_limits = pp.contingency.get_element_limits(net) + element_limits = get_element_limits(net) nminus1_cases = {"line": {"index": net.line.index.values}} - res = pp.contingency.run_contingency(net, nminus1_cases) - pp.contingency.report_contingency_results(element_limits, res) + res = run_contingency(net, nminus1_cases) + report_contingency_results(element_limits, res) - pp.contingency.check_elements_within_limits(element_limits, res, True) + check_elements_within_limits(element_limits, res, True) net.line["max_loading_percent"] = np.nan net.line.loc[0:5, 'max_loading_percent'] = 70 - element_limits = pp.contingency.get_element_limits(net) + element_limits = get_element_limits(net) nminus1_cases = {"line": {"index": net.line.index.values}} - res = pp.contingency.run_contingency(net, nminus1_cases) - pp.contingency.report_contingency_results(element_limits, res) + res = run_contingency(net, nminus1_cases) + report_contingency_results(element_limits, res) def test_contingency_timeseries(get_net): nminus1_cases = {element: {"index": get_net[element].index.values} for element in ("line", "trafo") if len(get_net[element]) > 0} - contingency_functions = [pp.contingency.run_contingency] + contingency_functions = [run_contingency] if lightsim2grid_installed: - contingency_functions = [*contingency_functions, pp.contingency.run_contingency_ls2g] + contingency_functions = [*contingency_functions, run_contingency_ls2g] for contingency_function in contingency_functions: net0 = get_net.deepcopy() setup_timeseries(net0) ow = net0.output_writer.object.at[0] - pp.timeseries.run_timeseries(net0, time_steps=range(2), run_control_fct=contingency_function, + run_timeseries(net0, time_steps=range(2), run_control_fct=contingency_function, nminus1_cases=nminus1_cases, contingency_evaluation_function=run_for_from_bus_loading) # check for the last time step: - res1 = pp.contingency.run_contingency(net0, nminus1_cases, + res1 = run_contingency(net0, nminus1_cases, contingency_evaluation_function=run_for_from_bus_loading) net1 = net0.deepcopy() @@ -77,7 +85,7 @@ def test_contingency_timeseries(get_net): for c in net0.controller.object.values: c.time_step(net0, 0) c.control_step(net0) - res0 = pp.contingency.run_contingency(net0, nminus1_cases, + res0 = run_contingency(net0, nminus1_cases, contingency_evaluation_function=run_for_from_bus_loading) for var in ("vm_pu", "max_vm_pu", "min_vm_pu"): @@ -115,9 +123,9 @@ def test_with_lightsim2grid(get_net, get_case): for element in ("line", "trafo") if len(net[element]) > 0} net.line.max_loading_percent = 50 - res = pp.contingency.run_contingency(net, nminus1_cases, contingency_evaluation_function=run_for_from_bus_loading) + res = run_contingency(net, nminus1_cases, contingency_evaluation_function=run_for_from_bus_loading) - pp.contingency.run_contingency_ls2g(net, nminus1_cases) + run_contingency_ls2g(net, nminus1_cases) assert np.array_equal(res["line"]["causes_overloading"], net.res_line.causes_overloading.values) if len(net.trafo) > 0: @@ -135,14 +143,14 @@ def test_with_lightsim2grid(get_net, get_case): @pytest.mark.xfail(reason="remove this xfail when new version of lightsim2grid available") @pytest.mark.skipif(not lightsim2grid_installed, reason="lightsim2grid package is not installed") def test_case118(): - net = pp.networks.case118() + net = case118() net2 = copy.deepcopy(net) nminus1_cases = {"line": {"index": net.line.index.values}, "trafo": {"index": net.trafo.index.values}} - res = pp.contingency.run_contingency(net2, nminus1_cases, contingency_evaluation_function=run_for_from_bus_loading) + res = run_contingency(net2, nminus1_cases, contingency_evaluation_function=run_for_from_bus_loading) - pp.contingency.run_contingency_ls2g(net, nminus1_cases) + run_contingency_ls2g(net, nminus1_cases) for s in ("min", "max"): assert np.allclose(res["bus"][f"{s}_vm_pu"], net.res_bus[f"{s}_vm_pu"].values, atol=1e-9, rtol=0), s @@ -156,26 +164,26 @@ def test_case118(): @pytest.mark.xfail(reason="remove this xfail when new version of lightsim2grid available") @pytest.mark.skipif(not lightsim2grid_installed, reason="lightsim2grid package is not installed") def test_unequal_trafo_hv_lv_impedances(): - net = pp.create_empty_network() - pp.create_buses(net, 4, 110) - pp.create_ext_grid(net, 0) + net = create_empty_network() + create_buses(net, 4, 110) + create_ext_grid(net, 0) - pp.create_lines(net, [0, 0], [1, 1], 40, "243-AL1/39-ST1A 110.0", + create_lines(net, [0, 0], [1, 1], 40, "243-AL1/39-ST1A 110.0", max_loading_percent=100) - pp.create_transformer_from_parameters(net, 1, 2, 150, 110, 110, 0.5, + create_transformer_from_parameters(net, 1, 2, 150, 110, 110, 0.5, 10, 15, 0.1, 150, 'hv', 0, 10, -10, 0, 1, 5, max_loading_percent=100, leakage_resistance_ratio_hv=0.2, leakage_reactance_ratio_hv=0.4) - pp.create_lines(net, [2, 2], [3, 3], 25, "243-AL1/39-ST1A 110.0", + create_lines(net, [2, 2], [3, 3], 25, "243-AL1/39-ST1A 110.0", max_loading_percent=100) - pp.create_load(net, 3, 110) + create_load(net, 3, 110) nminus1_cases = {"line": {"index": net.line.index.values}} - res = pp.contingency.run_contingency(net, nminus1_cases, contingency_evaluation_function=run_for_from_bus_loading) + res = run_contingency(net, nminus1_cases, contingency_evaluation_function=run_for_from_bus_loading) - pp.contingency.run_contingency_ls2g(net, nminus1_cases, contingency_evaluation_function=run_for_from_bus_loading) + run_contingency_ls2g(net, nminus1_cases, contingency_evaluation_function=run_for_from_bus_loading) for s in ("min", "max"): assert np.allclose(res["bus"][f"{s}_vm_pu"], net.res_bus[f"{s}_vm_pu"].values, atol=1e-9, rtol=0), s @@ -188,21 +196,21 @@ def test_unequal_trafo_hv_lv_impedances(): @pytest.mark.skipif(not lightsim2grid_installed, reason="lightsim2grid package is not installed") def test_lightsim2grid_distributed_slack(): - net = pp.networks.case9() + net = case9() net.gen["slack_weight"] = 1 - pp.replace_ext_grid_by_gen(net, slack=True, cols_to_keep=["slack_weight"]) + replace_ext_grid_by_gen(net, slack=True, cols_to_keep=["slack_weight"]) nminus1_cases = {"line": {"index": np.array([1, 2, 4, 5, 7, 8])}} net1 = net.deepcopy() net1.gen.loc[~net1.gen.slack, 'slack_weight'] = 0 - res = pp.contingency.run_contingency(net, nminus1_cases, contingency_evaluation_function=run_for_from_bus_loading, + res = run_contingency(net, nminus1_cases, contingency_evaluation_function=run_for_from_bus_loading, distributed_slack=True) - res1 = pp.contingency.run_contingency(net1, nminus1_cases, contingency_evaluation_function=run_for_from_bus_loading) + res1 = run_contingency(net1, nminus1_cases, contingency_evaluation_function=run_for_from_bus_loading) - pp.contingency.run_contingency_ls2g(net, nminus1_cases, contingency_evaluation_function=run_for_from_bus_loading, + run_contingency_ls2g(net, nminus1_cases, contingency_evaluation_function=run_for_from_bus_loading, distributed_slack=True) - pp.contingency.run_contingency_ls2g(net1, nminus1_cases, contingency_evaluation_function=run_for_from_bus_loading) + run_contingency_ls2g(net1, nminus1_cases, contingency_evaluation_function=run_for_from_bus_loading) assert np.array_equal(res["line"]["causes_overloading"], net.res_line.causes_overloading.values) if len(net.trafo) > 0: @@ -218,22 +226,22 @@ def test_lightsim2grid_distributed_slack(): @pytest.mark.skipif(not lightsim2grid_installed, reason="lightsim2grid package is not installed") def test_lightsim2grid_phase_shifters(): - net = pp.create_empty_network() - pp.set_user_pf_options(net, calculate_voltage_angles=True) - pp.create_buses(net, 4, 110) - pp.create_gen(net, 0, 0, slack=True, slack_weight=1) + net = create_empty_network() + set_user_pf_options(net, calculate_voltage_angles=True) + create_buses(net, 4, 110) + create_gen(net, 0, 0, slack=True, slack_weight=1) - pp.create_lines(net, [0, 0], [1, 1], 40, "243-AL1/39-ST1A 110.0", max_loading_percent=100) - pp.create_transformer_from_parameters(net, 1, 2, 150, 110, 110, 0.5, 10, 15, 0.1, 150, + create_lines(net, [0, 0], [1, 1], 40, "243-AL1/39-ST1A 110.0", max_loading_percent=100) + create_transformer_from_parameters(net, 1, 2, 150, 110, 110, 0.5, 10, 15, 0.1, 150, 'hv', 0, 10, -10, 0, 1, 5, True, max_loading_percent=100) - pp.create_lines(net, [2, 2], [3, 3], 25, "243-AL1/39-ST1A 110.0", max_loading_percent=100) + create_lines(net, [2, 2], [3, 3], 25, "243-AL1/39-ST1A 110.0", max_loading_percent=100) - pp.create_load(net, 3, 110) + create_load(net, 3, 110) nminus1_cases = {"line": {"index": net.line.index.values}} - res = pp.contingency.run_contingency(net, nminus1_cases, contingency_evaluation_function=run_for_from_bus_loading) + res = run_contingency(net, nminus1_cases, contingency_evaluation_function=run_for_from_bus_loading) - pp.contingency.run_contingency_ls2g(net, nminus1_cases, contingency_evaluation_function=run_for_from_bus_loading, + run_contingency_ls2g(net, nminus1_cases, contingency_evaluation_function=run_for_from_bus_loading, distributed_slack=True) assert net.trafo.shift_degree.values[0] == 150 @@ -249,23 +257,23 @@ def test_lightsim2grid_phase_shifters(): for var in ("vm_pu", "max_vm_pu", "min_vm_pu"): assert np.allclose(res["bus"][var], net.res_bus[var].values, atol=1e-9, rtol=0) - pp.runpp(net) + runpp(net) bus_res = net.res_bus.copy() _convert_trafo_phase_shifter(net) - pp.runpp(net) + runpp(net) assert_frame_equal(bus_res, net.res_bus) @pytest.mark.skipif(not lightsim2grid_installed, reason="lightsim2grid package is not installed") def test_cause_congestion(): - net = pp.networks.case14() + net = case14() for c in ("tap_neutral", "tap_step_percent", "tap_pos", "tap_step_degree"): net.trafo[c] = 0 net.trafo.sn_mva /= 200 net.trafo.vk_percent /= 200 net.line.max_i_ka /= 100 net.gen["slack_weight"] = 1 - pp.replace_ext_grid_by_gen(net, slack=True, cols_to_keep=["slack_weight"]) + replace_ext_grid_by_gen(net, slack=True, cols_to_keep=["slack_weight"]) _randomize_indices(net) @@ -274,7 +282,7 @@ def test_cause_congestion(): # trafo with iloc index 3 causes 2 disconnected grid areas, which is handled differently by # lightsim2grid and pandapower, so the results do not match for the contingency defined by net.trafo.iloc[3] - pp.contingency.run_contingency_ls2g(net, nminus1_cases, + run_contingency_ls2g(net, nminus1_cases, contingency_evaluation_function=run_for_from_bus_loading) res = {"trafo": net.res_trafo.copy(), "line": net.res_line.copy()} for element, val in nminus1_cases.items(): @@ -301,18 +309,18 @@ def test_cause_congestion(): def test_cause_element_index(): - net = pp.networks.case14() + net = case14() for c in ("tap_neutral", "tap_step_percent", "tap_pos", "tap_step_degree"): net.trafo[c] = 0 net.gen["slack_weight"] = 1 - pp.replace_ext_grid_by_gen(net, slack=True, cols_to_keep=["slack_weight"]) + replace_ext_grid_by_gen(net, slack=True, cols_to_keep=["slack_weight"]) _randomize_indices(net) nminus1_cases = {"line": {"index": net.line.iloc[[4, 2, 1, 5, 7, 8]].index.values}, "trafo": {"index": net.trafo.iloc[[2, 3, 1, 0, 4]].index.values}} - _ = pp.contingency.run_contingency(net, nminus1_cases, contingency_evaluation_function=run_for_from_bus_loading) + _ = run_contingency(net, nminus1_cases, contingency_evaluation_function=run_for_from_bus_loading) cause_res_copy_line = net.res_line.copy() cause_res_copy_trafo = net.res_trafo.copy() @@ -320,7 +328,7 @@ def test_cause_element_index(): check_cause_index(net, nminus1_cases) if lightsim2grid_installed: - pp.contingency.run_contingency_ls2g(net, nminus1_cases, + run_contingency_ls2g(net, nminus1_cases, contingency_evaluation_function=run_for_from_bus_loading) columns = ["loading_percent", "max_loading_percent", "min_loading_percent", "causes_overloading", @@ -363,7 +371,7 @@ def check_cause_index(net, nminus1_cases): def run_for_from_bus_loading(net, **kwargs): - pp.runpp(net, **kwargs) + runpp(net, **kwargs) net.res_line["loading_percent"] = net.res_line.i_from_ka / net.line.max_i_ka * 100 if len(net.trafo) > 0: max_i_ka_limit = net.trafo.sn_mva.values / (net.trafo.vn_hv_kv.values * np.sqrt(3)) @@ -373,17 +381,17 @@ def run_for_from_bus_loading(net, **kwargs): def setup_timeseries(net): load_profiles = pd.DataFrame(net.load.p_mw.values * (np.random.random((4, len(net.load))) * 0.4 + 0.8), index=np.arange(4), columns=net.load.index.values) - dsl = pp.timeseries.DFData(load_profiles) - pp.control.ConstControl(net, element="load", variable="p_mw", element_index=net.load.index.values, + dsl = DFData(load_profiles) + ConstControl(net, element="load", variable="p_mw", element_index=net.load.index.values, profile_name=net.load.index.values, data_source=dsl) gen_profiles = pd.DataFrame(net.gen.p_mw.values * (np.random.random((4, len(net.gen))) * 0.4 + 0.8), index=np.arange(4), columns=net.gen.index.values) - dsg = pp.timeseries.DFData(gen_profiles) - pp.control.ConstControl(net, element="gen", variable="p_mw", element_index=net.gen.index.values, + dsg = DFData(gen_profiles) + ConstControl(net, element="gen", variable="p_mw", element_index=net.gen.index.values, profile_name=net.gen.index.values, data_source=dsg) - ow = pp.timeseries.OutputWriter(net) + ow = OutputWriter(net) ow.log_variable("res_bus", "max_vm_pu") ow.log_variable("res_bus", "min_vm_pu") ow.log_variable("res_line", "max_loading_percent") @@ -401,7 +409,7 @@ def _randomize_indices(net): continue new_index = net[element].index.values + rng.integers(1, 10) rng.shuffle(new_index) - pp.reindex_elements(net, element, new_index) + reindex_elements(net, element, new_index) def test_reminder_bring_back_case118(): @@ -412,20 +420,20 @@ def test_reminder_bring_back_case118(): # todo: bring back case 118 when lightsim2grid new version is released # (created a test that fails if lightsim2grid new version is available so that this is not missed (above) -# @pytest.fixture(params=["case9", "case14", "case118"]) -@pytest.fixture(params=["case9", "case14"]) +# @pytest.fixture(params=[case9, case14, case118]) +@pytest.fixture(params=[case9, case14]) def get_net(request): # pandapower and lightsim2grid behave differently when the grid becomes isolated from the ext_grid: # pandapower selects next gen and uses it as ext_grid, and lightsim2grid does not and therefore has nan for results # to circumvent this issue in this test, we add parallel lines to the grid - net = pp.networks.__dict__[request.param]() - pp.replace_ext_grid_by_gen(net, slack=True, cols_to_keep=["slack_weight"]) + net = request.param() + replace_ext_grid_by_gen(net, slack=True, cols_to_keep=["slack_weight"]) add_parallel = True if add_parallel: - pp.create_lines_from_parameters(net, net.line.from_bus.values, net.line.to_bus.values, + create_lines_from_parameters(net, net.line.from_bus.values, net.line.to_bus.values, net.line.length_km.values, net.line.r_ohm_per_km.values, net.line.x_ohm_per_km.values, net.line.c_nf_per_km.values, @@ -433,7 +441,7 @@ def get_net(request): max_loading_percent=net.line.max_loading_percent.values) if len(net.trafo) > 0: - pp.create_transformers_from_parameters(net, net.trafo.hv_bus.values, net.trafo.lv_bus.values, + create_transformers_from_parameters(net, net.trafo.hv_bus.values, net.trafo.lv_bus.values, net.trafo.sn_mva.values, net.trafo.vn_hv_kv.values, net.trafo.vn_lv_kv.values, net.trafo.vkr_percent.values, net.trafo.vk_percent.values, net.trafo.pfe_kw.values, @@ -445,7 +453,7 @@ def get_net(request): _randomize_indices(net) - pp.create_continuous_bus_index(net) + create_continuous_bus_index(net) if np.any(net.line.max_i_ka > 10): net.line.max_i_ka = 1 diff --git a/pandapower/test/control/test_const_control.py b/pandapower/test/control/test_const_control.py index eceb8c413..840e13e95 100644 --- a/pandapower/test/control/test_const_control.py +++ b/pandapower/test/control/test_const_control.py @@ -6,22 +6,22 @@ import pytest import numpy as np import pandas as pd - -import pandapower as pp -import pandapower.networks as nw -import pandapower.control -import pandapower.timeseries import logging as log +from pandapower.create import create_sgen +from pandapower.networks import simple_four_bus_system +from pandapower.timeseries import DFData +from pandapower.control import ConstControl, ContinuousTapControl + logger = log.getLogger(__name__) def test_write(): - net = nw.simple_four_bus_system() - ds = pp.timeseries.DFData(pd.DataFrame(data=[[0., 1., 2.], [2., 3., 4.]])) - c1 = pp.control.ConstControl(net, 'sgen', 'p_mw', element_index=[0, 1], profile_name=[0, 1], data_source=ds) - pp.create_sgen(net, 0, 0) - c2 = pp.control.ConstControl(net, 'sgen', 'p_mw', element_index=[2], profile_name=[2], data_source=ds, + net = simple_four_bus_system() + ds = DFData(pd.DataFrame(data=[[0., 1., 2.], [2., 3., 4.]])) + c1 = ConstControl(net, 'sgen', 'p_mw', element_index=[0, 1], profile_name=[0, 1], data_source=ds) + create_sgen(net, 0, 0) + c2 = ConstControl(net, 'sgen', 'p_mw', element_index=[2], profile_name=[2], data_source=ds, scale_factor=0.5) for t in range(2): c1.time_step(net, t) @@ -32,10 +32,10 @@ def test_write(): def test_write_to_object_attribute(): - net = nw.simple_four_bus_system() - ds = pp.timeseries.DFData(pd.DataFrame(data=[1.01, 1.02, 1.03])) - c1 = pp.control.ContinuousTapControl(net, 0, 1.) - c2 = pp.control.ConstControl(net, 'controller', 'object.vm_set_pu', element_index=0, profile_name=0, data_source=ds) + net = simple_four_bus_system() + ds = DFData(pd.DataFrame(data=[1.01, 1.02, 1.03])) + c1 = ContinuousTapControl(net, 0, 1.) + c2 = ConstControl(net, 'controller', 'object.vm_set_pu', element_index=0, profile_name=0, data_source=ds) for t in range(2): c2.time_step(net, t) c2.control_step(net) diff --git a/pandapower/test/control/test_continuous_tap_control.py b/pandapower/test/control/test_continuous_tap_control.py index dd1f25388..9e1176c96 100644 --- a/pandapower/test/control/test_continuous_tap_control.py +++ b/pandapower/test/control/test_continuous_tap_control.py @@ -4,20 +4,23 @@ # and Energy System Technology (IEE), Kassel. All rights reserved. from copy import deepcopy -import pandapower as pp import pytest -import pandapower.networks as nw import logging as log import numpy as np logger = log.getLogger(__name__) + +from pandapower import set_user_pf_options, runpp +from pandapower.create import create_empty_network, create_buses, create_ext_grid, create_lines, create_transformer, \ + create_load, create_bus, create_line, create_transformer3w +from pandapower.networks import simple_four_bus_system, mv_oberrhein from pandapower.control import ContinuousTapControl def test_continuous_tap_control_lv(): # --- load system and run power flow - net = nw.simple_four_bus_system() - pp.set_user_pf_options(net, init='dc', calculate_voltage_angles=True) + net = simple_four_bus_system() + set_user_pf_options(net, init='dc', calculate_voltage_angles=True) # --- initial tap data net.trafo.tap_side = 'lv' net.trafo.tap_neutral = 0 @@ -26,7 +29,7 @@ def test_continuous_tap_control_lv(): net.trafo.tap_step_percent = 1.25 net.trafo.tap_pos = 0 # --- run loadflow - pp.runpp(net) + runpp(net) # todo: rewrite to not compare to hardcoded values tid = 0 @@ -38,8 +41,8 @@ def test_continuous_tap_control_lv(): % (net.res_trafo.vm_lv_pu.at[tid], net.trafo.tap_pos.at[tid])) # run control - pp.runpp(net, run_control=True) - pp.runpp(net) + runpp(net, run_control=True) + runpp(net) logger.info( "after ContinuousTapControl: trafo voltage at low voltage bus is %f, tap position is %f" % (net.res_trafo.vm_lv_pu.at[tid], net.trafo.tap_pos.at[tid])) @@ -50,15 +53,15 @@ def test_continuous_tap_control_lv(): net.ext_grid.vm_pu = 1.03 # switch back tap position net.trafo.at[0, "tap_pos"] = 0 - pp.runpp(net) + runpp(net) logger.info("case2: high voltage") logger.info("before control: trafo voltage at low voltage bus is %f, tap position is %u" % (net.res_trafo.vm_lv_pu.at[tid], net.trafo.tap_pos.at[tid])) # run control - pp.runpp(net, run_control=True) - pp.runpp(net) + runpp(net, run_control=True) + runpp(net) logger.info( "after ContinuousTapControl: trafo voltage at low voltage bus is %f, tap position is %f" % (net.res_trafo.vm_lv_pu.at[tid], net.trafo.tap_pos.at[tid])) @@ -68,15 +71,15 @@ def test_continuous_tap_control_lv(): net.ext_grid.vm_pu = 0.98 # switch back tap position net.trafo.at[0, "tap_pos"] = 0 - pp.runpp(net) + runpp(net) logger.info("case2: high voltage") logger.info("before control: trafo voltage at low voltage bus is %f, tap position is %u" % (net.res_trafo.vm_lv_pu.at[tid], net.trafo.tap_pos.at[tid])) # run control - pp.runpp(net, run_control=True) - pp.runpp(net) + runpp(net, run_control=True) + runpp(net) logger.info( "after ContinuousTapControl: trafo voltage at low voltage bus is %f, tap position is %f" % (net.res_trafo.vm_lv_pu.at[tid], net.trafo.tap_pos.at[tid])) @@ -86,7 +89,7 @@ def test_continuous_tap_control_lv(): def test_continuous_tap_control_hv(): # --- load system and run power flow - net = nw.simple_four_bus_system() + net = simple_four_bus_system() # --- initial tap data net.trafo.tap_side = 'hv' net.trafo.tap_neutral = 0 @@ -95,7 +98,7 @@ def test_continuous_tap_control_hv(): net.trafo.tap_step_percent = 1.25 net.trafo.tap_pos = 0 # --- run loadflow - pp.runpp(net) + runpp(net) tid = 0 ContinuousTapControl(net, tid, vm_set_pu=0.99, side='lv') # td = control.DiscreteTapControl(net, 0, side='lv', vm_lower_pu=0.95, vm_upper_pu=0.99) @@ -105,8 +108,8 @@ def test_continuous_tap_control_hv(): % (net.res_trafo.vm_lv_pu.at[tid], net.trafo.tap_pos.at[tid])) # run control - pp.runpp(net, run_control=True) - pp.runpp(net) + runpp(net, run_control=True) + runpp(net) logger.info( "after ContinuousTapControl: trafo voltage at low voltage bus is %f, tap position is %f" % (net.res_trafo.vm_lv_pu.at[tid], net.trafo.tap_pos.at[tid])) @@ -118,15 +121,15 @@ def test_continuous_tap_control_hv(): net.ext_grid.vm_pu = 1.03 # switch back tap position net.trafo.at[0, "tap_pos"] = 0 - pp.runpp(net) + runpp(net) logger.info("case2: high voltage") logger.info("before control: trafo voltage at low voltage bus is %f, tap position is %u" % (net.res_trafo.vm_lv_pu.at[tid], net.trafo.tap_pos.at[tid])) # run control - pp.runpp(net, run_control=True) - pp.runpp(net) + runpp(net, run_control=True) + runpp(net) logger.info( "after ContinuousTapControl: trafo voltage at low voltage bus is %f, tap position is %f" % (net.res_trafo.vm_lv_pu.at[tid], net.trafo.tap_pos.at[tid])) @@ -136,15 +139,15 @@ def test_continuous_tap_control_hv(): net.ext_grid.vm_pu = 0.98 # switch back tap position net.trafo.at[0, "tap_pos"] = 0 - pp.runpp(net) + runpp(net) logger.info("case2: high voltage") logger.info("before control: trafo voltage at low voltage bus is %f, tap position is %u" % (net.res_trafo.vm_lv_pu.at[tid], net.trafo.tap_pos.at[tid])) # run control - pp.runpp(net, run_control=True) - pp.runpp(net) + runpp(net, run_control=True) + runpp(net) logger.info( "after ContinuousTapControl: trafo voltage at low voltage bus is %f, tap position is %f" % (net.res_trafo.vm_lv_pu.at[tid], net.trafo.tap_pos.at[tid])) @@ -154,21 +157,21 @@ def test_continuous_tap_control_hv(): def test_continuous_tap_control_vectorized_lv(): # --- load system and run power flow - net = pp.create_empty_network() - pp.create_buses(net, 6, 110) - pp.create_buses(net, 5, 20) - pp.create_ext_grid(net, 0) - pp.create_lines(net, np.zeros(5), np.arange(1, 6), 10, "243-AL1/39-ST1A 110.0") - for hv, lv in zip(np.arange(1, 6), np.arange(6,11)): - pp.create_transformer(net, hv, lv, "63 MVA 110/20 kV") - pp.create_load(net, lv, 25*(lv-8), 25*(lv-8) * 0.4) - pp.set_user_pf_options(net, init='dc', calculate_voltage_angles=True) + net = create_empty_network() + create_buses(net, 6, 110) + create_buses(net, 5, 20) + create_ext_grid(net, 0) + create_lines(net, np.zeros(5), np.arange(1, 6), 10, "243-AL1/39-ST1A 110.0") + for hv, lv in zip(np.arange(1, 6), np.arange(6, 11)): + create_transformer(net, hv, lv, "63 MVA 110/20 kV") + create_load(net, lv, 25 * (lv - 8), 25 * (lv - 8) * 0.4) + set_user_pf_options(net, init='dc', calculate_voltage_angles=True) net.trafo.iloc[3:, net.trafo.columns.get_loc("tap_side")] = "lv" tol = 1e-4 # --- run loadflow - pp.runpp(net) + runpp(net) assert not np.allclose(net.res_trafo.vm_lv_pu.values, 1.02, atol=tol) # there should be - # something to do for the controllers + # something to do for the controllers net_ref = deepcopy(net) @@ -177,36 +180,35 @@ def test_continuous_tap_control_vectorized_lv(): ContinuousTapControl(net_ref, tid, side='lv', vm_set_pu=1.02, tol=tol) # run control reference - pp.runpp(net_ref, run_control=True) + runpp(net_ref, run_control=True) assert np.allclose(net_ref.res_trafo.vm_lv_pu.values, 1.02, atol=tol) assert not np.allclose(net_ref.trafo.tap_pos.values, 0) # now create the vectorized version ContinuousTapControl(net, net.trafo.index.values, side='lv', vm_set_pu=1.02, tol=tol) - pp.runpp(net, run_control=True) + runpp(net, run_control=True) assert np.allclose(net_ref.trafo.tap_pos, net.trafo.tap_pos, atol=1e-2, rtol=0) - def test_continuous_tap_control_vectorized_hv(): # --- load system and run power flow - net = pp.create_empty_network() - pp.create_buses(net, 6, 20) - pp.create_buses(net, 5, 110) - pp.create_ext_grid(net, 0) - pp.create_lines(net, np.zeros(5), np.arange(1, 6), 10, "243-AL1/39-ST1A 110.0") + net = create_empty_network() + create_buses(net, 6, 20) + create_buses(net, 5, 110) + create_ext_grid(net, 0) + create_lines(net, np.zeros(5), np.arange(1, 6), 10, "243-AL1/39-ST1A 110.0") for lv, hv in zip(np.arange(1, 6), np.arange(6, 11)): - pp.create_transformer(net, hv, lv, "63 MVA 110/20 kV") - pp.create_load(net, hv, 2.5*(hv-8), 2.5*(hv-8) * 0.4) - pp.set_user_pf_options(net, init='dc', calculate_voltage_angles=True) + create_transformer(net, hv, lv, "63 MVA 110/20 kV") + create_load(net, hv, 2.5 * (hv - 8), 2.5 * (hv - 8) * 0.4) + set_user_pf_options(net, init='dc', calculate_voltage_angles=True) net.trafo.iloc[3:, net.trafo.columns.get_loc("tap_side")] = "lv" tol = 1e-4 # --- run loadflow - pp.runpp(net) + runpp(net) assert not np.allclose(net.res_trafo.vm_hv_pu.values, 1.02, atol=tol) # there should be - # something to do for the controllers + # something to do for the controllers net_ref = deepcopy(net) @@ -215,42 +217,42 @@ def test_continuous_tap_control_vectorized_hv(): ContinuousTapControl(net_ref, tid, side='hv', vm_set_pu=1.02, tol=tol) # run control reference - pp.runpp(net_ref, run_control=True) + runpp(net_ref, run_control=True) assert np.allclose(net_ref.res_trafo.vm_hv_pu.values, 1.02, atol=tol) assert not np.allclose(net_ref.trafo.tap_pos.values, 0) # now create the vectorized version ContinuousTapControl(net, net.trafo.index.values, side='hv', vm_set_pu=1.02, tol=tol) - pp.runpp(net, run_control=True) + runpp(net, run_control=True) assert np.allclose(net_ref.trafo.tap_pos, net.trafo.tap_pos, atol=1e-2, rtol=0) def test_continuous_tap_control_side_mv(): # --- load system and run power flow - net = pp.create_empty_network() - pp.create_buses(net, 2, 110) - pp.create_buses(net, 1, 20) - pp.create_bus(net, 10) - pp.create_ext_grid(net, 0) - pp.create_line(net, 0, 1, 10, "243-AL1/39-ST1A 110.0") - pp.create_transformer3w(net, 1, 2, 3, "63/25/38 MVA 110/20/10 kV") - pp.create_load(net, 2, 5., 2.) - pp.create_load(net, 3, 5., 2.) - pp.set_user_pf_options(net, init='dc', calculate_voltage_angles=True) + net = create_empty_network() + create_buses(net, 2, 110) + create_buses(net, 1, 20) + create_bus(net, 10) + create_ext_grid(net, 0) + create_line(net, 0, 1, 10, "243-AL1/39-ST1A 110.0") + create_transformer3w(net, 1, 2, 3, "63/25/38 MVA 110/20/10 kV") + create_load(net, 2, 5., 2.) + create_load(net, 3, 5., 2.) + set_user_pf_options(net, init='dc', calculate_voltage_angles=True) tol = 1e-4 # --- run loadflow - pp.runpp(net) + runpp(net) assert not np.allclose(net.res_trafo3w.vm_mv_pu.values, 1.02, atol=tol) # there should be - # something to do for the controllers + # something to do for the controllers net_ref = deepcopy(net) ContinuousTapControl(net, 0, side='mv', vm_set_pu=1.02, tol=tol, element="trafo3w") # --- run control reference - pp.runpp(net, run_control=True) + runpp(net, run_control=True) assert not np.allclose(net_ref.res_trafo3w.vm_mv_pu.values, 1.02, atol=tol) assert np.allclose(net_ref.trafo3w.tap_pos.values, 0) @@ -260,39 +262,41 @@ def test_continuous_tap_control_side_mv(): def test_continuous_tap_control_side_hv_reversed_3w(): # --- load system and run power flow - net = pp.create_empty_network() - pp.create_buses(net, 2, 110) - pp.create_buses(net, 1, 20) - pp.create_bus(net, 10) - pp.create_ext_grid(net, 2) - pp.create_line(net, 0, 1, 10, "243-AL1/39-ST1A 110.0") - pp.create_transformer3w(net, 1, 2, 3, "63/25/38 MVA 110/20/10 kV") - pp.create_load(net, 2, 5., 2.) - pp.create_load(net, 3, 5., 2.) - pp.set_user_pf_options(net, init='dc', calculate_voltage_angles=True) + net = create_empty_network() + create_buses(net, 2, 110) + create_buses(net, 1, 20) + create_bus(net, 10) + create_ext_grid(net, 2) + create_line(net, 0, 1, 10, "243-AL1/39-ST1A 110.0") + create_transformer3w(net, 1, 2, 3, "63/25/38 MVA 110/20/10 kV") + create_load(net, 2, 5., 2.) + create_load(net, 3, 5., 2.) + set_user_pf_options(net, init='dc', calculate_voltage_angles=True) tol = 1e-4 # --- run loadflow - pp.runpp(net) + runpp(net) assert not np.allclose(net.res_trafo3w.vm_mv_pu.values, 1.02, atol=tol) # there should be - # something to do for the controllers + # something to do for the controllers net_ref = deepcopy(net) ContinuousTapControl(net, 0, side='hv', vm_set_pu=1.02, tol=tol, element="trafo3w") # --- run control reference - pp.runpp(net, run_control=True) + runpp(net, run_control=True) assert not np.allclose(net_ref.res_trafo3w.vm_hv_pu.values, 1.02, atol=tol) assert np.allclose(net_ref.trafo3w.tap_pos.values, 0) assert np.allclose(net.res_trafo3w.vm_hv_pu.values, 1.02, atol=tol) assert not np.allclose(net.trafo3w.tap_pos.values, 0) + def test_continuous_trafo_control_with_oos_trafo(): - net = pp.networks.mv_oberrhein() + net = mv_oberrhein() # switch transformer out of service net.trafo.loc[114, 'in_service'] = False ContinuousTapControl(net=net, element_index=114, vm_set_pu=1.0, tol=0.001) + if __name__ == '__main__': pytest.main([__file__, "-xs"]) diff --git a/pandapower/test/control/test_control.py b/pandapower/test/control/test_control.py index 922f20d44..72de44243 100644 --- a/pandapower/test/control/test_control.py +++ b/pandapower/test/control/test_control.py @@ -5,9 +5,16 @@ import copy import pytest -import pandapower.control as ct -import pandapower.networks as networks -import pandapower as pp + +try: + import pandaplan.core.pplog as pplog +except: + import logging as pplog + +from pandapower import runpp +from pandapower.create import create_sgen +from pandapower.networks import create_kerber_vorstadtnetz_kabel_1 +from pandapower.control import ControllerNotConverged from pandapower.control.run_control import get_controller_order from pandapower.control.basic_controller import Controller from pandapower.control.controller.trafo_control import TrafoController @@ -15,11 +22,6 @@ from pandapower.timeseries.output_writer import OutputWriter from pandapower.timeseries.run_time_series import run_timeseries -try: - import pandaplan.core.pplog as pplog -except: - import logging as pplog - logger = pplog.getLogger(__name__) ctrl_logger = pplog.getLogger("hp.control.control_handler") logger.setLevel(pplog.CRITICAL) @@ -47,10 +49,10 @@ def is_converged(self, net): @pytest.fixture def net(): - net = networks.create_kerber_vorstadtnetz_kabel_1() + net = create_kerber_vorstadtnetz_kabel_1() for i, load in net.load.iterrows(): - pp.create_sgen(net, load.bus, p_mw=1 * 1e-3, sn_mva=2 * 1e-3) + create_sgen(net, load.bus, p_mw=1 * 1e-3, sn_mva=2 * 1e-3) return net @@ -93,7 +95,7 @@ def is_converged(self, net): DivergentController(net) - with pytest.raises(ct.ControllerNotConverged): + with pytest.raises(ControllerNotConverged): run_timeseries(net, time_steps=range(0, 3), output_writer=output_writer, max_iter=3, verbose=False) # assert no exceptions but appropriate output in outputwriter @@ -115,8 +117,8 @@ def test_conflicting_controllers(net): ContinuousTapControl(net, 0, vm_set_pu=1.02, tol=tol, order=1) ContinuousTapControl(net, 0, vm_set_pu=1.05, tol=tol, order=2) - with pytest.raises(ct.ControllerNotConverged): - pp.runpp(net, run_control=True) + with pytest.raises(ControllerNotConverged): + runpp(net, run_control=True) @pytest.mark.xfail( @@ -126,15 +128,15 @@ def test_in_service_bool(net): with pytest.raises(KeyError): cnet = copy.deepcopy(net) TrafoController(cnet, 0, side="lv", element="trafo", level=1, in_service="True", tol=1e-6) - pp.runpp(cnet, run_control=True) + runpp(cnet, run_control=True) with pytest.raises(KeyError): cnet = copy.deepcopy(net) TrafoController(cnet, 0, side="lv", element="trafo", level=1, in_service=1.0, tol=1e-6) - pp.runpp(cnet, run_control=True) + runpp(cnet, run_control=True) with pytest.raises(TypeError): cnet = copy.deepcopy(net) TrafoController(cnet, 0, side="lv", element="trafo", level=1, in_service=[1, 2, 3], tol=1e-6) - pp.runpp(cnet, run_control=True) + runpp(cnet, run_control=True) def test_multiple_levels(net): @@ -151,7 +153,7 @@ def test_multiple_levels(net): assert order[1][1][0].index == 2 assert level == [1, 2] - pp.runpp(net, run_control=True) + runpp(net, run_control=True) def test_level(net): @@ -159,7 +161,7 @@ def test_level(net): c2 = DummyController(net, level=1) c3 = DummyController(net, level=2) - pp.runpp(net, run_control=True) + runpp(net, run_control=True) assert c1.is_converged(net) assert c2.is_converged(net) @@ -173,7 +175,7 @@ def test_level_in_service(net): c4 = DummyController(net, level=1, order=-2, in_service=False) net.controller.at[0, 'in_service'] = False - pp.runpp(net, run_control=True) + runpp(net, run_control=True) assert not c1.applied assert c2.applied assert c3.applied diff --git a/pandapower/test/control/test_der_control.py b/pandapower/test/control/test_der_control.py index 3a5ccca74..c5f9ab840 100644 --- a/pandapower/test/control/test_der_control.py +++ b/pandapower/test/control/test_der_control.py @@ -3,13 +3,22 @@ # Copyright (c) 2016-2024 by University of Kassel and Fraunhofer Institute for Energy Economics # and Energy System Technology (IEE), Kassel. All rights reserved. -import pytest -import os from copy import deepcopy + import numpy as np import pandas as pd -import pandapower as pp -import pandapower.control.controller.DERController as DERModels +import pytest + +from pandapower.control.controller import DERController as DERModels +from pandapower.control.controller.DERController import DERController +from pandapower.control.controller.const_control import ConstControl +from pandapower.create import create_empty_network, create_buses, create_ext_grid, create_sgen, create_line, \ + create_bus +from pandapower.run import runpp +from pandapower.timeseries.data_sources.frame_data import DFData +from pandapower.timeseries.output_writer import OutputWriter +from pandapower.timeseries.run_time_series import run_timeseries +from pandapower.toolbox.power_factor import cosphi_from_pq, cosphi_pos_neg_from_pq try: from pandaplan.core import pplog as logging @@ -20,19 +29,19 @@ def simple_test_net(): - net = pp.create_empty_network() - pp.create_buses(net, 2, vn_kv=20) - pp.create_ext_grid(net, 0) - pp.create_sgen(net, 1, p_mw=2., sn_mva=3, name="DER1") - pp.create_line(net, 0, 1, length_km=0.1, std_type="NAYY 4x50 SE") + net = create_empty_network() + create_buses(net, 2, vn_kv=20) + create_ext_grid(net, 0) + create_sgen(net, 1, p_mw=2., sn_mva=3, name="DER1") + create_line(net, 0, 1, length_km=0.1, std_type="NAYY 4x50 SE") return net def simple_test_net2(): net = simple_test_net() - bus = pp.create_bus(net, vn_kv=20) - pp.create_line(net, 0, bus, 0.1, std_type="NAYY 4x50 SE") - pp.create_sgen(net, bus, 2., sn_mva=3., name="DER2") + bus = create_bus(net, vn_kv=20) + create_line(net, 0, bus, 0.1, std_type="NAYY 4x50 SE") + create_sgen(net, bus, 2., sn_mva=3., name="DER2") return net @@ -48,101 +57,97 @@ def test_qofv(): "cosphi_points": (0.9, 0.9, 1, -0.9)}) qofv_q = DERModels.QModelQVCurve({ "vm_points_pu": (0, 0.96, 1., 1.04), - "q_points_pu": (0.4843221*p/sn, 0.4843221*p/sn, 0., -0.4843221*p/sn)}) + "q_points_pu": (0.4843221 * p / sn, 0.4843221 * p / sn, 0., -0.4843221 * p / sn)}) # the following, applied pqv_area has no influence in this test (vm near 1, p > 0.2 -> no # limitation). The functionality is not tested here. It is only tested that using it produces # no errors - pp.control.DERController(net, 0, q_model=qofv_cosphi, pqv_area=DERModels.PQVArea4120V2()) - pp.control.DERController(net, 0, q_model=qofv_q, pqv_area=DERModels.PQVArea4120V2()) + DERController(net, 0, q_model=qofv_cosphi, pqv_area=DERModels.PQVArea4120V2()) + DERController(net, 0, q_model=qofv_q, pqv_area=DERModels.PQVArea4120V2()) - pp.runpp(net) + runpp(net) # check that vm difference to ext_grid is low - assert 0.995 <= net.res_bus.vm_pu.at[1] <= 1.005 + assert 0.995 <= net.res_bus.vm_pu.at[1] <= 1.005 assert np.isclose(net.res_sgen.q_mvar.at[0], 0) - # --- run control -> nearly no q injection since vm is nearly 1.0 # pf without controller net.controller.in_service = [True, False] - pp.runpp(net, run_control=True) - assert 0.991 <= pp.cosphi_from_pq(-net.res_sgen.p_mw.at[0], -net.res_sgen.q_mvar.at[0])[0] + runpp(net, run_control=True) + assert 0.991 <= cosphi_from_pq(-net.res_sgen.p_mw.at[0], -net.res_sgen.q_mvar.at[0])[0] # pf with 2nd controller (should have same result) net.controller.in_service = [False, True] - pp.runpp(net, run_control=True) - assert 0.995 <= pp.cosphi_from_pq(-net.res_sgen.p_mw.at[0], -net.res_sgen.q_mvar.at[0])[0] - + runpp(net, run_control=True) + assert 0.995 <= cosphi_from_pq(-net.res_sgen.p_mw.at[0], -net.res_sgen.q_mvar.at[0])[0] # --- run control -> q injection is positive with cosphi=0.9 since vm is nearly 1.05 net.ext_grid.vm_pu = 1.05 net.sgen.q_mvar = 0. # pf without controller - pp.runpp(net) + runpp(net) vmb4 = net.res_bus.vm_pu.at[1] # pf with 1st controller net.controller.in_service = [True, False] - pp.runpp(net, run_control=True) + runpp(net, run_control=True) assert net.res_bus.vm_pu.at[1] < vmb4 assert net.res_sgen.q_mvar.at[0] < 0 cosphi_expected = 0.9 - q_expected = ((net.res_sgen.p_mw.at[0]/cosphi_expected)**2 - net.res_sgen.p_mw.at[0]**2)**0.5 + q_expected = ((net.res_sgen.p_mw.at[0] / cosphi_expected) ** 2 - net.res_sgen.p_mw.at[0] ** 2) ** 0.5 assert np.isclose(net.res_sgen.q_mvar.at[0], -q_expected, atol=1e-5) # pf with 2nd controller (should have same result) net.controller.in_service = [False, True] - pp.runpp(net, run_control=True) + runpp(net, run_control=True) assert net.res_bus.vm_pu.at[1] < vmb4 assert np.isclose(net.res_sgen.q_mvar.at[0], -q_expected, atol=1e-5) - # --- run control -> q injection is negative with cosphi=0.9 since vm is nearly 0.93 net.ext_grid.vm_pu = 0.93 net.sgen.q_mvar = 0. # pf without controller - pp.runpp(net) + runpp(net) vmb4 = net.res_bus.vm_pu.at[1] # pf with 1st controller net.controller.in_service = [True, False] - pp.runpp(net, run_control=True) + runpp(net, run_control=True) assert net.res_bus.vm_pu.at[1] > vmb4 assert net.res_sgen.q_mvar.at[0] > 0 cosphi_expected = 0.9 - q_expected = ((net.res_sgen.p_mw.at[0]/cosphi_expected)**2 - net.res_sgen.p_mw.at[0]**2)**0.5 + q_expected = ((net.res_sgen.p_mw.at[0] / cosphi_expected) ** 2 - net.res_sgen.p_mw.at[0] ** 2) ** 0.5 assert np.isclose(net.res_sgen.q_mvar.at[0], q_expected, atol=1e-5) # pf with 2nd controller (should have same result) net.controller.in_service = [False, True] - pp.runpp(net, run_control=True) + runpp(net, run_control=True) assert net.res_bus.vm_pu.at[1] > vmb4 assert np.isclose(net.res_sgen.q_mvar.at[0], q_expected, atol=1e-5) - # --- run control -> q injection is negative with cosphi is nearly 0.95 since vm is nearly 0.98 net.ext_grid.vm_pu = 0.98 net.sgen.q_mvar = 0. # pf without controller - pp.runpp(net) + runpp(net) vmb4 = net.res_bus.vm_pu.at[1] # pf with 1st controller net.controller.in_service = [True, False] - pp.runpp(net, run_control=True) + runpp(net, run_control=True) assert net.res_bus.vm_pu.at[1] > vmb4 assert net.res_sgen.q_mvar.at[0] > 0 - assert 0.95 < pp.cosphi_from_pq(-net.res_sgen.p_mw.at[0], -net.res_sgen.q_mvar.at[0])[0] < 0.96 + assert 0.95 < cosphi_from_pq(-net.res_sgen.p_mw.at[0], -net.res_sgen.q_mvar.at[0])[0] < 0.96 # pf with 2nd controller (should have different result because slope is not given by cosphi # points but by q points) net.sgen.q_mvar = 0. net.controller.in_service = [False, True] - pp.runpp(net, run_control=True) + runpp(net, run_control=True) assert net.res_bus.vm_pu.at[1] > vmb4 - assert 0.2*p < net.res_sgen.q_mvar.at[0] < 0.243*p + assert 0.2 * p < net.res_sgen.q_mvar.at[0] < 0.243 * p def test_cosphi_of_p_timeseries(): @@ -150,36 +155,36 @@ def test_cosphi_of_p_timeseries(): net = simple_test_net() sn = net.sgen.sn_mva.at[0] - ts_data = pd.DataFrame({"P_0": list(range(-50, -1360, -100))+[-1400, -1425, -1450, -1475]}) - ds = pp.timeseries.DFData(ts_data) + ts_data = pd.DataFrame({"P_0": list(range(-50, -1360, -100)) + [-1400, -1425, -1450, -1475]}) + ds = DFData(ts_data) # Create, add output and set outputwriter - ow = pp.timeseries.OutputWriter(net) + ow = OutputWriter(net) ow.log_variable("res_sgen", "p_mw") ow.log_variable("res_sgen", "q_mvar") - DER_no_q = pp.control.DERController( + DER_no_q = DERController( net, 0, data_source=ds, p_profile="P_0", profile_scale=-2e-3, q_model=DERModels.QModelCosphiPCurve({ 'p_points_pu': (0, 0.5, 1), 'cosphi_points': (1, 1, 1)})) - DER_no_q2 = pp.control.DERController( + DER_no_q2 = DERController( net, 0, data_source=ds, p_profile="P_0", profile_scale=-2e-3) - DER_ue = pp.control.DERController( + DER_ue = DERController( net, 0, data_source=ds, p_profile="P_0", profile_scale=-2e-3, q_model=DERModels.QModelCosphiPCurve({ 'p_points_pu': (0, 0.5, 1), 'cosphi_points': (1, 1, -0.95)})) - DER_ue2 = pp.control.DERController( + DER_ue2 = DERController( net, 0, data_source=ds, p_profile="P_0", profile_scale=-2e-3, q_model=DERModels.QModelCosphiPCurve({ 'p_points_pu': (0, 0.2, 0.25, 0.3, 0.5, 1), 'cosphi_points': (1, 1, 0.975, 1, 1, -0.95)})) - DER_oe = pp.control.DERController( + DER_oe = DERController( net, 0, data_source=ds, p_profile="P_0", profile_scale=-2e-3, q_model=DERModels.QModelCosphiPCurve({ 'p_points_pu': (0, 0.5, 1), @@ -188,23 +193,23 @@ def test_cosphi_of_p_timeseries(): # Run timeseries net.controller["in_service"] = False net.controller.in_service.at[DER_ue.index] = True - pp.timeseries.run_timeseries(net, time_steps=range(len(ts_data))) + run_timeseries(net, time_steps=range(len(ts_data))) res_ue = deepcopy(ow.output) net.controller["in_service"] = False net.controller.in_service.at[DER_ue2.index] = True - pp.timeseries.run_timeseries(net, time_steps=range(len(ts_data))) + run_timeseries(net, time_steps=range(len(ts_data))) res_ue2 = deepcopy(ow.output) net.controller["in_service"] = False net.controller.in_service.at[DER_oe.index] = True - pp.timeseries.run_timeseries(net, time_steps=range(len(ts_data))) + run_timeseries(net, time_steps=range(len(ts_data))) res_oe = deepcopy(ow.output) net.controller["in_service"] = False net.controller.in_service.at[DER_no_q.index] = True - pp.timeseries.run_timeseries(net, time_steps=range(len(ts_data))) + run_timeseries(net, time_steps=range(len(ts_data))) res_no_q = deepcopy(ow.output) net.controller["in_service"] = False net.controller.in_service.at[DER_no_q2.index] = True - pp.timeseries.run_timeseries(net, time_steps=range(len(ts_data))) + run_timeseries(net, time_steps=range(len(ts_data))) res_no_q2 = deepcopy(ow.output) if False: # plot cosphi course @@ -221,11 +226,11 @@ def test_cosphi_of_p_timeseries(): fig = plt.figure(figsize=(9, 5)) ax = fig.gca() for i_key, (key, res) in enumerate(res_to_plot.items()): - cosphi_pos_neg = pp.toolbox.cosphi_pos_neg_from_pq( + cosphi_pos_neg = toolbox.cosphi_pos_neg_from_pq( res["res_sgen.p_mw"], res["res_sgen.q_mvar"]) cosphi_pos_neg[np.isnan(cosphi_pos_neg[0])] = 1 - cosphi_pos = pp.toolbox.cosphi_to_pos(cosphi_pos_neg) - x = res["res_sgen.p_mw"].values.flatten()/net.sgen.sn_mva.at[0] + cosphi_pos = toolbox.cosphi_to_pos(cosphi_pos_neg) + x = res["res_sgen.p_mw"].values.flatten() / net.sgen.sn_mva.at[0] plt.plot(x, cosphi_pos, label=key, c=colors[i_key], marker="+") yticks = ax.get_yticks() yticks_signed = deepcopy(yticks) @@ -245,10 +250,10 @@ def test_cosphi_of_p_timeseries(): assert (res_oe["res_bus.vm_pu"][1] + 1e-8 >= res_no_q["res_bus.vm_pu"][1]).all() assert (res_ue["res_sgen.q_mvar"][0] <= 1e-5).all() assert np.allclose(res_ue["res_sgen.q_mvar"][0], - -res_oe["res_sgen.q_mvar"][0], atol=1e-5) + -res_oe["res_sgen.q_mvar"][0], atol=1e-5) # diff between ue and ue2 - should_be_same = ((ts_data["P_0"]*-2e-3/sn <= 0.2) | (ts_data["P_0"]*-2e-3/sn >= 0.3)).values + should_be_same = ((ts_data["P_0"] * -2e-3 / sn <= 0.2) | (ts_data["P_0"] * -2e-3 / sn >= 0.3)).values assert np.allclose(res_ue["res_sgen.q_mvar"].values[should_be_same, 0], res_ue2["res_sgen.q_mvar"].values[should_be_same, 0], atol=1e-5) assert np.allclose(res_ue["res_sgen.q_mvar"].values[~should_be_same, 0], 0, atol=1e-5) @@ -259,46 +264,46 @@ def test_QModels_with_2Dim_timeseries(): def define_outputwriters(nets): ows = list() for net in nets: - ow = pp.timeseries.OutputWriter(net) + ow = OutputWriter(net) ow.log_variable("res_sgen", "p_mw") ow.log_variable("res_sgen", "q_mvar") ows.append(ow) return tuple(ows) ts_data = pd.DataFrame({"P_DER1": [2., 2.5], "P_DER2": [1.75, 2.25]}) - ds = pp.timeseries.DFData(ts_data) + ds = DFData(ts_data) net0 = simple_test_net2() net1 = simple_test_net2() net2 = simple_test_net2() net3 = simple_test_net2() - pp.control.ConstControl(net0, element="sgen", variable="p_mw", element_index=[0, 1], - data_source=ds, profile_name=["P_DER1", "P_DER2"]) + ConstControl(net0, element="sgen", variable="p_mw", element_index=[0, 1], + data_source=ds, profile_name=["P_DER1", "P_DER2"]) net0.sgen["q_mvar"] = 0.1 * net0.sgen["sn_mva"] - pp.control.DERController( + DERController( net1, [0, 1], data_source=ds, p_profile=["P_DER1", "P_DER2"], q_model=DERModels.QModelConstQ(0.1), pqv_area=DERModels.PQArea4105(1), - ) - pp.control.DERController( + ) + DERController( net2, [0, 1], data_source=ds, profile_from_name=True, q_model=DERModels.QModelCosphiP(0.98), pqv_area=DERModels.PQArea4105(2), - ) - pp.control.DERController( + ) + DERController( net3, [0, 1], data_source=ds, profile_from_name=True, q_model=DERModels.QModelCosphiPQ(0.98), pqv_area=DERModels.PQVArea4130V3(380.), - ) + ) ows = define_outputwriters([net0, net1, net2, net3]) ow0, ow1, ow2, ow3 = ows - pp.timeseries.run_timeseries(net0, time_steps=[0, 1]) - pp.timeseries.run_timeseries(net1, time_steps=[0, 1]) - pp.timeseries.run_timeseries(net2, time_steps=[0, 1]) - pp.timeseries.run_timeseries(net3, time_steps=[0, 1]) + run_timeseries(net0, time_steps=[0, 1]) + run_timeseries(net1, time_steps=[0, 1]) + run_timeseries(net2, time_steps=[0, 1]) + run_timeseries(net3, time_steps=[0, 1]) # --- check results # ow0 and ow1 are equal @@ -312,11 +317,11 @@ def define_outputwriters(nets): # q of ow2 is as expected p = ow2.output["res_sgen.p_mw"].values.reshape((-1,)) q = ow2.output["res_sgen.q_mvar"].values.reshape((-1,)) - assert np.allclose(np.sin(np.arccos(0.98))*p, q, atol=1e-5) + assert np.allclose(np.sin(np.arccos(0.98)) * p, q, atol=1e-5) # cosphi of ow3 is correct p = ow3.output["res_sgen.p_mw"].values.reshape((-1,)) q = ow3.output["res_sgen.q_mvar"].values.reshape((-1,)) - assert np.allclose(pp.toolbox.cosphi_pos_neg_from_pq(p, q), 0.98, atol=1e-6) + assert np.allclose(cosphi_pos_neg_from_pq(p, q), 0.98, atol=1e-6) if __name__ == '__main__': diff --git a/pandapower/test/control/test_discrete_tap_control.py b/pandapower/test/control/test_discrete_tap_control.py index 3798d8d09..97b9e19ee 100644 --- a/pandapower/test/control/test_discrete_tap_control.py +++ b/pandapower/test/control/test_discrete_tap_control.py @@ -5,12 +5,16 @@ from copy import deepcopy import numpy as np -import pandapower as pp from pandapower.control import DiscreteTapControl import pytest -import pandapower.networks as nw import logging as log +from pandapower.run import runpp, set_user_pf_options +from pandapower.create import create_empty_network, create_buses, create_ext_grid, create_lines, create_transformer, \ + create_load, create_bus, create_line, create_transformer3w +from pandapower.networks.mv_oberrhein import mv_oberrhein +from pandapower.networks.simple_pandapower_test_networks import simple_four_bus_system + logger = log.getLogger(__name__) @@ -23,8 +27,8 @@ def _vm_in_desired_area(net, lower_vm, higher_vm, side, idx=None, trafo_table="t def test_discrete_tap_control_lv(): # --- load system and run power flow - net = nw.simple_four_bus_system() - pp.set_user_pf_options(net, init='dc', calculate_voltage_angles=True) + net = simple_four_bus_system() + set_user_pf_options(net, init='dc', calculate_voltage_angles=True) # --- initial tap data net.trafo.tap_side = 'lv' net.trafo.tap_neutral = 0 @@ -33,7 +37,7 @@ def test_discrete_tap_control_lv(): net.trafo.tap_step_percent = 1.25 net.trafo.tap_pos = 0 # --- run loadflow - pp.runpp(net) + runpp(net) DiscreteTapControl(net, 0, side='lv', vm_lower_pu=0.95, vm_upper_pu=0.99) @@ -42,7 +46,7 @@ def test_discrete_tap_control_lv(): % (net.res_bus.vm_pu[net.trafo.lv_bus].values.item(), net.trafo.tap_pos.values.item())) # run control - pp.runpp(net, run_control=True) + runpp(net, run_control=True) logger.info( "after DiscreteTapControl: trafo voltage at low voltage bus is %f, tap position is %f" % (net.res_bus.vm_pu[net.trafo.lv_bus].values.item(), net.trafo.tap_pos.values.item())) @@ -52,14 +56,14 @@ def test_discrete_tap_control_lv(): net.ext_grid.vm_pu = 1.03 # switch back tap position net.trafo.at[0, "tap_pos"] = 0 - pp.runpp(net) + runpp(net) logger.info("case2: high voltage") logger.info("before control: trafo voltage at low voltage bus is %f, tap position is %u" % (net.res_bus.vm_pu[net.trafo.lv_bus].values.item(), net.trafo.tap_pos.values.item())) # run control - pp.runpp(net, run_control=True) + runpp(net, run_control=True) logger.info( "after DiscreteTapControl: trafo voltage at low voltage bus is %f, tap position is %f" % (net.res_bus.vm_pu[net.trafo.lv_bus].values.item(), net.trafo.tap_pos.values.item())) @@ -68,14 +72,14 @@ def test_discrete_tap_control_lv(): net.ext_grid.vm_pu = 0.949 # switch back tap position net.trafo.at[0, "tap_pos"] = 0 - pp.runpp(net) + runpp(net) logger.info("case2: high voltage") logger.info("before control: trafo voltage at low voltage bus is %f, tap position is %u" % (net.res_bus.vm_pu[net.trafo.lv_bus].values.item(), net.trafo.tap_pos.values.item())) # run control - pp.runpp(net, run_control=True) + runpp(net, run_control=True) logger.info( "after DiscreteTapControl: trafo voltage at low voltage bus is %f, tap position is %f" % (net.res_bus.vm_pu[net.trafo.lv_bus].values.item(), net.trafo.tap_pos.values.item())) @@ -84,8 +88,8 @@ def test_discrete_tap_control_lv(): def test_discrete_tap_control_hv(): # --- load system and run power flow - net = nw.simple_four_bus_system() - pp.set_user_pf_options(net, init='dc', calculate_voltage_angles=True) + net = simple_four_bus_system() + set_user_pf_options(net, init='dc', calculate_voltage_angles=True) # --- initial tap data net.trafo.tap_side = 'hv' net.trafo.tap_neutral = 0 @@ -94,7 +98,7 @@ def test_discrete_tap_control_hv(): net.trafo.tap_step_percent = 1.25 net.trafo.tap_pos = 0 # --- run loadflow - pp.runpp(net) + runpp(net) DiscreteTapControl(net, 0, side='lv', vm_lower_pu=0.95, vm_upper_pu=0.99) @@ -103,7 +107,7 @@ def test_discrete_tap_control_hv(): % (net.res_bus.vm_pu[net.trafo.lv_bus].values.item(), net.trafo.tap_pos.values.item())) # run control - pp.runpp(net, run_control=True) + runpp(net, run_control=True) logger.info( "after DiscreteTapControl: trafo voltage at low voltage bus is %f, tap position is %f" % (net.res_bus.vm_pu[net.trafo.lv_bus].values.item(), net.trafo.tap_pos.values.item())) @@ -112,14 +116,14 @@ def test_discrete_tap_control_hv(): net.ext_grid.vm_pu = 1.03 # switch back tap position net.trafo.at[0, "tap_pos"] = 0 - pp.runpp(net) + runpp(net) logger.info("case2: high voltage") logger.info("before control: trafo voltage at low voltage bus is %f, tap position is %u" % (net.res_bus.vm_pu[net.trafo.lv_bus].values.item(), net.trafo.tap_pos.values.item())) # run control - pp.runpp(net, run_control=True) + runpp(net, run_control=True) logger.info( "after DiscreteTapControl: trafo voltage at low voltage bus is %f, tap position is %f" % (net.res_bus.vm_pu[net.trafo.lv_bus].values.item(), net.trafo.tap_pos.values.item())) @@ -128,14 +132,14 @@ def test_discrete_tap_control_hv(): net.ext_grid.vm_pu = 0.949 # switch back tap position net.trafo.at[0, "tap_pos"] = 0 - pp.runpp(net) + runpp(net) logger.info("case2: high voltage") logger.info("before control: trafo voltage at low voltage bus is %f, tap position is %u" % (net.res_bus.vm_pu[net.trafo.lv_bus].values.item(), net.trafo.tap_pos.values.item())) # run control - pp.runpp(net, run_control=True) + runpp(net, run_control=True) logger.info( "after DiscreteTapControl: trafo voltage at low voltage bus is %f, tap position is %f" % (net.res_bus.vm_pu[net.trafo.lv_bus].values.item(), net.trafo.tap_pos.values.item())) @@ -144,8 +148,8 @@ def test_discrete_tap_control_hv(): def test_discrete_tap_control_lv_from_tap_step_percent(): # --- load system and run power flow - net = nw.simple_four_bus_system() - pp.set_user_pf_options(net, init='dc', calculate_voltage_angles=True) + net = simple_four_bus_system() + set_user_pf_options(net, init='dc', calculate_voltage_angles=True) # --- initial tap data net.trafo.tap_side = 'lv' net.trafo.tap_neutral = 0 @@ -154,7 +158,7 @@ def test_discrete_tap_control_lv_from_tap_step_percent(): net.trafo.tap_step_percent = 1.25 net.trafo.tap_pos = 0 # --- run loadflow - pp.runpp(net) + runpp(net) DiscreteTapControl.from_tap_step_percent(net, 0, side='lv', vm_set_pu=0.98) @@ -163,7 +167,7 @@ def test_discrete_tap_control_lv_from_tap_step_percent(): % (net.res_bus.vm_pu[net.trafo.lv_bus].values.item(), net.trafo.tap_pos.values.item())) # run control - pp.runpp(net, run_control=True) + runpp(net, run_control=True) logger.info( "after DiscreteTapControl: trafo voltage at low voltage bus is %f, tap position is %f" % (net.res_bus.vm_pu[net.trafo.lv_bus].values.item(), net.trafo.tap_pos.values.item())) @@ -171,11 +175,11 @@ def test_discrete_tap_control_lv_from_tap_step_percent(): # check if it changes the lower and upper limits net.controller.object.at[0].vm_set_pu = 1 - pp.runpp(net, run_control=True) + runpp(net, run_control=True) assert abs(net.controller.object.at[0].vm_upper_pu - 1.00725) < 1e-6 assert abs(net.controller.object.at[0].vm_lower_pu - 0.99275) < 1e-6 net.controller.object.at[0].vm_set_pu = 0.98 - pp.runpp(net, run_control=True) + runpp(net, run_control=True) assert abs(net.controller.object.at[0].vm_upper_pu - 0.98725) < 1e-6 assert abs(net.controller.object.at[0].vm_lower_pu - 0.97275) < 1e-6 @@ -183,14 +187,14 @@ def test_discrete_tap_control_lv_from_tap_step_percent(): net.ext_grid.vm_pu = 1.03 # switch back tap position net.trafo.at[0, "tap_pos"] = 0 - pp.runpp(net) + runpp(net) logger.info("case2: high voltage") logger.info("before control: trafo voltage at low voltage bus is %f, tap position is %u" % (net.res_bus.vm_pu[net.trafo.lv_bus].values.item(), net.trafo.tap_pos.values.item())) # run control - pp.runpp(net, run_control=True) + runpp(net, run_control=True) logger.info( "after DiscreteTapControl: trafo voltage at low voltage bus is %f, tap position is %f" % (net.res_bus.vm_pu[net.trafo.lv_bus].values.item(), net.trafo.tap_pos.values.item())) @@ -199,14 +203,14 @@ def test_discrete_tap_control_lv_from_tap_step_percent(): net.ext_grid.vm_pu = 0.969 # switch back tap position net.trafo.at[0, "tap_pos"] = 0 - pp.runpp(net) + runpp(net) logger.info("case2: high voltage") logger.info("before control: trafo voltage at low voltage bus is %f, tap position is %u" % (net.res_bus.vm_pu[net.trafo.lv_bus].values.item(), net.trafo.tap_pos.values.item())) # run control - pp.runpp(net, run_control=True) + runpp(net, run_control=True) logger.info( "after DiscreteTapControl: trafo voltage at low voltage bus is %f, tap position is %f" % (net.res_bus.vm_pu[net.trafo.lv_bus].values.item(), net.trafo.tap_pos.values.item())) @@ -215,8 +219,8 @@ def test_discrete_tap_control_lv_from_tap_step_percent(): def test_discrete_tap_control_hv_from_tap_step_percent(): # --- load system and run power flow - net = nw.simple_four_bus_system() - pp.set_user_pf_options(net, init='dc', calculate_voltage_angles=True) + net = simple_four_bus_system() + set_user_pf_options(net, init='dc', calculate_voltage_angles=True) # --- initial tap data net.trafo.tap_side = 'hv' net.trafo.tap_neutral = 0 @@ -225,7 +229,7 @@ def test_discrete_tap_control_hv_from_tap_step_percent(): net.trafo.tap_step_percent = 1.25 net.trafo.tap_pos = 0 # --- run loadflow - pp.runpp(net) + runpp(net) DiscreteTapControl.from_tap_step_percent(net, 0, side='lv', vm_set_pu=0.98) @@ -234,7 +238,7 @@ def test_discrete_tap_control_hv_from_tap_step_percent(): % (net.res_bus.vm_pu[net.trafo.lv_bus].values.item(), net.trafo.tap_pos.values.item())) # run control - pp.runpp(net, run_control=True) + runpp(net, run_control=True) logger.info( "after DiscreteTapControl: trafo voltage at low voltage bus is %f, tap position is %f" % (net.res_bus.vm_pu[net.trafo.lv_bus].values.item(), net.trafo.tap_pos.values.item())) @@ -242,11 +246,11 @@ def test_discrete_tap_control_hv_from_tap_step_percent(): # check if it changes the lower and upper limits net.controller.object.at[0].vm_set_pu = 1 - pp.runpp(net, run_control=True) + runpp(net, run_control=True) assert abs(net.controller.object.at[0].vm_upper_pu - 1.00725) < 1e-6 assert abs(net.controller.object.at[0].vm_lower_pu - 0.99275) < 1e-6 net.controller.object.at[0].vm_set_pu = 0.98 - pp.runpp(net, run_control=True) + runpp(net, run_control=True) assert abs(net.controller.object.at[0].vm_upper_pu - 0.98725) < 1e-6 assert abs(net.controller.object.at[0].vm_lower_pu - 0.97275) < 1e-6 @@ -254,14 +258,14 @@ def test_discrete_tap_control_hv_from_tap_step_percent(): net.ext_grid.vm_pu = 1.03 # switch back tap position net.trafo.at[0, "tap_pos"] = 0 - pp.runpp(net) + runpp(net) logger.info("case2: high voltage") logger.info("before control: trafo voltage at low voltage bus is %f, tap position is %u" % (net.res_bus.vm_pu[net.trafo.lv_bus].values.item(), net.trafo.tap_pos.values.item())) # run control - pp.runpp(net, run_control=True) + runpp(net, run_control=True) logger.info( "after DiscreteTapControl: trafo voltage at low voltage bus is %f, tap position is %f" % (net.res_bus.vm_pu[net.trafo.lv_bus].values.item(), net.trafo.tap_pos.values.item())) @@ -270,14 +274,14 @@ def test_discrete_tap_control_hv_from_tap_step_percent(): net.ext_grid.vm_pu = 0.969 # switch back tap position net.trafo.at[0, "tap_pos"] = 0 - pp.runpp(net) + runpp(net) logger.info("case2: high voltage") logger.info("before control: trafo voltage at low voltage bus is %f, tap position is %u" % (net.res_bus.vm_pu[net.trafo.lv_bus].values.item(), net.trafo.tap_pos.values.item())) # run control - pp.runpp(net, run_control=True) + runpp(net, run_control=True) logger.info( "after DiscreteTapControl: trafo voltage at low voltage bus is %f, tap position is %f" % (net.res_bus.vm_pu[net.trafo.lv_bus].values.item(), net.trafo.tap_pos.values.item())) @@ -286,18 +290,18 @@ def test_discrete_tap_control_hv_from_tap_step_percent(): def test_discrete_tap_control_vectorized_lv(): # --- load system and run power flow - net = pp.create_empty_network() - pp.create_buses(net, 6, 110) - pp.create_buses(net, 5, 20) - pp.create_ext_grid(net, 0) - pp.create_lines(net, np.zeros(5), np.arange(1, 6), 10, "243-AL1/39-ST1A 110.0") + net = create_empty_network() + create_buses(net, 6, 110) + create_buses(net, 5, 20) + create_ext_grid(net, 0) + create_lines(net, np.zeros(5), np.arange(1, 6), 10, "243-AL1/39-ST1A 110.0") for hv, lv in zip(np.arange(1, 6), np.arange(6,11)): - pp.create_transformer(net, hv, lv, "63 MVA 110/20 kV") - pp.create_load(net, lv, 25*(lv-8), 25*(lv-8) * 0.4) - pp.set_user_pf_options(net, init='dc', calculate_voltage_angles=True) + create_transformer(net, hv, lv, "63 MVA 110/20 kV") + create_load(net, lv, 25*(lv-8), 25*(lv-8) * 0.4) + set_user_pf_options(net, init='dc', calculate_voltage_angles=True) net.trafo.iloc[3:, net.trafo.columns.get_loc("tap_side")] = "lv" # --- run loadflow - pp.runpp(net) + runpp(net) assert not all(_vm_in_desired_area(net, 1.01, 1.03, "lv")) # there should be something # to do for the controllers @@ -305,11 +309,11 @@ def test_discrete_tap_control_vectorized_lv(): # create with individual controllers for comparison for tid in net.trafo.index.values: - # pp.control.ContinuousTapControl(net_ref, tid, side='lv', vm_set_pu=1.02) + # control.ContinuousTapControl(net_ref, tid, side='lv', vm_set_pu=1.02) DiscreteTapControl(net_ref, tid, side='lv', vm_lower_pu=1.01, vm_upper_pu=1.03) # run control reference - pp.runpp(net_ref, run_control=True) + runpp(net_ref, run_control=True) assert not np.allclose(net_ref.trafo.tap_pos.values, 0) # since there is something to do, the # tap_pos shouldn't be 0 @@ -317,25 +321,25 @@ def test_discrete_tap_control_vectorized_lv(): # now create the vectorized version DiscreteTapControl(net, net.trafo.index.values, side='lv', vm_lower_pu=1.01, vm_upper_pu=1.03) - pp.runpp(net, run_control=True) + runpp(net, run_control=True) assert np.all(net_ref.trafo.tap_pos == net.trafo.tap_pos) def test_discrete_tap_control_vectorized_hv(): # --- load system and run power flow - net = pp.create_empty_network() - pp.create_buses(net, 6, 20) - pp.create_buses(net, 5, 110) - pp.create_ext_grid(net, 0) - pp.create_lines(net, np.zeros(5), np.arange(1, 6), 10, "243-AL1/39-ST1A 110.0") + net = create_empty_network() + create_buses(net, 6, 20) + create_buses(net, 5, 110) + create_ext_grid(net, 0) + create_lines(net, np.zeros(5), np.arange(1, 6), 10, "243-AL1/39-ST1A 110.0") for lv, hv in zip(np.arange(1, 6), np.arange(6, 11)): - pp.create_transformer(net, hv, lv, "63 MVA 110/20 kV") - pp.create_load(net, hv, 2.5*(hv-8), 2.5*(hv-8) * 0.4) - pp.set_user_pf_options(net, init='dc', calculate_voltage_angles=True) + create_transformer(net, hv, lv, "63 MVA 110/20 kV") + create_load(net, hv, 2.5*(hv-8), 2.5*(hv-8) * 0.4) + set_user_pf_options(net, init='dc', calculate_voltage_angles=True) net.trafo.loc[3:, 'tap_side'] = "lv" # --- run loadflow - pp.runpp(net) + runpp(net) assert not all(_vm_in_desired_area(net, 1.01, 1.03, "hv")) # there should be something # to do for the controllers @@ -343,11 +347,11 @@ def test_discrete_tap_control_vectorized_hv(): # create with individual controllers for comparison for tid in net.trafo.index.values: - # pp.control.ContinuousTapControl(net_ref, tid, side='hv', vm_set_pu=1.02) + # control.ContinuousTapControl(net_ref, tid, side='hv', vm_set_pu=1.02) DiscreteTapControl(net_ref, tid, side='hv', vm_lower_pu=1.01, vm_upper_pu=1.03) # run control reference - pp.runpp(net_ref, run_control=True) + runpp(net_ref, run_control=True) assert not np.allclose(net_ref.trafo.tap_pos.values, 0) # since there is something to do, the # tap_pos shouldn't be 0 @@ -355,27 +359,27 @@ def test_discrete_tap_control_vectorized_hv(): # now create the vectorized version DiscreteTapControl(net, net.trafo.index, side='hv', vm_lower_pu=1.01, vm_upper_pu=1.03) - pp.runpp(net, run_control=True) + runpp(net, run_control=True) assert np.all(net_ref.trafo.tap_pos == net.trafo.tap_pos) def test_continuous_tap_control_side_mv(): # --- load system and run power flow - net = pp.create_empty_network() - pp.create_buses(net, 2, 110) - pp.create_buses(net, 1, 20) - pp.create_bus(net, 10) - pp.create_ext_grid(net, 0) - pp.create_line(net, 0, 1, 10, "243-AL1/39-ST1A 110.0") - pp.create_transformer3w(net, 1, 2, 3, "63/25/38 MVA 110/20/10 kV") - pp.create_load(net, 2, 5., 2.) - pp.create_load(net, 3, 5., 2.) - pp.set_user_pf_options(net, init='dc', calculate_voltage_angles=True) + net = create_empty_network() + create_buses(net, 2, 110) + create_buses(net, 1, 20) + create_bus(net, 10) + create_ext_grid(net, 0) + create_line(net, 0, 1, 10, "243-AL1/39-ST1A 110.0") + create_transformer3w(net, 1, 2, 3, "63/25/38 MVA 110/20/10 kV") + create_load(net, 2, 5., 2.) + create_load(net, 3, 5., 2.) + set_user_pf_options(net, init='dc', calculate_voltage_angles=True) tol = 1e-4 # --- run loadflow - pp.runpp(net) + runpp(net) assert not any(_vm_in_desired_area(net, 1.01, 1.03, "mv", trafo_table="trafo3w")) # there should be # something to do for the controllers @@ -383,7 +387,7 @@ def test_continuous_tap_control_side_mv(): DiscreteTapControl(net, 0, vm_lower_pu=1.01, vm_upper_pu=1.03, side='mv', tol=tol, element="trafo3w") # --- run control reference - pp.runpp(net, run_control=True) + runpp(net, run_control=True) assert not any(_vm_in_desired_area(net_ref, 1.01, 1.03, "mv", trafo_table="trafo3w")) assert np.allclose(net_ref.trafo3w.tap_pos.values, 0) @@ -391,7 +395,7 @@ def test_continuous_tap_control_side_mv(): assert not np.allclose(net.trafo3w.tap_pos.values, 0) def test_discrete_trafo_control_with_oos_trafo(): - net = pp.networks.mv_oberrhein() + net = mv_oberrhein() # switch transformer out of service net.trafo.loc[114, 'in_service'] = False DiscreteTapControl(net=net, element_index=114, vm_lower_pu=1.01, vm_upper_pu=1.03) diff --git a/pandapower/test/control/test_shunt_control.py b/pandapower/test/control/test_shunt_control.py index 2f53ad098..e76adcf83 100644 --- a/pandapower/test/control/test_shunt_control.py +++ b/pandapower/test/control/test_shunt_control.py @@ -1,16 +1,18 @@ import pytest -import pandapower as pp from pandapower.control.controller.shunt_control import DiscreteShuntController from pandapower.control.controller.station_control import BinarySearchControl +from pandapower.create import create_empty_network, create_buses, create_ext_grid, create_line_from_parameters, \ + create_shunt +from pandapower.run import runpp def simple_test_net_shunt_control(): - net = pp.create_empty_network() - b = pp.create_buses(net, 2, 110) - pp.create_ext_grid(net, b[0]) - pp.create_line_from_parameters(net, from_bus=b[0], to_bus=b[1], length_km=50, r_ohm_per_km=0.1021, + net = create_empty_network() + b = create_buses(net, 2, 110) + create_ext_grid(net, b[0]) + create_line_from_parameters(net, from_bus=b[0], to_bus=b[1], length_km=50, r_ohm_per_km=0.1021, x_ohm_per_km=0.1570796, max_i_ka=0.461, c_nf_per_km=130) - pp.create_shunt(net, bus=b[1], q_mvar=-50, p_mw=0, step=1, max_step=5) + create_shunt(net, bus=b[1], q_mvar=-50, p_mw=0, step=1, max_step=5) return net def test_continuous_shunt_control(tol=1e-6): @@ -19,18 +21,18 @@ def test_continuous_shunt_control(tol=1e-6): output_element_index=[0], output_element_in_service=[True], output_values_distribution=[1], input_element='res_bus', input_variable='vm_pu', input_element_index=[1], set_point=1.08, voltage_ctrl=True, tol=tol) - pp.runpp(net, run_control=False) + runpp(net, run_control=False) assert (abs(net.res_bus.loc[1, "vm_pu"] - 1.041789) < tol) - pp.runpp(net, run_control=True) + runpp(net, run_control=True) assert (abs(net.res_bus.loc[1, "vm_pu"] - 1.08) < tol) assert (abs(net.shunt.loc[0, "step"] - 2.075275) < tol) def test_discrete_shunt_control(tol=1e-6): net = simple_test_net_shunt_control() DiscreteShuntController(net, shunt_index=0, bus_index=1, vm_set_pu=1.08, tol=1e-2) - pp.runpp(net, run_control=False) + runpp(net, run_control=False) assert (abs(net.res_bus.loc[1, "vm_pu"] - 1.041789) < tol) - pp.runpp(net, run_control=True) + runpp(net, run_control=True) assert (abs(net.res_bus.loc[1, "vm_pu"] - 1.077258) < tol) assert net.shunt.loc[0, "step"] == 2 diff --git a/pandapower/test/control/test_stactrl.py b/pandapower/test/control/test_stactrl.py index 9d2f14560..30facadfe 100644 --- a/pandapower/test/control/test_stactrl.py +++ b/pandapower/test/control/test_stactrl.py @@ -5,11 +5,13 @@ import pytest import os -# from copy import deepcopy -# import numpy as np -# import pandas as pd -import pandapower as pp -# import powerfactory as pf + +from pandapower.control.controller.station_control import BinarySearchControl, DroopControl +from pandapower.create import create_empty_network, create_bus, create_buses, create_ext_grid, create_transformer, \ + create_load, create_line, create_sgen +from pandapower.run import runpp +from pandapower.file_io import from_json +from pandapower import pp_dir try: from pandaplan.core import pplog as logging @@ -20,58 +22,58 @@ def simple_test_net(): - net = pp.create_empty_network() - pp.create_bus(net, 110) - pp.create_buses(net, 2, 20) - pp.create_ext_grid(net, 0) - pp.create_transformer(net, 0, 1, "63 MVA 110/20 kV") - pp.create_load(net, 1, 3, 0.1) - pp.create_sgen(net, 2, p_mw=2., sn_mva=10, name="sgen1") - pp.create_line(net, 1, 2, length_km=0.1, std_type="NAYY 4x50 SE") + net = create_empty_network() + create_bus(net, 110) + create_buses(net, 2, 20) + create_ext_grid(net, 0) + create_transformer(net, 0, 1, "63 MVA 110/20 kV") + create_load(net, 1, 3, 0.1) + create_sgen(net, 2, p_mw=2., sn_mva=10, name="sgen1") + create_line(net, 1, 2, length_km=0.1, std_type="NAYY 4x50 SE") return net def test_voltctrl(): net = simple_test_net() tol = 1e-6 - pp.control.BinarySearchControl(net, ctrl_in_service=True, + BinarySearchControl(net, ctrl_in_service=True, output_element="sgen", output_variable="q_mvar", output_element_index=[0], output_element_in_service=[True], output_values_distribution=[1], input_element="res_bus", input_variable="vm_pu", input_element_index=[1], set_point=1.02, voltage_ctrl=True, tol=tol) - pp.runpp(net, run_control=False) + runpp(net, run_control=False) assert (abs(net.res_bus.loc[1, "vm_pu"] - 0.999648) < tol) - pp.runpp(net, run_control=True) + runpp(net, run_control=True) assert (abs(net.res_bus.loc[1, "vm_pu"] - 1.02) < tol) def test_voltctrl_droop(): net = simple_test_net() tol = 1e-3 - bsc = pp.control.BinarySearchControl(net, ctrl_in_service=True, + bsc = BinarySearchControl(net, ctrl_in_service=True, output_element="sgen", output_variable="q_mvar", output_element_index=[0], output_element_in_service=[True], output_values_distribution=[1], input_element="res_trafo", input_variable="q_hv_mvar", input_element_index=[0], set_point=1.02, voltage_ctrl=True, bus_idx=1, tol=tol) - pp.control.DroopControl(net, q_droop_mvar=40, bus_idx=1, + DroopControl(net, q_droop_mvar=40, bus_idx=1, vm_set_pu=1.02, controller_idx=bsc.index, voltage_ctrl=True) - pp.runpp(net, run_control=False) + runpp(net, run_control=False) assert (abs(net.res_bus.loc[1, "vm_pu"] - 0.999648) < tol) - pp.runpp(net, run_control=True) + runpp(net, run_control=True) assert (abs(net.res_bus.loc[1, "vm_pu"] - (1.02 + net.res_trafo.loc[0, "q_hv_mvar"] / 40)) < tol) def test_qctrl(): net = simple_test_net() tol = 1e-6 - pp.control.BinarySearchControl(net, ctrl_in_service=True, output_element="sgen", output_variable="q_mvar", + BinarySearchControl(net, ctrl_in_service=True, output_element="sgen", output_variable="q_mvar", output_element_index=[0], output_element_in_service=[True], output_values_distribution=[1], input_element="res_line", damping_factor=0.9, input_variable=["q_to_mvar"], input_element_index=0, set_point=1, voltage_ctrl=False, tol=1e-6) - pp.runpp(net, run_control=False) + runpp(net, run_control=False) assert (abs(net.res_line.loc[0, "q_to_mvar"] - (-6.092016e-12)) < tol) - pp.runpp(net, run_control=True) + runpp(net, run_control=True) assert (abs(net.res_line.loc[0, "q_to_mvar"] - 1.0) < tol) @@ -79,26 +81,26 @@ def test_qctrl_droop(): net = simple_test_net() tol = 1e-6 net.load.loc[0, "p_mw"] = 60 # create voltage drop at bus 1 - bsc = pp.control.BinarySearchControl(net, ctrl_in_service=True, + bsc = BinarySearchControl(net, ctrl_in_service=True, output_element="sgen", output_variable="q_mvar", output_element_index=[0], output_element_in_service=[True], output_values_distribution=[1], input_element="res_line", damping_factor=0.9, input_variable=["q_to_mvar"], input_element_index=0, set_point=1, voltage_ctrl=False, tol=1e-6) - pp.control.DroopControl(net, q_droop_mvar=40, bus_idx=1, + DroopControl(net, q_droop_mvar=40, bus_idx=1, vm_set_pu=1, vm_set_ub=1.005, vm_set_lb=0.995, controller_idx=bsc.index, voltage_ctrl=False) - pp.runpp(net, run_control=False) + runpp(net, run_control=False) assert (abs(net.res_line.loc[0, "q_to_mvar"] - (-7.094325e-13)) < tol) - pp.runpp(net, run_control=True) + runpp(net, run_control=True) assert (abs(net.res_line.loc[0, "q_to_mvar"] - (1 + (0.995 - net.res_bus.loc[1, "vm_pu"]) * 40)) < tol) def test_stactrl_pf_import(): - path = os.path.join(pp.pp_dir, 'test', 'control', 'testfiles', 'stactrl_test.json') - net = pp.from_json(path) + path = os.path.join(pp_dir, 'test', 'control', 'testfiles', 'stactrl_test.json') + net = from_json(path) tol = 1e-3 - pp.runpp(net, run_control=True) + runpp(net, run_control=True) print("\n") print("--------------------------------------") print("Scenario 1 - Constant Q") diff --git a/pandapower/test/control/test_tap_dependent_impedance.py b/pandapower/test/control/test_tap_dependent_impedance.py index a6af15ce2..a33c392a4 100644 --- a/pandapower/test/control/test_tap_dependent_impedance.py +++ b/pandapower/test/control/test_tap_dependent_impedance.py @@ -7,59 +7,62 @@ import numpy as np import logging -import pandapower as pp from pandapower.control import Characteristic, SplineCharacteristic, TapDependentImpedance, \ - trafo_characteristics_diagnostic + trafo_characteristics_diagnostic, create_trafo_characteristics +from pandapower.control.util.diagnostic import logger as control_logger +from pandapower.create import create_empty_network, create_bus, create_ext_grid, create_transformer_from_parameters, \ + create_load, create_line_from_parameters, create_transformer, create_transformer3w_from_parameters +from pandapower.run import runpp def test_tap_dependent_impedance_control(): - net = pp.create_empty_network() - b1 = pp.create_bus(net, 110) - b2 = pp.create_bus(net, 20) - pp.create_ext_grid(net, b1) - pp.create_transformer_from_parameters(net, b1, b2, 40, 110, 21, 0.5, 12.3, 25, 0.11, 0, 'hv', 10, 20, 0, 1.8, 180, 10) + net = create_empty_network() + b1 = create_bus(net, 110) + b2 = create_bus(net, 20) + create_ext_grid(net, b1) + create_transformer_from_parameters(net, b1, b2, 40, 110, 21, 0.5, 12.3, 25, 0.11, 0, 'hv', 10, 20, 0, 1.8, 180, 10) characteristic_vk = Characteristic.from_points(net, ((0, 13.5), (10, 12.3), (20, 11.1))) characteristic_vkr = Characteristic.from_points(net, ((0, 0.52), (10, 0.5), (20, 0.53))) TapDependentImpedance(net, 0, characteristic_vk.index, output_variable='vk_percent', restore=False) TapDependentImpedance(net, 0, characteristic_vkr.index, output_variable='vkr_percent', restore=False) - pp.runpp(net, run_control=True) + runpp(net, run_control=True) assert net.trafo.vk_percent.at[0] == 12.3 assert net.trafo.vkr_percent.at[0] == 0.5 net.trafo.tap_pos = 0 - pp.runpp(net, run_control=True) + runpp(net, run_control=True) assert net.trafo.vk_percent.at[0] == 13.5 assert net.trafo.vkr_percent.at[0] == 0.52 net.trafo.tap_pos = 20 - pp.runpp(net, run_control=True) + runpp(net, run_control=True) assert net.trafo.vk_percent.at[0] == 11.1 assert net.trafo.vkr_percent.at[0] == 0.53 def test_tap_dependent_impedance_restore(): - net = pp.create_empty_network() - b1 = pp.create_bus(net, 110) - b2 = pp.create_bus(net, 20) - pp.create_ext_grid(net, b1) - pp.create_load(net, b2, 20) - pp.create_transformer_from_parameters(net, b1, b2, 40, 110, 21, 0.5, 12.3, 25, 0.11, 0, 'hv', 10, 20, 0, 1.8, 180, 10) + net = create_empty_network() + b1 = create_bus(net, 110) + b2 = create_bus(net, 20) + create_ext_grid(net, b1) + create_load(net, b2, 20) + create_transformer_from_parameters(net, b1, b2, 40, 110, 21, 0.5, 12.3, 25, 0.11, 0, 'hv', 10, 20, 0, 1.8, 180, 10) characteristic_vk = Characteristic.from_points(net, ((0, 13.5), (10, 12.3), (20, 11.1))) characteristic_vkr = Characteristic.from_points(net, ((0, 0.52), (10, 0.5), (20, 0.53))) TapDependentImpedance(net, 0, characteristic_vk.index, output_variable='vk_percent', restore=True) TapDependentImpedance(net, 0, characteristic_vkr.index, output_variable='vkr_percent', restore=True) - pp.runpp(net, run_control=True) + runpp(net, run_control=True) # remember the losses for the neutral position pl_mw_neutral = net.res_trafo.pl_mw.at[0] assert net.trafo.vk_percent.at[0] == 12.3 assert net.trafo.vkr_percent.at[0] == 0.5 net.trafo.tap_pos = 0 - pp.runpp(net, run_control=True) + runpp(net, run_control=True) # check if the impedance has been restored assert net.trafo.vk_percent.at[0] == 12.3 assert net.trafo.vkr_percent.at[0] == 0.5 @@ -67,7 +70,7 @@ def test_tap_dependent_impedance_restore(): assert abs(net.res_trafo.pl_mw.at[0] - pl_mw_neutral) > 0.015 net.trafo.tap_pos = 20 - pp.runpp(net, run_control=True) + runpp(net, run_control=True) # check if the impedance has been restored assert net.trafo.vk_percent.at[0] == 12.3 assert net.trafo.vkr_percent.at[0] == 0.5 @@ -76,7 +79,7 @@ def test_tap_dependent_impedance_restore(): def test_characteristic(): - net = pp.create_empty_network() + net = create_empty_network() x_points = [0, 1, 2] y_points = [3, 4, 5] c = Characteristic(net, x_points, y_points) @@ -111,37 +114,37 @@ def test_characteristic(): def test_characteristic_diagnostic(): - net = pp.create_empty_network() + net = create_empty_network() vn_kv = 20 - b1 = pp.create_bus(net, vn_kv=vn_kv) - pp.create_ext_grid(net, b1, vm_pu=1.01) - b2 = pp.create_bus(net, vn_kv=vn_kv) - l1 = pp.create_line_from_parameters(net, b1, b2, 12.2, r_ohm_per_km=0.08, x_ohm_per_km=0.12, + b1 = create_bus(net, vn_kv=vn_kv) + create_ext_grid(net, b1, vm_pu=1.01) + b2 = create_bus(net, vn_kv=vn_kv) + l1 = create_line_from_parameters(net, b1, b2, 12.2, r_ohm_per_km=0.08, x_ohm_per_km=0.12, c_nf_per_km=300, max_i_ka=.2, df=.8) - cb = pp.create_bus(net, vn_kv=0.4) - pp.create_load(net, cb, 0.2, 0.05) - pp.create_transformer(net, hv_bus=b2, lv_bus=cb, std_type="0.25 MVA 20/0.4 kV", tap_pos=2) + cb = create_bus(net, vn_kv=0.4) + create_load(net, cb, 0.2, 0.05) + create_transformer(net, hv_bus=b2, lv_bus=cb, std_type="0.25 MVA 20/0.4 kV", tap_pos=2) - pp.control.create_trafo_characteristics(net, 'trafo', 0, 'vk_percent', + create_trafo_characteristics(net, 'trafo', 0, 'vk_percent', [-2, -1, 0, 1, 2], [5, 5.2, 6, 6.8, 7]) # single mode - pp.control.create_trafo_characteristics(net, 'trafo', [0], 'vkr_percent', + create_trafo_characteristics(net, 'trafo', [0], 'vkr_percent', [[-2, -1, 0, 1, 2]], [[1.3, 1.4, 1.44, 1.5, 1.6]]) # multiple indices # let's make some invalid configurations net.trafo.at[0, "vk_percent"] += 1e-6 # missing any characteristic - pp.create_transformer(net, hv_bus=net.trafo.at[0, 'hv_bus'], + create_transformer(net, hv_bus=net.trafo.at[0, 'hv_bus'], lv_bus=net.trafo.at[0, 'lv_bus'], std_type="0.25 MVA 20/0.4 kV", tap_pos=2, tap_dependent_impedance=True) b2 = net.trafo.at[0, "hv_bus"] - cb = pp.create_bus(net, vn_kv=0.4) - pp.create_load(net, cb, 0.2, 0.05) - pp.create_transformer(net, hv_bus=b2, lv_bus=cb, std_type="0.25 MVA 20/0.4 kV", tap_pos=2) + cb = create_bus(net, vn_kv=0.4) + create_load(net, cb, 0.2, 0.05) + create_transformer(net, hv_bus=b2, lv_bus=cb, std_type="0.25 MVA 20/0.4 kV", tap_pos=2) # missing columns for characteristics - cbm = pp.create_bus(net, vn_kv=0.9) - pp.create_load(net, cbm, 0.1, 0.03) - pp.create_transformer3w_from_parameters(net, hv_bus=b2, mv_bus=cbm, lv_bus=cb, + cbm = create_bus(net, vn_kv=0.9) + create_load(net, cbm, 0.1, 0.03) + create_transformer3w_from_parameters(net, hv_bus=b2, mv_bus=cbm, lv_bus=cb, vn_hv_kv=20., vn_mv_kv=0.9, vn_lv_kv=0.45, sn_hv_mva=0.6, sn_mv_mva=0.5, sn_lv_mva=0.4, vk_hv_percent=1., vk_mv_percent=1., vk_lv_percent=1., vkr_hv_percent=0.3, @@ -154,7 +157,7 @@ def test_characteristic_diagnostic(): import io s = io.StringIO() h = logging.StreamHandler(stream=s) - logger = pp.control.util.diagnostic.logger + logger = control_logger logger.addHandler(h) old_level = logger.level @@ -179,7 +182,7 @@ def test_characteristic_diagnostic(): assert "vk_lv_percent_characteristic is missing" in msg assert "vkr_lv_percent_characteristic is missing" in msg - pp.control.util.diagnostic.logger.removeHandler(h) + control_logger.removeHandler(h) del h del s diff --git a/pandapower/test/control/test_vm_set_tap_control.py b/pandapower/test/control/test_vm_set_tap_control.py index 033a3dfd9..d6b1540ca 100644 --- a/pandapower/test/control/test_vm_set_tap_control.py +++ b/pandapower/test/control/test_vm_set_tap_control.py @@ -3,43 +3,47 @@ # Copyright (c) 2016-2024 by University of Kassel and Fraunhofer Institute for Energy Economics # and Energy System Technology (IEE), Kassel. All rights reserved. -import pandapower as pp import pytest -from pandapower import control -from pandapower.control import Characteristic + +from pandapower.control.controller.trafo.ContinuousTapControl import ContinuousTapControl +from pandapower.control.controller.trafo.VmSetTapControl import VmSetTapControl +from pandapower.control.util.characteristic import Characteristic +from pandapower.create import create_empty_network, create_bus, create_ext_grid, create_load, create_sgen, \ + create_transformer +from pandapower.run import runpp def test_continuous_p(): - net = pp.create_empty_network() - hv = pp.create_bus(net, vn_kv=110.) - lv = pp.create_bus(net, vn_kv=20) - t = pp.create_transformer(net, hv, lv, std_type='40 MVA 110/20 kV') - pp.create_ext_grid(net, hv) + net = create_empty_network() + hv = create_bus(net, vn_kv=110.) + lv = create_bus(net, vn_kv=20) + t = create_transformer(net, hv, lv, std_type='40 MVA 110/20 kV') + create_ext_grid(net, hv) eps = 0.0005 - c = control.ContinuousTapControl(net, t, 1., tol=eps) + c = ContinuousTapControl(net, t, 1., tol=eps) characteristic = Characteristic(net, [10, 20], [0.95, 1.05]) - tc = control.VmSetTapControl(net, 0, characteristic.index, tol=eps) + tc = VmSetTapControl(net, 0, characteristic.index, tol=eps) # create 20kW load - lid = pp.create_load(net, lv, 20) - gid = pp.create_sgen(net, lv, 0) - pp.runpp(net, run_control=True) + lid = create_load(net, lv, 20) + gid = create_sgen(net, lv, 0) + runpp(net, run_control=True) # we expect the tap to converge at upper voltage limit assert abs(net.res_bus.vm_pu.at[c.trafobus] - 1.05) < eps # power sums up to 15kW net.sgen.at[gid, "p_mw"] = 5 - pp.runpp(net, run_control=True) + runpp(net, run_control=True) # we expect the tap to converge at 1.0 pu assert abs(net.res_bus.vm_pu.at[c.trafobus] - 1.) < eps # generation now cancels load net.sgen.at[gid, "p_mw"] = 10 - pp.runpp(net, run_control=True) + runpp(net, run_control=True) # we expect the tap to converge at lower voltage limit assert abs(net.res_bus.vm_pu.at[c.trafobus] - 0.95) < eps @@ -47,7 +51,7 @@ def test_continuous_p(): # testing limits # power flowing back net.sgen.at[gid, "p_mw"] = 30 - pp.runpp(net, run_control=True) + runpp(net, run_control=True) # we expect the tap to converge at lower voltage limit and not drop even lower assert abs(net.res_bus.vm_pu.at[c.trafobus] - 0.95) < eps @@ -55,44 +59,44 @@ def test_continuous_p(): # excessive load net.sgen.at[gid, "p_mw"] = 0 net.load.at[lid, "p_mw"] = 30 - pp.runpp(net, run_control=True) + runpp(net, run_control=True) # we expect the tap to converge at upper voltage limit and not to go beyond assert abs(net.res_bus.vm_pu.at[c.trafobus] - 1.05) < eps def test_continuous_i(): - net = pp.create_empty_network() - hv = pp.create_bus(net, vn_kv=110.) - lv = pp.create_bus(net, vn_kv=20) - t = pp.create_transformer(net, hv, lv, std_type='40 MVA 110/20 kV') - pp.create_ext_grid(net, hv) + net = create_empty_network() + hv = create_bus(net, vn_kv=110.) + lv = create_bus(net, vn_kv=20) + t = create_transformer(net, hv, lv, std_type='40 MVA 110/20 kV') + create_ext_grid(net, hv) eps = 0.0005 - c = control.ContinuousTapControl(net, t, 1., tol=eps) + c = ContinuousTapControl(net, t, 1., tol=eps) # a different characteristic for i_lv_ka rather than for p_lv_mw characteristic = Characteristic(net, [0.315, 0.55], [0.95, 1.05]) - tc = control.VmSetTapControl(net, 0, characteristic.index, variable='i_lv_ka', tol=eps) + tc = VmSetTapControl(net, 0, characteristic.index, variable='i_lv_ka', tol=eps) # create 20kW load - lid = pp.create_load(net, lv, 20) - gid = pp.create_sgen(net, lv, 0) - pp.runpp(net, run_control=True) + lid = create_load(net, lv, 20) + gid = create_sgen(net, lv, 0) + runpp(net, run_control=True) # we expect the tap to converge at upper voltage limit assert abs(net.res_bus.vm_pu.at[c.trafobus] - 1.05) < eps # power sums up to 15kW net.sgen.at[gid, "p_mw"] = 5 - pp.runpp(net, run_control=True) + runpp(net, run_control=True) # we expect the tap to converge at 1.0 pu assert abs(net.res_bus.vm_pu.at[c.trafobus] - 1.) < eps # generation now cancels load net.sgen.at[gid, "p_mw"] = 10 - pp.runpp(net, run_control=True) + runpp(net, run_control=True) # we expect the tap to converge at lower voltage limit assert abs(net.res_bus.vm_pu.at[c.trafobus] - 0.95) < eps @@ -100,7 +104,7 @@ def test_continuous_i(): # testing limits # power flowing back net.sgen.at[gid, "p_mw"] = 30 - pp.runpp(net, run_control=True) + runpp(net, run_control=True) # we expect the tap to converge at lower voltage limit and not drop even lower assert abs(net.res_bus.vm_pu.at[c.trafobus] - 0.95) < eps @@ -108,10 +112,11 @@ def test_continuous_i(): # excessive load net.sgen.at[gid, "p_mw"] = 0 net.load.at[lid, "p_mw"] = 30 - pp.runpp(net, run_control=True) + runpp(net, run_control=True) # we expect the tap to converge at upper voltage limit and not to go beyond assert abs(net.res_bus.vm_pu.at[c.trafobus] - 1.05) < eps + if __name__ == '__main__': - pytest.main([__file__, "-xs"]) \ No newline at end of file + pytest.main([__file__, "-xs"]) diff --git a/pandapower/test/converter/test_from_cim.py b/pandapower/test/converter/test_from_cim.py index 41dad1e7a..5bd92c423 100644 --- a/pandapower/test/converter/test_from_cim.py +++ b/pandapower/test/converter/test_from_cim.py @@ -3,10 +3,10 @@ import math import pandas as pd -import pandapower as pp from pandapower.test import test_path -from pandapower.converter import from_cim as cim2pp +from pandapower.converter.cim.cim2pp.from_cim import from_cim +from pandapower.run import runpp @pytest.fixture(scope="session") @@ -16,7 +16,7 @@ def fullgrid_v2(): cgmes_files = [os.path.join(folder_path, 'CGMES_v2.4.15_FullGridTestConfiguration_BB_BE_v1.zip'), os.path.join(folder_path, 'CGMES_v2.4.15_FullGridTestConfiguration_BD_v1.zip')] - return cim2pp.from_cim(file_list=cgmes_files) + return from_cim(file_list=cgmes_files) @pytest.fixture(scope="session") def fullgrid_v3(): @@ -24,7 +24,7 @@ def fullgrid_v3(): cgmes_files = [os.path.join(folder_path, 'CGMES_v3.0_FullGrid-Merged_v3.0.2.zip')] - return cim2pp.from_cim(file_list=cgmes_files) + return from_cim(file_list=cgmes_files) @pytest.fixture(scope="session") @@ -34,7 +34,7 @@ def smallgrid_GL(): cgmes_files = [os.path.join(folder_path, 'CGMES_v2.4.15_SmallGridTestConfiguration_Boundary_v3.0.0.zip'), os.path.join(folder_path, 'CGMES_v2.4.15_SmallGridTestConfiguration_BaseCase_Complete_v3.0.0.zip')] - return cim2pp.from_cim(file_list=cgmes_files, use_GL_or_DL_profile='GL') + return from_cim(file_list=cgmes_files, use_GL_or_DL_profile='GL') @pytest.fixture(scope="session") @@ -44,7 +44,7 @@ def smallgrid_DL(): cgmes_files = [os.path.join(folder_path, 'CGMES_v2.4.15_SmallGridTestConfiguration_Boundary_v3.0.0.zip'), os.path.join(folder_path, 'CGMES_v2.4.15_SmallGridTestConfiguration_BaseCase_Complete_v3.0.0.zip')] - return cim2pp.from_cim(file_list=cgmes_files, use_GL_or_DL_profile='DL') + return from_cim(file_list=cgmes_files, use_GL_or_DL_profile='DL') @pytest.fixture(scope="session") @@ -53,7 +53,7 @@ def realgrid(): cgmes_files = [os.path.join(folder_path, 'CGMES_v2.4.15_RealGridTestConfiguration_v2.zip')] - return cim2pp.from_cim(file_list=cgmes_files) + return from_cim(file_list=cgmes_files) @pytest.fixture(scope="session") @@ -62,7 +62,7 @@ def SimBench_1_HVMVmixed_1_105_0_sw_modified(): cgmes_files = [os.path.join(folder_path, 'SimBench_1-HVMV-mixed-1.105-0-sw_modified.zip')] - return cim2pp.from_cim(file_list=cgmes_files, run_powerflow=True) + return from_cim(file_list=cgmes_files, run_powerflow=True) @pytest.fixture(scope="session") @@ -71,7 +71,7 @@ def Simbench_1_EHV_mixed__2_no_sw(): cgmes_files = [os.path.join(folder_path, 'Simbench_1-EHV-mixed--2-no_sw.zip')] - return cim2pp.from_cim(file_list=cgmes_files, create_measurements='SV', run_powerflow=True) + return from_cim(file_list=cgmes_files, create_measurements='SV', run_powerflow=True) @pytest.fixture(scope="session") @@ -80,8 +80,8 @@ def example_multivoltage(): cgmes_files = [os.path.join(folder_path, 'example_multivoltage.zip')] - net = cim2pp.from_cim(file_list=cgmes_files) - pp.runpp(net, calculate_voltage_angles="auto") + net = from_cim(file_list=cgmes_files) + runpp(net, calculate_voltage_angles="auto") return net @@ -91,7 +91,7 @@ def SimBench_1_HVMVmixed_1_105_0_sw_modified_no_load_flow(): cgmes_files = [os.path.join(folder_path, 'SimBench_1-HVMV-mixed-1.105-0-sw_modified.zip')] - return cim2pp.from_cim(file_list=cgmes_files) + return from_cim(file_list=cgmes_files) def test_SimBench_1_HVMVmixed_1_105_0_sw_modified_no_load_flow_res_bus( diff --git a/pandapower/test/converter/test_from_mpc.py b/pandapower/test/converter/test_from_mpc.py index aa7258ce2..b47e72567 100644 --- a/pandapower/test/converter/test_from_mpc.py +++ b/pandapower/test/converter/test_from_mpc.py @@ -8,13 +8,15 @@ import pytest -import pandapower as pp -import pandapower.networks as pn -import pandapower.toolbox +from pandapower import pp_dir from pandapower.converter import from_mpc +from pandapower.networks import case24_ieee_rts +from pandapower.run import runpp, set_user_pf_options +from pandapower.toolbox import nets_equal try: import matpowercaseframes + matpowercaseframes_imported = True except ImportError: matpowercaseframes_imported = False @@ -28,33 +30,33 @@ def test_from_mpc_mat(): - case24 = pn.case24_ieee_rts() - pp.set_user_pf_options(case24) - this_folder = os.path.join(pp.pp_dir, "test", "converter") + case24 = case24_ieee_rts() + set_user_pf_options(case24) + this_folder = os.path.join(pp_dir, "test", "converter") mat_case = os.path.join(this_folder, 'case24_ieee_rts.mat') case24_from_mpc = from_mpc(mat_case, f_hz=60, casename_mpc_file='mpc', tap_side="hv") - pp.runpp(case24) - pp.runpp(case24_from_mpc) + runpp(case24) + runpp(case24_from_mpc) assert case24_from_mpc.converged - assert pandapower.toolbox.nets_equal(case24, case24_from_mpc, check_only_results=True) + assert nets_equal(case24, case24_from_mpc, check_only_results=True) @pytest.mark.skipif(not matpowercaseframes_imported, reason="matpowercaseframes is needed to convert .m files.") def test_from_mpc_m(): - this_folder = os.path.join(pp.pp_dir, "test", "converter") + this_folder = os.path.join(pp_dir, "test", "converter") mat_case = os.path.join(this_folder, 'case24_ieee_rts.mat') m_case = os.path.join(this_folder, 'case24_ieee_rts.m') case24_mat = from_mpc(mat_case, f_hz=60, casename_mpc_file='mpc', tap_side="hv") case24_m = from_mpc(m_case, f_hz=60, tap_side="hv") - pp.runpp(case24_mat) - pp.runpp(case24_m) + runpp(case24_mat) + runpp(case24_m) assert case24_m.converged - assert pandapower.toolbox.nets_equal(case24_mat, case24_m) + assert nets_equal(case24_mat, case24_m) if __name__ == '__main__': diff --git a/pandapower/test/converter/test_from_powerfactory.py b/pandapower/test/converter/test_from_powerfactory.py index 8a2c076a5..247cf3ad9 100644 --- a/pandapower/test/converter/test_from_powerfactory.py +++ b/pandapower/test/converter/test_from_powerfactory.py @@ -1,13 +1,13 @@ import numpy as np import pandas as pd -import pandapower as pp - import os import pytest from pandapower.converter.powerfactory.validate import validate_pf_conversion from pandapower.converter.powerfactory.export_pfd_to_pp import import_project, from_pfd +from pandapower import pp_dir +from pandapower.file_io import from_json try: import pandaplan.core.pplog as logging @@ -54,7 +54,7 @@ def test_pf_export(): app = pf.GetApplication() # first, import the test grid to powerfactory - path = os.path.join(pp.pp_dir, 'test', 'converter', 'testfiles', 'test_export.pfd') + path = os.path.join(pp_dir, 'test', 'converter', 'testfiles', 'test_export.pfd') prj = import_project(path, app, 'TEST_PF_CONVERTER', import_folder='TEST_IMPORT', clear_import_folder=True) prj_name = prj.GetFullName() @@ -75,7 +75,7 @@ def test_pf_export_trafo3w(): app = pf.GetApplication() # import the 3W-Trafo test grid to powerfactory # todo: at the moment the 3W-Trafo model is not accurate enough, here testing with lower tol - path = os.path.join(pp.pp_dir, 'test', 'converter', 'testfiles', 'test_trafo3w.pfd') + path = os.path.join(pp_dir, 'test', 'converter', 'testfiles', 'test_trafo3w.pfd') prj = import_project(path, app, 'TEST_PF_CONVERTER', import_folder='TEST_IMPORT', clear_import_folder=True) prj_name = prj.GetFullName() @@ -91,8 +91,8 @@ def test_pf_export_trafo3w(): assert delta < tol[key], "%s has too high difference: %f > %f" % (key, delta, tol[key]) def test_trafo_tap2_results(): - path = os.path.join(pp.pp_dir, 'test', 'converter', 'testfiles', 'trafo_tap_model.json') - net = pp.from_json(path) + path = os.path.join(pp_dir, 'test', 'converter', 'testfiles', 'trafo_tap_model.json') + net = from_json(path) all_diffs = validate_pf_conversion(net, tolerance_mva=1e-9) tol = 2e-7 for key, diff in all_diffs.items(): diff --git a/pandapower/test/converter/test_from_powerfactory_3ph.py b/pandapower/test/converter/test_from_powerfactory_3ph.py index 4fb0555a3..9b4ddf852 100644 --- a/pandapower/test/converter/test_from_powerfactory_3ph.py +++ b/pandapower/test/converter/test_from_powerfactory_3ph.py @@ -1,20 +1,22 @@ # -*- coding: utf-8 -*- import os - -import pandapower as pp +import json import pytest import numpy as np +from pandapower import pp_dir +from pandapower.pf.runpp_3ph import runpp_3ph +from pandapower.file_io import from_json + try: from pandaplan.core import pplog as logging except ImportError: import logging -import json logger = logging.getLogger(__name__) -testfiles_path = os.path.join(pp.pp_dir, 'test', 'converter', 'testfiles') +testfiles_path = os.path.join(pp_dir, 'test', 'converter', 'testfiles') try: import powerfactory as pf @@ -38,7 +40,7 @@ # # and Yyn needs to be corrected, so there will be xfail atm # prj_name= "\\e2n049.IntUser\\Transformer 2 bus_trafo_11.03.20.IntPrj" # app = initialize_powerfactory(prj_name) -# net = pp.from_json(os.path.join(this_file_path, "test_trafo_3ph.json")) +# net = from_json(os.path.join(this_file_path, "test_trafo_3ph.json")) # for loadtype in ["delta", "wye", "bal_wye"]: # for vector_group in [ "Dyn", "YNyn","Yzn"]: # print(loadtype, vector_group) @@ -51,8 +53,8 @@ # # Only works with PowerFactory installed and configured atm # prj_name= "\\e2n049.IntUser\\2 bus_line_load_25.02.20.IntPrj" # app = initialize_powerfactory(prj_name) -# net = pp.from_json(os.path.join(this_file_path, "test_line_3ph.json")) -# pp.runpp_3ph(net) +# net = from_json(os.path.join(this_file_path, "test_line_3ph.json")) +# runpp_3ph(net) # get_pf_results(app, net) # compare_3ph_pp_pf_results(net) # return net @@ -65,7 +67,7 @@ # # and Yyn needs to be corrected, so there will be xfail atm # prj_name= "\\e2n049.IntUser\\3 bus_trafo_line_load_22.06.20.IntPrj" # app = initialize_powerfactory(prj_name) -# net = pp.from_json(os.path.join(this_file_path, "test_net_3ph.json")) +# net = from_json(os.path.join(this_file_path, "test_net_3ph.json")) # for loadtype in ["delta", "wye", "bal_wye"]: # for vector_group in [ "Dyn", "YNyn","Yzn"]: # print(loadtype, vector_group) @@ -73,13 +75,13 @@ def test_trafo_asym(): - net = pp.from_json(os.path.join(testfiles_path, "test_trafo_3ph.json")) + net = from_json(os.path.join(testfiles_path, "test_trafo_3ph.json")) for loadtype in ["delta", "wye"]: # , "bal_wye"]: for vector_group in ["Dyn", "YNyn", "Yzn"]: logger.debug(loadtype, vector_group) net.asymmetric_load.type = loadtype net.trafo.vector_group = vector_group - pp.runpp_3ph(net) + runpp_3ph(net) read_pf_results_from_file_to_net(os.path.join(testfiles_path, "pf_combinations_results_trafo.json"), net, vector_group + "_" + loadtype) compare_3ph_pp_pf_results(net) @@ -87,21 +89,21 @@ def test_trafo_asym(): def test_line_asym(): - net = pp.from_json(os.path.join(testfiles_path, "test_line_3ph.json")) - pp.runpp_3ph(net) + net = from_json(os.path.join(testfiles_path, "test_line_3ph.json")) + runpp_3ph(net) read_pf_results_from_file_to_net(os.path.join(testfiles_path, "pf_results_line.json"), net) compare_3ph_pp_pf_results(net) return net def test_net_asym(): - net = pp.from_json(os.path.join(testfiles_path, "test_net_3ph_test_2020_10_19.json")) + net = from_json(os.path.join(testfiles_path, "test_net_3ph_test_2020_10_19.json")) for loadtype in ["wye", "delta"]: for vector_group in ["Dyn", "YNyn", "Yzn"]: logger.debug(loadtype, vector_group) net.asymmetric_load.type = loadtype net.trafo.vector_group = vector_group - pp.runpp_3ph(net) + runpp_3ph(net) read_pf_results_from_file_to_net( os.path.join(testfiles_path, "pf_combinations_results_net_bus_trafo_line_load_19.10.20.json"), net, vector_group + "_" + loadtype) @@ -129,7 +131,7 @@ def analyse_3ph_loadtypes_and_vectorgroups(app, net, loadtype, vector_group): if not loadtype.startswith("bal_"): net.asymmetric_load.type = loadtype net.trafo.vector_group = vector_group - pp.runpp_3ph(net) + runpp_3ph(net) study_case_name = "Study Case_%s_%s" % (vector_group, loadtype) activate_study_case(app, study_case_name) get_pf_results(app, net) diff --git a/pandapower/test/converter/test_from_ppc.py b/pandapower/test/converter/test_from_ppc.py index 9e3008985..634c9f660 100644 --- a/pandapower/test/converter/test_from_ppc.py +++ b/pandapower/test/converter/test_from_ppc.py @@ -3,27 +3,24 @@ # Copyright (c) 2016-2024 by University of Kassel and Fraunhofer Institute for Energy Economics # and Energy System Technology (IEE), Kassel. All rights reserved. - -from copy import deepcopy import os import pickle import pytest -import sys import numpy as np import pandas as pd -import pandapower as pp -import pandapower.networks as pn -import pandapower.toolbox +from pandapower import pp_dir +from pandapower.file_io import from_json +from pandapower.toolbox.data_modification import reindex_buses +from pandapower.toolbox.comparison import nets_equal +from pandapower.run import set_user_pf_options, runpp, runopp +from pandapower.networks.power_system_test_cases import case9, case24_ieee_rts + from pandapower.converter import from_ppc, validate_from_ppc, to_ppc from pandapower.converter.pypower.from_ppc import _branch_to_which, _gen_to_which -from pandapower.pypower.idx_bus import \ - BUS_I, BUS_TYPE, PD, QD, GS, BS, BUS_AREA, VM, VA, BASE_KV, ZONE, VMAX, VMIN -from pandapower.pypower.idx_gen import \ - GEN_BUS, PG, QG, QMAX, QMIN, VG, MBASE, GEN_STATUS, PMAX, PMIN -from pandapower.pypower.idx_brch import \ - F_BUS, T_BUS, BR_R, BR_X, BR_B, RATE_A, RATE_B, RATE_C, TAP, SHIFT, PF, QF, PT, QT - +from pandapower.pypower.idx_bus import PD, VM, VA +from pandapower.pypower.idx_gen import PG, QG +from pandapower.pypower.idx_brch import PF, QF, PT, QT try: import pypower.case24_ieee_rts as c24 pypower_installed = True @@ -45,33 +42,33 @@ def get_testgrids(foldername, filename): This function return the ppc (or pp net) which is saved in ppc_testgrids.p to validate the from_ppc function via validate_from_ppc. """ - folder = os.path.join(pp.pp_dir, 'test', 'converter', foldername) + folder = os.path.join(pp_dir, 'test', 'converter', foldername) file = os.path.join(folder, filename) convert = "ppc" in filename - ppcs = pp.from_json(file, convert=convert) + ppcs = from_json(file, convert=convert) return ppcs def test_from_ppc_simple_against_target(): ppc = get_testgrids('ppc_testgrids', 'case2_2.json') net_by_ppc = from_ppc(ppc) - net_by_code = pp.from_json(os.path.join(pp.pp_dir, 'test', 'converter', 'case2_2_by_code.json')) - pp.reindex_buses(net_by_code, dict(zip(net_by_code.bus.index, net_by_ppc.bus.index))) - pp.set_user_pf_options(net_by_code) # for assertion of nets_equal - pp.runpp(net_by_ppc, trafo_model="pi") - pp.runpp(net_by_code, trafo_model="pi") + net_by_code = from_json(os.path.join(pp_dir, 'test', 'converter', 'case2_2_by_code.json')) + reindex_buses(net_by_code, dict(zip(net_by_code.bus.index, net_by_ppc.bus.index))) + set_user_pf_options(net_by_code) # for assertion of nets_equal + runpp(net_by_ppc, trafo_model="pi") + runpp(net_by_code, trafo_model="pi") assert type(net_by_ppc) == type(net_by_code) assert net_by_ppc.converged assert len(net_by_ppc.bus) == len(net_by_code.bus) assert len(net_by_ppc.impedance) == len(net_by_code.impedance) assert len(net_by_ppc.ext_grid) == len(net_by_code.ext_grid) - assert pandapower.toolbox.nets_equal(net_by_ppc, net_by_code, check_only_results=True, atol=1e-9) + assert nets_equal(net_by_ppc, net_by_code, check_only_results=True, atol=1e-9) def test_validate_from_ppc_simple_against_target(): ppc = get_testgrids('ppc_testgrids', 'case2_2.json') - net = pp.from_json(os.path.join(pp.pp_dir, 'test', 'converter', 'case2_2_by_code.json')) + net = from_json(os.path.join(pp_dir, 'test', 'converter', 'case2_2_by_code.json')) assert validate_from_ppc(ppc, net, max_diff_values=max_diff_values1) @@ -105,15 +102,15 @@ def test_pypower_cases(): def test_to_and_from_ppc(): - net9 = pn.case9() - net24 = pn.case24_ieee_rts() + net9 = case9() + net24 = case24_ieee_rts() net24.trafo.tap_side.iat[1] = "hv" for i, net in enumerate([net24, net9]): # set max_loading_percent to enable line limit conversion net.line["max_loading_percent"] = 100 - pp.runpp(net) + runpp(net) ppc = to_ppc(net, mode="opf", take_slack_vm_limits=False) # correct ppc data (to_ppc() does not convert completely) @@ -127,15 +124,15 @@ def test_to_and_from_ppc(): net2.line["max_loading_percent"] = 100 # compare loadflow results - pp.runpp(net) - pp.runpp(net2) - assert pandapower.toolbox.nets_equal(net, net2, check_only_results=True, atol=1e-10) + runpp(net) + runpp(net2) + assert nets_equal(net, net2, check_only_results=True, atol=1e-10) # compare optimal powerflow results if i == 1: - pp.runopp(net, delta=1e-16) - pp.runopp(net2, delta=1e-16) - assert pandapower.toolbox.nets_equal(net, net2, check_only_results=True, atol=1e-10) + runopp(net, delta=1e-16) + runopp(net2, delta=1e-16) + assert nets_equal(net, net2, check_only_results=True, atol=1e-10) def test_gencost_pwl(): @@ -290,7 +287,7 @@ def test_gencost_poly_pwl_part_mix(): reason="c24 test net is taken from mandatory pypower installation") def test_case24_from_pypower(): net = from_ppc(c24.case24_ieee_rts()) - pp.runopp(net) + runopp(net) assert net.OPF_converged @@ -299,14 +296,14 @@ def _bool_arr_to_positional_column_vector(arr): def overwrite_results_data_of_ppc_pickle(file_name, grid_names): - folder = os.path.join(pp.pp_dir, 'test', 'converter') + folder = os.path.join(pp_dir, 'test', 'converter') file = os.path.join(folder, file_name) ppcs = pickle.load(open(file, "rb")) for i in grid_names: ppc = ppcs[i] net = from_ppc(ppc, f_hz=60) - pp.runpp(net) + runpp(net) # --- determine is_line - same as in from_ppc() is_line, to_vn_is_leq = _branch_to_which(ppc) diff --git a/pandapower/test/converter/test_to_ppc_and_mpc.py b/pandapower/test/converter/test_to_ppc_and_mpc.py index 644417590..b2c2eaaae 100644 --- a/pandapower/test/converter/test_to_ppc_and_mpc.py +++ b/pandapower/test/converter/test_to_ppc_and_mpc.py @@ -6,14 +6,15 @@ import numpy as np import pytest -import pandapower as pp -import pandapower.converter as cv -from pandapower.test.converter.test_from_ppc import get_testgrids -from pandapower.pypower.idx_bus import VM, BUS_I, VA + +from pandapower.converter import to_ppc, to_mpc +from pandapower.networks import case4gs, case6ww, case30, case39 +from pandapower.pf.runpf_pypower import _runpf_pypower from pandapower.powerflow import LoadflowNotConverged +from pandapower.pypower.idx_bus import VM, BUS_I, VA from pandapower.results import reset_results -from pandapower.pf.runpf_pypower import _runpf_pypower -from pandapower.networks import case4gs, case6ww, case30, case39 +from pandapower.run import runpp +from pandapower.test.converter.test_from_ppc import get_testgrids def test_to_ppc_and_mpc(): @@ -29,12 +30,12 @@ def test_to_ppc_and_mpc(): reset_results(net) # This should be reviewed - pp.runpp(net) + runpp(net) # convert pandapower grids to ppc - ppc = cv.to_ppc(net) + ppc = to_ppc(net) # convert pandapower grids to mpc (no result validation) - mpc = cv.to_mpc(net) + mpc = to_mpc(net) # validate voltage results of pandapower-to-ppc-converted grids vs. original pypower results net["_options"]['ac'] = True diff --git a/pandapower/test/estimation/test_conditions.py b/pandapower/test/estimation/test_conditions.py index de6315894..21afe47df 100644 --- a/pandapower/test/estimation/test_conditions.py +++ b/pandapower/test/estimation/test_conditions.py @@ -1,7 +1,6 @@ import pytest from pandapower.estimation import estimate from pandapower.test.estimation.test_wls_estimation import create_net_with_bb_switch -import pandapower as pp def test_none_net(): diff --git a/pandapower/test/estimation/test_irwls_estimation.py b/pandapower/test/estimation/test_irwls_estimation.py index 14e21ea7d..1f017023c 100644 --- a/pandapower/test/estimation/test_irwls_estimation.py +++ b/pandapower/test/estimation/test_irwls_estimation.py @@ -9,8 +9,8 @@ import numpy as np import pytest -import pandapower as pp -import pandapower.networks as nw +from pandapower.run import runpp +from pandapower.networks.power_system_test_cases import case14 from pandapower.estimation import estimate from pandapower.estimation.util import add_virtual_meas_from_loadflow from pandapower.estimation.ppc_conversion import pp2eppci @@ -21,8 +21,8 @@ def test_irwls_comp_wls(): # it should be the same since wls will not update weight matrix - net = nw.case14() - pp.runpp(net) + net = case14() + runpp(net) add_virtual_meas_from_loadflow(net) success = estimate(net, init='flat', algorithm="irwls", estimator='wls') @@ -36,8 +36,8 @@ def test_irwls_comp_wls(): def test_shgm_ps(): # we need an random eppci object to initialize estimator - net = nw.case14() - pp.runpp(net) + net = case14() + runpp(net) add_virtual_meas_from_loadflow(net) _,_,eppci = pp2eppci(net) @@ -57,8 +57,8 @@ def test_shgm_ps(): def test_irwls_shgm(): - net = nw.case14() - pp.runpp(net) + net = case14() + runpp(net) add_virtual_meas_from_loadflow(net, p_std_dev=0.01, q_std_dev=0.01) success = estimate(net, algorithm="irwls", estimator="shgm", a=3, maximum_iterations=50) diff --git a/pandapower/test/estimation/test_opt_lp_estimation.py b/pandapower/test/estimation/test_opt_lp_estimation.py index 7efc8c8c1..042269ac4 100644 --- a/pandapower/test/estimation/test_opt_lp_estimation.py +++ b/pandapower/test/estimation/test_opt_lp_estimation.py @@ -3,24 +3,25 @@ # Copyright (c) 2016-2024 by University of Kassel and Fraunhofer Institute for Energy Economics # and Energy System Technology (IEE), Kassel. All rights reserved. +import sys + import numpy as np import pytest -import sys -import pandapower as pp -import pandapower.networks as nw -from pandapower.estimation import estimate -from pandapower.estimation.util import add_virtual_meas_from_loadflow -from pandapower.estimation.algorithm.optimization import OptAlgorithm +from pandapower.estimation import estimate from pandapower.estimation.algorithm.base import WLSAlgorithm from pandapower.estimation.algorithm.lp import LPAlgorithm +from pandapower.estimation.algorithm.optimization import OptAlgorithm from pandapower.estimation.ppc_conversion import pp2eppci from pandapower.estimation.results import eppci2pp +from pandapower.estimation.util import add_virtual_meas_from_loadflow +from pandapower.networks.power_system_test_cases import case9 +from pandapower.run import runpp def test_case9_compare_classical_wls_opt_wls(): - net = nw.case9() - pp.runpp(net) + net = case9() + runpp(net) add_virtual_meas_from_loadflow(net) # give it a warm start @@ -45,17 +46,17 @@ def test_case9_compare_classical_wls_opt_wls(): def test_lp_scipy_lav(): - ''' + """ If OR-Tools is installed, run this test. - ''' + """ # Set the solver LPAlgorithm.ortools_available = False - net = nw.case9() - pp.runpp(net) + net = case9() + runpp(net) add_virtual_meas_from_loadflow(net, with_random_error=False) - net, ppc, eppci = pp2eppci(net) + net, ppc, eppci = pp2eppci(net) estimation_ortools_lp = LPAlgorithm(1e-3, 5) estimation_ortools = estimation_ortools_lp.estimate(eppci, with_ortools=False) @@ -68,13 +69,13 @@ def test_lp_scipy_lav(): def test_lp_ortools_lav(): - ''' + """ If OR-Tools is installed, run this test. - ''' + """ # Set the solver LPAlgorithm.ortools_available = True - net = nw.case9() - pp.runpp(net) + net = case9() + runpp(net) add_virtual_meas_from_loadflow(net, with_random_error=False) net, ppc, eppci = pp2eppci(net) @@ -88,13 +89,14 @@ def test_lp_ortools_lav(): not np.allclose(net.res_bus.va_degree, net.res_bus_est.va_degree, atol=5e-2): raise AssertionError("Estimation failed!") + def test_lp_lav(): - ''' + """ This will test the default LP solver installed. If OR-Tools is installed, it will use it. Otherwise scipy is used. - ''' - net = nw.case9() - pp.runpp(net) + """ + net = case9() + runpp(net) add_virtual_meas_from_loadflow(net, p_std_dev=0.01, q_std_dev=0.01) estimate(net, algorithm="lp") @@ -103,9 +105,10 @@ def test_lp_lav(): not np.allclose(net.res_bus.va_degree, net.res_bus_est.va_degree, atol=5e-2): raise AssertionError("Estimation failed!") + def test_opt_lav(): - net = nw.case9() - pp.runpp(net) + net = case9() + runpp(net) add_virtual_meas_from_loadflow(net, with_random_error=False) net, ppc, eppci = pp2eppci(net) @@ -121,13 +124,14 @@ def test_opt_lav(): not np.allclose(net.res_bus.va_degree, net.res_bus_est.va_degree, atol=5e-2): raise AssertionError("Estimation failed!") -@pytest.mark.skipif((sys.version_info[0] == 3) & (sys.version_info[1] <= 7), - reason="This test can fail under Python 3.7 depending" - "on the processing power of the hardware used.") + +@pytest.mark.skipif((sys.version_info[0] == 3) & (sys.version_info[1] <= 7), + reason="This test can fail under Python 3.7 depending" + "on the processing power of the hardware used.") def test_ql_qc(): - net = nw.case9() + net = case9() net.sn_mva = 1. - pp.runpp(net) + runpp(net) add_virtual_meas_from_loadflow(net, p_std_dev=0.01, q_std_dev=0.01) pf_vm_pu, pf_va_degree = net.res_bus.vm_pu, net.res_bus.va_degree diff --git a/pandapower/test/estimation/test_pmu.py b/pandapower/test/estimation/test_pmu.py index 4054053f1..ad88ab2ce 100644 --- a/pandapower/test/estimation/test_pmu.py +++ b/pandapower/test/estimation/test_pmu.py @@ -6,8 +6,10 @@ import numpy as np import pytest -import pandapower as pp -import pandapower.networks as nw +from pandapower.run import runpp +from pandapower.networks.power_system_test_cases import case9 +from pandapower.create import create_empty_network, create_bus, create_ext_grid, create_sgen, create_load, \ + create_line, create_transformer3w from pandapower.estimation import estimate from pandapower.estimation.util import add_virtual_pmu_meas_from_loadflow @@ -19,33 +21,33 @@ def run_se_lp_verify(net): def test_pmu_case14(): - net = nw.case9() + net = case9() - pp.runpp(net) + runpp(net) add_virtual_pmu_meas_from_loadflow(net) run_se_lp_verify(net) def test_pmu_with_trafo3w(): - net = pp.create_empty_network() + net = create_empty_network() - bus_slack = pp.create_bus(net, vn_kv=110) - pp.create_ext_grid(net, bus=bus_slack) + bus_slack = create_bus(net, vn_kv=110) + create_ext_grid(net, bus=bus_slack) - bus_20_1 = pp.create_bus(net, vn_kv=20, name="b") - pp.create_sgen(net, bus=bus_20_1, p_mw=0.03, q_mvar=0.02) + bus_20_1 = create_bus(net, vn_kv=20, name="b") + create_sgen(net, bus=bus_20_1, p_mw=0.03, q_mvar=0.02) - bus_10_1 = pp.create_bus(net, vn_kv=10) - pp.create_sgen(net, bus=bus_10_1, p_mw=0.02, q_mvar=0.02) + bus_10_1 = create_bus(net, vn_kv=10) + create_sgen(net, bus=bus_10_1, p_mw=0.02, q_mvar=0.02) - bus_10_2 = pp.create_bus(net, vn_kv=10) - pp.create_load(net, bus=bus_10_2, p_mw=0.06, q_mvar=0.01) - pp.create_line(net, from_bus=bus_10_1, to_bus=bus_10_2, std_type="149-AL1/24-ST1A 10.0", length_km=2) + bus_10_2 = create_bus(net, vn_kv=10) + create_load(net, bus=bus_10_2, p_mw=0.06, q_mvar=0.01) + create_line(net, from_bus=bus_10_1, to_bus=bus_10_2, std_type="149-AL1/24-ST1A 10.0", length_km=2) - pp.create_transformer3w(net, bus_slack, bus_20_1, bus_10_1, std_type="63/25/38 MVA 110/20/10 kV") + create_transformer3w(net, bus_slack, bus_20_1, bus_10_1, std_type="63/25/38 MVA 110/20/10 kV") - pp.runpp(net) + runpp(net) add_virtual_pmu_meas_from_loadflow(net, with_random_error=False) run_se_lp_verify(net) diff --git a/pandapower/test/estimation/test_recycle.py b/pandapower/test/estimation/test_recycle.py index 4ae431dee..cccb524fd 100644 --- a/pandapower/test/estimation/test_recycle.py +++ b/pandapower/test/estimation/test_recycle.py @@ -3,36 +3,32 @@ # Copyright (c) 2016-2024 by University of Kassel and Fraunhofer Institute for Energy Economics # and Energy System Technology (IEE), Kassel. All rights reserved. - -import os - import numpy as np import pytest -import pandapower as pp -import pandapower.networks as nw -from pandapower.estimation import StateEstimation, estimate +from pandapower.run import runpp +from pandapower.networks.power_system_test_cases import case30 +from pandapower.estimation import StateEstimation from pandapower.estimation.util import add_virtual_meas_from_loadflow -from copy import deepcopy def test_recycle_case30(): - net = nw.case30() - pp.runpp(net) + net = case30() + runpp(net) add_virtual_meas_from_loadflow(net) se = StateEstimation(net, recycle=True) se.estimate() assert np.allclose(net.res_bus.vm_pu, net.res_bus_est.vm_pu, atol=1e-5) - assert np.allclose(net.res_bus.va_degree, net.res_bus_est.va_degree, atol=1e-5) + assert np.allclose(net.res_bus.va_degree, net.res_bus_est.va_degree, atol=1e-5) # Run SE again net.load.p_mw -= 10 - pp.runpp(net) - net.measurement.drop(net.measurement.index,inplace=True) + runpp(net) + net.measurement.drop(net.measurement.index, inplace=True) add_virtual_meas_from_loadflow(net) assert se.estimate() assert np.allclose(net.res_bus.vm_pu, net.res_bus_est.vm_pu, atol=1e-5) - assert np.allclose(net.res_bus.va_degree, net.res_bus_est.va_degree, atol=1e-5) + assert np.allclose(net.res_bus.va_degree, net.res_bus_est.va_degree, atol=1e-5) if __name__ == '__main__': pytest.main([__file__, "-xs"]) diff --git a/pandapower/test/estimation/test_wls_estimation.py b/pandapower/test/estimation/test_wls_estimation.py index 371354a7d..67c68f4c5 100644 --- a/pandapower/test/estimation/test_wls_estimation.py +++ b/pandapower/test/estimation/test_wls_estimation.py @@ -5,30 +5,36 @@ import os +from copy import deepcopy import numpy as np import pytest -import pandapower as pp -import pandapower.networks as nw +from pandapower import pp_dir +from pandapower.create import create_empty_network, create_bus, create_ext_grid, create_line_from_parameters, \ + create_measurement, create_load, create_transformer, create_line, create_sgen, create_transformer3w, create_switch from pandapower.estimation import chi2_analysis, remove_bad_data, estimate -from copy import deepcopy +from pandapower.file_io import from_json +from pandapower.networks.cigre_networks import create_cigre_network_mv +from pandapower.networks.power_system_test_cases import case9 +from pandapower.run import runpp +from pandapower.std_types import create_std_type def test_2bus(): # 1. Create network - net = pp.create_empty_network() - pp.create_bus(net, name="bus1", vn_kv=1.) - pp.create_bus(net, name="bus2", vn_kv=1.) - pp.create_ext_grid(net, 0) - pp.create_line_from_parameters(net, 0, 1, 1, r_ohm_per_km=1, x_ohm_per_km=0.5, - c_nf_per_km=0, max_i_ka=1) + net = create_empty_network() + create_bus(net, name="bus1", vn_kv=1.) + create_bus(net, name="bus2", vn_kv=1.) + create_ext_grid(net, 0) + create_line_from_parameters(net, 0, 1, 1, r_ohm_per_km=1, x_ohm_per_km=0.5, + c_nf_per_km=0, max_i_ka=1) - pp.create_measurement(net, "p", "line", 0.0111, 0.05, 0, 0) # p12 - pp.create_measurement(net, "q", "line", 0.06, 0.05, 0, 0) # q12 + create_measurement(net, "p", "line", 0.0111, 0.05, 0, 0) # p12 + create_measurement(net, "q", "line", 0.06, 0.05, 0, 0) # q12 - pp.create_measurement(net, "v", "bus", 1.019, 0.01, 0) # u1 - pp.create_measurement(net, "v", "bus", 1.04, 0.01, 1) # u2 + create_measurement(net, "v", "bus", 1.019, 0.01, 0) # u1 + create_measurement(net, "v", "bus", 1.04, 0.01, 1) # u2 # 2. Do state estimation if not estimate(net, init='flat'): @@ -42,33 +48,32 @@ def test_2bus(): target_delta = np.array([[0.0, 3.11356604]]) diff_delta = target_delta - delta_result - if not (np.nanmax(abs(diff_v)) < 1e-6) or\ - not (np.nanmax(abs(diff_delta)) < 1e-6): + if not (np.nanmax(abs(diff_v)) < 1e-6) or not (np.nanmax(abs(diff_delta)) < 1e-6): raise AssertionError("Estimation failed!") def test_3bus(): # 1. Create network - net = pp.create_empty_network() - pp.create_bus(net, name="bus1", vn_kv=1.) - pp.create_bus(net, name="bus2", vn_kv=1.) - pp.create_bus(net, name="bus3", vn_kv=1.) - pp.create_ext_grid(net, 0) - pp.create_line_from_parameters(net, 0, 1, 1, r_ohm_per_km=0.7, x_ohm_per_km=0.2, c_nf_per_km=0, - max_i_ka=1) - pp.create_line_from_parameters(net, 0, 2, 1, r_ohm_per_km=0.8, x_ohm_per_km=0.8, c_nf_per_km=0, - max_i_ka=1) - pp.create_line_from_parameters(net, 1, 2, 1, r_ohm_per_km=1, x_ohm_per_km=0.6, c_nf_per_km=0, - max_i_ka=1) - - pp.create_measurement(net, "p", "line", -0.0011, 0.01, 0, 0) # p12 - pp.create_measurement(net, "q", "line", 0.024, 0.01, 0, 0) # q12 - - pp.create_measurement(net, "p", "bus", -0.018, 0.01, 2) # p3 - pp.create_measurement(net, "q", "bus", 0.1, 0.01, 2) # q3 - - pp.create_measurement(net, "v", "bus", 1.08, 0.05, 0) # u1 - pp.create_measurement(net, "v", "bus", 1.015, 0.05, 2) # u3 + net = create_empty_network() + create_bus(net, name="bus1", vn_kv=1.) + create_bus(net, name="bus2", vn_kv=1.) + create_bus(net, name="bus3", vn_kv=1.) + create_ext_grid(net, 0) + create_line_from_parameters(net, 0, 1, 1, r_ohm_per_km=0.7, x_ohm_per_km=0.2, c_nf_per_km=0, + max_i_ka=1) + create_line_from_parameters(net, 0, 2, 1, r_ohm_per_km=0.8, x_ohm_per_km=0.8, c_nf_per_km=0, + max_i_ka=1) + create_line_from_parameters(net, 1, 2, 1, r_ohm_per_km=1, x_ohm_per_km=0.6, c_nf_per_km=0, + max_i_ka=1) + + create_measurement(net, "p", "line", -0.0011, 0.01, 0, 0) # p12 + create_measurement(net, "q", "line", 0.024, 0.01, 0, 0) # q12 + + create_measurement(net, "p", "bus", -0.018, 0.01, 2) # p3 + create_measurement(net, "q", "bus", 0.1, 0.01, 2) # q3 + + create_measurement(net, "v", "bus", 1.08, 0.05, 0) # u1 + create_measurement(net, "v", "bus", 1.015, 0.05, 2) # u3 # 2. Do state estimation if not estimate(net, init='flat'): @@ -81,45 +86,45 @@ def test_3bus(): target_delta = np.array([0., 0.8677, 3.1381]) diff_delta = target_delta - delta_result - if not (np.nanmax(abs(diff_v)) < 1e-4) or\ - not (np.nanmax(abs(diff_delta)) < 1e-4): + if not (np.nanmax(abs(diff_v)) < 1e-4) or \ + not (np.nanmax(abs(diff_delta)) < 1e-4): raise AssertionError("Estimation failed!") # Backwards check. Use state estimation results for power flow and check for equality net.ext_grid.vm_pu = net.res_bus_est.vm_pu.iloc[0] - pp.create_load(net, 0, net.res_bus_est.p_mw.iloc[0], net.res_bus_est.q_mvar.iloc[0]) - pp.create_load(net, 1, net.res_bus_est.p_mw.iloc[1], net.res_bus_est.q_mvar.iloc[1]) - pp.create_load(net, 2, net.res_bus_est.p_mw.iloc[2], net.res_bus_est.q_mvar.iloc[2]) + create_load(net, 0, net.res_bus_est.p_mw.iloc[0], net.res_bus_est.q_mvar.iloc[0]) + create_load(net, 1, net.res_bus_est.p_mw.iloc[1], net.res_bus_est.q_mvar.iloc[1]) + create_load(net, 2, net.res_bus_est.p_mw.iloc[2], net.res_bus_est.q_mvar.iloc[2]) _compare_pf_and_se_results(net) def test_3bus_with_bad_data(): - net = pp.create_empty_network() - pp.create_bus(net, name="bus1", vn_kv=1.) - pp.create_bus(net, name="bus2", vn_kv=1.) - pp.create_bus(net, name="bus3", vn_kv=1.) - pp.create_ext_grid(net, 0) - pp.create_line_from_parameters(net, 0, 1, 1, r_ohm_per_km=0.7, x_ohm_per_km=0.2, c_nf_per_km=0, - max_i_ka=1) - pp.create_line_from_parameters(net, 0, 2, 1, r_ohm_per_km=0.8, x_ohm_per_km=0.8, c_nf_per_km=0, - max_i_ka=1) - pp.create_line_from_parameters(net, 1, 2, 1, r_ohm_per_km=1, x_ohm_per_km=0.6, c_nf_per_km=0, - max_i_ka=1) - - pp.create_measurement(net, "p", "line", -0.0011, 0.01, 0, 0) # p12 - pp.create_measurement(net, "q", "line", 0.024, 0.01, 0, 0) # q12 - - pp.create_measurement(net, "p", "bus", -0.018, 0.01, 2) # p3 - pp.create_measurement(net, "q", "bus", 0.1, 0.01, 2) # q3 - - pp.create_measurement(net, "v", "bus", 1.08, 0.05, 0) # u1 - pp.create_measurement(net, "v", "bus", 1.015, 0.05, 2) # u3 + net = create_empty_network() + create_bus(net, name="bus1", vn_kv=1.) + create_bus(net, name="bus2", vn_kv=1.) + create_bus(net, name="bus3", vn_kv=1.) + create_ext_grid(net, 0) + create_line_from_parameters(net, 0, 1, 1, r_ohm_per_km=0.7, x_ohm_per_km=0.2, c_nf_per_km=0, + max_i_ka=1) + create_line_from_parameters(net, 0, 2, 1, r_ohm_per_km=0.8, x_ohm_per_km=0.8, c_nf_per_km=0, + max_i_ka=1) + create_line_from_parameters(net, 1, 2, 1, r_ohm_per_km=1, x_ohm_per_km=0.6, c_nf_per_km=0, + max_i_ka=1) + + create_measurement(net, "p", "line", -0.0011, 0.01, 0, 0) # p12 + create_measurement(net, "q", "line", 0.024, 0.01, 0, 0) # q12 + + create_measurement(net, "p", "bus", -0.018, 0.01, 2) # p3 + create_measurement(net, "q", "bus", 0.1, 0.01, 2) # q3 + + create_measurement(net, "v", "bus", 1.08, 0.05, 0) # u1 + create_measurement(net, "v", "bus", 1.015, 0.05, 2) # u3 # 0. Do chi2-test for corret data assert not chi2_analysis(net, init='flat') # 1. Create false voltage measurement for testing bad data detection (-> should be removed) - pp.create_measurement(net, "v", "bus", 1.3, 0.01, 1) # V at bus 2 + create_measurement(net, "v", "bus", 1.3, 0.01, 1) # V at bus 2 # 2. Do chi2-test bad_data_detected = chi2_analysis(net, init='flat') @@ -136,8 +141,8 @@ def test_3bus_with_bad_data(): assert bad_data_detected assert success_rn_max - if not (np.nanmax(abs(diff_v)) < 1e-4) or\ - not (np.nanmax(abs(diff_delta)) < 1e-4): + if not (np.nanmax(abs(diff_v)) < 1e-4) or \ + not (np.nanmax(abs(diff_delta)) < 1e-4): raise AssertionError("Estimation failed!") @@ -151,29 +156,29 @@ def test_3bus_with_out_of_service_bus(): # Measurements should be in kW/kVar/A - Voltage in p.u. # 1. Create network - net = pp.create_empty_network() - pp.create_bus(net, name="bus1", vn_kv=1.) - pp.create_bus(net, name="bus2", vn_kv=1.) - pp.create_bus(net, name="bus3", vn_kv=1.) - pp.create_bus(net, name="bus4", vn_kv=1., in_service=0) # out-of-service bus test - pp.create_ext_grid(net, 0) - pp.create_line_from_parameters(net, 0, 1, 1, r_ohm_per_km=.01, x_ohm_per_km=.03, c_nf_per_km=0., - max_i_ka=1) - pp.create_line_from_parameters(net, 0, 2, 1, r_ohm_per_km=.02, x_ohm_per_km=.05, c_nf_per_km=0., - max_i_ka=1) - pp.create_line_from_parameters(net, 1, 2, 1, r_ohm_per_km=.03, x_ohm_per_km=.08, c_nf_per_km=0., - max_i_ka=1) - - pp.create_measurement(net, "v", "bus", 1.006, .004, 0) # V at bus 1 - pp.create_measurement(net, "v", "bus", .968, .004, 1) # V at bus 2 - - pp.create_measurement(net, "p", "bus", .501, .010, 1) # P at bus 2 - pp.create_measurement(net, "q", "bus", .286, .010, 1) # Q at bus 2 - - pp.create_measurement(net, "p", "line", .888, .008, 0, 0) # Pline (bus 1 -> bus 2) at bus 1 - pp.create_measurement(net, "p", "line", 1.173, .008, 1, 0) # Pline (bus 1 -> bus 3) at bus 1 - pp.create_measurement(net, "q", "line", .568, .008, 0, 0) # Qline (bus 1 -> bus 2) at bus 1 - pp.create_measurement(net, "q", "line", .663, .008, 1, 0) # Qline (bus 1 -> bus 3) at bus 1 + net = create_empty_network() + create_bus(net, name="bus1", vn_kv=1.) + create_bus(net, name="bus2", vn_kv=1.) + create_bus(net, name="bus3", vn_kv=1.) + create_bus(net, name="bus4", vn_kv=1., in_service=0) # out-of-service bus test + create_ext_grid(net, 0) + create_line_from_parameters(net, 0, 1, 1, r_ohm_per_km=.01, x_ohm_per_km=.03, c_nf_per_km=0., + max_i_ka=1) + create_line_from_parameters(net, 0, 2, 1, r_ohm_per_km=.02, x_ohm_per_km=.05, c_nf_per_km=0., + max_i_ka=1) + create_line_from_parameters(net, 1, 2, 1, r_ohm_per_km=.03, x_ohm_per_km=.08, c_nf_per_km=0., + max_i_ka=1) + + create_measurement(net, "v", "bus", 1.006, .004, 0) # V at bus 1 + create_measurement(net, "v", "bus", .968, .004, 1) # V at bus 2 + + create_measurement(net, "p", "bus", .501, .010, 1) # P at bus 2 + create_measurement(net, "q", "bus", .286, .010, 1) # Q at bus 2 + + create_measurement(net, "p", "line", .888, .008, 0, 0) # Pline (bus 1 -> bus 2) at bus 1 + create_measurement(net, "p", "line", 1.173, .008, 1, 0) # Pline (bus 1 -> bus 3) at bus 1 + create_measurement(net, "q", "line", .568, .008, 0, 0) # Qline (bus 1 -> bus 2) at bus 1 + create_measurement(net, "q", "line", .663, .008, 1, 0) # Qline (bus 1 -> bus 3) at bus 1 # 2. Do state estimation if not estimate(net, init='flat'): @@ -187,8 +192,8 @@ def test_3bus_with_out_of_service_bus(): target_delta = np.array([[0., -1.2475, -2.7457, np.nan]]) diff_delta = target_delta - delta_result - if not (np.nanmax(abs(diff_v)) < 1e-4) or\ - not (np.nanmax(abs(diff_delta)) < 1e-4): + if not (np.nanmax(abs(diff_v)) < 1e-4) or \ + not (np.nanmax(abs(diff_delta)) < 1e-4): raise AssertionError("Estimation failed!") @@ -196,51 +201,51 @@ def test_3bus_with_transformer(): np.random.seed(12) # 1. Create network - net = pp.create_empty_network() - pp.create_bus(net, name="bus1", vn_kv=10.) - pp.create_bus(net, name="bus2", vn_kv=10.) - pp.create_bus(net, name="bus3", vn_kv=10.) - pp.create_bus(net, name="bus4", vn_kv=110.) - pp.create_ext_grid(net, bus=3, vm_pu=1.01) - pp.create_line_from_parameters(net, 0, 1, 1, r_ohm_per_km=.01, x_ohm_per_km=.03, c_nf_per_km=0., - max_i_ka=1) - pp.create_line_from_parameters(net, 0, 2, 1, r_ohm_per_km=.02, x_ohm_per_km=.05, c_nf_per_km=0., - max_i_ka=1) - pp.create_line_from_parameters(net, 1, 2, 1, r_ohm_per_km=.03, x_ohm_per_km=.08, c_nf_per_km=0., - max_i_ka=1) - - pp.create_std_type(net, {"sn_mva": 25, "vn_hv_kv": 110, "vn_lv_kv": 10, "vk_percent": 10.04, - "vkr_percent": 0.276, "pfe_kw": 28.51, "i0_percent": 0.073, "shift_degree": 150, - "tap_side": "hv", "tap_neutral": 0, "tap_min": -9, "tap_max": 9, "tap_step_degree": 0, - "tap_step_percent": 1.5, "tap_phase_shifter": False}, - "25 MVA 110/10 kV v1.4.3 and older", element="trafo") - pp.create_transformer(net, 3, 0, std_type="25 MVA 110/10 kV v1.4.3 and older") - - pp.create_load(net, bus=1, p_mw=0.45, q_mvar=0.3) - pp.create_load(net, bus=2, p_mw=0.35, q_mvar=0.2) - - pp.runpp(net, calculate_voltage_angles=True) - - pp.create_measurement(net, "v", "bus", r2(net.res_bus.vm_pu.iloc[0], .004), .004, element=0) - pp.create_measurement(net, "v", "bus", r2(net.res_bus.vm_pu.iloc[1], .004), .004, element=1) - pp.create_measurement(net, "v", "bus", r2(net.res_bus.vm_pu.iloc[3], .004), .004, element=3) - - pp.create_measurement(net, "p", "bus", r2(net.res_bus.p_mw.iloc[1], .01), .01, element=1) - pp.create_measurement(net, "q", "bus", r2(net.res_bus.q_mvar.iloc[1], .01), .01, element=1) - - pp.create_measurement(net, "p", "bus", r2(net.res_bus.p_mw.iloc[2], .01), .010, element=2) - pp.create_measurement(net, "q", "bus", r2(net.res_bus.q_mvar.iloc[2], .01), .01, element=2) - - pp.create_measurement(net, "p", "bus", 0., 0.001, element=0) - pp.create_measurement(net, "q", "bus", 0., 0.001, element=0) - - pp.create_measurement(net, "p", "line", r2(net.res_line.p_from_mw.iloc[0], .008), .008, 0, 0) - pp.create_measurement(net, "p", "line", r2(net.res_line.p_from_mw.iloc[1], .008), .008, 1, 0) - - pp.create_measurement(net, "p", "trafo", r2(net.res_trafo.p_hv_mw.iloc[0], .01), .01, - side="hv", element=0) # transformer meas. - pp.create_measurement(net, "q", "trafo", r2(net.res_trafo.q_hv_mvar.iloc[0], .01), .01, - side=3, element=0) # at hv side + net = create_empty_network() + create_bus(net, name="bus1", vn_kv=10.) + create_bus(net, name="bus2", vn_kv=10.) + create_bus(net, name="bus3", vn_kv=10.) + create_bus(net, name="bus4", vn_kv=110.) + create_ext_grid(net, bus=3, vm_pu=1.01) + create_line_from_parameters(net, 0, 1, 1, r_ohm_per_km=.01, x_ohm_per_km=.03, c_nf_per_km=0., + max_i_ka=1) + create_line_from_parameters(net, 0, 2, 1, r_ohm_per_km=.02, x_ohm_per_km=.05, c_nf_per_km=0., + max_i_ka=1) + create_line_from_parameters(net, 1, 2, 1, r_ohm_per_km=.03, x_ohm_per_km=.08, c_nf_per_km=0., + max_i_ka=1) + + create_std_type(net, {"sn_mva": 25, "vn_hv_kv": 110, "vn_lv_kv": 10, "vk_percent": 10.04, + "vkr_percent": 0.276, "pfe_kw": 28.51, "i0_percent": 0.073, "shift_degree": 150, + "tap_side": "hv", "tap_neutral": 0, "tap_min": -9, "tap_max": 9, "tap_step_degree": 0, + "tap_step_percent": 1.5, "tap_phase_shifter": False}, + "25 MVA 110/10 kV v1.4.3 and older", element="trafo") + create_transformer(net, 3, 0, std_type="25 MVA 110/10 kV v1.4.3 and older") + + create_load(net, bus=1, p_mw=0.45, q_mvar=0.3) + create_load(net, bus=2, p_mw=0.35, q_mvar=0.2) + + runpp(net, calculate_voltage_angles=True) + + create_measurement(net, "v", "bus", r2(net.res_bus.vm_pu.iloc[0], .004), .004, element=0) + create_measurement(net, "v", "bus", r2(net.res_bus.vm_pu.iloc[1], .004), .004, element=1) + create_measurement(net, "v", "bus", r2(net.res_bus.vm_pu.iloc[3], .004), .004, element=3) + + create_measurement(net, "p", "bus", r2(net.res_bus.p_mw.iloc[1], .01), .01, element=1) + create_measurement(net, "q", "bus", r2(net.res_bus.q_mvar.iloc[1], .01), .01, element=1) + + create_measurement(net, "p", "bus", r2(net.res_bus.p_mw.iloc[2], .01), .010, element=2) + create_measurement(net, "q", "bus", r2(net.res_bus.q_mvar.iloc[2], .01), .01, element=2) + + create_measurement(net, "p", "bus", 0., 0.001, element=0) + create_measurement(net, "q", "bus", 0., 0.001, element=0) + + create_measurement(net, "p", "line", r2(net.res_line.p_from_mw.iloc[0], .008), .008, 0, 0) + create_measurement(net, "p", "line", r2(net.res_line.p_from_mw.iloc[1], .008), .008, 1, 0) + + create_measurement(net, "p", "trafo", r2(net.res_trafo.p_hv_mw.iloc[0], .01), .01, + side="hv", element=0) # transformer meas. + create_measurement(net, "q", "trafo", r2(net.res_trafo.q_hv_mvar.iloc[0], .01), .01, + side=3, element=0) # at hv side # 2. Do state estimation if not estimate(net, init='slack', tolerance=1e-6, @@ -252,16 +257,16 @@ def test_3bus_with_transformer(): diff_v = net.res_bus.vm_pu.values - v_result diff_delta = net.res_bus.va_degree.values - delta_result - if not (np.nanmax(abs(diff_v)) < 6e-4) or\ - not (np.nanmax(abs(diff_delta)) < 8e-4): + if not (np.nanmax(abs(diff_v)) < 6e-4) or \ + not (np.nanmax(abs(diff_delta)) < 8e-4): raise AssertionError("Estimation failed!") # Backwards check. Use state estimation results for power flow and check for equality net.load = net.load.drop(net.load.index) net.ext_grid.vm_pu = net.res_bus_est.vm_pu.iloc[net.ext_grid.bus.iloc[0]] - pp.create_load(net, 0, net.res_bus_est.p_mw.iloc[0], net.res_bus_est.q_mvar.iloc[0]) - pp.create_load(net, 1, net.res_bus_est.p_mw.iloc[1], net.res_bus_est.q_mvar.iloc[1]) - pp.create_load(net, 2, net.res_bus_est.p_mw.iloc[2], net.res_bus_est.q_mvar.iloc[2]) + create_load(net, 0, net.res_bus_est.p_mw.iloc[0], net.res_bus_est.q_mvar.iloc[0]) + create_load(net, 1, net.res_bus_est.p_mw.iloc[1], net.res_bus_est.q_mvar.iloc[1]) + create_load(net, 2, net.res_bus_est.p_mw.iloc[2], net.res_bus_est.q_mvar.iloc[2]) _compare_pf_and_se_results(net) @@ -271,27 +276,27 @@ def test_3bus_with_2_slacks(): net = load_3bus_network() # add the same net with different slack (no galvanic connection) # skip bus index 4 as further stability test - pp.create_bus(net, name="bus5", vn_kv=1., index=5) - pp.create_bus(net, name="bus6", vn_kv=1., index=6) - pp.create_bus(net, name="bus7", vn_kv=1., index=7) - pp.create_ext_grid(net, 5) - pp.create_line_from_parameters(net, 5, 6, 1, r_ohm_per_km=.01, x_ohm_per_km=.03, c_nf_per_km=0., - max_i_ka=1) - pp.create_line_from_parameters(net, 5, 7, 1, r_ohm_per_km=.02, x_ohm_per_km=.05, c_nf_per_km=0., - max_i_ka=1) - pp.create_line_from_parameters(net, 6, 7, 1, r_ohm_per_km=.03, x_ohm_per_km=.08, c_nf_per_km=0., - max_i_ka=1) - - pp.create_measurement(net, "v", "bus", 1.006, .004, element=5) # V at bus 5 - pp.create_measurement(net, "v", "bus", .968, .004, element=6) # V at bus 6 - - pp.create_measurement(net, "p", "bus", .501, .010, element=6) # P at bus 6 - pp.create_measurement(net, "q", "bus", .286, .010, element=6) # Q at bus 6 - - pp.create_measurement(net, "p", "line", .888, .008, 3, 5) # Pline (bus 5 -> bus 6) at bus 5 - pp.create_measurement(net, "p", "line", 1.173, .008, 4, 5) # Pline (bus 5 -> bus 7) at bus 5 - pp.create_measurement(net, "q", "line", .568, .008, 3, 5) # Qline (bus 5 -> bus 6) at bus 5 - pp.create_measurement(net, "q", "line", .663, .008, 4, 5) # Qline (bus 5 -> bus 7) at bus 5 + create_bus(net, name="bus5", vn_kv=1., index=5) + create_bus(net, name="bus6", vn_kv=1., index=6) + create_bus(net, name="bus7", vn_kv=1., index=7) + create_ext_grid(net, 5) + create_line_from_parameters(net, 5, 6, 1, r_ohm_per_km=.01, x_ohm_per_km=.03, c_nf_per_km=0., + max_i_ka=1) + create_line_from_parameters(net, 5, 7, 1, r_ohm_per_km=.02, x_ohm_per_km=.05, c_nf_per_km=0., + max_i_ka=1) + create_line_from_parameters(net, 6, 7, 1, r_ohm_per_km=.03, x_ohm_per_km=.08, c_nf_per_km=0., + max_i_ka=1) + + create_measurement(net, "v", "bus", 1.006, .004, element=5) # V at bus 5 + create_measurement(net, "v", "bus", .968, .004, element=6) # V at bus 6 + + create_measurement(net, "p", "bus", .501, .010, element=6) # P at bus 6 + create_measurement(net, "q", "bus", .286, .010, element=6) # Q at bus 6 + + create_measurement(net, "p", "line", .888, .008, 3, 5) # Pline (bus 5 -> bus 6) at bus 5 + create_measurement(net, "p", "line", 1.173, .008, 4, 5) # Pline (bus 5 -> bus 7) at bus 5 + create_measurement(net, "q", "line", .568, .008, 3, 5) # Qline (bus 5 -> bus 6) at bus 5 + create_measurement(net, "q", "line", .663, .008, 4, 5) # Qline (bus 5 -> bus 7) at bus 5 # 2. Do state estimation if not estimate(net, init='flat', maximum_iterations=10): @@ -301,10 +306,10 @@ def test_3bus_with_2_slacks(): target_v = np.array([0.9996, 0.9741, 0.9438, np.nan, 0.9996, 0.9741, 0.9438]) target_delta = np.array([0.0, -1.2475469989322963, -2.7457167371166862, np.nan, 0.0, - -1.2475469989322963, -2.7457167371166862]) + -1.2475469989322963, -2.7457167371166862]) - if not np.allclose(v_result, target_v, atol=1e-4, equal_nan=True) or\ - not np.allclose(delta_result, target_delta, atol=1e-4, equal_nan=True): + if not np.allclose(v_result, target_v, atol=1e-4, equal_nan=True) or \ + not np.allclose(delta_result, target_delta, atol=1e-4, equal_nan=True): raise AssertionError("Estimation failed!") @@ -312,27 +317,27 @@ def test_3bus_with_i_line_measurements(): np.random.seed(1) net = load_3bus_network() net.measurement = net.measurement.drop(net.measurement.index) - pp.create_load(net, 1, p_mw=0.495974966, q_mvar=0.297749528) - pp.create_load(net, 2, p_mw=1.514220983, q_mvar=0.787528929) - pp.runpp(net) - pp.create_measurement(net, "v", "bus", net.res_bus.vm_pu[0] * r(0.01), 0.01, 0) - pp.create_measurement(net, "v", "bus", net.res_bus.vm_pu[2] * r(0.01), 0.01, 1) - pp.create_measurement(net, "p", "bus", net.res_bus.p_mw[0] * r(), - max(1.0e-3, abs(0.03 * net.res_bus.p_mw[0])), 0) - pp.create_measurement(net, "q", "bus", net.res_bus.q_mvar[0] * r(), - max(1.0e-3, abs(0.03 * net.res_bus.q_mvar[0])), 0) - pp.create_measurement(net, "p", "bus", net.res_bus.p_mw[2] * r(), - max(1.0e-3, abs(0.03 * net.res_bus.p_mw[2])), 2) - pp.create_measurement(net, "q", "bus", net.res_bus.q_mvar[2] * r(), - max(1.0e-3, abs(0.03 * net.res_bus.q_mvar[2])), 2) - pp.create_measurement(net, "p", "line", net.res_line.p_from_mw[0] * r(), - max(1.0e-3, abs(0.03 * net.res_line.p_from_mw[0])), element=0, side=0) - pp.create_measurement(net, "q", "line", net.res_line.q_from_mvar[0] * r(), - max(1.0e-3, abs(0.03 * net.res_line.q_from_mvar[0])), element=0, side=0) - pp.create_measurement(net, "i", "line", net.res_line.i_from_ka[0] * 1e3 * r(), - max(1.0, abs(30 * net.res_line.i_from_ka[0])), element=0, side=0) - pp.create_measurement(net, "i", "line", net.res_line.i_from_ka[1] * 1e3 * r(), - max(1.0, abs(30 * net.res_line.i_from_ka[1])), element=1, side=0) + create_load(net, 1, p_mw=0.495974966, q_mvar=0.297749528) + create_load(net, 2, p_mw=1.514220983, q_mvar=0.787528929) + runpp(net) + create_measurement(net, "v", "bus", net.res_bus.vm_pu[0] * r(0.01), 0.01, 0) + create_measurement(net, "v", "bus", net.res_bus.vm_pu[2] * r(0.01), 0.01, 1) + create_measurement(net, "p", "bus", net.res_bus.p_mw[0] * r(), + max(1.0e-3, abs(0.03 * net.res_bus.p_mw[0])), 0) + create_measurement(net, "q", "bus", net.res_bus.q_mvar[0] * r(), + max(1.0e-3, abs(0.03 * net.res_bus.q_mvar[0])), 0) + create_measurement(net, "p", "bus", net.res_bus.p_mw[2] * r(), + max(1.0e-3, abs(0.03 * net.res_bus.p_mw[2])), 2) + create_measurement(net, "q", "bus", net.res_bus.q_mvar[2] * r(), + max(1.0e-3, abs(0.03 * net.res_bus.q_mvar[2])), 2) + create_measurement(net, "p", "line", net.res_line.p_from_mw[0] * r(), + max(1.0e-3, abs(0.03 * net.res_line.p_from_mw[0])), element=0, side=0) + create_measurement(net, "q", "line", net.res_line.q_from_mvar[0] * r(), + max(1.0e-3, abs(0.03 * net.res_line.q_from_mvar[0])), element=0, side=0) + create_measurement(net, "i", "line", net.res_line.i_from_ka[0] * 1e3 * r(), + max(1.0, abs(30 * net.res_line.i_from_ka[0])), element=0, side=0) + create_measurement(net, "i", "line", net.res_line.i_from_ka[1] * 1e3 * r(), + max(1.0, abs(30 * net.res_line.i_from_ka[1])), element=1, side=0) if not estimate(net, init='flat'): raise AssertionError("Estimation failed!") @@ -345,27 +350,27 @@ def test_3bus_with_pq_line_from_to_measurements(): np.random.seed(2017) net = load_3bus_network() net.measurement = net.measurement.drop(net.measurement.index) - pp.create_load(net, 1, p_mw=0.495974966, q_mvar=0.297749528) - pp.create_load(net, 2, p_mw=1.514220983, q_mvar=0.787528929) - pp.runpp(net) - pp.create_measurement(net, "v", "bus", net.res_bus.vm_pu[0] * r(0.01), 0.01, 0) - pp.create_measurement(net, "v", "bus", net.res_bus.vm_pu[2] * r(0.01), 0.01, 1) - pp.create_measurement(net, "p", "bus", net.res_bus.p_mw[0] * r(), - max(1.0e-3, abs(0.03 * net.res_bus.p_mw[0])), 0) - pp.create_measurement(net, "q", "bus", net.res_bus.q_mvar[0] * r(), - max(1.0e-3, abs(0.03 * net.res_bus.q_mvar[0])), 0) - pp.create_measurement(net, "p", "bus", net.res_bus.p_mw[2] * r(), - max(1.0e-3, abs(0.03 * net.res_bus.p_mw[2])), 2) - pp.create_measurement(net, "q", "bus", net.res_bus.q_mvar[2] * r(), - max(1.0e-3, abs(0.03 * net.res_bus.q_mvar[2])), 2) - pp.create_measurement(net, "p", "line", net.res_line.p_from_mw[0] * r(), - max(1.0e-3, abs(0.03 * net.res_line.p_from_mw[0])), element=0, side=0) - pp.create_measurement(net, "q", "line", net.res_line.q_from_mvar[0] * r(), - max(1.0e-3, abs(0.03 * net.res_line.q_from_mvar[0])), element=0, side=0) - pp.create_measurement(net, "p", "line", net.res_line.p_to_mw[0] * r(), - max(1.0e-3, abs(0.03 * net.res_line.p_to_mw[0])), element=0, side=1) - pp.create_measurement(net, "q", "line", net.res_line.q_to_mvar[0] * r(), - max(1.0e-3, abs(0.03 * net.res_line.q_to_mvar[0])), element=0, side=1) + create_load(net, 1, p_mw=0.495974966, q_mvar=0.297749528) + create_load(net, 2, p_mw=1.514220983, q_mvar=0.787528929) + runpp(net) + create_measurement(net, "v", "bus", net.res_bus.vm_pu[0] * r(0.01), 0.01, 0) + create_measurement(net, "v", "bus", net.res_bus.vm_pu[2] * r(0.01), 0.01, 1) + create_measurement(net, "p", "bus", net.res_bus.p_mw[0] * r(), + max(1.0e-3, abs(0.03 * net.res_bus.p_mw[0])), 0) + create_measurement(net, "q", "bus", net.res_bus.q_mvar[0] * r(), + max(1.0e-3, abs(0.03 * net.res_bus.q_mvar[0])), 0) + create_measurement(net, "p", "bus", net.res_bus.p_mw[2] * r(), + max(1.0e-3, abs(0.03 * net.res_bus.p_mw[2])), 2) + create_measurement(net, "q", "bus", net.res_bus.q_mvar[2] * r(), + max(1.0e-3, abs(0.03 * net.res_bus.q_mvar[2])), 2) + create_measurement(net, "p", "line", net.res_line.p_from_mw[0] * r(), + max(1.0e-3, abs(0.03 * net.res_line.p_from_mw[0])), element=0, side=0) + create_measurement(net, "q", "line", net.res_line.q_from_mvar[0] * r(), + max(1.0e-3, abs(0.03 * net.res_line.q_from_mvar[0])), element=0, side=0) + create_measurement(net, "p", "line", net.res_line.p_to_mw[0] * r(), + max(1.0e-3, abs(0.03 * net.res_line.p_to_mw[0])), element=0, side=1) + create_measurement(net, "q", "line", net.res_line.q_to_mvar[0] * r(), + max(1.0e-3, abs(0.03 * net.res_line.q_to_mvar[0])), element=0, side=1) if not estimate(net, init='flat'): raise AssertionError("Estimation failed!") @@ -378,27 +383,27 @@ def test_3bus_with_side_names(): np.random.seed(2017) net = load_3bus_network() net.measurement = net.measurement.drop(net.measurement.index) - pp.create_load(net, 1, p_mw=0.495974966, q_mvar=0.297749528) - pp.create_load(net, 2, p_mw=1.514220983, q_mvar=0.787528929) - pp.runpp(net) - pp.create_measurement(net, "v", "bus", net.res_bus.vm_pu[0] * r(0.01), 0.01, 0) - pp.create_measurement(net, "v", "bus", net.res_bus.vm_pu[2] * r(0.01), 0.01, 1) - pp.create_measurement(net, "p", "bus", net.res_bus.p_mw[0] * r(), - max(1.0e-3, abs(0.03 * net.res_bus.p_mw[0])), 0) - pp.create_measurement(net, "q", "bus", net.res_bus.q_mvar[0] * r(), - max(1.0e-3, abs(0.03 * net.res_bus.q_mvar[0])), 0) - pp.create_measurement(net, "p", "bus", net.res_bus.p_mw[2] * r(), - max(1.0e-3, abs(0.03 * net.res_bus.p_mw[2])), 2) - pp.create_measurement(net, "q", "bus", net.res_bus.q_mvar[2] * r(), - max(1.0e-3, abs(0.03 * net.res_bus.q_mvar[2])), 2) - pp.create_measurement(net, "p", "line", net.res_line.p_from_mw[0] * r(), - max(1.0e-3, abs(0.03 * net.res_line.p_from_mw[0])), element=0, side="from") - pp.create_measurement(net, "q", "line", net.res_line.q_from_mvar[0] * r(), - max(1.0e-3, abs(0.03 * net.res_line.q_from_mvar[0])), element=0, side="from") - pp.create_measurement(net, "p", "line", net.res_line.p_to_mw[0] * r(), - max(1.0e-3, abs(0.03 * net.res_line.p_to_mw[0])), element=0, side="to") - pp.create_measurement(net, "q", "line", net.res_line.q_to_mvar[0] * r(), - max(1.0e-3, abs(0.03 * net.res_line.q_to_mvar[0])), element=0, side="to") + create_load(net, 1, p_mw=0.495974966, q_mvar=0.297749528) + create_load(net, 2, p_mw=1.514220983, q_mvar=0.787528929) + runpp(net) + create_measurement(net, "v", "bus", net.res_bus.vm_pu[0] * r(0.01), 0.01, 0) + create_measurement(net, "v", "bus", net.res_bus.vm_pu[2] * r(0.01), 0.01, 1) + create_measurement(net, "p", "bus", net.res_bus.p_mw[0] * r(), + max(1.0e-3, abs(0.03 * net.res_bus.p_mw[0])), 0) + create_measurement(net, "q", "bus", net.res_bus.q_mvar[0] * r(), + max(1.0e-3, abs(0.03 * net.res_bus.q_mvar[0])), 0) + create_measurement(net, "p", "bus", net.res_bus.p_mw[2] * r(), + max(1.0e-3, abs(0.03 * net.res_bus.p_mw[2])), 2) + create_measurement(net, "q", "bus", net.res_bus.q_mvar[2] * r(), + max(1.0e-3, abs(0.03 * net.res_bus.q_mvar[2])), 2) + create_measurement(net, "p", "line", net.res_line.p_from_mw[0] * r(), + max(1.0e-3, abs(0.03 * net.res_line.p_from_mw[0])), element=0, side="from") + create_measurement(net, "q", "line", net.res_line.q_from_mvar[0] * r(), + max(1.0e-3, abs(0.03 * net.res_line.q_from_mvar[0])), element=0, side="from") + create_measurement(net, "p", "line", net.res_line.p_to_mw[0] * r(), + max(1.0e-3, abs(0.03 * net.res_line.p_to_mw[0])), element=0, side="to") + create_measurement(net, "q", "line", net.res_line.q_to_mvar[0] * r(), + max(1.0e-3, abs(0.03 * net.res_line.q_to_mvar[0])), element=0, side="to") if not estimate(net, init='flat'): raise AssertionError("Estimation failed!") @@ -412,17 +417,17 @@ def test_cigre_network(init='flat'): # test the mv ring network with all available voltage measurements and bus powers # test if switches and transformer will work correctly with the state estimation np.random.seed(123456) - net = nw.create_cigre_network_mv(with_der=False) - pp.runpp(net) + net = create_cigre_network_mv(with_der=False) + runpp(net) for bus, row in net.res_bus.iterrows(): - pp.create_measurement(net, "v", "bus", row.vm_pu * r(0.01), 0.01, bus) + create_measurement(net, "v", "bus", row.vm_pu * r(0.01), 0.01, bus) # if np.random.randint(0, 4) == 0: # continue - pp.create_measurement(net, "p", "bus", row.p_mw * r(), max(0.001, abs(0.03 * row.p_mw)), - bus) - pp.create_measurement(net, "q", "bus", row.q_mvar * r(), max(0.001, abs(0.03 * row.q_mvar)), - bus) + create_measurement(net, "p", "bus", row.p_mw * r(), max(0.001, abs(0.03 * row.p_mw)), + bus) + create_measurement(net, "q", "bus", row.q_mvar * r(), max(0.001, abs(0.03 * row.q_mvar)), + bus) # 2. Do state estimation if not estimate(net, init="flat", calculate_voltage_angles=True): @@ -446,17 +451,17 @@ def test_cigre_network_with_slack_init(): def test_cigre_with_bad_data(): np.random.seed(123456) - net = nw.create_cigre_network_mv(with_der=False) + net = create_cigre_network_mv(with_der=False) net.load.q_mvar = net.load["p_mw"].apply(lambda p: p * np.tan(np.arccos(np.random.choice([0.95, 0.9, 0.97])))) - pp.runpp(net) + runpp(net) for bus, row in net.res_bus.iterrows(): if bus == 2: continue if bus != 6: - pp.create_measurement(net, "v", "bus", row.vm_pu * r(0.01), 0.01, bus) # skip our bad data measurement - pp.create_measurement(net, "p", "bus", row.p_mw * r(), max(0.001, abs(0.03 * row.p_mw)), bus) - pp.create_measurement(net, "q", "bus", row.q_mvar * r(), max(0.001, abs(0.03 * row.q_mvar)), bus) + create_measurement(net, "v", "bus", row.vm_pu * r(0.01), 0.01, bus) # skip our bad data measurement + create_measurement(net, "p", "bus", row.p_mw * r(), max(0.001, abs(0.03 * row.p_mw)), bus) + create_measurement(net, "q", "bus", row.q_mvar * r(), max(0.001, abs(0.03 * row.q_mvar)), bus) # 2. Do state estimation success_SE = estimate(net, init='slack') @@ -464,7 +469,7 @@ def test_cigre_with_bad_data(): delta_SE = net.res_bus_est.va_degree.values # 3. Create false measurement (very close to useful values) - pp.create_measurement(net, "v", "bus", 0.85, 0.01, element=6) + create_measurement(net, "v", "bus", 0.85, 0.01, element=6) # 4. Do chi2-test bad_data_detected = chi2_analysis(net, init='slack') @@ -486,53 +491,53 @@ def test_cigre_with_bad_data(): def test_init_slack_with_multiple_transformers(angles=True): np.random.seed(123) - net = pp.create_empty_network() - pp.create_bus(net, 220, index=0) - pp.create_bus(net, 110, index=1) - pp.create_bus(net, 110, index=2) - pp.create_bus(net, 110, index=3) - pp.create_bus(net, 10, index=4) - pp.create_bus(net, 10, index=5) - pp.create_bus(net, 10, index=6) - pp.create_bus(net, 10, index=7, in_service=False) - pp.create_std_type(net, {"sn_mva": 63, "vn_hv_kv": 110, "vn_lv_kv": 10, "vk_percent": 10.04, - "vkr_percent": 0.31, "pfe_kw": 31.51, "i0_percent": 0.078, "shift_degree": 150, - "tap_side": "hv", "tap_neutral": 0, "tap_min": -9, "tap_max": 9, "tap_step_degree": 0, - "tap_step_percent": 1.5, "tap_phase_shifter": False}, - "63 MVA 110/10 kV v1.4.3 and older", element="trafo") - - pp.create_transformer(net, 3, 7, std_type="63 MVA 110/10 kV v1.4.3 and older", in_service=False) - pp.create_transformer(net, 3, 4, std_type="63 MVA 110/10 kV v1.4.3 and older") - pp.create_transformer(net, 0, 1, std_type="100 MVA 220/110 kV") - pp.create_line(net, 1, 2, 2.0, std_type="N2XS(FL)2Y 1x120 RM/35 64/110 kV") - pp.create_line(net, 1, 3, 2.0, std_type="N2XS(FL)2Y 1x120 RM/35 64/110 kV") - pp.create_line(net, 4, 5, 2.0, std_type="NA2XS2Y 1x95 RM/25 12/20 kV") - pp.create_line(net, 5, 6, 2.0, std_type="NA2XS2Y 1x95 RM/25 12/20 kV") - pp.create_load(net, 2, p_mw=5, q_mvar=3.3) - pp.create_load(net, 5, p_mw=0.9, q_mvar=0.5) - pp.create_load(net, bus=6, p_mw=0.7, q_mvar=0.3) - pp.create_ext_grid(net, bus=0, vm_pu=1.04, va_degree=10., name="Slack 220 kV") - pp.runpp(net, calculate_voltage_angles=angles) + net = create_empty_network() + create_bus(net, 220, index=0) + create_bus(net, 110, index=1) + create_bus(net, 110, index=2) + create_bus(net, 110, index=3) + create_bus(net, 10, index=4) + create_bus(net, 10, index=5) + create_bus(net, 10, index=6) + create_bus(net, 10, index=7, in_service=False) + create_std_type(net, {"sn_mva": 63, "vn_hv_kv": 110, "vn_lv_kv": 10, "vk_percent": 10.04, + "vkr_percent": 0.31, "pfe_kw": 31.51, "i0_percent": 0.078, "shift_degree": 150, + "tap_side": "hv", "tap_neutral": 0, "tap_min": -9, "tap_max": 9, "tap_step_degree": 0, + "tap_step_percent": 1.5, "tap_phase_shifter": False}, + "63 MVA 110/10 kV v1.4.3 and older", element="trafo") + + create_transformer(net, 3, 7, std_type="63 MVA 110/10 kV v1.4.3 and older", in_service=False) + create_transformer(net, 3, 4, std_type="63 MVA 110/10 kV v1.4.3 and older") + create_transformer(net, 0, 1, std_type="100 MVA 220/110 kV") + create_line(net, 1, 2, 2.0, std_type="N2XS(FL)2Y 1x120 RM/35 64/110 kV") + create_line(net, 1, 3, 2.0, std_type="N2XS(FL)2Y 1x120 RM/35 64/110 kV") + create_line(net, 4, 5, 2.0, std_type="NA2XS2Y 1x95 RM/25 12/20 kV") + create_line(net, 5, 6, 2.0, std_type="NA2XS2Y 1x95 RM/25 12/20 kV") + create_load(net, 2, p_mw=5, q_mvar=3.3) + create_load(net, 5, p_mw=0.9, q_mvar=0.5) + create_load(net, bus=6, p_mw=0.7, q_mvar=0.3) + create_ext_grid(net, bus=0, vm_pu=1.04, va_degree=10., name="Slack 220 kV") + runpp(net, calculate_voltage_angles=angles) for bus, row in net.res_bus[net.bus.in_service].iterrows(): - pp.create_measurement(net, "v", "bus", row.vm_pu * r(0.01), 0.01, bus) + create_measurement(net, "v", "bus", row.vm_pu * r(0.01), 0.01, bus) if row.p_mw != 0.: continue - pp.create_measurement(net, "p", "bus", row.p_mw * r(), max(0.001, abs(0.03 * row.p_mw)), - bus) - pp.create_measurement(net, "q", "bus", row.q_mvar * r(), max(.0001, abs(0.03 * row.q_mvar)), - bus) - pp.create_measurement(net, "p", "line", net.res_line.p_from_mw[0], .01, side=1, element=0) - pp.create_measurement(net, "q", "line", net.res_line.q_from_mvar[0], 0.01, side=1, element=0) - pp.create_measurement(net, "p", "line", net.res_line.p_from_mw[2], .01, side=4, element=2) - pp.create_measurement(net, "q", "line", net.res_line.q_from_mvar[2], .01, side=4, element=2) - pp.create_measurement(net, "p", "line", net.res_line.p_from_mw[3], .01, side=5, element=3) - pp.create_measurement(net, "q", "line", net.res_line.q_from_mvar[3], 0.01, side=5, element=3) + create_measurement(net, "p", "bus", row.p_mw * r(), max(0.001, abs(0.03 * row.p_mw)), + bus) + create_measurement(net, "q", "bus", row.q_mvar * r(), max(.0001, abs(0.03 * row.q_mvar)), + bus) + create_measurement(net, "p", "line", net.res_line.p_from_mw[0], .01, side=1, element=0) + create_measurement(net, "q", "line", net.res_line.q_from_mvar[0], 0.01, side=1, element=0) + create_measurement(net, "p", "line", net.res_line.p_from_mw[2], .01, side=4, element=2) + create_measurement(net, "q", "line", net.res_line.q_from_mvar[2], .01, side=4, element=2) + create_measurement(net, "p", "line", net.res_line.p_from_mw[3], .01, side=5, element=3) + create_measurement(net, "q", "line", net.res_line.q_from_mvar[3], 0.01, side=5, element=3) success = estimate(net, init='slack', calculate_voltage_angles=angles, tolerance=1e-9) # pretty high error for vm_pu (half percent!) assert success assert (np.nanmax(np.abs(net.res_bus.vm_pu.values - net.res_bus_est.vm_pu.values)) < 0.006) - assert (np.nanmax(np.abs(net.res_bus.va_degree.values- net.res_bus_est.va_degree.values)) < 0.006) + assert (np.nanmax(np.abs(net.res_bus.va_degree.values - net.res_bus_est.va_degree.values)) < 0.006) def test_init_slack_with_multiple_transformers_angles_off(): @@ -541,197 +546,198 @@ def test_init_slack_with_multiple_transformers_angles_off(): def test_check_existing_measurements(): np.random.seed(2017) - net = pp.create_empty_network() - pp.create_bus(net, 10.) - pp.create_bus(net, 10.) - pp.create_line(net, 0, 1, 0.5, std_type="149-AL1/24-ST1A 10.0") - m1 = pp.create_measurement(net, "v", "bus", 1.006, .004, 0) - m2 = pp.create_measurement(net, "v", "bus", 1.006, .004, 0) + net = create_empty_network() + create_bus(net, 10.) + create_bus(net, 10.) + create_line(net, 0, 1, 0.5, std_type="149-AL1/24-ST1A 10.0") + m1 = create_measurement(net, "v", "bus", 1.006, .004, 0) + m2 = create_measurement(net, "v", "bus", 1.006, .004, 0) # assert m1 == m2 assert len(net.measurement) == 2 - m3 = pp.create_measurement(net, "v", "bus", 1.006, .004, 0, check_existing=False) + m3 = create_measurement(net, "v", "bus", 1.006, .004, 0, check_existing=False) # assert m3 != m2 assert len(net.measurement) == 3 - m4 = pp.create_measurement(net, "p", "line", -0.0011, 0.01, side=0, element=0, - check_existing=True) - m5 = pp.create_measurement(net, "p", "line", -0.0011, 0.01, side=0, element=0, - check_existing=True) - # assert m4 == m5 + m4 = create_measurement(net, "p", "line", -0.0011, 0.01, side=0, element=0, + check_existing=True) + m5 = create_measurement(net, "p", "line", -0.0011, 0.01, side=0, element=0, + check_existing=True) + assert m4 == m5 - m6 = pp.create_measurement(net, "p", "line", -0.0011, 0.01, side=0, element=0, - check_existing=False) - # assert m5 != m6 + m6 = create_measurement(net, "p", "line", -0.0011, 0.01, side=0, element=0, + check_existing=False) + assert m5 != m6 assert len(net.measurement) == 5 def load_3bus_network(): - return pp.from_json(os.path.join(pp.pp_dir, "test", "estimation", "3bus_wls.json")) + return from_json(os.path.join(pp_dir, "test", "estimation", "3bus_wls.json")) + def test_network_with_trafo3w_pq(): - net = pp.create_empty_network() + net = create_empty_network() - bus_slack = pp.create_bus(net, vn_kv=110) - pp.create_ext_grid(net, bus=bus_slack) + bus_slack = create_bus(net, vn_kv=110) + create_ext_grid(net, bus=bus_slack) - bus_20_1 = pp.create_bus(net, vn_kv=20,name="b") - pp.create_sgen(net, bus=bus_20_1, p_mw=0.03, q_mvar=0.02) + bus_20_1 = create_bus(net, vn_kv=20, name="b") + create_sgen(net, bus=bus_20_1, p_mw=0.03, q_mvar=0.02) - bus_10_1 = pp.create_bus(net, vn_kv=10) - pp.create_sgen(net, bus=bus_10_1, p_mw=0.02, q_mvar=0.02) + bus_10_1 = create_bus(net, vn_kv=10) + create_sgen(net, bus=bus_10_1, p_mw=0.02, q_mvar=0.02) - bus_10_2 = pp.create_bus(net, vn_kv=10) - pp.create_load(net, bus=bus_10_2, p_mw=0.06, q_mvar=0.01) - pp.create_line(net, from_bus=bus_10_1, to_bus=bus_10_2, std_type="149-AL1/24-ST1A 10.0", length_km=2) + bus_10_2 = create_bus(net, vn_kv=10) + create_load(net, bus=bus_10_2, p_mw=0.06, q_mvar=0.01) + create_line(net, from_bus=bus_10_1, to_bus=bus_10_2, std_type="149-AL1/24-ST1A 10.0", length_km=2) - pp.create_transformer3w(net, bus_slack, bus_20_1, bus_10_1, std_type="63/25/38 MVA 110/20/10 kV") + create_transformer3w(net, bus_slack, bus_20_1, bus_10_1, std_type="63/25/38 MVA 110/20/10 kV") - pp.runpp(net) + runpp(net) - pp.create_measurement(net, "p", "line", net.res_line.p_from_mw[0], 0.001, 0, 'from') - pp.create_measurement(net, "q", "line", net.res_line.q_from_mvar[0], 0.001, 0, 'from') - pp.create_measurement(net, "p", "line", net.res_line.p_to_mw[0], 0.001, 0, 'to') - pp.create_measurement(net, "q", "line", net.res_line.q_to_mvar[0], 0.001, 0, 'to') + create_measurement(net, "p", "line", net.res_line.p_from_mw[0], 0.001, 0, 'from') + create_measurement(net, "q", "line", net.res_line.q_from_mvar[0], 0.001, 0, 'from') + create_measurement(net, "p", "line", net.res_line.p_to_mw[0], 0.001, 0, 'to') + create_measurement(net, "q", "line", net.res_line.q_to_mvar[0], 0.001, 0, 'to') - pp.create_measurement(net, "p", "trafo3w", net.res_trafo3w.p_hv_mw[0], 0.001, 0, 'hv') - pp.create_measurement(net, "q", "trafo3w", net.res_trafo3w.q_hv_mvar[0], 0.001, 0, 'hv') - pp.create_measurement(net, "p", "trafo3w", net.res_trafo3w.p_mv_mw[0], 0.002, 0, 'mv') - pp.create_measurement(net, "q", "trafo3w", net.res_trafo3w.q_mv_mvar[0], 0.002, 0, 'mv') - pp.create_measurement(net, "p", "trafo3w", net.res_trafo3w.p_lv_mw[0], 0.001, 0, 'lv') - pp.create_measurement(net, "q", "trafo3w", net.res_trafo3w.q_lv_mvar[0], 0.001, 0, 'lv') + create_measurement(net, "p", "trafo3w", net.res_trafo3w.p_hv_mw[0], 0.001, 0, 'hv') + create_measurement(net, "q", "trafo3w", net.res_trafo3w.q_hv_mvar[0], 0.001, 0, 'hv') + create_measurement(net, "p", "trafo3w", net.res_trafo3w.p_mv_mw[0], 0.002, 0, 'mv') + create_measurement(net, "q", "trafo3w", net.res_trafo3w.q_mv_mvar[0], 0.002, 0, 'mv') + create_measurement(net, "p", "trafo3w", net.res_trafo3w.p_lv_mw[0], 0.001, 0, 'lv') + create_measurement(net, "q", "trafo3w", net.res_trafo3w.q_lv_mvar[0], 0.001, 0, 'lv') - pp.create_measurement(net, "v", "bus", net.res_bus.vm_pu[0], 0.01, 0) - pp.create_measurement(net, "v", "bus", net.res_bus.vm_pu[1], 0.01, 1) + create_measurement(net, "v", "bus", net.res_bus.vm_pu[0], 0.01, 0) + create_measurement(net, "v", "bus", net.res_bus.vm_pu[1], 0.01, 1) if not estimate(net): raise AssertionError("Estimation failed!") - if not (np.nanmax(np.abs(net.res_bus.vm_pu.values - net.res_bus_est.vm_pu.values)) < 0.006) or\ - not (np.nanmax(np.abs(net.res_bus.va_degree.values- net.res_bus_est.va_degree.values)) < 0.006): + if not (np.nanmax(np.abs(net.res_bus.vm_pu.values - net.res_bus_est.vm_pu.values)) < 0.006) or \ + not (np.nanmax(np.abs(net.res_bus.va_degree.values - net.res_bus_est.va_degree.values)) < 0.006): raise AssertionError("Estimation failed") - #Try estimate with results initialization + # Try estimate with results initialization if not estimate(net, init="results"): raise AssertionError("Estimation failed!") def test_network_with_trafo3w_with_disabled_branch(): - net = pp.create_empty_network() + net = create_empty_network() - bus_slack = pp.create_bus(net, vn_kv=110) - pp.create_ext_grid(net, bus=bus_slack) + bus_slack = create_bus(net, vn_kv=110) + create_ext_grid(net, bus=bus_slack) - bus_20_1 = pp.create_bus(net, vn_kv=20,name="b") - pp.create_sgen(net, bus=bus_20_1, p_mw=0.03, q_mvar=0.02) + bus_20_1 = create_bus(net, vn_kv=20, name="b") + create_sgen(net, bus=bus_20_1, p_mw=0.03, q_mvar=0.02) - bus_10_1 = pp.create_bus(net, vn_kv=10) - pp.create_sgen(net, bus=bus_10_1, p_mw=0.02, q_mvar=0.02) + bus_10_1 = create_bus(net, vn_kv=10) + create_sgen(net, bus=bus_10_1, p_mw=0.02, q_mvar=0.02) - bus_10_2 = pp.create_bus(net, vn_kv=10) - pp.create_load(net, bus=bus_10_2, p_mw=0.06, q_mvar=0.01) - pp.create_line(net, from_bus=bus_10_1, to_bus=bus_10_2, std_type="149-AL1/24-ST1A 10.0", length_km=2) - disabled_line = pp.create_line(net, from_bus=bus_10_1, to_bus=bus_10_2, std_type="149-AL1/24-ST1A 10.0", length_km=2) + bus_10_2 = create_bus(net, vn_kv=10) + create_load(net, bus=bus_10_2, p_mw=0.06, q_mvar=0.01) + create_line(net, from_bus=bus_10_1, to_bus=bus_10_2, std_type="149-AL1/24-ST1A 10.0", length_km=2) + disabled_line = create_line(net, from_bus=bus_10_1, to_bus=bus_10_2, std_type="149-AL1/24-ST1A 10.0", length_km=2) net.line.at[disabled_line, 'in_service'] = False - pp.create_transformer3w(net, bus_slack, bus_20_1, bus_10_1, std_type="63/25/38 MVA 110/20/10 kV") + create_transformer3w(net, bus_slack, bus_20_1, bus_10_1, std_type="63/25/38 MVA 110/20/10 kV") - pp.runpp(net) + runpp(net) - pp.create_measurement(net, "p", "line", net.res_line.p_from_mw[0], 0.001, 0, 'from') - pp.create_measurement(net, "q", "line", net.res_line.q_from_mvar[0], 0.001, 0, 'from') - pp.create_measurement(net, "p", "line", net.res_line.p_to_mw[0], 0.001, 0, 'to') - pp.create_measurement(net, "q", "line", net.res_line.q_to_mvar[0], 0.001, 0, 'to') - pp.create_measurement(net, "p", "line", net.res_line.p_to_mw[1], 0.001, 1, 'to') - pp.create_measurement(net, "q", "line", net.res_line.q_to_mvar[1], 0.001, 1, 'to') + create_measurement(net, "p", "line", net.res_line.p_from_mw[0], 0.001, 0, 'from') + create_measurement(net, "q", "line", net.res_line.q_from_mvar[0], 0.001, 0, 'from') + create_measurement(net, "p", "line", net.res_line.p_to_mw[0], 0.001, 0, 'to') + create_measurement(net, "q", "line", net.res_line.q_to_mvar[0], 0.001, 0, 'to') + create_measurement(net, "p", "line", net.res_line.p_to_mw[1], 0.001, 1, 'to') + create_measurement(net, "q", "line", net.res_line.q_to_mvar[1], 0.001, 1, 'to') - pp.create_measurement(net, "p", "trafo3w", net.res_trafo3w.p_hv_mw[0], 0.001, 0, 'hv') - pp.create_measurement(net, "q", "trafo3w", net.res_trafo3w.q_hv_mvar[0], 0.001, 0, 'hv') - pp.create_measurement(net, "p", "trafo3w", net.res_trafo3w.p_mv_mw[0], 0.002, 0, 'mv') - pp.create_measurement(net, "q", "trafo3w", net.res_trafo3w.q_mv_mvar[0], 0.002, 0, 'mv') - pp.create_measurement(net, "p", "trafo3w", net.res_trafo3w.p_lv_mw[0], 0.001, 0, 'lv') - pp.create_measurement(net, "q", "trafo3w", net.res_trafo3w.q_lv_mvar[0], 0.001, 0, 'lv') + create_measurement(net, "p", "trafo3w", net.res_trafo3w.p_hv_mw[0], 0.001, 0, 'hv') + create_measurement(net, "q", "trafo3w", net.res_trafo3w.q_hv_mvar[0], 0.001, 0, 'hv') + create_measurement(net, "p", "trafo3w", net.res_trafo3w.p_mv_mw[0], 0.002, 0, 'mv') + create_measurement(net, "q", "trafo3w", net.res_trafo3w.q_mv_mvar[0], 0.002, 0, 'mv') + create_measurement(net, "p", "trafo3w", net.res_trafo3w.p_lv_mw[0], 0.001, 0, 'lv') + create_measurement(net, "q", "trafo3w", net.res_trafo3w.q_lv_mvar[0], 0.001, 0, 'lv') - pp.create_measurement(net, "v", "bus", net.res_bus.vm_pu[0], 0.01, 0) - pp.create_measurement(net, "v", "bus", net.res_bus.vm_pu[1], 0.01, 1) + create_measurement(net, "v", "bus", net.res_bus.vm_pu[0], 0.01, 0) + create_measurement(net, "v", "bus", net.res_bus.vm_pu[1], 0.01, 1) success = estimate(net) assert success assert (np.nanmax(np.abs(net.res_bus.vm_pu.values - net.res_bus_est.vm_pu.values)) < 0.006) - assert (np.nanmax(np.abs(net.res_bus.va_degree.values- net.res_bus_est.va_degree.values)) < 0.006) + assert (np.nanmax(np.abs(net.res_bus.va_degree.values - net.res_bus_est.va_degree.values)) < 0.006) def create_net_with_bb_switch(): - net = pp.create_empty_network() - bus1 = pp.create_bus(net, name="bus1", vn_kv=10.) - bus2 = pp.create_bus(net, name="bus2", vn_kv=10.) - bus3 = pp.create_bus(net, name="bus3", vn_kv=10.) - bus4 = pp.create_bus(net, name="bus4", vn_kv=10.) - bus5 = pp.create_bus(net, name="bus5", vn_kv=110.) - - pp.create_line_from_parameters(net, bus1, bus2, 10, r_ohm_per_km=.59, x_ohm_per_km=.35, c_nf_per_km=10.1, - max_i_ka=1) - pp.create_transformer(net, bus5, bus1, std_type="40 MVA 110/10 kV") - pp.create_ext_grid(net, bus=bus5, vm_pu=1.0) - pp.create_load(net, bus1, p_mw=.350, q_mvar=.100) - pp.create_load(net, bus2, p_mw=.450, q_mvar=.100) - pp.create_load(net, bus3, p_mw=.250, q_mvar=.100) - pp.create_load(net, bus4, p_mw=.150, q_mvar=.100) + net = create_empty_network() + bus1 = create_bus(net, name="bus1", vn_kv=10.) + bus2 = create_bus(net, name="bus2", vn_kv=10.) + bus3 = create_bus(net, name="bus3", vn_kv=10.) + bus4 = create_bus(net, name="bus4", vn_kv=10.) + bus5 = create_bus(net, name="bus5", vn_kv=110.) + + create_line_from_parameters(net, bus1, bus2, 10, r_ohm_per_km=.59, x_ohm_per_km=.35, c_nf_per_km=10.1, + max_i_ka=1) + create_transformer(net, bus5, bus1, std_type="40 MVA 110/10 kV") + create_ext_grid(net, bus=bus5, vm_pu=1.0) + create_load(net, bus1, p_mw=.350, q_mvar=.100) + create_load(net, bus2, p_mw=.450, q_mvar=.100) + create_load(net, bus3, p_mw=.250, q_mvar=.100) + create_load(net, bus4, p_mw=.150, q_mvar=.100) # Created bb switch - pp.create_switch(net, bus2, element=bus3, et='b') - pp.create_switch(net, bus1, element=bus4, et='b') - pp.runpp(net, calculate_voltage_angles=True) + create_switch(net, bus2, element=bus3, et='b') + create_switch(net, bus1, element=bus4, et='b') + runpp(net, calculate_voltage_angles=True) - pp.create_measurement(net, "v", "bus", r2(net.res_bus.vm_pu.iloc[bus1], .002), .002, element=bus1) - pp.create_measurement(net, "v", "bus", r2(net.res_bus.vm_pu.iloc[bus3], .002), .002, element=bus3) - pp.create_measurement(net, "v", "bus", r2(net.res_bus.vm_pu.iloc[bus5], .002), .002, element=bus5) + create_measurement(net, "v", "bus", r2(net.res_bus.vm_pu.iloc[bus1], .002), .002, element=bus1) + create_measurement(net, "v", "bus", r2(net.res_bus.vm_pu.iloc[bus3], .002), .002, element=bus3) + create_measurement(net, "v", "bus", r2(net.res_bus.vm_pu.iloc[bus5], .002), .002, element=bus5) - pp.create_measurement(net, "p", "bus", r2(net.res_bus.p_mw.iloc[bus5], .002), .002, element=bus5) - pp.create_measurement(net, "q", "bus", r2(net.res_bus.q_mvar.iloc[bus5], .002), .002, element=bus5) + create_measurement(net, "p", "bus", r2(net.res_bus.p_mw.iloc[bus5], .002), .002, element=bus5) + create_measurement(net, "q", "bus", r2(net.res_bus.q_mvar.iloc[bus5], .002), .002, element=bus5) # If measurement on the bus with bb-switch activated, it will incluence the results of the merged bus - pp.create_measurement(net, "p", "bus", r2(net.res_bus.p_mw.iloc[bus4], .002), .002, element=bus4) - pp.create_measurement(net, "q", "bus", r2(net.res_bus.q_mvar.iloc[bus4], .002), .002, element=bus4) - pp.create_measurement(net, "p", "bus", r2(net.res_bus.p_mw.iloc[bus3], .001), .001, element=bus3) - pp.create_measurement(net, "q", "bus", r2(net.res_bus.q_mvar.iloc[bus3], .001), .001, element=bus3) - pp.create_measurement(net, "p", "bus", r2(net.res_bus.p_mw.iloc[bus2], .001), .001, element=bus2) - pp.create_measurement(net, "q", "bus", r2(net.res_bus.q_mvar.iloc[bus2], .001), .001, element=bus2) - pp.create_measurement(net, "p", "bus", r2(net.res_bus.p_mw.iloc[bus1], .001), .001, element=bus1) - pp.create_measurement(net, "q", "bus", r2(net.res_bus.q_mvar.iloc[bus1], .001), .001, element=bus1) - - pp.create_measurement(net, "p", "line", r2(net.res_line.p_from_mw.iloc[0], .002), .002, 0, side='from') - pp.create_measurement(net, "q", "line", r2(net.res_line.q_from_mvar.iloc[0], .002), .002, 0, side='from') - - pp.create_measurement(net, "p", "trafo", r2(net.res_trafo.p_hv_mw.iloc[0], .001), .01, - side="hv", element=0) - pp.create_measurement(net, "q", "trafo", r2(net.res_trafo.q_hv_mvar.iloc[0], .001), .01, - side="hv", element=0) + create_measurement(net, "p", "bus", r2(net.res_bus.p_mw.iloc[bus4], .002), .002, element=bus4) + create_measurement(net, "q", "bus", r2(net.res_bus.q_mvar.iloc[bus4], .002), .002, element=bus4) + create_measurement(net, "p", "bus", r2(net.res_bus.p_mw.iloc[bus3], .001), .001, element=bus3) + create_measurement(net, "q", "bus", r2(net.res_bus.q_mvar.iloc[bus3], .001), .001, element=bus3) + create_measurement(net, "p", "bus", r2(net.res_bus.p_mw.iloc[bus2], .001), .001, element=bus2) + create_measurement(net, "q", "bus", r2(net.res_bus.q_mvar.iloc[bus2], .001), .001, element=bus2) + create_measurement(net, "p", "bus", r2(net.res_bus.p_mw.iloc[bus1], .001), .001, element=bus1) + create_measurement(net, "q", "bus", r2(net.res_bus.q_mvar.iloc[bus1], .001), .001, element=bus1) + + create_measurement(net, "p", "line", r2(net.res_line.p_from_mw.iloc[0], .002), .002, 0, side='from') + create_measurement(net, "q", "line", r2(net.res_line.q_from_mvar.iloc[0], .002), .002, 0, side='from') + + create_measurement(net, "p", "trafo", r2(net.res_trafo.p_hv_mw.iloc[0], .001), .01, + side="hv", element=0) + create_measurement(net, "q", "trafo", r2(net.res_trafo.q_hv_mvar.iloc[0], .001), .01, + side="hv", element=0) return net def test_net_with_bb_switch_no_fusing(): net = create_net_with_bb_switch() success_none = estimate(net, tolerance=1e-5, fuse_buses_with_bb_switch=None) - pp.runpp(net, calculate_voltage_angles=True) + runpp(net, calculate_voltage_angles=True) assert success_none - assert np.allclose(net.res_bus.va_degree.values,net.res_bus_est.va_degree.values, 1e-2) - assert np.allclose(net.res_bus.vm_pu.values,net.res_bus_est.vm_pu.values, 1e-2) + assert np.allclose(net.res_bus.va_degree.values, net.res_bus_est.va_degree.values, 1e-2) + assert np.allclose(net.res_bus.vm_pu.values, net.res_bus_est.vm_pu.values, 1e-2) # asserting with more tolerance since the added impedance will cause some inaccuracy - assert np.allclose(net.res_bus.p_mw.values,net.res_bus_est.p_mw.values, 1e-1) - assert np.allclose(net.res_bus.q_mvar.values,net.res_bus_est.q_mvar.values, 1e-1) + assert np.allclose(net.res_bus.p_mw.values, net.res_bus_est.p_mw.values, 1e-1) + assert np.allclose(net.res_bus.q_mvar.values, net.res_bus_est.q_mvar.values, 1e-1) def test_net_with_bb_switch_fuse_one(): net = create_net_with_bb_switch() success = estimate(net, tolerance=1e-5, fuse_buses_with_bb_switch=[1]) - pp.runpp(net, calculate_voltage_angles=True) + runpp(net, calculate_voltage_angles=True) assert success - assert np.allclose(net.res_bus.va_degree.values,net.res_bus_est.va_degree.values, 1e-2) - assert np.allclose(net.res_bus.vm_pu.values,net.res_bus_est.vm_pu.values, 1e-2) + assert np.allclose(net.res_bus.va_degree.values, net.res_bus_est.va_degree.values, 1e-2) + assert np.allclose(net.res_bus.vm_pu.values, net.res_bus_est.vm_pu.values, 1e-2) # asserting with more tolerance since the added impedance will cause some inaccuracy - assert np.allclose(net.res_bus.p_mw.values[[0,3,4]],net.res_bus_est.p_mw.values[[0,3,4]], 1e-1) - assert np.allclose(net.res_bus.q_mvar.values[[0,3,4]],net.res_bus_est.q_mvar.values[[0,3,4]], 1e-1) + assert np.allclose(net.res_bus.p_mw.values[[0, 3, 4]], net.res_bus_est.p_mw.values[[0, 3, 4]], 1e-1) + assert np.allclose(net.res_bus.q_mvar.values[[0, 3, 4]], net.res_bus_est.q_mvar.values[[0, 3, 4]], 1e-1) @pytest.mark.xfail @@ -739,49 +745,49 @@ def test_net_with_bb_switch_fuse_one_identify_pq(): net = create_net_with_bb_switch() estimate(net, tolerance=1e-5, fuse_buses_with_bb_switch=[1]) # asserting with more tolerance since the added impedance will cause some inaccuracy - assert np.allclose(net.res_bus.p_mw.values,net.res_bus_est.p_mw.values, 1e-1) - assert np.allclose(net.res_bus.q_mvar.values,net.res_bus_est.q_mvar.values, 1e-1) + assert np.allclose(net.res_bus.p_mw.values, net.res_bus_est.p_mw.values, 1e-1) + assert np.allclose(net.res_bus.q_mvar.values, net.res_bus_est.q_mvar.values, 1e-1) def test_net_with_bb_switch_fusing(): net = create_net_with_bb_switch() estimate(net, tolerance=1e-5, fuse_buses_with_bb_switch='all') - assert np.allclose(net.res_bus.va_degree.values,net.res_bus_est.va_degree.values, 5e-2) - assert np.allclose(net.res_bus.vm_pu.values,net.res_bus_est.vm_pu.values, 5e-2) + assert np.allclose(net.res_bus.va_degree.values, net.res_bus_est.va_degree.values, 5e-2) + assert np.allclose(net.res_bus.vm_pu.values, net.res_bus_est.vm_pu.values, 5e-2) def test_net_with_zero_injection(): # @author: AndersLi - net = pp.create_empty_network() - b1 = pp.create_bus(net, name="Bus 1", vn_kv=220, index=1) - b2 = pp.create_bus(net, name="Bus 2", vn_kv=220, index=2) - b3 = pp.create_bus(net, name="Bus 3", vn_kv=220, index=3) - b4 = pp.create_bus(net, name="Bus 4", vn_kv=220, index=4) + net = create_empty_network() + b1 = create_bus(net, name="Bus 1", vn_kv=220, index=1) + b2 = create_bus(net, name="Bus 2", vn_kv=220, index=2) + b3 = create_bus(net, name="Bus 3", vn_kv=220, index=3) + b4 = create_bus(net, name="Bus 4", vn_kv=220, index=4) - pp.create_ext_grid(net, b1) # set the slack bus to bus 1 + create_ext_grid(net, b1) # set the slack bus to bus 1 factor = 48.4 * 2 * np.pi * 50 * 1e-9 # capacity factor - pp.create_line_from_parameters(net, 1, 2, 1, r_ohm_per_km=.0221*48.4, - x_ohm_per_km=.1603*48.4, c_nf_per_km=0.00274/factor, max_i_ka=1) - pp.create_line_from_parameters(net, 2, 3, 1, r_ohm_per_km=.0428*48.4, - x_ohm_per_km=.242*48.4, c_nf_per_km=0.00384/factor, max_i_ka=1) - l3 = pp.create_line_from_parameters(net, 2, 4, 1, r_ohm_per_km=.002*48.4, - x_ohm_per_km=.0111*48.4, c_nf_per_km=0.00018/factor, max_i_ka=1) - - pp.create_measurement(net, "v", "bus", 1.063548, .001, b1) # V at bus 1 - pp.create_measurement(net, "v", "bus", 1.068342, .001, b3) # V at bus 3 - pp.create_measurement(net, "v", "bus", 1.069861, .001, b4) # V at bus 4 - pp.create_measurement(net, "p", "bus", 40.0, 1, b1) # P at bus 1 - pp.create_measurement(net, "q", "bus", 9.2, 1, b1) # Q at bus 1 - # pp.create_measurement(net, "p", "bus", 0, 0.01, b2) # P at bus 2 - not required anymore - # pp.create_measurement(net, "q", "bus", 0, 0.01, b2) # Q at bus 2 - not required anymore - pp.create_measurement(net, "p", "bus", -10.0, 1, b3) # P at bus 3 - pp.create_measurement(net, "q", "bus", -1.0, 1, b3) # Q at bus 3 - pp.create_measurement(net, "p", "bus", -30.0, 1, b4) # P at bus 4 - pp.create_measurement(net, "q", "bus", 0.100, 1, b4) # Q at bus 4 - pp.create_measurement(net, "p", "line", 30.100, 1, l3, side="to") # Pline (bus 2 -> bus 4) at bus 4 - pp.create_measurement(net, "q", "line", -0.099, 1, l3, side="to") # Qline (bus 2 -> bus 4) at bus 4 + create_line_from_parameters(net, 1, 2, 1, r_ohm_per_km=.0221 * 48.4, + x_ohm_per_km=.1603 * 48.4, c_nf_per_km=0.00274 / factor, max_i_ka=1) + create_line_from_parameters(net, 2, 3, 1, r_ohm_per_km=.0428 * 48.4, + x_ohm_per_km=.242 * 48.4, c_nf_per_km=0.00384 / factor, max_i_ka=1) + l3 = create_line_from_parameters(net, 2, 4, 1, r_ohm_per_km=.002 * 48.4, + x_ohm_per_km=.0111 * 48.4, c_nf_per_km=0.00018 / factor, max_i_ka=1) + + create_measurement(net, "v", "bus", 1.063548, .001, b1) # V at bus 1 + create_measurement(net, "v", "bus", 1.068342, .001, b3) # V at bus 3 + create_measurement(net, "v", "bus", 1.069861, .001, b4) # V at bus 4 + create_measurement(net, "p", "bus", 40.0, 1, b1) # P at bus 1 + create_measurement(net, "q", "bus", 9.2, 1, b1) # Q at bus 1 + # create_measurement(net, "p", "bus", 0, 0.01, b2) # P at bus 2 - not required anymore + # create_measurement(net, "q", "bus", 0, 0.01, b2) # Q at bus 2 - not required anymore + create_measurement(net, "p", "bus", -10.0, 1, b3) # P at bus 3 + create_measurement(net, "q", "bus", -1.0, 1, b3) # Q at bus 3 + create_measurement(net, "p", "bus", -30.0, 1, b4) # P at bus 4 + create_measurement(net, "q", "bus", 0.100, 1, b4) # Q at bus 4 + create_measurement(net, "p", "line", 30.100, 1, l3, side="to") # Pline (bus 2 -> bus 4) at bus 4 + create_measurement(net, "q", "line", -0.099, 1, l3, side="to") # Qline (bus 2 -> bus 4) at bus 4 estimate(net, tolerance=1e-10, zero_injection='auto', algorithm='wls_with_zero_constraint') assert np.abs(net.res_bus_est.at[b2, 'p_mw']) < 1e-8 @@ -791,51 +797,51 @@ def test_net_with_zero_injection(): success = estimate(net, tolerance=1e-6, zero_injection="auto") success_given_bus = estimate(net, tolerance=1e-6, zero_injection=[b2]) assert success and success_given_bus - assert np.allclose(net.res_bus_est.va_degree.values,net_given_bus.res_bus_est.va_degree.values, 1e-3) - assert np.allclose(net.res_bus_est.vm_pu.values,net_given_bus.res_bus_est.vm_pu.values, 1e-3) + assert np.allclose(net.res_bus_est.va_degree.values, net_given_bus.res_bus_est.va_degree.values, 1e-3) + assert np.allclose(net.res_bus_est.vm_pu.values, net_given_bus.res_bus_est.vm_pu.values, 1e-3) def test_zero_injection_aux_bus(): - net = pp.create_empty_network() - bus1 = pp.create_bus(net, name="bus1", vn_kv=10.) - bus2 = pp.create_bus(net, name="bus2", vn_kv=10.) - bus3 = pp.create_bus(net, name="bus3", vn_kv=10.) - bus4 = pp.create_bus(net, name="bus4", vn_kv=110.) - - pp.create_line_from_parameters(net, bus1, bus2, 10, r_ohm_per_km=.59, x_ohm_per_km=.35, c_nf_per_km=10.1, - max_i_ka=1) - pp.create_line_from_parameters(net, bus2, bus3, 10, r_ohm_per_km=.59, x_ohm_per_km=.35, c_nf_per_km=10.1, - max_i_ka=1) - pp.create_transformer(net, bus4, bus1, std_type="40 MVA 110/10 kV") - pp.create_ext_grid(net, bus=bus4, vm_pu=1.0) - pp.create_load(net, bus1, p_mw=.350, q_mvar=.100) - pp.create_load(net, bus2, p_mw=.450, q_mvar=.100) - pp.create_load(net, bus3, p_mw=.250, q_mvar=.100) + net = create_empty_network() + bus1 = create_bus(net, name="bus1", vn_kv=10.) + bus2 = create_bus(net, name="bus2", vn_kv=10.) + bus3 = create_bus(net, name="bus3", vn_kv=10.) + bus4 = create_bus(net, name="bus4", vn_kv=110.) + + create_line_from_parameters(net, bus1, bus2, 10, r_ohm_per_km=.59, x_ohm_per_km=.35, c_nf_per_km=10.1, + max_i_ka=1) + create_line_from_parameters(net, bus2, bus3, 10, r_ohm_per_km=.59, x_ohm_per_km=.35, c_nf_per_km=10.1, + max_i_ka=1) + create_transformer(net, bus4, bus1, std_type="40 MVA 110/10 kV") + create_ext_grid(net, bus=bus4, vm_pu=1.0) + create_load(net, bus1, p_mw=.350, q_mvar=.100) + create_load(net, bus2, p_mw=.450, q_mvar=.100) + create_load(net, bus3, p_mw=.250, q_mvar=.100) net.bus.at[bus3, 'in_service'] = False # Created bb switch - pp.runpp(net, calculate_voltage_angles=True) + runpp(net, calculate_voltage_angles=True) - pp.create_measurement(net, "v", "bus", r2(net.res_bus.vm_pu.iloc[bus1], .002), .002, element=bus1) - pp.create_measurement(net, "v", "bus", r2(net.res_bus.vm_pu.iloc[bus4], .002), .002, element=bus4) + create_measurement(net, "v", "bus", r2(net.res_bus.vm_pu.iloc[bus1], .002), .002, element=bus1) + create_measurement(net, "v", "bus", r2(net.res_bus.vm_pu.iloc[bus4], .002), .002, element=bus4) - pp.create_measurement(net, "p", "bus", r2(net.res_bus.p_mw.iloc[bus4], .002), .002, element=bus4) - pp.create_measurement(net, "q", "bus", r2(net.res_bus.q_mvar.iloc[bus4], .002), .002, element=bus4) + create_measurement(net, "p", "bus", r2(net.res_bus.p_mw.iloc[bus4], .002), .002, element=bus4) + create_measurement(net, "q", "bus", r2(net.res_bus.q_mvar.iloc[bus4], .002), .002, element=bus4) # If measurement on the bus with bb-switch activated, it will incluence the results of the merged bus - pp.create_measurement(net, "p", "bus", r2(net.res_bus.p_mw.iloc[bus2], .001), .001, element=bus2) - pp.create_measurement(net, "q", "bus", r2(net.res_bus.q_mvar.iloc[bus2], .001), .001, element=bus2) - pp.create_measurement(net, "p", "bus", r2(net.res_bus.p_mw.iloc[bus1], .001), .001, element=bus1) - pp.create_measurement(net, "q", "bus", r2(net.res_bus.q_mvar.iloc[bus1], .001), .001, element=bus1) + create_measurement(net, "p", "bus", r2(net.res_bus.p_mw.iloc[bus2], .001), .001, element=bus2) + create_measurement(net, "q", "bus", r2(net.res_bus.q_mvar.iloc[bus2], .001), .001, element=bus2) + create_measurement(net, "p", "bus", r2(net.res_bus.p_mw.iloc[bus1], .001), .001, element=bus1) + create_measurement(net, "q", "bus", r2(net.res_bus.q_mvar.iloc[bus1], .001), .001, element=bus1) - pp.create_measurement(net, "p", "line", r2(net.res_line.p_from_mw.iloc[0], .002), .002, 0, side='from') - pp.create_measurement(net, "q", "line", r2(net.res_line.q_from_mvar.iloc[0], .002), .002, 0, side='from') + create_measurement(net, "p", "line", r2(net.res_line.p_from_mw.iloc[0], .002), .002, 0, side='from') + create_measurement(net, "q", "line", r2(net.res_line.q_from_mvar.iloc[0], .002), .002, 0, side='from') - pp.create_measurement(net, "p", "trafo", r2(net.res_trafo.p_hv_mw.iloc[0], .001), .01, - side="hv", element=0) - pp.create_measurement(net, "q", "trafo", r2(net.res_trafo.q_hv_mvar.iloc[0], .001), .01, - side="hv", element=0) + create_measurement(net, "p", "trafo", r2(net.res_trafo.p_hv_mw.iloc[0], .001), .01, + side="hv", element=0) + create_measurement(net, "q", "trafo", r2(net.res_trafo.q_hv_mvar.iloc[0], .001), .01, + side="hv", element=0) net_auto = deepcopy(net) net_aux = deepcopy(net) @@ -846,71 +852,73 @@ def test_zero_injection_aux_bus(): success_aux = estimate(net_aux, tolerance=1e-5, zero_injection='aux_bus') success_auto = estimate(net_auto, tolerance=1e-5, zero_injection='auto') assert success_none and success_aux and success_auto - assert np.allclose(net_auto.res_bus_est.va_degree.values,net_aux.res_bus_est.va_degree.values, 1e-4, equal_nan=True) - assert np.allclose(net_auto.res_bus_est.vm_pu.values,net_aux.res_bus_est.vm_pu.values, 1e-4, equal_nan=True) + assert np.allclose(net_auto.res_bus_est.va_degree.values, net_aux.res_bus_est.va_degree.values, 1e-4, + equal_nan=True) + assert np.allclose(net_auto.res_bus_est.vm_pu.values, net_aux.res_bus_est.vm_pu.values, 1e-4, equal_nan=True) # in case zero injection was set to none, the results should be different - assert ~np.allclose(net.res_bus_est.vm_pu.values,net_aux.res_bus_est.vm_pu.values, 1e-2, equal_nan=True) + assert ~np.allclose(net.res_bus_est.vm_pu.values, net_aux.res_bus_est.vm_pu.values, 1e-2, equal_nan=True) @pytest.mark.xfail def test_net_unobserved_island(): - net = pp.create_empty_network() - bus1 = pp.create_bus(net, name="bus1", vn_kv=10.) - bus2 = pp.create_bus(net, name="bus2", vn_kv=10.) - bus3 = pp.create_bus(net, name="bus3", vn_kv=10.) - bus4 = pp.create_bus(net, name="bus4", vn_kv=110.) - - pp.create_line_from_parameters(net, bus1, bus2, 10, r_ohm_per_km=.59, x_ohm_per_km=.35, c_nf_per_km=10.1, - max_i_ka=1) - pp.create_line_from_parameters(net, bus2, bus3, 10, r_ohm_per_km=.59, x_ohm_per_km=.35, c_nf_per_km=10.1, - max_i_ka=1) - pp.create_transformer(net, bus4, bus1, std_type="40 MVA 110/10 kV") - pp.create_ext_grid(net, bus=bus4, vm_pu=1.0) - pp.create_load(net, bus1, p_mw=.350, q_mvar=.100) - pp.create_load(net, bus2, p_mw=.450, q_mvar=.100) - pp.create_load(net, bus3, p_mw=.250, q_mvar=.100) + net = create_empty_network() + bus1 = create_bus(net, name="bus1", vn_kv=10.) + bus2 = create_bus(net, name="bus2", vn_kv=10.) + bus3 = create_bus(net, name="bus3", vn_kv=10.) + bus4 = create_bus(net, name="bus4", vn_kv=110.) + + create_line_from_parameters(net, bus1, bus2, 10, r_ohm_per_km=.59, x_ohm_per_km=.35, c_nf_per_km=10.1, + max_i_ka=1) + create_line_from_parameters(net, bus2, bus3, 10, r_ohm_per_km=.59, x_ohm_per_km=.35, c_nf_per_km=10.1, + max_i_ka=1) + create_transformer(net, bus4, bus1, std_type="40 MVA 110/10 kV") + create_ext_grid(net, bus=bus4, vm_pu=1.0) + create_load(net, bus1, p_mw=.350, q_mvar=.100) + create_load(net, bus2, p_mw=.450, q_mvar=.100) + create_load(net, bus3, p_mw=.250, q_mvar=.100) # Created bb switch - pp.runpp(net, calculate_voltage_angles=True) + runpp(net, calculate_voltage_angles=True) - pp.create_measurement(net, "v", "bus", r2(net.res_bus.vm_pu.iloc[bus1], .002), .002, element=bus1) - pp.create_measurement(net, "v", "bus", r2(net.res_bus.vm_pu.iloc[bus4], .002), .002, element=bus4) + create_measurement(net, "v", "bus", r2(net.res_bus.vm_pu.iloc[bus1], .002), .002, element=bus1) + create_measurement(net, "v", "bus", r2(net.res_bus.vm_pu.iloc[bus4], .002), .002, element=bus4) - pp.create_measurement(net, "p", "bus", r2(net.res_bus.p_mw.iloc[bus4], .002), .002, element=bus4) - pp.create_measurement(net, "q", "bus", r2(net.res_bus.q_mvar.iloc[bus4], .002), .002, element=bus4) + create_measurement(net, "p", "bus", r2(net.res_bus.p_mw.iloc[bus4], .002), .002, element=bus4) + create_measurement(net, "q", "bus", r2(net.res_bus.q_mvar.iloc[bus4], .002), .002, element=bus4) # IF pq of bus2 is not available makes bus3 an unobserved island -# pp.create_measurement(net, "p", "bus", -r2(net.res_bus.p_mw.iloc[bus2], .001), .001, element=bus2) -# pp.create_measurement(net, "q", "bus", -r2(net.res_bus.q_mvar.iloc[bus2], .001), .001, element=bus2) - pp.create_measurement(net, "p", "bus", r2(net.res_bus.p_mw.iloc[bus1], .001), .001, element=bus1) - pp.create_measurement(net, "q", "bus", r2(net.res_bus.q_mvar.iloc[bus1], .001), .001, element=bus1) + # create_measurement(net, "p", "bus", -r2(net.res_bus.p_mw.iloc[bus2], .001), .001, element=bus2) + # create_measurement(net, "q", "bus", -r2(net.res_bus.q_mvar.iloc[bus2], .001), .001, element=bus2) + create_measurement(net, "p", "bus", r2(net.res_bus.p_mw.iloc[bus1], .001), .001, element=bus1) + create_measurement(net, "q", "bus", r2(net.res_bus.q_mvar.iloc[bus1], .001), .001, element=bus1) - pp.create_measurement(net, "p", "line", r2(net.res_line.p_from_mw.iloc[0], .002), .002, 0, side='from') - pp.create_measurement(net, "q", "line", r2(net.res_line.q_from_mvar.iloc[0], .002), .002, 0, side='from') + create_measurement(net, "p", "line", r2(net.res_line.p_from_mw.iloc[0], .002), .002, 0, side='from') + create_measurement(net, "q", "line", r2(net.res_line.q_from_mvar.iloc[0], .002), .002, 0, side='from') - pp.create_measurement(net, "p", "trafo", r2(net.res_trafo.p_hv_mw.iloc[0], .001), .01, - side="hv", element=0) - pp.create_measurement(net, "q", "trafo", r2(net.res_trafo.q_hv_mvar.iloc[0], .001), .01, - side="hv", element=0) + create_measurement(net, "p", "trafo", r2(net.res_trafo.p_hv_mw.iloc[0], .001), .01, + side="hv", element=0) + create_measurement(net, "q", "trafo", r2(net.res_trafo.q_hv_mvar.iloc[0], .001), .01, + side="hv", element=0) if not estimate(net, tolerance=1e-6, zero_injection=None): raise AssertionError("Estimation failed!") + def test_net_oos_line(): - net = nw.case9() + net = case9() net.line.in_service.iat[4] = False - pp.runpp(net) + runpp(net) for line_ix in net.line.index: - pp.create_measurement(net, "p", "line", net.res_line.at[line_ix, "p_from_mw"], - 0.01, element=line_ix, side="from") - pp.create_measurement(net, "q", "line", net.res_line.at[line_ix, "q_from_mvar"], - 0.01, element=line_ix, side="from") + create_measurement(net, "p", "line", net.res_line.at[line_ix, "p_from_mw"], + 0.01, element=line_ix, side="from") + create_measurement(net, "q", "line", net.res_line.at[line_ix, "q_from_mvar"], + 0.01, element=line_ix, side="from") for bus_ix in net.bus.index: - pp.create_measurement(net, "v", "bus", net.res_bus.at[bus_ix, "vm_pu"], - 0.01, element=bus_ix) + create_measurement(net, "v", "bus", net.res_bus.at[bus_ix, "vm_pu"], + 0.01, element=bus_ix) if not estimate(net, tolerance=1e-6, zero_injection=None): raise AssertionError("Estimation failed!") @@ -925,7 +933,7 @@ def r2(base, v): def _compare_pf_and_se_results(net): - pp.runpp(net, calculate_voltage_angles=True, trafo_model="t") + runpp(net, calculate_voltage_angles=True, trafo_model="t") assert (np.allclose(net.res_bus_est.p_mw.values, net.res_bus.p_mw.values, 1e-6)) assert (np.allclose(net.res_bus_est.q_mvar.values, net.res_bus.q_mvar.values, 1e-6)) assert (np.allclose(net.res_line_est.p_from_mw.values, net.res_line.p_from_mw.values, 1e-6)) diff --git a/pandapower/test/grid_equivalents/test_get_equivalent.py b/pandapower/test/grid_equivalents/test_get_equivalent.py index 1f0f926a7..658b7d560 100644 --- a/pandapower/test/grid_equivalents/test_get_equivalent.py +++ b/pandapower/test/grid_equivalents/test_get_equivalent.py @@ -1,102 +1,109 @@ -import pytest -import numpy as np -import pandapower as pp -import pandapower.networks -import pandapower.grid_equivalents import os -import pandas as pd from random import sample -import pandapower.toolbox -from pandapower.control import ConstControl +import numpy as np +import pandas as pd +import pytest + from pandapower import pp_dir +from pandapower.control import ConstControl +from pandapower.control.util.auxiliary import create_trafo_characteristics +from pandapower.create import create_empty_network, create_buses, create_ext_grid, create_poly_cost, create_line, \ + create_load, create_sgen, create_pwl_cost, create_bus, create_switch, create_motor +from pandapower.grid_equivalents.auxiliary import replace_motor_by_load, _runpp_except_voltage_angles +from pandapower.grid_equivalents.get_equivalent import get_equivalent, merge_internal_net_and_equivalent_external_net +from pandapower.grid_equivalents.ward_generation import create_passive_external_net_for_ward_admittance +from pandapower.groups import group_element_lists, create_group, compare_group_elements, group_row, \ + set_group_reference_column, count_group_elements, group_element_index +from pandapower.networks.create_examples import example_multivoltage +from pandapower.networks.power_system_test_cases import case9, case30 +from pandapower.run import runpp from pandapower.timeseries import DFData -from pandapower.grid_equivalents.auxiliary import replace_motor_by_load -from pandapower.grid_equivalents.ward_generation import \ - create_passive_external_net_for_ward_admittance -from pandapower.grid_equivalents.auxiliary import _runpp_except_voltage_angles +from pandapower.toolbox.comparison import nets_equal, dataframes_equal +from pandapower.toolbox.data_modification import reindex_buses +from pandapower.toolbox.element_selection import pp_elements +from pandapower.toolbox.grid_modification import select_subnet, replace_gen_by_sgen, replace_ext_grid_by_gen def create_test_net(): - net = pp.create_empty_network() + net = create_empty_network() # buses - pp.create_buses(net, 7, 20, zone=[0, 0, 1, 1, 1, 0, 0], name=["bus %i" % i for i in range(7)], - min_vm_pu=np.append(np.arange(.9, 0.94, .01), [np.nan, np.nan, np.nan])) + create_buses(net, 7, 20, zone=[0, 0, 1, 1, 1, 0, 0], name=["bus %i" % i for i in range(7)], + min_vm_pu=np.append(np.arange(.9, 0.94, .01), [np.nan, np.nan, np.nan])) # ext_grid - idx = pp.create_ext_grid(net, 0, 1.0, 0.0) - pp.create_poly_cost(net, idx, "ext_grid", 10) + idx = create_ext_grid(net, 0, 1.0, 0.0) + create_poly_cost(net, idx, "ext_grid", 10) # sgens - idx = pp.create_sgen(net, 6, 1.2) - pp.create_poly_cost(net, idx, "sgen", 12) - idx = pp.create_sgen(net, 5, 1.5, index=5) - pp.create_poly_cost(net, idx, "sgen", 14) + idx = create_sgen(net, 6, 1.2) + create_poly_cost(net, idx, "sgen", 12) + idx = create_sgen(net, 5, 1.5, index=5) + create_poly_cost(net, idx, "sgen", 14) # loads for load_bus in [0, 2, 3, 4, 6]: - pp.create_load(net, load_bus, 1.2) + create_load(net, load_bus, 1.2) # lines for i in range(6): - pp.create_line(net, i, i+1, 1.1, 'NA2XS2Y 1x185 RM/25 12/20 kV') - pp.create_line(net, 0, 6, 3.2, 'NA2XS2Y 1x185 RM/25 12/20 kV') + create_line(net, i, i + 1, 1.1, 'NA2XS2Y 1x185 RM/25 12/20 kV') + create_line(net, 0, 6, 3.2, 'NA2XS2Y 1x185 RM/25 12/20 kV') # runpp and return - pp.runpp(net, calculate_voltage_angles=True) + runpp(net, calculate_voltage_angles=True) return net def run_basic_usecases(eq_type, net=None): - if net is None: net = create_test_net() # UC1: get internal buses [0, 1, 5, 6] and equivalent connected to buses [1, 5] - eq_net1 = pp.grid_equivalents.get_equivalent( + eq_net1 = get_equivalent( net, eq_type, boundary_buses=[1, 5], internal_buses=[0, 6]) - pp.runpp(eq_net1, calculate_voltage_angles=True) + runpp(eq_net1, calculate_voltage_angles=True) # UC2: don't get the internal buses [0, 1, 5, 6] but the boundary buses [2, 4] and the # equivalent - eq_net2 = pp.grid_equivalents.get_equivalent(net, eq_type, boundary_buses=[2, 4], - internal_buses=[0, 1, 5, 6], return_internal=False) + eq_net2 = get_equivalent(net, eq_type, boundary_buses=[2, 4], + internal_buses=[0, 1, 5, 6], return_internal=False) # UC3: the input is only the subnet including the external buses [2, 3, 4] and the # boundary buses [1, 5] -> expected return are the boundary buses and the equivalent - subnet = pp.select_subnet(net, list(range(1, 6)), include_results=True) - subnet_rest = pp.select_subnet(net, [0, 1, 5, 6], include_results=True) - eq_net3a = pp.grid_equivalents.get_equivalent( + subnet = select_subnet(net, list(range(1, 6)), include_results=True) + subnet_rest = select_subnet(net, [0, 1, 5, 6], include_results=True) + eq_net3a = get_equivalent( subnet, eq_type, boundary_buses=[1, 5], internal_buses=None) # UC3b tests whether this also works for 'internal_buses' as empty list - eq_net3b = pp.grid_equivalents.get_equivalent( + eq_net3b = get_equivalent( subnet, eq_type, boundary_buses=[1, 5], internal_buses=[]) eq_net3a.sgen = eq_net3a.sgen.drop(columns=["origin_id"]) eq_net3b.sgen = eq_net3b.sgen.drop(columns=["origin_id"]) assert set(eq_net3a["group"].index) == set(eq_net3b["group"].index) - assert pandapower.toolbox.nets_equal(eq_net3a, eq_net3b, exclude_elms=["group"]) + assert nets_equal(eq_net3a, eq_net3b, exclude_elms=["group"]) - elm_lists = pp.group_element_lists(eq_net3b, eq_net3b.group.index[0]) - idx2comp = pp.create_group(eq_net3a, elm_lists[0], elm_lists[1], reference_columns=elm_lists[2]) - assert pp.compare_group_elements(eq_net3a, eq_net3a.group.index[0], idx2comp) + elm_lists = group_element_lists(eq_net3b, eq_net3b.group.index[0]) + idx2comp = create_group(eq_net3a, elm_lists[0], elm_lists[1], reference_columns=elm_lists[2]) + assert compare_group_elements(eq_net3a, eq_net3a.group.index[0], idx2comp) # UC3: merge eq_net3 with subnet_rest - eq_net3 = pp.grid_equivalents.merge_internal_net_and_equivalent_external_net( + eq_net3 = merge_internal_net_and_equivalent_external_net( eq_net3a, subnet_rest) - pp.runpp(eq_net3, calculate_voltage_angles=True) - assert pandapower.toolbox.nets_equal(net, create_test_net()) + runpp(eq_net3, calculate_voltage_angles=True) + assert nets_equal(net, create_test_net()) return eq_net1, eq_net2, eq_net3 def check_elements_amount(net, elms_dict, check_all_pp_elements=True): if check_all_pp_elements: - elms_dict.update({elm: 0 for elm in pandapower.toolbox.pp_elements() if elm not in elms_dict.keys()}) + elms_dict.update({elm: 0 for elm in pp_elements() if elm not in elms_dict.keys()}) for key, val in elms_dict.items(): if not net[key].shape[0] == val: raise ValueError("The net has %i %ss but %i are expected." % ( - net[key].shape[0], key, int(val))) + net[key].shape[0], key, int(val))) def check_res_bus(net_orig, net_eq): @@ -114,8 +121,8 @@ def check_res_bus(net_orig, net_eq): def check_results_without_order(eq_net2, eq_net3): - for elm in pandapower.toolbox.pp_elements(): - res_table = "res_"+elm + for elm in pp_elements(): + res_table = "res_" + elm if res_table in eq_net2.keys() and eq_net2[res_table].shape[0]: idxs3 = list(eq_net3[res_table].index) for idx2 in eq_net2[res_table].index: @@ -137,9 +144,9 @@ def test_cost_consideration(): """ # input net = create_test_net() - idx = pp.create_sgen(net, 1, 1.3, index=2) - pp.create_poly_cost(net, idx, "sgen", 2.3, index=4) - pp.runpp(net) + idx = create_sgen(net, 1, 1.3, index=2) + create_poly_cost(net, idx, "sgen", 2.3, index=4) + runpp(net) assert all(net.sgen.index.values == np.array([0, 5, 2])) assert all(net.poly_cost.element == np.array([0, 0, 5, 2])) @@ -148,14 +155,14 @@ def test_cost_consideration(): if cost_type == "pwl_cost": for poly in net.poly_cost.itertuples(): net.poly_cost = net.poly_cost.drop(poly.Index) - pp.create_pwl_cost(net, poly.element, poly.et, [[0, 20, 1]], index=poly.Index) + create_pwl_cost(net, poly.element, poly.et, [[0, 20, 1]], index=poly.Index) # eq generation boundary_buses = [0, 2] internal_buses = [1] - eq_net1 = pp.grid_equivalents.get_equivalent(net, "rei", boundary_buses, internal_buses) - eq_net2 = pp.grid_equivalents.get_equivalent(net, "rei", boundary_buses, internal_buses, - return_internal=False) + eq_net1 = get_equivalent(net, "rei", boundary_buses, internal_buses) + eq_net2 = get_equivalent(net, "rei", boundary_buses, internal_buses, + return_internal=False) # check elements check_elements_amount(eq_net1, {"bus": 6, "load": 3, "sgen": 3, "shunt": 5, "ext_grid": 1, @@ -177,24 +184,24 @@ def test_cost_consideration(): idx_eq_net = eq_net1.sgen.sort_values("p_mw").index[i] assert np.all(net[cost_type].loc[(net[cost_type].element == idx_net) & (net[cost_type].et == "sgen")].drop( - columns=["element"]).values == + columns=["element"]).values == eq_net1[cost_type].loc[(eq_net1[cost_type].element == idx_eq_net) & (eq_net1[cost_type].et == "sgen")].drop( - columns=["element"]).values) + columns=["element"]).values) # eq_net2 assert np.all(net[cost_type].loc[net[cost_type].et == "ext_grid"].values == eq_net2[cost_type].loc[eq_net2[cost_type].et == "ext_grid"]) for i in range(2): - idx_net = net.sgen.loc[~net.sgen.bus.isin(boundary_buses+internal_buses)].sort_values( + idx_net = net.sgen.loc[~net.sgen.bus.isin(boundary_buses + internal_buses)].sort_values( "p_mw").index[i] idx_eq_net = eq_net2.sgen.sort_values("p_mw").index[i] assert np.all(net[cost_type].loc[(net[cost_type].element == idx_net) & (net[cost_type].et == "sgen")].drop( - columns=["element"]).values == + columns=["element"]).values == eq_net2[cost_type].loc[(eq_net2[cost_type].element == idx_eq_net) & (eq_net2[cost_type].et == "sgen")].drop( - columns=["element"]).values) + columns=["element"]).values) def test_basic_usecases(): @@ -237,10 +244,10 @@ def test_basic_usecases(): def test_case9_with_slack_generator_in_external_net(): - net = pp.networks.case9() - idx = pp.replace_ext_grid_by_gen(net) + net = case9() + idx = replace_ext_grid_by_gen(net) net.gen.loc[idx, 'slack'] = True - pp.runpp(net) + runpp(net) # since the only slack is in the external_buses, we expect get_equivalent() to move the slack # bus into the boundary for use case 1 and 2. In use case 3 the slack generator stays in the @@ -257,11 +264,11 @@ def test_case9_with_slack_generator_in_external_net(): # --- # UC1 - eq_net1 = pp.grid_equivalents.get_equivalent(net, eq_type, boundary_buses, internal_buses) - eq_net1b = pp.grid_equivalents.get_equivalent(net, eq_type, list(boundary_buses), list(internal_buses)) + eq_net1 = get_equivalent(net, eq_type, boundary_buses, internal_buses) + eq_net1b = get_equivalent(net, eq_type, list(boundary_buses), list(internal_buses)) eq_net1.gen = eq_net1.gen.drop(columns=["origin_id"]) eq_net1b.gen = eq_net1b.gen.drop(columns=["origin_id"]) - assert pandapower.toolbox.nets_equal(eq_net1, eq_net1b) + assert nets_equal(eq_net1, eq_net1b) assert net.bus.name.loc[list(boundary_buses | internal_buses | slack_bus)].isin( eq_net1.bus.name).all() assert eq_net1.gen.slack.sum() == 1 @@ -269,7 +276,7 @@ def test_case9_with_slack_generator_in_external_net(): if eq_type == "rei": check_elements_amount(eq_net1, {"bus": 7, "load": 2, "gen": 3, "shunt": 4, "line": 4, "impedance": 6}, check_all_pp_elements=True) - pp.runpp(eq_net1) + runpp(eq_net1) check_res_bus(net, eq_net1) elif "ward" in eq_type: check_elements_amount(eq_net1, {"bus": 6, "load": 1, "gen": 3, eq_type: 3, @@ -277,8 +284,8 @@ def test_case9_with_slack_generator_in_external_net(): check_res_bus(net, eq_net1) # --- # UC2: return_internal=False - eq_net2 = pp.grid_equivalents.get_equivalent(net, eq_type, boundary_buses, internal_buses, - return_internal=False) + eq_net2 = get_equivalent(net, eq_type, boundary_buses, internal_buses, + return_internal=False) assert net.bus.name.loc[list(boundary_buses | slack_bus)].isin(eq_net2.bus.name).all() assert eq_net2.gen.slack.all() if eq_type == "rei": @@ -291,9 +298,9 @@ def test_case9_with_slack_generator_in_external_net(): check_res_bus(net, eq_net1) # --- # UC3: input is only boundary and external net - ib_net = pp.select_subnet(net, internal_buses | boundary_buses, include_results=True) - be_net = pp.select_subnet(net, boundary_buses | external_buses, include_results=True) - eq_net3 = pp.grid_equivalents.get_equivalent(be_net, eq_type, boundary_buses, internal_buses=[]) + ib_net = select_subnet(net, internal_buses | boundary_buses, include_results=True) + be_net = select_subnet(net, boundary_buses | external_buses, include_results=True) + eq_net3 = get_equivalent(be_net, eq_type, boundary_buses, internal_buses=[]) assert not net.bus.name.loc[list(external_buses)].isin(eq_net3.bus.name).all() if eq_type == "rei": assert eq_net3.gen.slack.all() @@ -308,9 +315,9 @@ def test_case9_with_slack_generator_in_external_net(): "impedance": 6}, check_all_pp_elements=True) # merge eq_net with internal net to get a power flow runable net to check the results eq_net3.gen.slack = True - eq_net4 = pp.grid_equivalents.merge_internal_net_and_equivalent_external_net( + eq_net4 = merge_internal_net_and_equivalent_external_net( eq_net3, ib_net) - pp.runpp(eq_net4) + runpp(eq_net4) check_res_bus(net, eq_net4) elif "ward" in eq_type: check_elements_amount(eq_net3, {"bus": 2, eq_type: 2, "impedance": 1}, @@ -319,39 +326,38 @@ def test_case9_with_slack_generator_in_external_net(): def test_adopt_columns_to_separated_eq_elms(): - # --- gen_separate - net = pp.networks.case9() - pp.replace_ext_grid_by_gen(net, slack=True) + net = case9() + replace_ext_grid_by_gen(net, slack=True) net.gen.index = [1, 2, 0] net.poly_cost["element"] = net.gen.index.values net.gen.sort_index(inplace=True) - net.gen["origin_id"] = ["gen_"+str(i) for i in range(net.gen.shape[0])] + net.gen["origin_id"] = ["gen_" + str(i) for i in range(net.gen.shape[0])] - eq_net = pp.grid_equivalents.get_equivalent(net, "rei", boundary_buses={4, 8}, internal_buses={0, 3}, - gen_separate=True) + eq_net = get_equivalent(net, "rei", boundary_buses={4, 8}, internal_buses={0, 3}, + gen_separate=True) columns_to_check = ["p_mw", "vm_pu", "sn_mva", "scaling", "controllable", "origin_id", "max_p_mw", "min_p_mw", "max_q_mvar", "min_q_mvar"] - assert pandapower.toolbox.dataframes_equal(net.gen[columns_to_check], eq_net.gen[columns_to_check]) + assert dataframes_equal(net.gen[columns_to_check], eq_net.gen[columns_to_check]) assert (net.gen.origin_id.loc[net.poly_cost.element].values == eq_net.gen.origin_id.loc[eq_net.poly_cost.element].values).all() # --- sgen_separate0 - net = pp.networks.case9() - pp.replace_gen_by_sgen(net) + net = case9() + replace_gen_by_sgen(net) net.sgen["origin_id"] = ["sgen_%i" % i for i in range(net.sgen.shape[0])] - eq_net = pp.grid_equivalents.get_equivalent(net, "rei", boundary_buses={4, 8}, internal_buses={0, 3}, - sgen_separate=True) + eq_net = get_equivalent(net, "rei", boundary_buses={4, 8}, internal_buses={0, 3}, + sgen_separate=True) columns_to_check = ["p_mw", "q_mvar", "scaling", "sn_mva", "controllable", "origin_id", "max_p_mw", "min_p_mw", "max_q_mvar", "min_q_mvar"] - assert pandapower.toolbox.dataframes_equal(net.sgen[columns_to_check], eq_net.sgen[columns_to_check]) + assert dataframes_equal(net.sgen[columns_to_check], eq_net.sgen[columns_to_check]) def test_equivalent_groups(): - net = pp.networks.example_multivoltage() + net = example_multivoltage() # net.sn_mva = 100 - for elm in pandapower.toolbox.pp_elements(): + for elm in pp_elements(): if net[elm].shape[0] and not net[elm].name.duplicated().any(): net[elm]["origin_id"] = net[elm].name @@ -362,99 +368,99 @@ def test_equivalent_groups(): ext1 = {42, 43, 44} bb1 = {37, 41} int1 = set(net.bus.index) - ext1 - bb1 - net_eq1 = pp.grid_equivalents.get_equivalent(net, "rei", bb1, int1, - reference_column="origin_id") + net_eq1 = get_equivalent(net, "rei", bb1, int1, + reference_column="origin_id") assert len(set(net_eq1.group.index)) == 1 gr1_idx = net_eq1.group.index[0] for elm, no in [("bus", 3), ("load", 1), ("sgen", 2)]: - assert len(pp.group_row(net_eq1, gr1_idx, elm).at["element_index"]) == no - assert len(pp.group_row(net_eq1, gr1_idx, "impedance").at["element_index"]) == \ - net_eq1.impedance.shape[0] - 1 - assert len(pp.group_row(net_eq1, gr1_idx, "shunt").at["element_index"]) == \ - net_eq1.shunt.shape[0] - 1 - pp.set_group_reference_column(net_eq1, gr1_idx, "origin_id") + assert len(group_row(net_eq1, gr1_idx, elm).at["element_index"]) == no + assert len(group_row(net_eq1, gr1_idx, "impedance").at["element_index"]) == \ + net_eq1.impedance.shape[0] - 1 + assert len(group_row(net_eq1, gr1_idx, "shunt").at["element_index"]) == \ + net_eq1.shunt.shape[0] - 1 + set_group_reference_column(net_eq1, gr1_idx, "origin_id") bb2 = {37} - int2 = set(net_eq1.bus.index[net_eq1.bus.vn_kv > 11]) | set(pp.group_element_index( - net_eq1, gr1_idx,"bus")) + int2 = set(net_eq1.bus.index[net_eq1.bus.vn_kv > 11]) | set(group_element_index( + net_eq1, gr1_idx, "bus")) # test 2nd rei for sgen_separate in [True, False]: print("sgen_separate is " + str(sgen_separate)) # test fails with lightsim2grid, for unknown reason - net_eq2 = pp.grid_equivalents.get_equivalent( + net_eq2 = get_equivalent( net_eq1, "rei", bb2, int2, sgen_separate=sgen_separate, reference_column="origin_id", lightsim2grid=False) gr2_idx = net_eq2.group.index[-1] assert len(set(net_eq2.group.index)) == 2 - assert len(set(pp.count_group_elements(net_eq2, gr2_idx).index) ^ { + assert len(set(count_group_elements(net_eq2, gr2_idx).index) ^ { "bus", "load", "sgen", "impedance", "shunt"}) == 0 no_sg = 6 if sgen_separate else 1 # number of expected sgens no_l = 1 # number of expected loads - no_b = no_sg + no_l # number of expected buses + no_b = no_sg + no_l # number of expected buses # print(pp.count_group_elements(net_eq2, gr2_idx)) for elm, no in [("bus", no_b), ("load", no_l), ("sgen", no_sg)]: - assert len(pp.group_row(net_eq2, gr2_idx, elm).at["element_index"]) == no - assert len(pp.group_row(net_eq2, gr2_idx, "impedance").at["element_index"]) > \ - 0.5 * (no_b-1)**2 # the number of impedances is lower than no_b**2 since imp < 1e-8 - # were dropped + assert len(group_row(net_eq2, gr2_idx, elm).at["element_index"]) == no + assert len(group_row(net_eq2, gr2_idx, "impedance").at["element_index"]) > \ + 0.5 * (no_b - 1) ** 2 # the number of impedances is lower than no_b**2 since imp < 1e-8 + # were dropped # test 2nd xward - net_eq2 = pp.grid_equivalents.get_equivalent( + net_eq2 = get_equivalent( net_eq1, "xward", bb2, int2, reference_column="origin_id") gr2_idx = net_eq2.group.index[-1] assert len(set(net_eq2.group.index)) == 2 - assert len(set(pp.count_group_elements(net_eq2, gr2_idx).index) ^ {"xward"}) == 0 + assert len(set(count_group_elements(net_eq2, gr2_idx).index) ^ {"xward"}) == 0 for elm, no in [("xward", 1)]: - assert len(pp.group_row(net_eq2, gr2_idx, elm).at["element_index"]) == no + assert len(group_row(net_eq2, gr2_idx, elm).at["element_index"]) == no def test_shifter_degree(): - net = pp.networks.example_multivoltage() + net = example_multivoltage() net.trafo.at[0, "shift_degree"] = 30 net.trafo.at[1, "shift_degree"] = -60 net.trafo3w.at[0, "shift_mv_degree"] = 90 net.trafo3w.at[0, "shift_lv_degree"] = 150 - pp.runpp(net, calculate_voltage_angles=True) + runpp(net, calculate_voltage_angles=True) boundary_buses = list([net.trafo.hv_bus.values[1]]) + list(net.trafo.lv_bus.values) + \ - list(net.trafo3w.hv_bus.values) + list(net.trafo3w.lv_bus.values) + list(net.trafo3w.hv_bus.values) + list(net.trafo3w.lv_bus.values) i = net.ext_grid.bus.values[0] - for eq_type in ["rei"]: + for eq_type in ["rei"]: for b in boundary_buses: - net_rei = pp.grid_equivalents.get_equivalent(net, eq_type, [b], [i], - calculate_voltage_angles=True, - sgen_separate=False) + net_rei = get_equivalent(net, eq_type, [b], [i], + calculate_voltage_angles=True, + sgen_separate=False) all_i_buses = net_rei.bus_lookups["origin_all_internal_buses"] vm_error = max(abs(net_rei.res_bus.vm_pu[all_i_buses].values - - net.res_bus.vm_pu[all_i_buses].values)) + net.res_bus.vm_pu[all_i_buses].values)) va_error = max(abs(net_rei.res_bus.va_degree[all_i_buses].values - - net.res_bus.va_degree[all_i_buses].values)) + net.res_bus.va_degree[all_i_buses].values)) assert vm_error < 1e-3 assert va_error < 0.5 def test_retain_original_internal_indices(): - net = pp.networks.case30() - pp.replace_gen_by_sgen(net) + net = case30() + replace_gen_by_sgen(net) sgen_idxs = sample(list(range(100)), len(net.sgen)) line_idxs = sample(list(range(100)), len(net.line)) bus_idxs = sample(list(range(100)), len(net.bus)) bus_lookup = dict(zip(net.bus.index.tolist(), bus_idxs)) net.sgen.index = sgen_idxs net.line.index = line_idxs - pp.reindex_buses(net, bus_lookup) + reindex_buses(net, bus_lookup) first3buses = net.bus.index.tolist()[0:3] assert not np.array_equal(first3buses, list(range(3))) - pp.runpp(net) + runpp(net) eq_type = "rei" boundary_buses = [bus_lookup[b] for b in [3, 9, 22]] internal_buses = [bus_lookup[0]] - net_eq = pp.grid_equivalents.get_equivalent(net, eq_type, boundary_buses, internal_buses, - calculate_voltage_angles=True, - retain_original_internal_indices=True) + net_eq = get_equivalent(net, eq_type, boundary_buses, internal_buses, + calculate_voltage_angles=True, + retain_original_internal_indices=True) assert net_eq.sgen.index.tolist()[:3] == sgen_idxs[:3] assert set(net_eq.line.index.tolist()) - set(line_idxs) == set() @@ -463,31 +469,31 @@ def test_retain_original_internal_indices(): def test_switch_sgens(): - net = pp.networks.case9() - pp.replace_gen_by_sgen(net) - pp.create_bus(net, 345) - pp.create_switch(net, 9, 1, "b") - pp.create_sgen(net, 9, 10, 10) - pp.runpp(net) - net_eq = pp.grid_equivalents.get_equivalent(net, "rei", [4, 8], [0]) + net = case9() + replace_gen_by_sgen(net) + create_bus(net, 345) + create_switch(net, 9, 1, "b") + create_sgen(net, 9, 10, 10) + runpp(net) + net_eq = get_equivalent(net, "rei", [4, 8], [0]) assert max(net.res_bus.vm_pu[[0, 3, 4, 8]].values - net_eq.res_bus.vm_pu[[0, 3, 4, 8]].values) < 1e-6 assert max(net.res_bus.va_degree[[0, 3, 4, 8]].values - net_eq.res_bus.va_degree[[0, 3, 4, 8]].values) < 1e-6 def test_characteristic(): - net = pp.networks.example_multivoltage() - pp.control.create_trafo_characteristics(net, "trafo", [1], 'vk_percent', - [[-2,-1,0,1,2]], [[2,3,4,5,6]]) - pp.runpp(net) - net_eq = pp.grid_equivalents.get_equivalent(net, "rei", [41], [0]) + net = example_multivoltage() + create_trafo_characteristics(net, "trafo", [1], 'vk_percent', + [[-2, -1, 0, 1, 2]], [[2, 3, 4, 5, 6]]) + runpp(net) + net_eq = get_equivalent(net, "rei", [41], [0]) assert len(net_eq.characteristic) == 1 def test_controller(): - net = pp.networks.case9() - pp.replace_gen_by_sgen(net) - pp.create_load(net, 5, 10, 10) - pp.create_sgen(net, 3, 1, 1) + net = case9() + replace_gen_by_sgen(net) + create_load(net, 5, 10, 10) + create_sgen(net, 3, 1, 1) net.sgen.loc[:, "type"] = "wind" net.load.loc[:, "type"] = "residential" @@ -514,21 +520,21 @@ def test_controller(): element_index=net.sgen.index.tolist(), profile_name=net.sgen.index.tolist(), data_source=DFData(sgen_ts)) - pp.runpp(net) + runpp(net) # getting equivalent - net_eq = pp.grid_equivalents.get_equivalent(net, "rei", [4, 8], [0]) + net_eq = get_equivalent(net, "rei", [4, 8], [0]) assert net_eq.controller.object[0].__dict__["element_index"] == [0, 2] assert net_eq.controller.object[0].__dict__["matching_params"]["element_index"] == [0, 2] for i in net.controller.index: assert set(net_eq.controller.object[i].__dict__["element_index"]) - \ - set(net.controller.object[i].__dict__["element_index"]) == set([]) + set(net.controller.object[i].__dict__["element_index"]) == set([]) assert set(net_eq.controller.object[i].__dict__["profile_name"]) - \ - set(net.controller.object[i].__dict__["profile_name"]) == set([]) + set(net.controller.object[i].__dict__["profile_name"]) == set([]) - net_eq = pp.grid_equivalents.get_equivalent(net, "rei", [4, 8], [0], - retain_original_internal_indices=True) + net_eq = get_equivalent(net, "rei", [4, 8], [0], + retain_original_internal_indices=True) assert net_eq.controller.object[0].__dict__["element_index"] == [0, 2] assert net_eq.controller.object[0].__dict__["matching_params"]["element_index"] == [0, 2] @@ -538,29 +544,29 @@ def test_controller(): ConstControl(net, element='load', variable='p_mw', element_index=[li], data_source=DFData(load_ts), profile_name=[li]) assert len(net.controller) == 4 - net_eq = pp.grid_equivalents.get_equivalent(net, "rei", [4, 8], [0], - retain_original_internal_indices=True) + net_eq = get_equivalent(net, "rei", [4, 8], [0], + retain_original_internal_indices=True) assert net_eq.controller.index.tolist() == [0, 2] def test_motor(): - net = pp.networks.case9() - pp.replace_gen_by_sgen(net) - pp.create_motor(net, 5, 12, 0.9, scaling=0.8, loading_percent=89, efficiency_percent=90) - pp.create_motor(net, 7, 18, 0.9, scaling=0.9, loading_percent=88, efficiency_percent=95, - in_service=False) - pp.create_motor(net, 6, 10, 0.6, scaling=0.4, loading_percent=98, efficiency_percent=88) - pp.create_motor(net, 3, 3, 0.6, scaling=0.4, loading_percent=89, efficiency_percent=99) - pp.create_motor(net, 4, 6, 0.96, scaling=0.4, loading_percent=78, efficiency_percent=90) - pp.runpp(net) + net = case9() + replace_gen_by_sgen(net) + create_motor(net, 5, 12, 0.9, scaling=0.8, loading_percent=89, efficiency_percent=90) + create_motor(net, 7, 18, 0.9, scaling=0.9, loading_percent=88, efficiency_percent=95, + in_service=False) + create_motor(net, 6, 10, 0.6, scaling=0.4, loading_percent=98, efficiency_percent=88) + create_motor(net, 3, 3, 0.6, scaling=0.4, loading_percent=89, efficiency_percent=99) + create_motor(net, 4, 6, 0.96, scaling=0.4, loading_percent=78, efficiency_percent=90) + runpp(net) values1 = net.res_bus.vm_pu.values.copy() for eq in ["rei", "ward", "xward"]: - net_eq = pp.grid_equivalents.get_equivalent(net, eq, [4, 8], [0], - retain_original_internal_indices=True, - show_computing_time=True) + net_eq = get_equivalent(net, eq, [4, 8], [0], + retain_original_internal_indices=True, + show_computing_time=True) - assert max(net_eq.res_bus.vm_pu[[0,3,4,8]].values - net.res_bus.vm_pu[[0,3,4,8]].values) < 1e-8 + assert max(net_eq.res_bus.vm_pu[[0, 3, 4, 8]].values - net.res_bus.vm_pu[[0, 3, 4, 8]].values) < 1e-8 assert net_eq.motor.bus.values.tolist() == [3, 4] replace_motor_by_load(net, net.bus.index.tolist()) @@ -569,47 +575,47 @@ def test_motor(): assert len(net.load) == 8 assert len(net.res_load) == 8 assert net.res_load.loc[4].values.tolist() == [0, 0] - pp.runpp(net) + runpp(net) values2 = net.res_bus.vm_pu.values.copy() assert max(values1 - values2) < 1e-10 def test_sgen_bswitch(): - net = pp.networks.case9() - pp.replace_gen_by_sgen(net) - pp.create_sgen(net, 1, 10) - pp.create_sgen(net, 1, 5, in_service=False) - pp.runpp(net) + net = case9() + replace_gen_by_sgen(net) + create_sgen(net, 1, 10) + create_sgen(net, 1, 5, in_service=False) + runpp(net) net.sgen.name = ["aa", "bb", "cc", "dd"] - net_eq = pp.grid_equivalents.get_equivalent(net, "rei", [4, 8], [0], - retain_original_internal_indices=True) + net_eq = get_equivalent(net, "rei", [4, 8], [0], + retain_original_internal_indices=True) assert net_eq.sgen.name[0] == 'aa//cc//dd-sgen_separate_rei_1' assert net_eq.sgen.p_mw[0] == 173 - net = pp.networks.case9() - pp.replace_gen_by_sgen(net) - pp.create_bus(net, 345) - pp.create_bus(net, 345) - pp.create_sgen(net, 9, 10) - pp.create_sgen(net, 10, 5, in_service=False) - pp.create_switch(net, 1, 9, "b") - pp.create_switch(net, 1, 10, "b") + net = case9() + replace_gen_by_sgen(net) + create_bus(net, 345) + create_bus(net, 345) + create_sgen(net, 9, 10) + create_sgen(net, 10, 5, in_service=False) + create_switch(net, 1, 9, "b") + create_switch(net, 1, 10, "b") net.sgen.name = ["aa", "bb", "cc", "dd"] - pp.runpp(net) - net_eq = pp.grid_equivalents.get_equivalent(net, "rei", [4, 8], [0], - retain_original_internal_indices=True) + runpp(net) + net_eq = get_equivalent(net, "rei", [4, 8], [0], + retain_original_internal_indices=True) assert net_eq.sgen.name[0] == 'aa//cc-sgen_separate_rei_1' assert net_eq.sgen.p_mw[0] == 173 # add some columns for test - net.bus["voltLvl"]=1 + net.bus["voltLvl"] = 1 net.sgen["col_mixed"] = ["1", 2, None, True] net.sgen["col_same_str"] = ["str_test", "str_test", "str_test", "str_test"] net.sgen["col_different_str"] = ["str_1", "str_2", "str_3", "str_4"] net.sgen["bool"] = [False, True, False, False] net.sgen["voltLvl"] = [1, 1, 1, 1] - net_eq = pp.grid_equivalents.get_equivalent(net, "rei", [4, 8], [0]) + net_eq = get_equivalent(net, "rei", [4, 8], [0]) assert net_eq.sgen["col_mixed"][0] == "mixed data type" assert net_eq.sgen["col_same_str"][0] == "str_test" assert net_eq.sgen["col_different_str"][0] == "str_3//str_1" @@ -620,13 +626,13 @@ def test_sgen_bswitch(): def test_ward_admittance(): - net = pp.networks.case9() - pp.runpp(net) + net = case9() + runpp(net) res_bus = net.res_bus.copy() create_passive_external_net_for_ward_admittance(net, [1, 2, 5, 6, 7], - [4,8], True, + [4, 8], True, _runpp_except_voltage_angles) - assert len(net.shunt)==3 + assert len(net.shunt) == 3 assert np.allclose(net.res_bus.vm_pu.values, res_bus.vm_pu.values) diff --git a/pandapower/test/grid_equivalents/test_get_equivalent_networks.py b/pandapower/test/grid_equivalents/test_get_equivalent_networks.py index b0f21cb32..b5887b051 100644 --- a/pandapower/test/grid_equivalents/test_get_equivalent_networks.py +++ b/pandapower/test/grid_equivalents/test_get_equivalent_networks.py @@ -1,10 +1,13 @@ import pytest from copy import deepcopy -import pandapower as pp -import pandapower.networks as pn -import pandapower.grid_equivalents import logging +from pandapower.grid_equivalents.get_equivalent import get_equivalent +from pandapower.run import runpp +from pandapower.create import create_switch + +from pandapower.networks.power_system_test_cases import case9, case30, case39, case118 + def test_networks(): epsilon = 1e-4 @@ -23,9 +26,9 @@ def test_networks(): for eq_type in ["xward", "rei", "ward"]: # case9 for sn_mva in [1.0, 23.0, 89.0]: - net = pn.case9() + net = case9() net.sn_mva = sn_mva - pp.runpp(net) + runpp(net) logging.debug('test with case9:') max_error, related_values = get_max_error( @@ -65,9 +68,9 @@ def test_networks(): # case30 logging.debug('test with case30:') - net = pn.case30() + net = case30() net.sn_mva = sn_mva - pp.runpp(net) + runpp(net) max_error, related_values = get_max_error( net, eq_type, boundary_buses=[8], internal_buses=[0], return_internal=True, @@ -100,9 +103,9 @@ def test_networks(): # case39 logging.debug('test with case39:') - net = pn.case39() + net = case39() net.sn_mva = sn_mva - pp.runpp(net) + runpp(net) max_error, related_values = get_max_error( net, eq_type, boundary_buses=[1, 7], internal_buses=[0], return_internal=False, buses_out_of_service=[4, 8], switch_changes=[['b', 2, 25]]) @@ -115,9 +118,9 @@ def test_networks(): # case118 logging.debug('case118:') - net = pn.case118() + net = case118() net.sn_mva = sn_mva - pp.runpp(net) + runpp(net) va_degree = eq_type != "xward" max_error, related_values = get_max_error( net, eq_type, boundary_buses=[7], internal_buses=[0], return_internal=True, @@ -161,13 +164,13 @@ def get_max_error(net, eq_type, boundary_buses, internal_buses, return_internal, if switch_changes: net = deepcopy(net) for i in range(len(switch_changes)): - pp.create_switch(net, bus=switch_changes[i][1], element=switch_changes[i][2], - et=switch_changes[i][0]) - pp.runpp(net) + create_switch(net, bus=switch_changes[i][1], element=switch_changes[i][2], + et=switch_changes[i][0]) + runpp(net) # --- get net_eq - net_eq = pp.grid_equivalents.get_equivalent(net, eq_type, boundary_buses, internal_buses, - return_internal=return_internal, - calculate_voltage_angles=True) + net_eq = get_equivalent(net, eq_type, boundary_buses, internal_buses, + return_internal=return_internal, + calculate_voltage_angles=True) # --- calulate max. error max_error, related_values = calc_max_error(net, net_eq, return_internal, **kwargs) @@ -206,4 +209,4 @@ def calc_max_error(net_org, net_eq, return_internal, va_degree=True): if __name__ == "__main__": - pytest.main([__file__, "-xs"]) \ No newline at end of file + pytest.main([__file__, "-xs"]) diff --git a/pandapower/test/grid_equivalents/test_grid_equivalents_auxiliary.py b/pandapower/test/grid_equivalents/test_grid_equivalents_auxiliary.py index a7b596a7b..122c9bb2d 100644 --- a/pandapower/test/grid_equivalents/test_grid_equivalents_auxiliary.py +++ b/pandapower/test/grid_equivalents/test_grid_equivalents_auxiliary.py @@ -1,46 +1,49 @@ import pytest import os -import pandapower as pp -import pandapower.grid_equivalents -import pandapower.networks import pandas as pd from pandapower import pp_dir +from pandapower.run import runpp +from pandapower.create import create_bus, create_transformer, create_transformer3w, create_dcline +from pandapower.networks.create_examples import example_simple +from pandapower.networks.power_system_test_cases import case9 +from pandapower.networks.cigre_networks import create_cigre_network_mv from pandapower.timeseries import DFData from pandapower.control import ConstControl from pandapower.grid_equivalents.auxiliary import drop_measurements_and_controllers, \ - _check_network, get_boundary_vp, adaptation_phase_shifter + _check_network, get_boundary_vp, adaptation_phase_shifter, drop_internal_branch_elements +from pandapower.grid_equivalents.get_equivalent import get_equivalent def test_drop_internal_branch_elements(): - net = pp.networks.example_simple() - pp.grid_equivalents.drop_internal_branch_elements(net, net.bus.index) + net = example_simple() + drop_internal_branch_elements(net, net.bus.index) assert not net.line.shape[0] assert not net.trafo.shape[0] - net = pp.networks.example_simple() + net = example_simple() n_trafo = net.trafo.shape[0] - pp.grid_equivalents.drop_internal_branch_elements(net, net.bus.index, branch_elements=["line"]) + drop_internal_branch_elements(net, net.bus.index, branch_elements=["line"]) assert not net.line.shape[0] assert net.trafo.shape[0] == n_trafo - net = pp.networks.example_simple() + net = example_simple() n_trafo = net.trafo.shape[0] - pp.grid_equivalents.drop_internal_branch_elements(net, [2, 3, 4, 5]) + drop_internal_branch_elements(net, [2, 3, 4, 5]) assert set(net.line.index) == {0, 2, 3} assert set(net.trafo.index) == set() - net = pp.networks.example_simple() + net = example_simple() n_trafo = net.trafo.shape[0] - pp.grid_equivalents.drop_internal_branch_elements(net, [4, 5, 6]) + drop_internal_branch_elements(net, [4, 5, 6]) assert set(net.line.index) == {0} assert set(net.trafo.index) == {0} def test_trafo_phase_shifter(): - net = pp.networks.create_cigre_network_mv(with_der="pv_wind") + net = create_cigre_network_mv(with_der="pv_wind") net.trafo.loc[0, 'shift_degree'] = 150 - pp.runpp(net) - net_eq = pp.grid_equivalents.get_equivalent(net, "rei", [4, 8], [0], + runpp(net) + net_eq = get_equivalent(net, "rei", [4, 8], [0], retain_original_internal_indices=True) v, p = get_boundary_vp(net_eq, net_eq.bus_lookups) net.res_bus.vm_pu = net.res_bus.vm_pu.values + 1e-3 @@ -51,14 +54,14 @@ def test_trafo_phase_shifter(): def test_drop_measurements_and_controllers(): # create measurements - net = pp.networks.case9() - pp.runpp(net) - pp.create_bus(net, net.bus.vn_kv.values[0]) - pp.create_bus(net, net.bus.vn_kv.values[0]) - pp.create_bus(net, net.bus.vn_kv.values[0]) + net = case9() + runpp(net) + create_bus(net, net.bus.vn_kv.values[0]) + create_bus(net, net.bus.vn_kv.values[0]) + create_bus(net, net.bus.vn_kv.values[0]) buses = [1, 2, 5, 6, 7, 9, 10, 11] - pp.create_transformer(net, 1, 9, "0.4 MVA 10/0.4 kV") - pp.create_transformer3w (net, 2, 10, 11, "63/25/38 MVA 110/20/10 kV") + create_transformer(net, 1, 9, "0.4 MVA 10/0.4 kV") + create_transformer3w (net, 2, 10, 11, "63/25/38 MVA 110/20/10 kV") net.measurement.loc[0] = ["mb", "v", "bus", 0, 1.0, 0.01, None] net.measurement.loc[1] = ["mb", "v", "bus", 5, 1.0, 0.01, None] net.measurement.loc[2] = ["mb", "i", "line", 0, 0.9, 0.01, "to"] @@ -101,18 +104,18 @@ def test_drop_measurements_and_controllers(): def test_check_network(): - net = pp.networks.case9() + net = case9() net.bus.loc[5, 'in_service'] = False - pp.runpp(net) + runpp(net) _check_network(net) net.bus.loc[5, 'in_service'] = True - pp.runpp(net) - pp.create_bus(net, net.bus.vn_kv.values[0]) - pp.create_bus(net, net.bus.vn_kv.values[0]) - pp.create_dcline(net, from_bus=4, to_bus=9, p_mw=1e4, loss_percent=1.2, loss_mw=25, \ + runpp(net) + create_bus(net, net.bus.vn_kv.values[0]) + create_bus(net, net.bus.vn_kv.values[0]) + create_dcline(net, from_bus=4, to_bus=9, p_mw=1e4, loss_percent=1.2, loss_mw=25, \ vm_from_pu=1.01, vm_to_pu=1.02) - pp.create_dcline(net, from_bus=8, to_bus=10, p_mw=1e4, loss_percent=1.2, loss_mw=25, \ + create_dcline(net, from_bus=8, to_bus=10, p_mw=1e4, loss_percent=1.2, loss_mw=25, \ vm_from_pu=1.01, vm_to_pu=1.02) _check_network(net) assert len(net.gen) == 6 diff --git a/pandapower/test/grid_equivalents/test_grid_equivalents_toolbox.py b/pandapower/test/grid_equivalents/test_grid_equivalents_toolbox.py index 005f68439..b3c5e6315 100644 --- a/pandapower/test/grid_equivalents/test_grid_equivalents_toolbox.py +++ b/pandapower/test/grid_equivalents/test_grid_equivalents_toolbox.py @@ -1,13 +1,18 @@ -import pytest import numpy as np -import pandapower as pp -import pandapower.networks as pn -import pandapower.grid_equivalents as geq +import pytest + +from pandapower.create import create_bus, create_line_from_parameters, create_transformer3w_from_parameters, \ + create_impedance, create_switch, create_transformer_from_parameters +from pandapower.grid_equivalents.toolbox import set_bus_zone_by_boundary_branches, \ + get_boundaries_by_bus_zone_with_boundary_branches, append_set_to_dict +from pandapower.networks.power_system_test_cases import case9 +from pandapower.run import runpp +from pandapower.toolbox.grid_modification import replace_ext_grid_by_gen, merge_nets def boundary_testnet(which): if which == "case9_27": - net = pn.case9() + net = case9() expected_bbr = {"line": {2, 7}} expected_bb = { "all": {4, 5, 7, 8}, @@ -20,7 +25,7 @@ def boundary_testnet(which): "external": {4, 8}, 0: {4, 8}}} elif which == "case9_abc": - net = pn.case9() + net = case9() net.bus["zone"] = ["a", "b", "c", "a", "a", "c", "c", "b", "b"] expected_bbr = {"all": {"line": {2, 5, 8}}, "a": {"line": {2, 8}}, @@ -30,29 +35,29 @@ def boundary_testnet(which): "a": {"internal": {3, 4}, "external": {5, 8}}} elif which == "case9_ab_merged": - net1 = pn.case9() + net1 = case9() net1.bus["zone"] = "a" - net2 = pn.case9() + net2 = case9() net2.bus["zone"] = "b" net2.ext_grid["p_disp_mw"] = 71.9547 - pp.replace_ext_grid_by_gen(net2) - net = pp.merge_nets(net1, net2, merge_results=False, validate=False, - net2_reindex_log_level=None) - new_bus = pp.create_bus(net, 345, zone="b") + replace_ext_grid_by_gen(net2) + net = merge_nets(net1, net2, merge_results=False, validate=False, + net2_reindex_log_level=None) + new_bus = create_bus(net, 345, zone="b") # expected_bbr expected_bbr = dict() - expected_bbr["line"] = {pp.create_line_from_parameters( + expected_bbr["line"] = {create_line_from_parameters( net, net.bus.index[net.bus.name == 9][0], net.bus.index[net.bus.name == 9][1], 1, 0, 65, 0, 0.41)} - expected_bbr["impedance"] = {pp.create_impedance(net, net.bus.index[net.bus.name == 5][0], - net.bus.index[net.bus.name == 5][1], 0, 0.06, 250)} - expected_bbr["switch"] = {pp.create_switch(net, net.bus.index[net.bus.name == 7][0], - net.bus.index[net.bus.name == 7][1], "b")} - expected_bbr["trafo"] = {pp.create_transformer_from_parameters( + expected_bbr["impedance"] = {create_impedance(net, net.bus.index[net.bus.name == 5][0], + net.bus.index[net.bus.name == 5][1], 0, 0.06, 250)} + expected_bbr["switch"] = {create_switch(net, net.bus.index[net.bus.name == 7][0], + net.bus.index[net.bus.name == 7][1], "b")} + expected_bbr["trafo"] = {create_transformer_from_parameters( net, net.bus.index[net.bus.name == 8][0], net.bus.index[net.bus.name == 8][1], 250, 345, 345, 0, 10, 50, 0)} - expected_bbr["trafo3w"] = {pp.create_transformer3w_from_parameters( + expected_bbr["trafo3w"] = {create_transformer3w_from_parameters( net, net.bus.index[net.bus.name == 3][0], new_bus, net.bus.index[net.bus.name == 3][1], 345, 345, 345, 250, 250, 250, 10, 10, 10, 0, 0, 0, 50, 0)} @@ -65,31 +70,31 @@ def boundary_testnet(which): expected_bb["b"]["internal"] = expected_bb["a"]["external"] - {18} expected_bb["b"]["external"] = expected_bb["a"]["internal"] | {18} - pp.runpp(net) + runpp(net) return net, expected_bb, expected_bbr def test_set_bus_zone_by_boundary_branches_and_get_boundaries_by_bus_zone_with_boundary_branches1(): net, expected_bb, expected_bbr = boundary_testnet("case9_27") - geq.set_bus_zone_by_boundary_branches(net, expected_bbr) + set_bus_zone_by_boundary_branches(net, expected_bbr) assert all(net.bus.zone.values == np.array([0, 1, 1, 0, 0, 1, 1, 1, 0])) boundary_buses, boundary_branches = \ - geq.get_boundaries_by_bus_zone_with_boundary_branches(net) + get_boundaries_by_bus_zone_with_boundary_branches(net) assert boundary_buses == expected_bb assert boundary_branches["all"] == expected_bbr # --- test against set_bus_zone_by_boundary_branches() bb_in = {"line": {2, 4, 7}} - geq.set_bus_zone_by_boundary_branches(net, bb_in) + set_bus_zone_by_boundary_branches(net, bb_in) assert all(net.bus.zone.values == np.array([0, 1, 2, 0, 0, 2, 1, 1, 0])) def test_set_bus_zone_by_boundary_branches_and_get_boundaries_by_bus_zone_with_boundary_branches2(): net, expected_bb, expected_bbr = boundary_testnet("case9_abc") boundary_buses, boundary_branches = \ - geq.get_boundaries_by_bus_zone_with_boundary_branches(net) + get_boundaries_by_bus_zone_with_boundary_branches(net) assert len(boundary_buses.keys()) == 4 for key in ["a", "b", "c"]: @@ -102,7 +107,7 @@ def test_set_bus_zone_by_boundary_branches_and_get_boundaries_by_bus_zone_with_b def test_set_bus_zone_by_boundary_branches_and_get_boundaries_by_bus_zone_with_boundary_branches3(): net, expected_bb, expected_bbr = boundary_testnet("case9_ab_merged") boundary_buses, boundary_branches = \ - geq.get_boundaries_by_bus_zone_with_boundary_branches(net) + get_boundaries_by_bus_zone_with_boundary_branches(net) # --- check form of boundary_buses assert sorted(boundary_buses.keys()) == ["a", "all", "b"] @@ -112,10 +117,10 @@ def test_set_bus_zone_by_boundary_branches_and_get_boundaries_by_bus_zone_with_b # --- check boundary_buses content trafo3w_buses = set(net.trafo3w[["hv_bus", "mv_bus", "lv_bus"]].values.flatten()) in_ext = ["internal", "external"] - for in_ext1, in_ext2 in zip(in_ext,in_ext[::-1]): + for in_ext1, in_ext2 in zip(in_ext, in_ext[::-1]): assert boundary_buses["a"][in_ext1] == expected_bb["a"][in_ext1] assert boundary_buses["b"][in_ext1] - trafo3w_buses == \ - boundary_buses["a"][in_ext2] - trafo3w_buses + boundary_buses["a"][in_ext2] - trafo3w_buses # --- check boundary_branches content assert boundary_branches["a"] == expected_bbr @@ -142,11 +147,11 @@ def test_append_set_to_dict(): val = {1, 2, 3} - geq.append_set_to_dict(dict1, val, keys) - geq.append_set_to_dict(dict2, val, keys) - geq.append_set_to_dict(dict3, val, keys) - geq.append_set_to_dict(dict4, val, keys) - geq.append_set_to_dict(dict5, val, keys) + append_set_to_dict(dict1, val, keys) + append_set_to_dict(dict2, val, keys) + append_set_to_dict(dict3, val, keys) + append_set_to_dict(dict4, val, keys) + append_set_to_dict(dict5, val, keys) assert dict1 == {2: {3: {5: {1, 2, 3}}}} assert dict2 == {2: {3: {5: {1, 2, 3}}}, 7: "hkj"} @@ -156,4 +161,4 @@ def test_append_set_to_dict(): if __name__ == "__main__": - pytest.main([__file__, "-xs"]) \ No newline at end of file + pytest.main([__file__, "-xs"]) diff --git a/pandapower/test/helper_functions.py b/pandapower/test/helper_functions.py index 02945ca09..4ad5a5aed 100644 --- a/pandapower/test/helper_functions.py +++ b/pandapower/test/helper_functions.py @@ -7,15 +7,19 @@ import os from copy import deepcopy -import pandapower as pp -import pandapower.toolbox +from pandapower import pp_dir +from pandapower.auxiliary import get_free_id +from pandapower.create import create_bus, create_empty_network, create_ext_grid, create_transformer_from_parameters, \ + create_line_from_parameters, create_load, create_gen, create_sgen +from pandapower.file_io import from_pickle +from pandapower.toolbox import nets_equal def assert_net_equal(net1, net2, **kwargs): """ Raises AssertionError if grids are not equal. """ - assert pandapower.toolbox.nets_equal(net1, net2, **kwargs) + assert nets_equal(net1, net2, **kwargs) def assert_res_equal(net1, net2, **kwargs): @@ -27,42 +31,42 @@ def assert_res_equal(net1, net2, **kwargs): raise ValueError("'check_only_results' cannot be False in assert_res_equal().") kwargs = deepcopy(kwargs) del kwargs["check_only_results"] - assert pandapower.toolbox.nets_equal(net1, net2, check_only_results=True, **kwargs) + assert nets_equal(net1, net2, check_only_results=True, **kwargs) def create_test_network(): """ Creates a simple pandapower test network """ - net = pp.create_empty_network(name='test_network') - b1 = pp.create_bus(net, name="bus1", vn_kv=10.) - pp.create_ext_grid(net, b1) - b2 = pp.create_bus(net, name="bus2", geodata=(1., 2.), vn_kv=.4) - b3 = pp.create_bus(net, name="bus3", geodata=(1., 3.), vn_kv=.4, index=7) - b4 = pp.create_bus(net, name="bus4", vn_kv=10.) - pp.create_transformer_from_parameters(net, b4, b2, vk_percent=3.75, - tap_max=2, vn_lv_kv=0.4, - shift_degree=150, tap_neutral=0, - vn_hv_kv=10.0, vkr_percent=2.8125, - tap_pos=0, tap_side="hv", tap_min=-2, - tap_step_percent=2.5, i0_percent=0.68751, - sn_mva=0.016, pfe_kw=0.11, name=None, - in_service=True, index=None) + net = create_empty_network(name='test_network') + b1 = create_bus(net, name="bus1", vn_kv=10.) + create_ext_grid(net, b1) + b2 = create_bus(net, name="bus2", geodata=(1., 2.), vn_kv=.4) + b3 = create_bus(net, name="bus3", geodata=(1., 3.), vn_kv=.4, index=7) + b4 = create_bus(net, name="bus4", vn_kv=10.) + create_transformer_from_parameters(net, b4, b2, vk_percent=3.75, + tap_max=2, vn_lv_kv=0.4, + shift_degree=150, tap_neutral=0, + vn_hv_kv=10.0, vkr_percent=2.8125, + tap_pos=0, tap_side="hv", tap_min=-2, + tap_step_percent=2.5, i0_percent=0.68751, + sn_mva=0.016, pfe_kw=0.11, name=None, + in_service=True, index=None) # 0.016 MVA 10/0.4 kV ET 16/23 SGB - pp.create_line_from_parameters(net, b2, b3, 1, name="line1", r_ohm_per_km=0.2067, - ices=0.389985, c_nf_per_km=720.0, max_i_ka=0.328, - x_ohm_per_km=0.1897522, geodata=[[1., 2.], [3., 4.]]) + create_line_from_parameters(net, b2, b3, 1, name="line1", r_ohm_per_km=0.2067, + ices=0.389985, c_nf_per_km=720.0, max_i_ka=0.328, + x_ohm_per_km=0.1897522, geodata=[[1., 2.], [3., 4.]]) # NAYY 1x150RM 0.6/1kV ir - pp.create_line_from_parameters(net, b1, b4, 1, name="line2", r_ohm_per_km=0.876, - c_nf_per_km=260.0, max_i_ka=0.123, x_ohm_per_km=0.1159876) + create_line_from_parameters(net, b1, b4, 1, name="line2", r_ohm_per_km=0.876, + c_nf_per_km=260.0, max_i_ka=0.123, x_ohm_per_km=0.1159876) # NAYSEY 3x35rm/16 6/10kV - pp.create_load(net, b2, p_mw=0.010, q_mvar=0, name="load1") - pp.create_load(net, b3, p_mw=0.040, q_mvar=0.002, name="load2") - pp.create_gen(net, b4, p_mw=0.200, vm_pu=1.0) - pp.create_sgen(net, b3, p_mw=0.050, sn_mva=0.1) + create_load(net, b2, p_mw=0.010, q_mvar=0, name="load1") + create_load(net, b3, p_mw=0.040, q_mvar=0.002, name="load2") + create_gen(net, b4, p_mw=0.200, vm_pu=1.0) + create_sgen(net, b3, p_mw=0.050, sn_mva=0.1) return net @@ -70,7 +74,7 @@ def create_test_network(): def create_test_network2(): """Creates a simple pandapower test network """ - net = pp.from_pickle(os.path.join(pp.pp_dir, "test", "loadflow", "testgrid.p")) + net = from_pickle(os.path.join(pp_dir, "test", "loadflow", "testgrid.p")) # net = pp.file_io.from_pickle("testgrid.p") return net @@ -79,15 +83,16 @@ def create_test_network2(): def add_grid_connection(net, vn_kv=20., zone=None): """Creates a new grid connection for create_result_test_network() """ - b1 = pp.create_bus(net, vn_kv=vn_kv, zone=zone) - pp.create_ext_grid(net, b1, vm_pu=1.01) - b2 = pp.get_free_id(net.bus) + 2 # shake up the indices so that non-consecutive indices are tested - b2 = pp.create_bus(net, vn_kv=vn_kv, zone=zone, index=b2) + b1 = create_bus(net, vn_kv=vn_kv, zone=zone) + create_ext_grid(net, b1, vm_pu=1.01) + b2 = get_free_id(net.bus) + 2 # shake up the indices so that non-consecutive indices are tested + b2 = create_bus(net, vn_kv=vn_kv, zone=zone, index=b2) l1 = create_test_line(net, b1, b2) return b1, b2, l1 def create_test_line(net, b1, b2, in_service=True): - return pp.create_line_from_parameters(net, b1, b2, 12.2, r_ohm_per_km=0.08, x_ohm_per_km=0.12, - c_nf_per_km=300, max_i_ka=.2, df=.8, - in_service=in_service, index=pp.get_free_id(net.line) + 1) + return create_line_from_parameters( + net, b1, b2, 12.2, r_ohm_per_km=0.08, x_ohm_per_km=0.12, c_nf_per_km=300, max_i_ka=.2, df=.8, + in_service=in_service, index=get_free_id(net.line) + 1 + ) diff --git a/pandapower/test/loadflow/result_test_network_generator.py b/pandapower/test/loadflow/result_test_network_generator.py index 21e349ff5..2b57c9e9f 100644 --- a/pandapower/test/loadflow/result_test_network_generator.py +++ b/pandapower/test/loadflow/result_test_network_generator.py @@ -3,10 +3,12 @@ # Copyright (c) 2016-2024 by University of Kassel and Fraunhofer Institute for Energy Economics # and Energy System Technology (IEE), Kassel. All rights reserved. - -import pandapower as pp +from pandapower.auxiliary import get_free_id +from pandapower.create import create_empty_network, create_load, create_bus, create_switch, create_ext_grid, \ + create_gen, create_sgen, create_transformer_from_parameters, create_ward, create_xward, \ + create_line_from_parameters, create_transformer3w_from_parameters, create_impedance, create_shunt, \ + create_shunt_as_capacitor from pandapower.test.helper_functions import add_grid_connection, create_test_line -from pandapower.toolbox import nets_equal def result_test_network_generator2(net, sn_mva=1, skip_test_impedance=False): @@ -15,7 +17,7 @@ def result_test_network_generator2(net, sn_mva=1, skip_test_impedance=False): different stages of adding elements """ yield add_test_trafo(net) -# yield add_test_line(net) + # yield add_test_line(net) yield add_test_load_sgen(net) yield add_test_load_sgen_split(net) yield add_test_ext_grid(net) @@ -43,7 +45,7 @@ def result_test_network_generator(sn_mva=1, skip_test_impedance=False): It is structured like this so it can be tested for consistency at different stages of adding elements """ - net = pp.create_empty_network(sn_mva=sn_mva) + net = create_empty_network(sn_mva=sn_mva) yield add_test_line(net) yield add_test_load_sgen(net) yield add_test_load_sgen_split(net) @@ -74,7 +76,7 @@ def result_test_network_generator_dcpp(sn_mva=1): """ # ToDo: Uncommented tests fail in rundcpp -> Check why and correct it - net = pp.create_empty_network(sn_mva=sn_mva) + net = create_empty_network(sn_mva=sn_mva) yield add_test_line(net) yield add_test_load_sgen(net) yield add_test_load_sgen_split(net) @@ -101,10 +103,10 @@ def add_test_line(net): b1, b2, l1 = add_grid_connection(net, zone="test_line") net.line.at[l1, "parallel"] = 2 net.line.at[l1, "g_us_per_km"] = 1 - pp.create_load(net, b2, p_mw=1.2, q_mvar=1.1) + create_load(net, b2, p_mw=1.2, q_mvar=1.1) l2 = create_test_line(net, b1, b2) net.line.at[l2, "g_us_per_km"] = 1 - pp.create_switch(net, b2, l2, et="l", closed=False) + create_switch(net, b2, l2, et="l", closed=False) create_test_line(net, b1, b2, in_service=False) net.last_added_case = "test_line" return net @@ -112,28 +114,28 @@ def add_test_line(net): def add_test_ext_grid(net): b1, b2, ln = add_grid_connection(net, zone="test_ext_grid") - b3 = pp.create_bus(net, vn_kv=20., zone="test_ext_grid") + b3 = create_bus(net, vn_kv=20., zone="test_ext_grid") create_test_line(net, b2, b3) - pp.create_ext_grid(net, b3, vm_pu=1.02, va_degree=3.) + create_ext_grid(net, b3, vm_pu=1.02, va_degree=3.) return net def add_test_ext_grid_gen_switch(net): zone = "test_ext_grid_gen_switch" vn_kv = 20. - b1 = pp.create_bus(net, vn_kv=vn_kv, zone=zone) - b2 = pp.create_bus(net, vn_kv=vn_kv, zone=zone) - b3 = pp.create_bus(net, vn_kv=vn_kv, zone=zone) - b4 = pp.create_bus(net, vn_kv=vn_kv, zone=zone) - b5 = pp.create_bus(net, vn_kv=vn_kv, zone=zone) + b1 = create_bus(net, vn_kv=vn_kv, zone=zone) + b2 = create_bus(net, vn_kv=vn_kv, zone=zone) + b3 = create_bus(net, vn_kv=vn_kv, zone=zone) + b4 = create_bus(net, vn_kv=vn_kv, zone=zone) + b5 = create_bus(net, vn_kv=vn_kv, zone=zone) - pp.create_switch(net, bus=b1, element=b2, et="b") + create_switch(net, bus=b1, element=b2, et="b") create_test_line(net, b2, b3) create_test_line(net, b3, b4) - pp.create_switch(net, bus=b4, element=b5, et="b") + create_switch(net, bus=b4, element=b5, et="b") - pp.create_ext_grid(net, bus=b1, vm_pu=1.01) - pp.create_gen(net, bus=b5, vm_pu=1.015, p_mw=0.3) + create_ext_grid(net, bus=b1, vm_pu=1.01) + create_gen(net, bus=b5, vm_pu=1.015, p_mw=0.3) return net @@ -144,13 +146,13 @@ def add_test_load_sgen(net): ps = 0.50 qs = -0.1 # load and sgen at one bus - pp.create_load(net, b2, p_mw=pl, q_mvar=ql) - pp.create_sgen(net, b2, p_mw=ps, q_mvar=qs) + create_load(net, b2, p_mw=pl, q_mvar=ql) + create_sgen(net, b2, p_mw=ps, q_mvar=qs) # adding out of serivce loads and sgens should not change the result - pp.create_load(net, b2, p_mw=pl, q_mvar=ql, in_service=False, - index=pp.get_free_id(net.load) + 1) - pp.create_sgen(net, b2, p_mw=ps, q_mvar=qs, in_service=False, - index=pp.get_free_id(net.sgen) + 1) + create_load(net, b2, p_mw=pl, q_mvar=ql, in_service=False, + index=get_free_id(net.load) + 1) + create_sgen(net, b2, p_mw=ps, q_mvar=qs, in_service=False, + index=get_free_id(net.sgen) + 1) net.last_added_case = "test_load_sgen" return net @@ -163,38 +165,38 @@ def add_test_load_sgen_split(net): ps = 0.5 qs = -0.1 for _ in list(range(nr)): - pp.create_load(net, b2, p_mw=pl, q_mvar=ql, scaling=1. / nr) - pp.create_sgen(net, b2, p_mw=ps, q_mvar=qs, scaling=1. / nr) + create_load(net, b2, p_mw=pl, q_mvar=ql, scaling=1. / nr) + create_sgen(net, b2, p_mw=ps, q_mvar=qs, scaling=1. / nr) net.last_added_case = "test_load_sgen_split" return net def add_test_trafo(net): b1, b2, ln = add_grid_connection(net, zone="test_trafo") - b3 = pp.create_bus(net, vn_kv=0.4, zone="test_trafo") - pp.create_transformer_from_parameters(net, b2, b3, vk_percent=5., vkr_percent=2., - i0_percent=.4, pfe_kw=2., sn_mva=0.4, vn_hv_kv=22, - vn_lv_kv=0.42, tap_max=10, tap_neutral=5, tap_min=0, - tap_step_percent=1.25, tap_pos=3, shift_degree=150, - tap_side="hv", parallel=2) - t2 = pp.create_transformer_from_parameters(net, b2, b3, vk_percent=5., vkr_percent=2., - i0_percent=.4, pfe_kw=2, sn_mva=0.4, vn_hv_kv=22, - vn_lv_kv=0.42, tap_max=10, tap_neutral=5, tap_min=0, - tap_step_percent=1.25, tap_pos=3, tap_side="hv", - shift_degree=150, index=pp.get_free_id(net.trafo) + 1) - pp.create_switch(net, b3, t2, et="t", closed=False) - pp.create_transformer_from_parameters(net, b2, b3, vk_percent=5., vkr_percent=2., - i0_percent=1., pfe_kw=20, sn_mva=0.4, vn_hv_kv=20, - vn_lv_kv=0.4, in_service=False) - pp.create_load(net, b3, p_mw=0.2, q_mvar=0.05) + b3 = create_bus(net, vn_kv=0.4, zone="test_trafo") + create_transformer_from_parameters(net, b2, b3, vk_percent=5., vkr_percent=2., + i0_percent=.4, pfe_kw=2., sn_mva=0.4, vn_hv_kv=22, + vn_lv_kv=0.42, tap_max=10, tap_neutral=5, tap_min=0, + tap_step_percent=1.25, tap_pos=3, shift_degree=150, + tap_side="hv", parallel=2) + t2 = create_transformer_from_parameters(net, b2, b3, vk_percent=5., vkr_percent=2., + i0_percent=.4, pfe_kw=2, sn_mva=0.4, vn_hv_kv=22, + vn_lv_kv=0.42, tap_max=10, tap_neutral=5, tap_min=0, + tap_step_percent=1.25, tap_pos=3, tap_side="hv", + shift_degree=150, index=get_free_id(net.trafo) + 1) + create_switch(net, b3, t2, et="t", closed=False) + create_transformer_from_parameters(net, b2, b3, vk_percent=5., vkr_percent=2., + i0_percent=1., pfe_kw=20, sn_mva=0.4, vn_hv_kv=20, + vn_lv_kv=0.4, in_service=False) + create_load(net, b3, p_mw=0.2, q_mvar=0.05) net.last_added_case = "test_trafo" return net def add_test_single_load_single_eg(net): - b1 = pp.create_bus(net, vn_kv=20., zone="test_single_load_single_eg") - pp.create_ext_grid(net, b1) - pp.create_load(net, b1, p_mw=0.1, q_mvar=0.1) + b1 = create_bus(net, vn_kv=20., zone="test_single_load_single_eg") + create_ext_grid(net, b1) + create_load(net, b1, p_mw=0.1, q_mvar=0.1) net.last_added_case = "test_single_load_single_eg" return net @@ -207,10 +209,10 @@ def add_test_ward(net): ps = 0.5 qs = 0.2 # one shunt at a bus - pp.create_ward(net, b2, pz_mw=pz, qz_mvar=qz, ps_mw=ps, qs_mvar=qs) + create_ward(net, b2, pz_mw=pz, qz_mvar=qz, ps_mw=ps, qs_mvar=qs) # add out of service ward shuold not change the result - pp.create_ward(net, b2, pz_mw=pz, qz_mvar=qz, ps_mw=ps, qs_mvar=qs, in_service=False, - index=pp.get_free_id(net.ward) + 1) + create_ward(net, b2, pz_mw=pz, qz_mvar=qz, ps_mw=ps, qs_mvar=qs, in_service=False, + index=get_free_id(net.ward) + 1) net.last_added_case = "test_ward" return net @@ -222,8 +224,8 @@ def add_test_ward_split(net): ps = 0.5 qs = 0.2 b1, b2, ln = add_grid_connection(net, zone="test_ward_split") - pp.create_ward(net, b2, pz_mw=pz / 2, qz_mvar=qz / 2, ps_mw=ps / 2, qs_mvar=qs / 2) - pp.create_ward(net, b2, pz_mw=pz / 2, qz_mvar=qz / 2, ps_mw=ps / 2, qs_mvar=qs / 2) + create_ward(net, b2, pz_mw=pz / 2, qz_mvar=qz / 2, ps_mw=ps / 2, qs_mvar=qs / 2) + create_ward(net, b2, pz_mw=pz / 2, qz_mvar=qz / 2, ps_mw=ps / 2, qs_mvar=qs / 2) net.last_added_case = "test_ward_split" return net @@ -239,12 +241,12 @@ def add_test_xward(net): r_ohm = 50 x_ohm = 70 # one xward at a bus - pp.create_xward(net, b2, pz_mw=pz, qz_mvar=qz, ps_mw=ps, qs_mvar=qs, - vm_pu=vm_pu, x_ohm=x_ohm, r_ohm=r_ohm) + create_xward(net, b2, pz_mw=pz, qz_mvar=qz, ps_mw=ps, qs_mvar=qs, + vm_pu=vm_pu, x_ohm=x_ohm, r_ohm=r_ohm) # add out of service xward should not change the result - pp.create_xward(net, b2, pz_mw=pz, qz_mvar=qz, ps_mw=ps, qs_mvar=qs, vm_pu=vm_pu, - x_ohm=x_ohm, r_ohm=r_ohm, in_service=False, - index=pp.get_free_id(net.xward) + 1) + create_xward(net, b2, pz_mw=pz, qz_mvar=qz, ps_mw=ps, qs_mvar=qs, vm_pu=vm_pu, + x_ohm=x_ohm, r_ohm=r_ohm, in_service=False, + index=get_free_id(net.xward) + 1) net.last_added_case = "test_xward" return net @@ -260,14 +262,14 @@ def add_test_xward_combination(net): r_ohm = 50 x_ohm = 70 # one xward at a bus - pp.create_xward(net, b2, pz_mw=pz, qz_mvar=qz, ps_mw=ps, qs_mvar=qs, - vm_pu=vm_pu, x_ohm=x_ohm, r_ohm=r_ohm) + create_xward(net, b2, pz_mw=pz, qz_mvar=qz, ps_mw=ps, qs_mvar=qs, + vm_pu=vm_pu, x_ohm=x_ohm, r_ohm=r_ohm) # add out of service xward should not change the result - pp.create_xward(net, b2, pz_mw=pz, qz_mvar=qz, ps_mw=ps, qs_mvar=qs, vm_pu=vm_pu, - x_ohm=x_ohm, r_ohm=r_ohm, in_service=False) + create_xward(net, b2, pz_mw=pz, qz_mvar=qz, ps_mw=ps, qs_mvar=qs, vm_pu=vm_pu, + x_ohm=x_ohm, r_ohm=r_ohm, in_service=False) # add second xward at the bus - pp.create_xward(net, b2, pz_mw=pz, qz_mvar=qz, ps_mw=ps, qs_mvar=qs, - vm_pu=vm_pu, x_ohm=x_ohm, r_ohm=r_ohm) + create_xward(net, b2, pz_mw=pz, qz_mvar=qz, ps_mw=ps, qs_mvar=qs, + vm_pu=vm_pu, x_ohm=x_ohm, r_ohm=r_ohm) net.last_added_case = "test_xward_combination" return net @@ -279,14 +281,14 @@ def add_test_gen(net): ps = 0.500 vm_set_pu = 1.0 - b3 = pp.create_bus(net, zone="test_gen", vn_kv=.4) - pp.create_line_from_parameters(net, b2, b3, 12.2, r_ohm_per_km=0.08, x_ohm_per_km=0.12, - c_nf_per_km=300, max_i_ka=.2, df=.8) + b3 = create_bus(net, zone="test_gen", vn_kv=.4) + create_line_from_parameters(net, b2, b3, 12.2, r_ohm_per_km=0.08, x_ohm_per_km=0.12, + c_nf_per_km=300, max_i_ka=.2, df=.8) - pp.create_load(net, b3, p_mw=pl, q_mvar=ql) - pp.create_gen(net, b3, p_mw=ps, vm_pu=vm_set_pu) + create_load(net, b3, p_mw=pl, q_mvar=ql) + create_gen(net, b3, p_mw=ps, vm_pu=vm_set_pu) # adding out of serivce gens should not change the result - pp.create_gen(net, b2, p_mw=ps, vm_pu=vm_set_pu, in_service=False, index=pp.get_free_id(net.gen) + 1) + create_gen(net, b2, p_mw=ps, vm_pu=vm_set_pu, in_service=False, index=get_free_id(net.gen) + 1) net.last_added_case = "test_gen" return net @@ -300,12 +302,12 @@ def add_test_enforce_qlims(net): qmin = -0.200 vm_set_pu = 1.0 - b3 = pp.create_bus(net, zone="test_enforce_qlims", vn_kv=.4) - pp.create_line_from_parameters(net, b2, b3, 12.2, r_ohm_per_km=0.08, x_ohm_per_km=0.12, - c_nf_per_km=300, max_i_ka=.2, df=.8) + b3 = create_bus(net, zone="test_enforce_qlims", vn_kv=.4) + create_line_from_parameters(net, b2, b3, 12.2, r_ohm_per_km=0.08, x_ohm_per_km=0.12, + c_nf_per_km=300, max_i_ka=.2, df=.8) - pp.create_load(net, b3, p_mw=pl, q_mvar=ql) - pp.create_gen(net, b3, p_mw=ps, vm_pu=vm_set_pu, min_q_mvar=qmin) + create_load(net, b3, p_mw=pl, q_mvar=ql) + create_gen(net, b3, p_mw=ps, vm_pu=vm_set_pu, min_q_mvar=qmin) net.last_added_case = "test_enforce_qlims" return net @@ -313,35 +315,35 @@ def add_test_enforce_qlims(net): def add_test_trafo3w(net): b1, b2, ln = add_grid_connection(net, zone="test_trafo3w") - b3 = pp.create_bus(net, vn_kv=0.6, zone="test_trafo3w") - pp.create_load(net, b3, p_mw=0.2, q_mvar=0) - b4 = pp.create_bus(net, vn_kv=0.4, zone="test_trafo3w") - pp.create_load(net, b4, p_mw=0.1, q_mvar=0) - - pp.create_transformer3w_from_parameters(net, hv_bus=b2, mv_bus=b3, lv_bus=b4, vn_hv_kv=22, - vn_mv_kv=.64, vn_lv_kv=.42, sn_hv_mva=1, - sn_mv_mva=0.7, sn_lv_mva=0.3, vk_hv_percent=1., - vkr_hv_percent=.03, vk_mv_percent=.5, - vkr_mv_percent=.02, vk_lv_percent=.25, - vkr_lv_percent=.01, pfe_kw=0.5, i0_percent=0.1, - name="test", index=pp.get_free_id(net.trafo3w) + 1, - tap_side="hv", tap_pos=2, tap_step_percent=1.25, - tap_min=-5, tap_neutral=0, tap_max=5) + b3 = create_bus(net, vn_kv=0.6, zone="test_trafo3w") + create_load(net, b3, p_mw=0.2, q_mvar=0) + b4 = create_bus(net, vn_kv=0.4, zone="test_trafo3w") + create_load(net, b4, p_mw=0.1, q_mvar=0) + + create_transformer3w_from_parameters(net, hv_bus=b2, mv_bus=b3, lv_bus=b4, vn_hv_kv=22, + vn_mv_kv=.64, vn_lv_kv=.42, sn_hv_mva=1, + sn_mv_mva=0.7, sn_lv_mva=0.3, vk_hv_percent=1., + vkr_hv_percent=.03, vk_mv_percent=.5, + vkr_mv_percent=.02, vk_lv_percent=.25, + vkr_lv_percent=.01, pfe_kw=0.5, i0_percent=0.1, + name="test", index=get_free_id(net.trafo3w) + 1, + tap_side="hv", tap_pos=2, tap_step_percent=1.25, + tap_min=-5, tap_neutral=0, tap_max=5) # adding out of service 3w trafo should not change results - pp.create_transformer3w_from_parameters(net, hv_bus=b2, mv_bus=b3, lv_bus=b4, vn_hv_kv=20, - vn_mv_kv=.6, vn_lv_kv=.4, sn_hv_mva=1, sn_mv_mva=0.7, - sn_lv_mva=0.3, vk_hv_percent=2., vkr_hv_percent=.3, - vk_mv_percent=1., vkr_mv_percent=.2, - vk_lv_percent=.5, vkr_lv_percent=.1, pfe_kw=50, - i0_percent=1., name="test", in_service=False, - index=pp.get_free_id(net.trafo3w) + 1) + create_transformer3w_from_parameters(net, hv_bus=b2, mv_bus=b3, lv_bus=b4, vn_hv_kv=20, + vn_mv_kv=.6, vn_lv_kv=.4, sn_hv_mva=1, sn_mv_mva=0.7, + sn_lv_mva=0.3, vk_hv_percent=2., vkr_hv_percent=.3, + vk_mv_percent=1., vkr_mv_percent=.2, + vk_lv_percent=.5, vkr_lv_percent=.1, pfe_kw=50, + i0_percent=1., name="test", in_service=False, + index=get_free_id(net.trafo3w) + 1) net.last_added_case = "test_trafo3w" return net def add_test_impedance(net): b1, b2, ln = add_grid_connection(net, zone="test_impedance") - b3 = pp.create_bus(net, vn_kv=220., zone="test_impedance") + b3 = create_bus(net, vn_kv=220., zone="test_impedance") rij = 0.02 xij = 0.01 rji = 0.03 @@ -351,19 +353,19 @@ def add_test_impedance(net): pl = 1 ql = 0.5 - pp.create_impedance(net, b2, b3, rft_pu=rij, xft_pu=xij, rtf_pu=rji, xtf_pu=xji, - sn_mva=s, index=pp.get_free_id(net.impedance) + 1) - pp.create_impedance(net, b2, b3, rft_pu=rij, xft_pu=xij, rtf_pu=rji, xtf_pu=xji, - sn_mva=s, index=pp.get_free_id(net.impedance) + 1, in_service=False) - pp.create_load(net, b3, p_mw=pl, q_mvar=ql) + create_impedance(net, b2, b3, rft_pu=rij, xft_pu=xij, rtf_pu=rji, xtf_pu=xji, + sn_mva=s, index=get_free_id(net.impedance) + 1) + create_impedance(net, b2, b3, rft_pu=rij, xft_pu=xij, rtf_pu=rji, xtf_pu=xji, + sn_mva=s, index=get_free_id(net.impedance) + 1, in_service=False) + create_load(net, b3, p_mw=pl, q_mvar=ql) net.last_added_case = "test_impedance" return net def add_test_bus_bus_switch(net): b1, b2, ln = add_grid_connection(net, zone="test_bus_bus_switch") - b3 = pp.create_bus(net, vn_kv=20., zone="test_bus_bus_switch") - pp.create_switch(net, b2, b3, et="b") + b3 = create_bus(net, vn_kv=20., zone="test_bus_bus_switch") + create_switch(net, b2, b3, et="b") pl = 1 ql = 0.5 @@ -380,19 +382,19 @@ def add_test_bus_bus_switch(net): r_ohm = 50 x_ohm = 70 - pp.create_load(net, b2, p_mw=pl, q_mvar=ql) - pp.create_load(net, b3, p_mw=pl, q_mvar=ql, scaling=0.5) + create_load(net, b2, p_mw=pl, q_mvar=ql) + create_load(net, b3, p_mw=pl, q_mvar=ql, scaling=0.5) - pp.create_sgen(net, b2, p_mw=psg, q_mvar=qsg) - pp.create_sgen(net, b3, p_mw=psg, q_mvar=qsg, scaling=0.5) + create_sgen(net, b2, p_mw=psg, q_mvar=qsg) + create_sgen(net, b3, p_mw=psg, q_mvar=qsg, scaling=0.5) - pp.create_ward(net, b2, pz_mw=pz, qz_mvar=qz, ps_mw=ps, qs_mvar=qs) - pp.create_ward(net, b3, pz_mw=0.5 * pz, qz_mvar=0.5 * qz, ps_mw=0.5 * ps, qs_mvar=0.5 * qs) + create_ward(net, b2, pz_mw=pz, qz_mvar=qz, ps_mw=ps, qs_mvar=qs) + create_ward(net, b3, pz_mw=0.5 * pz, qz_mvar=0.5 * qz, ps_mw=0.5 * ps, qs_mvar=0.5 * qs) - pp.create_xward(net, b3, pz_mw=0.5 * pz, qz_mvar=0.5 * qz, ps_mw=0.5 * ps, qs_mvar=0.5 * qs, - vm_pu=vm_pu, x_ohm=x_ohm, r_ohm=r_ohm) - pp.create_xward(net, b2, pz_mw=pz, qz_mvar=qz, ps_mw=ps, qs_mvar=qs, - vm_pu=vm_pu, x_ohm=x_ohm, r_ohm=r_ohm) + create_xward(net, b3, pz_mw=0.5 * pz, qz_mvar=0.5 * qz, ps_mw=0.5 * ps, qs_mvar=0.5 * qs, + vm_pu=vm_pu, x_ohm=x_ohm, r_ohm=r_ohm) + create_xward(net, b2, pz_mw=pz, qz_mvar=qz, ps_mw=ps, qs_mvar=qs, + vm_pu=vm_pu, x_ohm=x_ohm, r_ohm=r_ohm) net.last_added_case = "test_bus_bus_switch" return net @@ -414,25 +416,25 @@ def add_test_oos_bus_with_is_element(net): x_ohm = 70 # OOS buses - b3 = pp.create_bus(net, zone="test_oos_bus_with_is_element", vn_kv=0.4, in_service=False) - b4 = pp.create_bus(net, zone="test_oos_bus_with_is_element", vn_kv=0.4, in_service=False) - b5 = pp.create_bus(net, zone="test_oos_bus_with_is_element", vn_kv=0.4, in_service=False) + b3 = create_bus(net, zone="test_oos_bus_with_is_element", vn_kv=0.4, in_service=False) + b4 = create_bus(net, zone="test_oos_bus_with_is_element", vn_kv=0.4, in_service=False) + b5 = create_bus(net, zone="test_oos_bus_with_is_element", vn_kv=0.4, in_service=False) - pp.create_line_from_parameters(net, b2, b3, 12.2, r_ohm_per_km=0.08, x_ohm_per_km=0.12, - c_nf_per_km=300, max_i_ka=.2, df=.8) - pp.create_line_from_parameters(net, b2, b4, 12.2, r_ohm_per_km=0.08, x_ohm_per_km=0.12, - c_nf_per_km=300, max_i_ka=.2, df=.8) - pp.create_line_from_parameters(net, b2, b5, 12.2, r_ohm_per_km=0.08, x_ohm_per_km=0.12, - c_nf_per_km=300, max_i_ka=.2, df=.8) + create_line_from_parameters(net, b2, b3, 12.2, r_ohm_per_km=0.08, x_ohm_per_km=0.12, + c_nf_per_km=300, max_i_ka=.2, df=.8) + create_line_from_parameters(net, b2, b4, 12.2, r_ohm_per_km=0.08, x_ohm_per_km=0.12, + c_nf_per_km=300, max_i_ka=.2, df=.8) + create_line_from_parameters(net, b2, b5, 12.2, r_ohm_per_km=0.08, x_ohm_per_km=0.12, + c_nf_per_km=300, max_i_ka=.2, df=.8) # in service elements - pp.create_load(net, b3, p_mw=pl, q_mvar=ql) - pp.create_gen(net, b4, p_mw=ps, vm_pu=vm_set_pu) - pp.create_sgen(net, b5, p_mw=ps, q_mvar=ql) - pp.create_ward(net, b3, pz_mw=pz, qz_mvar=qz, ps_mw=ps, qs_mvar=qs) - pp.create_xward(net, b4, pz_mw=0.5 * pz, qz_mvar=0.5 * qz, ps_mw=0.5 * ps, qs_mvar=0.5 * qs, - vm_pu=vm_pu, x_ohm=x_ohm, r_ohm=r_ohm) - pp.create_shunt(net, b5, q_mvar=-800, p_mw=0) + create_load(net, b3, p_mw=pl, q_mvar=ql) + create_gen(net, b4, p_mw=ps, vm_pu=vm_set_pu) + create_sgen(net, b5, p_mw=ps, q_mvar=ql) + create_ward(net, b3, pz_mw=pz, qz_mvar=qz, ps_mw=ps, qs_mvar=qs) + create_xward(net, b4, pz_mw=0.5 * pz, qz_mvar=0.5 * qz, ps_mw=0.5 * ps, qs_mvar=0.5 * qs, + vm_pu=vm_pu, x_ohm=x_ohm, r_ohm=r_ohm) + create_shunt(net, b5, q_mvar=-800, p_mw=0) net.last_added_case = "test_oos_bus_with_is_element" return net @@ -443,9 +445,9 @@ def add_test_shunt(net): pz = 0.12 qz = -1.2 # one shunt at a bus - pp.create_shunt_as_capacitor(net, b2, q_mvar=1.2, loss_factor=0.1, vn_kv=22., step=2) + create_shunt_as_capacitor(net, b2, q_mvar=1.2, loss_factor=0.1, vn_kv=22., step=2) # add out of service shunt shuold not change the result - pp.create_shunt(net, b2, p_mw=pz, q_mvar=qz, in_service=False) + create_shunt(net, b2, p_mw=pz, q_mvar=qz, in_service=False) net.last_added_case = "test_shunt" return net @@ -455,19 +457,19 @@ def add_test_shunt_split(net): pz = 0.120 qz = -1.200 # one shunt at a bus - pp.create_shunt(net, b2, p_mw=pz / 2, q_mvar=qz / 2) - pp.create_shunt(net, b2, p_mw=pz / 2, q_mvar=qz / 2) + create_shunt(net, b2, p_mw=pz / 2, q_mvar=qz / 2) + create_shunt(net, b2, p_mw=pz / 2, q_mvar=qz / 2) net.last_added_case = "test_shunt_split" return net def add_test_two_open_switches_on_deactive_line(net): b1, b2, l1 = add_grid_connection(net, zone="two_open_switches_on_deactive_line") - b3 = pp.create_bus(net, vn_kv=20.) + b3 = create_bus(net, vn_kv=20.) l2 = create_test_line(net, b2, b3, in_service=False) create_test_line(net, b3, b1) - pp.create_switch(net, b2, l2, et="l", closed=False) - pp.create_switch(net, b3, l2, et="l", closed=False) + create_switch(net, b2, l2, et="l", closed=False) + create_switch(net, b3, l2, et="l", closed=False) net.last_added_case = "test_two_open_switches_on_deactive_line" return net @@ -475,10 +477,11 @@ def add_test_two_open_switches_on_deactive_line(net): if __name__ == '__main__': from pandapower.test.consistency_checks import runpp_with_consistency_checks from pandapower import LoadflowNotConverged + for net in result_test_network_generator(): try: runpp_with_consistency_checks(net, enforce_q_lims=True, numba=True) except (AssertionError): raise UserWarning("Consistency Error after adding %s" % net.last_added_case) except(LoadflowNotConverged): - raise UserWarning("Power flow did not converge after adding %s" % net.last_added_case) \ No newline at end of file + raise UserWarning("Power flow did not converge after adding %s" % net.last_added_case) diff --git a/pandapower/test/loadflow/test_PTDF_LODF.py b/pandapower/test/loadflow/test_PTDF_LODF.py index e7f4ddf53..9960e9a2b 100644 --- a/pandapower/test/loadflow/test_PTDF_LODF.py +++ b/pandapower/test/loadflow/test_PTDF_LODF.py @@ -7,19 +7,18 @@ import numpy as np import pytest -import pandapower as pp -import pandapower.networks as nw +from pandapower.networks.power_system_test_cases import case9, case30, case9241pegase from pandapower.pd2ppc import _pd2ppc -from pandapower.pypower.makePTDF import makePTDF from pandapower.pypower.makeLODF import makeLODF, makeOTDF, outage_results_OTDF - -from pandapower.test.loadflow.result_test_network_generator import result_test_network_generator_dcpp -from pandapower.test.helper_functions import add_grid_connection, create_test_line, assert_net_equal +from pandapower.pypower.makePTDF import makePTDF +from pandapower.run import rundcpp +from pandapower.topology.create_graph import create_nxgraph +from pandapower.topology.graph_searches import find_graph_characteristics, lines_on_path def test_PTDF(): - net = nw.case30() - pp.rundcpp(net) + net = case30() + rundcpp(net) _, ppci = _pd2ppc(net) ptdf = makePTDF(ppci["baseMVA"], ppci["bus"], ppci["branch"], @@ -28,11 +27,11 @@ def test_PTDF(): result_side=1, using_sparse_solver=False) ptdf_sparse = makePTDF(ppci["baseMVA"], ppci["bus"], ppci["branch"], using_sparse_solver=True) - ptdf_reduced = makePTDF(ppci["baseMVA"], ppci["bus"], ppci["branch"], - using_sparse_solver=False, + ptdf_reduced = makePTDF(ppci["baseMVA"], ppci["bus"], ppci["branch"], + using_sparse_solver=False, branch_id=list(range(15)), reduced=True) - ptdf_reduced_sparse = makePTDF(ppci["baseMVA"], ppci["bus"], ppci["branch"], - using_sparse_solver=True, + ptdf_reduced_sparse = makePTDF(ppci["baseMVA"], ppci["bus"], ppci["branch"], + using_sparse_solver=True, branch_id=list(range(15)), reduced=True) if not np.allclose(ptdf, ptdf_sparse): @@ -43,22 +42,24 @@ def test_PTDF(): raise AssertionError("PTDF has NaN value") if not ptdf_reduced.shape == (15, ppci["bus"].shape[0]): raise AssertionError("Reduced PTDF has wrong dimension") - if not ptdf_reduced_sparse.shape == (15,ppci["bus"].shape[0]): + if not ptdf_reduced_sparse.shape == (15, ppci["bus"].shape[0]): raise AssertionError("Sparse reduced PTDF has wrong dimension") + def test_PTDF_large(): - net = nw.case9241pegase() - pp.rundcpp(net) + net = case9241pegase() + rundcpp(net) _, ppci = _pd2ppc(net) ptdf_sparse = makePTDF(ppci["baseMVA"], ppci["bus"], ppci["branch"], - using_sparse_solver=True) + using_sparse_solver=True) if not ptdf_sparse.shape == (ppci["branch"].shape[0], ppci["bus"].shape[0]): raise AssertionError("PTDF has wrong dimension") + def test_LODF(): - net = nw.case9() - pp.rundcpp(net) + net = case9() + rundcpp(net) _, ppci = _pd2ppc(net) ptdf = makePTDF(ppci["baseMVA"], ppci["bus"], ppci["branch"]) @@ -68,16 +69,16 @@ def test_LODF(): def test_OTDF(): - net = nw.case9() - mg = pp.topology.create_nxgraph(net, respect_switches=True) + net = case9() + mg = create_nxgraph(net, respect_switches=True) # roots = np.r_[net.ext_grid.bus.values, net.gen.bus.values] - # stubs = pp.topology.determine_stubs(net, roots=roots, mg=mg, respect_switches=True) # no lines are stubs here? - # stubs = pp.toolbox.get_connected_elements(net, "line", roots) # because not n-1 lines here are those - c = pp.topology.find_graph_characteristics(g=mg, roots=net.ext_grid.bus.values, characteristics=["bridges"]) - bridges = np.array([pp.topology.lines_on_path(mg, p) for p in c["bridges"]]).flatten() + # stubs = determine_stubs(net, roots=roots, mg=mg, respect_switches=True) # no lines are stubs here? + # stubs = toolbox.get_connected_elements(net, "line", roots) # because not n-1 lines here are those + c = find_graph_characteristics(g=mg, roots=net.ext_grid.bus.values, characteristics=["bridges"]) + bridges = np.array([lines_on_path(mg, p) for p in c["bridges"]]).flatten() # outage_lines = [i for i in net.line.index.values if i not in stubs and i not in bridges] outage_lines = np.array([i for i in net.line.index.values if i not in bridges]) - pp.rundcpp(net) + rundcpp(net) _, ppci = _pd2ppc(net) ptdf = makePTDF(ppci["baseMVA"], ppci["bus"], ppci["branch"]) lodf = makeLODF(ppci["branch"], ptdf) @@ -92,7 +93,7 @@ def test_OTDF(): # Run power flow for the outage scenario net.line.at[line, "in_service"] = False - pp.rundcpp(net) + rundcpp(net) pf_outage_result = net.res_line.p_from_mw.values net.line.at[line, "in_service"] = True @@ -101,16 +102,16 @@ def test_OTDF(): def test_OTDF_outage_results(): - net = nw.case9() - mg = pp.topology.create_nxgraph(net, respect_switches=True) + net = case9() + mg = create_nxgraph(net, respect_switches=True) # roots = np.r_[net.ext_grid.bus.values, net.gen.bus.values] - # stubs = pp.topology.determine_stubs(net, roots=roots, mg=mg, respect_switches=True) # no lines are stubs here? - # stubs = pp.toolbox.get_connected_elements(net, "line", roots) # because not n-1 lines here are those - c = pp.topology.find_graph_characteristics(g=mg, roots=net.ext_grid.bus.values, characteristics=["bridges"]) - bridges = np.array([pp.topology.lines_on_path(mg, p) for p in c["bridges"]]).flatten() + # stubs = determine_stubs(net, roots=roots, mg=mg, respect_switches=True) # no lines are stubs here? + # stubs = toolbox.get_connected_elements(net, "line", roots) # because not n-1 lines here are those + c = find_graph_characteristics(g=mg, roots=net.ext_grid.bus.values, characteristics=["bridges"]) + bridges = np.array([lines_on_path(mg, p) for p in c["bridges"]]).flatten() # outage_lines = [i for i in net.line.index.values if i not in stubs and i not in bridges] outage_lines = np.array([i for i in net.line.index.values if i not in bridges]) - pp.rundcpp(net) + rundcpp(net) _, ppci = _pd2ppc(net) ptdf = makePTDF(ppci["baseMVA"], ppci["bus"], ppci["branch"]) lodf = makeLODF(ppci["branch"], ptdf) @@ -122,7 +123,7 @@ def test_OTDF_outage_results(): nminus1_pf = [] for i in outage_lines: net.line.at[i, "in_service"] = False - pp.rundcpp(net) + rundcpp(net) nminus1_pf.append(net.res_line.p_from_mw.values.copy()) net.line.at[i, "in_service"] = True diff --git a/pandapower/test/loadflow/test_dist_slack.py b/pandapower/test/loadflow/test_dist_slack.py index a14761dd0..dfdb34951 100644 --- a/pandapower/test/loadflow/test_dist_slack.py +++ b/pandapower/test/loadflow/test_dist_slack.py @@ -6,12 +6,18 @@ import numpy as np import pytest -import pandapower as pp -from pandapower import networks + from pandapower.control import ContinuousTapControl -from pandapower.pypower.idx_bus import PD, GS, VM +from pandapower.create import create_empty_network, create_buses, create_gen, create_load, create_ext_grid, \ + create_line_from_parameters, create_xward, create_bus, create_shunt +from pandapower.networks.create_examples import example_multivoltage +from pandapower.networks.power_system_test_cases import case9, case2848rte from pandapower.pypower.idx_brch import PF +from pandapower.pypower.idx_bus import PD, VM +from pandapower.run import runpp, set_user_pf_options from pandapower.test.helper_functions import assert_res_equal +from pandapower.toolbox.element_selection import get_connected_elements_dict + try: import numba @@ -28,20 +34,20 @@ def small_example_grid(): - net = pp.create_empty_network() - pp.create_buses(net, 3, 20) + net = create_empty_network() + create_buses(net, 3, 20) - pp.create_gen(net, 0, p_mw=100, vm_pu=1, slack=True, slack_weight=1) - # pp.create_ext_grid(net, 0) + create_gen(net, 0, p_mw=100, vm_pu=1, slack=True, slack_weight=1) + # create_ext_grid(net, 0) - pp.create_load(net, 1, p_mw=100, q_mvar=100) + create_load(net, 1, p_mw=100, q_mvar=100) - pp.create_line_from_parameters(net, 0, 1, length_km=3, r_ohm_per_km=0.01, x_ohm_per_km=0.1, c_nf_per_km=0, - max_i_ka=1) - pp.create_line_from_parameters(net, 1, 2, length_km=2, r_ohm_per_km=0.01, x_ohm_per_km=0.1, c_nf_per_km=0, - max_i_ka=1) - pp.create_line_from_parameters(net, 2, 0, length_km=1, r_ohm_per_km=0.01, x_ohm_per_km=0.1, c_nf_per_km=0, - max_i_ka=1) + create_line_from_parameters(net, 0, 1, length_km=3, r_ohm_per_km=0.01, x_ohm_per_km=0.1, c_nf_per_km=0, + max_i_ka=1) + create_line_from_parameters(net, 1, 2, length_km=2, r_ohm_per_km=0.01, x_ohm_per_km=0.1, c_nf_per_km=0, + max_i_ka=1) + create_line_from_parameters(net, 2, 0, length_km=1, r_ohm_per_km=0.01, x_ohm_per_km=0.1, c_nf_per_km=0, + max_i_ka=1) return net @@ -62,9 +68,9 @@ def _get_xward_result(net): p_bus = ppc['bus'][net._pd2ppc_lookups["bus"][b], PD] p_shunt = ppc['bus'][net._pd2ppc_lookups["bus"][b], VM] ** 2 * net["xward"].at[x_id, "pz_mw"] internal_results = np.append(internal_results, p_shunt) - connected = pp.get_connected_elements_dict(net, [b], respect_in_service=True, connected_buses=False, - connected_branch_elements=False, - connected_other_elements=False) + connected = get_connected_elements_dict(net, [b], respect_in_service=True, connected_buses=False, + connected_branch_elements=False, + connected_other_elements=False) for e, idx in connected.items(): # first, count the total slack weights per bus, and obtain the variable part of the active power total_weight = 0 @@ -103,8 +109,8 @@ def _get_injection_consumption(net): def _get_slack_weights(net): slack_weights = np.r_[net.gen.query("in_service").slack_weight, - net.ext_grid.query("in_service").slack_weight, - net.xward.query("in_service").slack_weight] + net.ext_grid.query("in_service").slack_weight, + net.xward.query("in_service").slack_weight] return slack_weights / sum(slack_weights) @@ -114,11 +120,11 @@ def _get_inputs_results(net): xward_pq_res, _ = _get_xward_result(net) # xward is in the consumption reference system, but here the results are all assumed in the generation reference system inputs = np.r_[net.gen.query("in_service").p_mw, - np.zeros(len(net.ext_grid.query("in_service"))), - -net.xward.query("in_service").ps_mw] + np.zeros(len(net.ext_grid.query("in_service"))), + -net.xward.query("in_service").ps_mw] results = np.r_[net.res_gen[net.gen.in_service].p_mw, - net.res_ext_grid[net.ext_grid.in_service].p_mw, - -xward_pq_res] + net.res_ext_grid[net.ext_grid.in_service].p_mw, + -xward_pq_res] return inputs, results @@ -143,20 +149,20 @@ def check_xward_results(net, tol=1e-9): def run_and_assert_numba(net, **kwargs): if numba_installed: net_temp = net.deepcopy() - pp.runpp(net_temp, distributed_slack=True, numba=False, **kwargs) - pp.runpp(net, distributed_slack=True, **kwargs) + runpp(net_temp, distributed_slack=True, numba=False, **kwargs) + runpp(net, distributed_slack=True, **kwargs) assert_res_equal(net, net_temp) else: - pp.runpp(net, distributed_slack=True, numba=False, **kwargs) + runpp(net, distributed_slack=True, numba=False, **kwargs) def test_get_xward_result(): # here we test the helper function that calculates the internal and PQ load results separately # it separates the results of other node ellments at the same bus, but only works for 1 xward at a bus net = small_example_grid() - pp.create_xward(net, 2, 100, 0, 0, 0, 0.02, 0.2, 1) - pp.create_load(net, 2, 50, 0, 0, 0, 0.02, 0.2, 1) - pp.runpp(net) + create_xward(net, 2, 100, 0, 0, 0, 0.02, 0.2, 1) + create_load(net, 2, 50, 0, 0, 0, 0.02, 0.2, 1) + runpp(net) check_xward_results(net) @@ -164,7 +170,7 @@ def test_numba(): net = small_example_grid() # if no slack_weight is given for ext_grid, 1 is assumed, because normally # ext_grids are responsible to take the slack power - pp.create_gen(net, 2, 200, 1., slack_weight=2) + create_gen(net, 2, 200, 1., slack_weight=2) run_and_assert_numba(net) assert_results_correct(net) @@ -178,9 +184,9 @@ def test_small_example(): net2 = net.deepcopy() - pp.runpp(net, distributed_slack=True, numba=False) + runpp(net, distributed_slack=True, numba=False) - pp.runpp(net2, distributed_slack=False) + runpp(net2, distributed_slack=False) assert_res_equal(net, net2) assert_results_correct(net) @@ -189,7 +195,7 @@ def test_small_example(): def test_two_gens(): # a three-bus example with 3 lines in a ring, 2 gens and 1 load net = small_example_grid() - pp.create_gen(net, 2, 200, 1., slack_weight=2) + create_gen(net, 2, 200, 1., slack_weight=2) run_and_assert_numba(net) assert_results_correct(net) @@ -206,8 +212,8 @@ def test_two_gens(): def test_three_gens(): net = small_example_grid() - pp.create_gen(net, 1, 200, 1., slack_weight=2) - pp.create_gen(net, 2, 200, 1., slack_weight=2) + create_gen(net, 1, 200, 1., slack_weight=2) + create_gen(net, 2, 200, 1., slack_weight=2) run_and_assert_numba(net) assert_results_correct(net) @@ -217,7 +223,7 @@ def test_gen_xward(): # here testing for numba only net = small_example_grid() # note: xward is in the consumption reference system, so positive ps_mw stands for consumption - pp.create_xward(net, 2, 200, 0, 0, 0, 0.02, 0.2, 1, slack_weight=2) + create_xward(net, 2, 200, 0, 0, 0, 0.02, 0.2, 1, slack_weight=2) run_and_assert_numba(net) # xward behavior is a bit different due to the shunt component and the impedance component of the xward # so we check the results by hand for the case when shunt values are != 0 @@ -229,8 +235,8 @@ def test_xward_pz_mw(): # here testing for numba only # for now, not implemented and should raise an error net = small_example_grid() - # pp.create_xward(net, 2, 0, 0, 0, 0, 0.02, 0.2, 1, slack_weight=2) - pp.create_xward(net, 2, 200, 20, 10, 1, 0.02, 0.2, 1, slack_weight=2) + # create_xward(net, 2, 0, 0, 0, 0, 0.02, 0.2, 1, slack_weight=2) + create_xward(net, 2, 200, 20, 10, 1, 0.02, 0.2, 1, slack_weight=2) run_and_assert_numba(net) # xward behavior is a bit different due to the shunt component of the xward # so we check the results by hand for the case when shunt values are != 0 @@ -240,8 +246,8 @@ def test_xward_pz_mw(): def test_xward_manually(): net_1 = small_example_grid() - # pp.create_xward(net, 2, 0, 0, 0, 0, 0.02, 0.2, 1, slack_weight=2) - pp.create_xward(net_1, 2, 200, 20, 10, 1, 0.02, 0.2, 1, slack_weight=2) + # create_xward(net, 2, 0, 0, 0, 0, 0.02, 0.2, 1, slack_weight=2) + create_xward(net_1, 2, 200, 20, 10, 1, 0.02, 0.2, 1, slack_weight=2) run_and_assert_numba(net_1) slack_power = (net_1.res_gen.p_mw.at[0] - net_1.gen.p_mw.at[0]) * 3 # factor 3 since gen has # slack_weight==1 and xward has slack_weight==2 @@ -249,15 +255,15 @@ def test_xward_manually(): # xward behavior is a bit different due to the shunt component of the xward # so we check the results by hand for the case when shunt values are != 0 net = small_example_grid() - pp.create_bus(net, 20) - pp.create_load(net, 2, 200, 20) - pp.create_shunt(net, 2, 1, 10) - pp.create_gen(net, 3, 0, 1, slack_weight=2) - pp.create_line_from_parameters(net, 2, 3, 1, 0.02, 0.2, 0, 1) + create_bus(net, 20) + create_load(net, 2, 200, 20) + create_shunt(net, 2, 1, 10) + create_gen(net, 3, 0, 1, slack_weight=2) + create_line_from_parameters(net, 2, 3, 1, 0.02, 0.2, 0, 1) net.load.at[1, 'p_mw'] = net_1._ppc['bus'][net_1.xward.bus.at[0], PD] assert np.isclose(200 - net.load.at[1, 'p_mw'], slack_power * 2 / 3, rtol=0, atol=1e-6) - pp.runpp(net) + runpp(net) assert np.isclose(net_1.res_gen.at[0, 'p_mw'], net.res_gen.at[0, 'p_mw'], rtol=0, atol=1e-6) assert np.isclose(net_1.res_gen.at[0, 'q_mvar'], net.res_gen.at[0, 'q_mvar'], rtol=0, atol=1e-6) @@ -270,8 +276,8 @@ def test_xward_manually(): def test_ext_grid(): net = small_example_grid() net.gen.in_service = False - pp.create_ext_grid(net, 0, slack_weight=1) - pp.create_ext_grid(net, 2, slack_weight=2) + create_ext_grid(net, 0, slack_weight=1) + create_ext_grid(net, 2, slack_weight=2) run_and_assert_numba(net) assert_results_correct(net) @@ -279,7 +285,7 @@ def test_ext_grid(): def test_gen_ext_grid(): net = small_example_grid() - pp.create_ext_grid(net, 2, slack_weight=2) + create_ext_grid(net, 2, slack_weight=2) run_and_assert_numba(net) assert_results_correct(net) @@ -288,10 +294,10 @@ def test_gen_ext_grid(): def test_pvgen_ext_grid(): # now test the behavior if gen is not slack net = small_example_grid() - pp.create_ext_grid(net, 2, slack_weight=2) + create_ext_grid(net, 2, slack_weight=2) net.gen.slack = False - pp.runpp(net, distributed_slack=True, numba=numba_installed) + runpp(net, distributed_slack=True, numba=numba_installed) run_and_assert_numba(net) assert_results_correct(net) @@ -299,7 +305,7 @@ def test_pvgen_ext_grid(): def test_same_bus(): net = small_example_grid() - pp.create_ext_grid(net, 0, slack_weight=2) + create_ext_grid(net, 0, slack_weight=2) run_and_assert_numba(net) assert_results_correct(net) @@ -307,7 +313,7 @@ def test_same_bus(): def test_gen_oos(): net = small_example_grid() - pp.create_gen(net, 2, 200, 1., slack_weight=2, in_service=False) + create_gen(net, 2, 200, 1., slack_weight=2, in_service=False) run_and_assert_numba(net) assert_results_correct(net) @@ -315,7 +321,7 @@ def test_gen_oos(): def test_ext_grid_oos(): net = small_example_grid() - pp.create_ext_grid(net, 0, slack_weight=2, in_service=False) + create_ext_grid(net, 0, slack_weight=2, in_service=False) run_and_assert_numba(net) assert_results_correct(net) @@ -323,57 +329,57 @@ def test_ext_grid_oos(): def test_xward_oos(): net = small_example_grid() - pp.create_xward(net, 2, 200, 20, 10, 1, 0.02, 0.2, 1, slack_weight=2, in_service=False) + create_xward(net, 2, 200, 20, 10, 1, 0.02, 0.2, 1, slack_weight=2, in_service=False) run_and_assert_numba(net) assert_results_correct(net) def test_only_xward(): - net = pp.create_empty_network() - pp.create_bus(net, 110) - pp.create_ext_grid(net, 0, vm_pu=1.05, slack_weight=2) - pp.create_xward(net, 0, 200, 20, 10, 1, 0.02, 0.2, 1, slack_weight=2) + net = create_empty_network() + create_bus(net, 110) + create_ext_grid(net, 0, vm_pu=1.05, slack_weight=2) + create_xward(net, 0, 200, 20, 10, 1, 0.02, 0.2, 1, slack_weight=2) with pytest.raises(NotImplementedError): - pp.runpp(net, distributed_slack=True) + runpp(net, distributed_slack=True) def test_xward_gen_same_bus(): net = small_example_grid() - pp.create_gen(net, 2, 200, 1., slack_weight=2) - pp.create_xward(net, 2, 200, 20, 10, 1, 0.02, 0.2, 1, slack_weight=4) + create_gen(net, 2, 200, 1., slack_weight=2) + create_xward(net, 2, 200, 20, 10, 1, 0.02, 0.2, 1, slack_weight=4) with pytest.raises(NotImplementedError): - pp.runpp(net, distributed_slack=True) + runpp(net, distributed_slack=True) def test_separate_zones(): net = small_example_grid() - b1, b2 = pp.create_buses(net, 2, 110) - pp.create_line_from_parameters(net, b1, b2, length_km=1, r_ohm_per_km=0.01, x_ohm_per_km=0.1, c_nf_per_km=0, - max_i_ka=1) - pp.create_ext_grid(net, b1) - pp.create_load(net, b2, 100) + b1, b2 = create_buses(net, 2, 110) + create_line_from_parameters(net, b1, b2, length_km=1, r_ohm_per_km=0.01, x_ohm_per_km=0.1, c_nf_per_km=0, + max_i_ka=1) + create_ext_grid(net, b1) + create_load(net, b2, 100) # distributed slack not implemented for separate zones with pytest.raises(NotImplementedError): - pp.runpp(net, distributed_slack=True, numba=False) + runpp(net, distributed_slack=True, numba=False) def case9_simplified(): - net = pp.create_empty_network() - pp.create_buses(net, 9, vn_kv=345.) + net = create_empty_network() + create_buses(net, 9, vn_kv=345.) lines = [[0, 3], [3, 4], [4, 5], [2, 5], [5, 6], [6, 7], [7, 1], [7, 8], [8, 3]] for i, (fb, tb) in enumerate(lines): - pp.create_line_from_parameters(net, fb, tb, 1, 20, 100, 0, 1) + create_line_from_parameters(net, fb, tb, 1, 20, 100, 0, 1) - pp.create_gen(net, 0, 0, slack=True, slack_weight=1) - pp.create_gen(net, 1, 163, slack_weight=1) - pp.create_gen(net, 2, 85, slack_weight=1) + create_gen(net, 0, 0, slack=True, slack_weight=1) + create_gen(net, 1, 163, slack_weight=1) + create_gen(net, 2, 85, slack_weight=1) - pp.create_load(net, 4, 90, 30) - pp.create_load(net, 6, 100, 35) - pp.create_load(net, 8, 125, 50) + create_load(net, 4, 90, 30) + create_load(net, 6, 100, 35) + create_load(net, 8, 125, 50) return net @@ -382,7 +388,7 @@ def test_case9(): basic test with ext_grid + gen, scaling != 1, slack_weight sum = 1 """ tol_mw = 1e-6 - net = networks.case9() + net = case9() # net = case9_simplified() # set slack_weight (distributed slack participation factor) @@ -422,18 +428,18 @@ def test_case9(): def test_case2848rte(): # check how it works with a large grid - net = networks.case2848rte() + net = case2848rte() net.ext_grid['slack_weight'] = 0 sl_gen = net.gen.loc[net.gen.p_mw > 1000].index net.gen.loc[sl_gen, 'slack_weight'] = net.gen.loc[sl_gen, 'p_mw'] - pp.runpp(net, distributed_slack=True, numba=numba_installed) + runpp(net, distributed_slack=True, numba=numba_installed) assert_results_correct(net) def test_multivoltage_example_with_controller(): do_output = False - net = networks.example_multivoltage() + net = example_multivoltage() gen_p_disp = 10 net.gen.at[0, "p_mw"] = gen_p_disp @@ -458,7 +464,7 @@ def test_multivoltage_example_with_controller(): net2.gen.p_mw = net.res_gen.p_mw net2.xward.ps_mw = net._ppc['bus'][net._pd2ppc_lookups['bus'][net.xward.bus], PD] - net.load.loc[ net.load.bus.isin([34, 32]), 'p_mw'].values - pp.runpp(net2) + runpp(net2) assert_res_equal(net, net2) check_xward_results(net) @@ -506,34 +512,34 @@ def test_dist_slack_user_pf_options(): net2 = net.deepcopy() - pp.runpp(net, distributed_slack=True) + runpp(net, distributed_slack=True) - pp.set_user_pf_options(net2, distributed_slack=True) - pp.runpp(net2) + set_user_pf_options(net2, distributed_slack=True) + runpp(net2) assert_res_equal(net, net2) assert_results_correct(net) assert_results_correct(net2) with pytest.raises(NotImplementedError): - pp.runpp(net, distributed_slack=True, algorithm="bfsw") + runpp(net, distributed_slack=True, algorithm="bfsw") with pytest.raises(NotImplementedError): - pp.runpp(net2, algorithm="bfsw") + runpp(net2, algorithm="bfsw") - pp.set_user_pf_options(net2, algorithm="bfsw") + set_user_pf_options(net2, algorithm="bfsw") with pytest.raises(NotImplementedError): - pp.runpp(net2) + runpp(net2) def test_dist_slack_with_enforce_q_lims(): - net = pp.networks.case9() + net = case9() net.ext_grid['slack_weight'] = 1 / 3 net.gen['slack_weight'] = 1 / 3 net.gen.at[0, 'max_q_mvar'] = 10 net.gen.at[1, 'max_q_mvar'] = 0.5 - pp.runpp(net, distributed_slack=True, enforce_q_lims=True, numba=False) + runpp(net, distributed_slack=True, enforce_q_lims=True, numba=False) assert net._options["distributed_slack"] and net._options["enforce_q_lims"] assert np.allclose(net.res_gen.q_mvar, net.gen.max_q_mvar, rtol=0, atol=1e-6) @@ -541,19 +547,19 @@ def test_dist_slack_with_enforce_q_lims(): def test_dist_slack_with_enforce_q_lims_duplicate_gens(): - net = pp.networks.case9() - pp.create_gen(net, net.ext_grid.bus.at[0], 1, slack=False, max_q_mvar=0.07) - pp.create_gen(net, net.ext_grid.bus.at[0], 1, slack=False, max_q_mvar=0.01) - pp.create_gen(net, net.ext_grid.bus.at[0], 2, slack=False, max_q_mvar=0.2) - pp.create_gen(net, net.ext_grid.bus.at[0], 2, slack=False, max_q_mvar=0.1) - pp.create_gen(net, net.ext_grid.bus.at[0], 0, slack=False, max_q_mvar=0.05) - pp.create_gen(net, net.ext_grid.bus.at[0], 0, slack=False, max_q_mvar=0.25) + net = case9() + create_gen(net, net.ext_grid.bus.at[0], 1, slack=False, max_q_mvar=0.07) + create_gen(net, net.ext_grid.bus.at[0], 1, slack=False, max_q_mvar=0.01) + create_gen(net, net.ext_grid.bus.at[0], 2, slack=False, max_q_mvar=0.2) + create_gen(net, net.ext_grid.bus.at[0], 2, slack=False, max_q_mvar=0.1) + create_gen(net, net.ext_grid.bus.at[0], 0, slack=False, max_q_mvar=0.05) + create_gen(net, net.ext_grid.bus.at[0], 0, slack=False, max_q_mvar=0.25) net.gen['slack_weight'] = 1 / 8 net.ext_grid['slack_weight'] = 1 / 8 net.gen.at[0, 'max_q_mvar'] = 10 net.gen.at[1, 'max_q_mvar'] = 0.5 - pp.runpp(net, distributed_slack=True, enforce_q_lims=True) + runpp(net, distributed_slack=True, enforce_q_lims=True) assert net._options["distributed_slack"] and net._options["enforce_q_lims"] assert np.allclose(net.res_gen.q_mvar, net.gen.max_q_mvar, rtol=0, atol=1e-6) diff --git a/pandapower/test/loadflow/test_facts.py b/pandapower/test/loadflow/test_facts.py index 6477e6399..877f9d370 100644 --- a/pandapower/test/loadflow/test_facts.py +++ b/pandapower/test/loadflow/test_facts.py @@ -4,19 +4,25 @@ # and Energy System Technology (IEE), Kassel. All rights reserved. -import os -import pytest import copy +import os +from itertools import product + import numpy as np -import pandas as pd +import pytest from pandas.testing import assert_frame_equal -from itertools import product -import pandapower as pp -from pandapower.test import assert_res_equal -from pandapower.test.consistency_checks import runpp_with_consistency_checks +from pandapower import pp_dir +from pandapower.converter.powerfactory.validate import validate_pf_conversion +from pandapower.create import create_impedance, create_shunts, create_buses, create_gens, create_svc, create_tcsc, \ + create_bus, create_empty_network, create_line_from_parameters, create_transformer_from_parameters, create_gen, \ + create_load, create_shunt, create_ext_grid, create_vsc, create_loads, create_ssc, create_line_dc_from_parameters, \ + create_buses_dc, create_bus_dc, create_line_dc, create_lines_from_parameters, create_lines_dc +from pandapower.file_io import from_json +from pandapower.networks.power_system_test_cases import case9 from pandapower.pf.makeYbus_facts import calc_y_svc_pu -from pandapower.auxiliary import _preserve_dtypes +from pandapower.run import runpp +from pandapower.test.consistency_checks import runpp_with_consistency_checks try: import matplotlib.pyplot as plt @@ -52,42 +58,42 @@ def copy_with_impedance(net): net_ref = copy.deepcopy(net) for i in net.tcsc.index.values: - pp.create_impedance(net_ref, net.tcsc.from_bus.at[i], net.tcsc.to_bus.at[i], 0, - net.res_tcsc.x_ohm.at[i] / baseZ[net.tcsc.to_bus.at[i]], baseMVA, - in_service=net.tcsc.in_service.at[i], name="tcsc") + create_impedance(net_ref, net.tcsc.from_bus.at[i], net.tcsc.to_bus.at[i], 0, + net.res_tcsc.x_ohm.at[i] / baseZ[net.tcsc.to_bus.at[i]], baseMVA, + in_service=net.tcsc.in_service.at[i], name="tcsc") net_ref.tcsc.in_service = False if len(net.svc) > 0: - # pp.create_loads(net_ref, net.svc.bus.values, 0, net.res_svc.q_mvar.values, in_service=net.svc.in_service.values) + # create_loads(net_ref, net.svc.bus.values, 0, net.res_svc.q_mvar.values, in_service=net.svc.in_service.values) # create shunts because of Ybus comparison q = np.square(net.bus.loc[net.svc.bus.values, 'vn_kv']) / net.res_svc.x_ohm.values - pp.create_shunts(net_ref, net.svc.bus.values, q.fillna(0), in_service=net.svc.in_service.values, name="svc") + create_shunts(net_ref, net.svc.bus.values, q.fillna(0), in_service=net.svc.in_service.values, name="svc") net_ref.svc.in_service = False if len(net.ssc) > 0: # create shunts because of Ybus comparison in_service = net.ssc.in_service.values ssc_bus = net.ssc.bus.values - aux_bus = pp.create_buses(net_ref, len(net.ssc), net.bus.loc[ssc_bus, "vn_kv"].values) + aux_bus = create_buses(net_ref, len(net.ssc), net.bus.loc[ssc_bus, "vn_kv"].values) for fb, tb, r, x, i in zip(ssc_bus, aux_bus, net.ssc.r_ohm.values / baseZ[ssc_bus], net.ssc.x_ohm.values / baseZ[ssc_bus], in_service): - pp.create_impedance(net_ref, fb, tb, r, x, baseMVA, name="ssc", in_service=i) + create_impedance(net_ref, fb, tb, r, x, baseMVA, name="ssc", in_service=i) if len(net.res_ssc) > 0: vm_pu = net.res_ssc.vm_internal_pu.fillna(1) else: vm_pu = net.ssc.set_vm_pu.fillna(1) - pp.create_gens(net_ref, aux_bus, 0, vm_pu, in_service=in_service) + create_gens(net_ref, aux_bus, 0, vm_pu, in_service=in_service) net_ref.ssc.in_service = False if len(net.vsc) > 0: # create shunts because of Ybus comparison in_service = net.vsc.in_service.values vsc_bus = net.vsc.bus.values - aux_bus = pp.create_buses(net_ref, len(net.vsc), net.bus.loc[vsc_bus, "vn_kv"].values) + aux_bus = create_buses(net_ref, len(net.vsc), net.bus.loc[vsc_bus, "vn_kv"].values) for fb, tb, r, x, i in zip(vsc_bus, aux_bus, net.vsc.r_ohm.values / baseZ[vsc_bus], net.vsc.x_ohm.values / baseZ[vsc_bus], in_service): - pp.create_impedance(net_ref, fb, tb, r, x, baseMVA, name="vsc", in_service=i) - g = pp.create_gens(net_ref, aux_bus, 0, net.res_vsc.vm_internal_pu.fillna(1), in_service=in_service) + create_impedance(net_ref, fb, tb, r, x, baseMVA, name="vsc", in_service=i) + g = create_gens(net_ref, aux_bus, 0, net.res_vsc.vm_internal_pu.fillna(1), in_service=in_service) vsc_pv = net.vsc.control_mode_ac.values == "vm_pu" net_ref.gen.loc[g[vsc_pv], "vm_pu"] = net.vsc.loc[vsc_pv, "control_value_ac"].values net_ref.vsc.in_service = False @@ -152,71 +158,71 @@ def compare_ssc_impedance_gen(net, net_ref, element="ssc"): def add_tcsc_to_line(net, xl, xc, set_p_mw, from_bus, line, side="from_bus"): - aux = pp.create_bus(net, net.bus.at[from_bus, "vn_kv"], "aux") + aux = create_bus(net, net.bus.at[from_bus, "vn_kv"], "aux") net.line.loc[line, side] = aux - idx = pp.create_tcsc(net, from_bus, aux, xl, xc, set_p_mw, 100, controllable=True) + idx = create_tcsc(net, from_bus, aux, xl, xc, set_p_mw, 100, controllable=True) return idx def facts_case_study_grid(): - net = pp.create_empty_network() - - b1 = pp.create_bus(net, name="B1", vn_kv=18) - b2 = pp.create_bus(net, name="B2", vn_kv=16.5) - b3 = pp.create_bus(net, name="B3", vn_kv=230) - b4 = pp.create_bus(net, name="B4", vn_kv=230) - b5 = pp.create_bus(net, name="B5", vn_kv=230) - b6 = pp.create_bus(net, name="B6", vn_kv=230) - b7 = pp.create_bus(net, name="B7", vn_kv=230) - b8 = pp.create_bus(net, name="B8", vn_kv=230) - - pp.create_ext_grid(net, bus=b1, vm_pu=1, va_degree=0) - - pp.create_line_from_parameters(net, name="L1", from_bus=b3, to_bus=b4, length_km=30, r_ohm_per_km=0.049, - x_ohm_per_km=0.136, g_us_per_km=0, c_nf_per_km=142, max_i_ka=1.5) - pp.create_line_from_parameters(net, name="L2", from_bus=b3, to_bus=b4, length_km=30, r_ohm_per_km=0.049, - x_ohm_per_km=0.136, g_us_per_km=0, c_nf_per_km=142, max_i_ka=1.5) - pp.create_line_from_parameters(net, name="L3", from_bus=b4, to_bus=b5, length_km=100, r_ohm_per_km=0.081, - x_ohm_per_km=0.312, g_us_per_km=0, c_nf_per_km=11, max_i_ka=1.5) - pp.create_line_from_parameters(net, name="L4", from_bus=b4, to_bus=b6, length_km=100, r_ohm_per_km=0.081, - x_ohm_per_km=0.312, g_us_per_km=0, c_nf_per_km=11, max_i_ka=1.5) - pp.create_line_from_parameters(net, name="L5", from_bus=b5, to_bus=b7, length_km=220, r_ohm_per_km=0.081, - x_ohm_per_km=0.312, g_us_per_km=0, c_nf_per_km=11, max_i_ka=1.5) - pp.create_line_from_parameters(net, name="L6", from_bus=b6, to_bus=b8, length_km=140, r_ohm_per_km=0.081, - x_ohm_per_km=0.312, g_us_per_km=0, c_nf_per_km=11, max_i_ka=1.5) - pp.create_line_from_parameters(net, name="L7", from_bus=b5, to_bus=b6, length_km=180, r_ohm_per_km=0.081, - x_ohm_per_km=0.312, g_us_per_km=0, c_nf_per_km=11, max_i_ka=1.5) - pp.create_line_from_parameters(net, name="L8", from_bus=b7, to_bus=b8, length_km=180, r_ohm_per_km=0.081, - x_ohm_per_km=0.312, g_us_per_km=0, c_nf_per_km=11, max_i_ka=1.5) - - # pp.create_line_from_parameters(net,name="L9",from_bus=3,to_bus=4,length_km=100, r_ohm_per_km=0.312, + net = create_empty_network() + + b1 = create_bus(net, name="B1", vn_kv=18) + b2 = create_bus(net, name="B2", vn_kv=16.5) + b3 = create_bus(net, name="B3", vn_kv=230) + b4 = create_bus(net, name="B4", vn_kv=230) + b5 = create_bus(net, name="B5", vn_kv=230) + b6 = create_bus(net, name="B6", vn_kv=230) + b7 = create_bus(net, name="B7", vn_kv=230) + b8 = create_bus(net, name="B8", vn_kv=230) + + create_ext_grid(net, bus=b1, vm_pu=1, va_degree=0) + + create_line_from_parameters(net, name="L1", from_bus=b3, to_bus=b4, length_km=30, r_ohm_per_km=0.049, + x_ohm_per_km=0.136, g_us_per_km=0, c_nf_per_km=142, max_i_ka=1.5) + create_line_from_parameters(net, name="L2", from_bus=b3, to_bus=b4, length_km=30, r_ohm_per_km=0.049, + x_ohm_per_km=0.136, g_us_per_km=0, c_nf_per_km=142, max_i_ka=1.5) + create_line_from_parameters(net, name="L3", from_bus=b4, to_bus=b5, length_km=100, r_ohm_per_km=0.081, + x_ohm_per_km=0.312, g_us_per_km=0, c_nf_per_km=11, max_i_ka=1.5) + create_line_from_parameters(net, name="L4", from_bus=b4, to_bus=b6, length_km=100, r_ohm_per_km=0.081, + x_ohm_per_km=0.312, g_us_per_km=0, c_nf_per_km=11, max_i_ka=1.5) + create_line_from_parameters(net, name="L5", from_bus=b5, to_bus=b7, length_km=220, r_ohm_per_km=0.081, + x_ohm_per_km=0.312, g_us_per_km=0, c_nf_per_km=11, max_i_ka=1.5) + create_line_from_parameters(net, name="L6", from_bus=b6, to_bus=b8, length_km=140, r_ohm_per_km=0.081, + x_ohm_per_km=0.312, g_us_per_km=0, c_nf_per_km=11, max_i_ka=1.5) + create_line_from_parameters(net, name="L7", from_bus=b5, to_bus=b6, length_km=180, r_ohm_per_km=0.081, + x_ohm_per_km=0.312, g_us_per_km=0, c_nf_per_km=11, max_i_ka=1.5) + create_line_from_parameters(net, name="L8", from_bus=b7, to_bus=b8, length_km=180, r_ohm_per_km=0.081, + x_ohm_per_km=0.312, g_us_per_km=0, c_nf_per_km=11, max_i_ka=1.5) + + # create_line_from_parameters(net,name="L9",from_bus=3,to_bus=4,length_km=100, r_ohm_per_km=0.312, # x_ohm_per_km=0.312,g_us_per_km=0,c_nf_per_km=11) - pp.create_transformer_from_parameters(net, name="trafo1", hv_bus=b8, lv_bus=b1, sn_mva=192, vn_hv_kv=230, - vn_lv_kv=18, vkr_percent=0, vector_group="Yy0", pfe_kw=0, vk_percent=12, - i0_percent=0) - pp.create_transformer_from_parameters(net, name="trafo2", hv_bus=b3, lv_bus=b2, sn_mva=500, vn_hv_kv=230, - vn_lv_kv=16.5, vkr_percent=0, vector_group="Yy0", pfe_kw=0, vk_percent=16, - i0_percent=0) + create_transformer_from_parameters(net, name="trafo1", hv_bus=b8, lv_bus=b1, sn_mva=192, vn_hv_kv=230, + vn_lv_kv=18, vkr_percent=0, vector_group="Yy0", pfe_kw=0, vk_percent=12, + i0_percent=0) + create_transformer_from_parameters(net, name="trafo2", hv_bus=b3, lv_bus=b2, sn_mva=500, vn_hv_kv=230, + vn_lv_kv=16.5, vkr_percent=0, vector_group="Yy0", pfe_kw=0, vk_percent=16, + i0_percent=0) - pp.create_gen(net, bus=b2, p_mw=500, vm_pu=1) - # pp.create_sgen(net,bus = 2, p_mw=500,name="WT") + create_gen(net, bus=b2, p_mw=500, vm_pu=1) + # create_sgen(net,bus = 2, p_mw=500,name="WT") # - pp.create_load(net, bus=b4, p_mw=130, q_mvar=50) - pp.create_load(net, bus=b5, p_mw=120, q_mvar=50) - pp.create_load(net, bus=b6, p_mw=80, q_mvar=25) - pp.create_load(net, bus=b7, p_mw=50, q_mvar=25) + create_load(net, bus=b4, p_mw=130, q_mvar=50) + create_load(net, bus=b5, p_mw=120, q_mvar=50) + create_load(net, bus=b6, p_mw=80, q_mvar=25) + create_load(net, bus=b7, p_mw=50, q_mvar=25) return net @pytest.mark.parametrize("vm_set_pu", [0.96, 1., 1.04]) def test_svc(vm_set_pu): - net = pp.networks.case9() + net = case9() net3 = copy.deepcopy(net) - pp.create_svc(net, bus=3, x_l_ohm=1, x_cvar_ohm=-10, set_vm_pu=vm_set_pu, thyristor_firing_angle_degree=90) + create_svc(net, bus=3, x_l_ohm=1, x_cvar_ohm=-10, set_vm_pu=vm_set_pu, thyristor_firing_angle_degree=90) net2 = copy.deepcopy(net) runpp_with_consistency_checks(net) assert 90 <= net.res_svc.at[0, "thyristor_firing_angle_degree"] <= 180 @@ -226,9 +232,9 @@ def test_svc(vm_set_pu): net.res_svc.x_ohm.at[0]) # try writing the values to a load and see if the effect is the same: - lidx = pp.create_load(net3, 3, 0, 0) + lidx = create_load(net3, 3, 0, 0) net3.load.loc[lidx, "q_mvar"] = net.res_svc.q_mvar.at[0] - pp.runpp(net3) + runpp(net3) assert np.isclose(net3.res_bus.at[3, 'vm_pu'], net.svc.at[0, 'set_vm_pu'], rtol=0, atol=1e-6) assert np.isclose(net3.res_bus.at[3, 'va_degree'], net.res_svc.at[0, 'va_degree'], rtol=0, atol=1e-6) assert np.isclose(net3.res_bus.at[3, 'q_mvar'], net.res_bus.at[3, 'q_mvar'], rtol=0, atol=1e-6) @@ -236,18 +242,18 @@ def test_svc(vm_set_pu): net3.load.at[3, "in_service"] = False baseZ = np.square(net.bus.at[3, 'vn_kv']) / net.sn_mva x_pu = net.res_svc.x_ohm.at[0] / baseZ - pp.create_shunt(net3, 3, 0) + create_shunt(net3, 3, 0) # net3.shunt.at[0, "q_mvar"] = x_pu * net.sn_mva net3.shunt.at[0, "q_mvar"] = net.res_svc.q_mvar.at[0] net3.shunt.at[0, "vn_kv"] = net.bus.at[3, 'vn_kv'] * vm_set_pu - pp.runpp(net3) + runpp(net3) assert np.isclose(net3.res_bus.at[3, 'vm_pu'], net.svc.at[0, 'set_vm_pu'], rtol=0, atol=1e-6) assert np.isclose(net3.res_bus.at[3, 'va_degree'], net.res_svc.at[0, 'va_degree'], rtol=0, atol=1e-6) assert np.isclose(net3.res_bus.at[3, 'q_mvar'], net.res_bus.at[3, 'q_mvar'], rtol=0, atol=1e-6) net2.svc.at[0, "thyristor_firing_angle_degree"] = net.res_svc.thyristor_firing_angle_degree.at[0] net2.svc.at[0, "controllable"] = False - pp.runpp(net2) + runpp(net2) assert np.isclose(net2.res_bus.at[3, 'vm_pu'], net.svc.at[0, 'set_vm_pu'], rtol=0, atol=1e-6) assert np.isclose(net2.res_bus.at[3, 'q_mvar'], net.res_bus.at[3, 'q_mvar'], rtol=0, atol=1e-6) assert np.isclose(net2.res_svc.at[0, 'vm_pu'], net.res_svc.at[0, 'vm_pu'], rtol=0, atol=1e-6) @@ -255,134 +261,134 @@ def test_svc(vm_set_pu): assert np.isclose(net2.res_svc.at[0, 'q_mvar'], net.res_svc.at[0, 'q_mvar'], rtol=0, atol=1e-6) assert np.isclose(net2.res_svc.at[0, 'x_ohm'], net.res_svc.at[0, 'x_ohm'], rtol=0, atol=1e-6) - # pp.create_svc(net, 6, 1, -10, vm_set_pu, net.res_svc.thyristor_firing_angle_degree.at[0], controllable=False) - # pp.create_svc(net, 7, 1, -10, vm_set_pu, 90, controllable=True) + # create_svc(net, 6, 1, -10, vm_set_pu, net.res_svc.thyristor_firing_angle_degree.at[0], controllable=False) + # create_svc(net, 7, 1, -10, vm_set_pu, 90, controllable=True) # runpp_with_consistency_checks(net) @pytest.mark.parametrize("vm_set_pu", [0.96, 1., 1.04]) def test_2_svcs(vm_set_pu): - net = pp.create_empty_network() - pp.create_buses(net, 3, 110) - pp.create_ext_grid(net, 0) - pp.create_line_from_parameters(net, 0, 1, 20, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 0, 2, 20, 0.0487, 0.13823, 160, 0.664) + net = create_empty_network() + create_buses(net, 3, 110) + create_ext_grid(net, 0) + create_line_from_parameters(net, 0, 1, 20, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 0, 2, 20, 0.0487, 0.13823, 160, 0.664) # both not controllable net1 = copy.deepcopy(net) - pp.create_svc(net1, bus=1, x_l_ohm=1, x_cvar_ohm=-10, set_vm_pu=vm_set_pu, thyristor_firing_angle_degree=145, - controllable=False) - pp.create_svc(net1, bus=2, x_l_ohm=1, x_cvar_ohm=-10, set_vm_pu=vm_set_pu, thyristor_firing_angle_degree=145, - controllable=False) - pp.runpp(net1) + create_svc(net1, bus=1, x_l_ohm=1, x_cvar_ohm=-10, set_vm_pu=vm_set_pu, thyristor_firing_angle_degree=145, + controllable=False) + create_svc(net1, bus=2, x_l_ohm=1, x_cvar_ohm=-10, set_vm_pu=vm_set_pu, thyristor_firing_angle_degree=145, + controllable=False) + runpp(net1) net2 = copy.deepcopy(net) - pp.create_loads(net2, [1, 2], 0, net1.res_svc.q_mvar.values) - pp.runpp(net2) + create_loads(net2, [1, 2], 0, net1.res_svc.q_mvar.values) + runpp(net2) assert_frame_equal(net1.res_bus, net2.res_bus) # first controllable net1 = copy.deepcopy(net) - pp.create_svc(net1, bus=1, x_l_ohm=1, x_cvar_ohm=-10, set_vm_pu=vm_set_pu, thyristor_firing_angle_degree=145) - pp.create_svc(net1, bus=2, x_l_ohm=1, x_cvar_ohm=-10, set_vm_pu=vm_set_pu, thyristor_firing_angle_degree=145, - controllable=False) - pp.runpp(net1) + create_svc(net1, bus=1, x_l_ohm=1, x_cvar_ohm=-10, set_vm_pu=vm_set_pu, thyristor_firing_angle_degree=145) + create_svc(net1, bus=2, x_l_ohm=1, x_cvar_ohm=-10, set_vm_pu=vm_set_pu, thyristor_firing_angle_degree=145, + controllable=False) + runpp(net1) net2 = copy.deepcopy(net) - pp.create_loads(net2, [1, 2], 0, net1.res_svc.q_mvar.values) - pp.runpp(net2) + create_loads(net2, [1, 2], 0, net1.res_svc.q_mvar.values) + runpp(net2) assert_frame_equal(net1.res_bus, net2.res_bus) # second controllable net1 = copy.deepcopy(net) - pp.create_svc(net1, bus=1, x_l_ohm=1, x_cvar_ohm=-10, set_vm_pu=vm_set_pu, thyristor_firing_angle_degree=145, - controllable=False) - pp.create_svc(net1, bus=2, x_l_ohm=1, x_cvar_ohm=-10, set_vm_pu=vm_set_pu, thyristor_firing_angle_degree=145) - pp.runpp(net1) + create_svc(net1, bus=1, x_l_ohm=1, x_cvar_ohm=-10, set_vm_pu=vm_set_pu, thyristor_firing_angle_degree=145, + controllable=False) + create_svc(net1, bus=2, x_l_ohm=1, x_cvar_ohm=-10, set_vm_pu=vm_set_pu, thyristor_firing_angle_degree=145) + runpp(net1) net2 = copy.deepcopy(net) - pp.create_loads(net2, [1, 2], 0, net1.res_svc.q_mvar.values) - pp.runpp(net2) + create_loads(net2, [1, 2], 0, net1.res_svc.q_mvar.values) + runpp(net2) assert_frame_equal(net1.res_bus, net2.res_bus) # both controllable net1 = copy.deepcopy(net) - pp.create_svc(net1, bus=1, x_l_ohm=1, x_cvar_ohm=-10, set_vm_pu=vm_set_pu, thyristor_firing_angle_degree=145) - pp.create_svc(net1, bus=2, x_l_ohm=1, x_cvar_ohm=-10, set_vm_pu=vm_set_pu, thyristor_firing_angle_degree=145) - pp.runpp(net1) + create_svc(net1, bus=1, x_l_ohm=1, x_cvar_ohm=-10, set_vm_pu=vm_set_pu, thyristor_firing_angle_degree=145) + create_svc(net1, bus=2, x_l_ohm=1, x_cvar_ohm=-10, set_vm_pu=vm_set_pu, thyristor_firing_angle_degree=145) + runpp(net1) net2 = copy.deepcopy(net) - pp.create_loads(net2, [1, 2], 0, net1.res_svc.q_mvar.values) - pp.runpp(net2) + create_loads(net2, [1, 2], 0, net1.res_svc.q_mvar.values) + runpp(net2) assert_frame_equal(net1.res_bus, net2.res_bus) # connected at ext_grid_bus - does not work - # pp.create_svc(net1, bus=0, x_l_ohm=1, x_cvar_ohm=-10, set_vm_pu=1, thyristor_firing_angle_degree=145, controllable=False) - # pp.runpp(net1) + # create_svc(net1, bus=0, x_l_ohm=1, x_cvar_ohm=-10, set_vm_pu=1, thyristor_firing_angle_degree=145, controllable=False) + # runpp(net1) def test_tcsc_simple(): - net = pp.create_empty_network() - pp.create_buses(net, 2, 110) - pp.create_ext_grid(net, 0) - # pp.create_line_from_parameters(net, 0, 1, 100, 0.0487, 0.13823, 160, 0.664) - pp.create_load(net, 1, 100, 25) - pp.create_tcsc(net, 0, 1, 1, -10, -100, 140, controllable=False) + net = create_empty_network() + create_buses(net, 2, 110) + create_ext_grid(net, 0) + # create_line_from_parameters(net, 0, 1, 100, 0.0487, 0.13823, 160, 0.664) + create_load(net, 1, 100, 25) + create_tcsc(net, 0, 1, 1, -10, -100, 140, controllable=False) runpp_with_consistency_checks(net) net_ref = copy_with_impedance(net) - pp.runpp(net_ref) + runpp(net_ref) compare_tcsc_impedance(net, net_ref, net.tcsc.index, net.impedance.index) net.tcsc.controllable = True runpp_with_consistency_checks(net) net_ref = copy_with_impedance(net) - pp.runpp(net_ref) + runpp(net_ref) compare_tcsc_impedance(net, net_ref, net.tcsc.index, net.impedance.index) def test_tcsc_simple1(): - net = pp.create_empty_network() - pp.create_buses(net, 3, 110) - pp.create_ext_grid(net, 0) - pp.create_line_from_parameters(net, 0, 1, 100, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 2, 1, 100, 0.0487, 0.13823, 160, 0.664) - pp.create_load(net, 1, 100, 25) - pp.create_tcsc(net, 0, 2, 1, -10, 6, 144, controllable=False) + net = create_empty_network() + create_buses(net, 3, 110) + create_ext_grid(net, 0) + create_line_from_parameters(net, 0, 1, 100, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 2, 1, 100, 0.0487, 0.13823, 160, 0.664) + create_load(net, 1, 100, 25) + create_tcsc(net, 0, 2, 1, -10, 6, 144, controllable=False) runpp_with_consistency_checks(net) net_ref = copy_with_impedance(net) - pp.runpp(net_ref) + runpp(net_ref) compare_tcsc_impedance(net, net_ref, net.tcsc.index, net.impedance.index) net.tcsc.controllable = True runpp_with_consistency_checks(net) net_ref = copy_with_impedance(net) - pp.runpp(net_ref) + runpp(net_ref) compare_tcsc_impedance(net, net_ref, net.tcsc.index, net.impedance.index) def test_tcsc_simple2(): - net = pp.create_empty_network() - pp.create_buses(net, 3, 110) - pp.create_ext_grid(net, 0) - # pp.create_line_from_parameters(net, 0, 1, 100, 0.0487, 0.13823, 160, 0.664) - pp.create_load(net, 1, 40, 25) - pp.create_load(net, 2, 60, 25) - pp.create_tcsc(net, 0, 1, 1, -10, -40, 140, controllable=False) - pp.create_tcsc(net, 0, 2, 1, -10, -60, 140, controllable=False) + net = create_empty_network() + create_buses(net, 3, 110) + create_ext_grid(net, 0) + # create_line_from_parameters(net, 0, 1, 100, 0.0487, 0.13823, 160, 0.664) + create_load(net, 1, 40, 25) + create_load(net, 2, 60, 25) + create_tcsc(net, 0, 1, 1, -10, -40, 140, controllable=False) + create_tcsc(net, 0, 2, 1, -10, -60, 140, controllable=False) runpp_with_consistency_checks(net) net_ref = copy_with_impedance(net) - pp.runpp(net_ref) + runpp(net_ref) compare_tcsc_impedance(net, net_ref, net.tcsc.index, net_ref.impedance.index) net.tcsc.at[0, "controllable"] = True runpp_with_consistency_checks(net) net_ref = copy_with_impedance(net) - pp.runpp(net_ref) + runpp(net_ref) compare_tcsc_impedance(net, net_ref, net.tcsc.index, net_ref.impedance.index) net.tcsc.at[1, "controllable"] = True runpp_with_consistency_checks(net) net_ref = copy_with_impedance(net) - pp.runpp(net_ref) + runpp(net_ref) compare_tcsc_impedance(net, net_ref, net.tcsc.index, net_ref.impedance.index) @@ -398,21 +404,21 @@ def test_tcsc_simple3(): # (0)-------------(1)-----------------(3)-> # |--(TCSC)--(2)------| - net = pp.create_empty_network(sn_mva=baseMVA) - pp.create_buses(net, 4, baseV) - pp.create_ext_grid(net, 0) - pp.create_line_from_parameters(net, 0, 1, 20, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 1, 3, 20, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 2, 3, 20, 0.0487, 0.13823, 160, 0.664) + net = create_empty_network(sn_mva=baseMVA) + create_buses(net, 4, baseV) + create_ext_grid(net, 0) + create_line_from_parameters(net, 0, 1, 20, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 1, 3, 20, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 2, 3, 20, 0.0487, 0.13823, 160, 0.664) - pp.create_load(net, 3, 100, 40) + create_load(net, 3, 100, 40) - pp.create_tcsc(net, 1, 2, xl, xc, 5, 170, "Test", controllable=True, min_angle_degree=90, max_angle_degree=180) + create_tcsc(net, 1, 2, xl, xc, 5, 170, "Test", controllable=True, min_angle_degree=90, max_angle_degree=180) runpp_with_consistency_checks(net, init="dc") net_ref = copy_with_impedance(net) - pp.runpp(net_ref) + runpp(net_ref) compare_tcsc_impedance(net, net_ref, net.tcsc.index, net_ref.impedance.index) # todo: @@ -432,23 +438,23 @@ def test_tcsc_simple3_slack(): # (0)-------------(1)-----------------(3)-> # |-----(TCSC)--(2)-------------------| - net = pp.create_empty_network(sn_mva=baseMVA) - pp.create_buses(net, 4, baseV) - pp.create_ext_grid(net, 0) - pp.create_line_from_parameters(net, 0, 1, 20, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 1, 3, 20, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 2, 3, 20, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 1, 2, 20, 0.0487, 0.13823, 160, 0.664) + net = create_empty_network(sn_mva=baseMVA) + create_buses(net, 4, baseV) + create_ext_grid(net, 0) + create_line_from_parameters(net, 0, 1, 20, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 1, 3, 20, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 2, 3, 20, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 1, 2, 20, 0.0487, 0.13823, 160, 0.664) - pp.create_load(net, 2, 100, 40) + create_load(net, 2, 100, 40) - # pp.plotting.simple_plot(net) - pp.create_tcsc(net, 2,0, xl, xc, 5, 170, "Test", controllable=True, min_angle_degree=90, max_angle_degree=180) + # plotting.simple_plot(net) + create_tcsc(net, 2, 0, xl, xc, 5, 170, "Test", controllable=True, min_angle_degree=90, max_angle_degree=180) runpp_with_consistency_checks(net, init="dc") net_ref = copy_with_impedance(net) - pp.runpp(net_ref) + runpp(net_ref) compare_tcsc_impedance(net, net_ref, net.tcsc.index, net_ref.impedance.index) # todo: @@ -468,24 +474,24 @@ def test_compare_to_impedance(): # (0)-------------(1)-----------------(3)-> # |--(TCSC)--(2)------| - net = pp.create_empty_network(sn_mva=baseMVA) - pp.create_buses(net, 4, baseV) - pp.create_ext_grid(net, 0) - pp.create_line_from_parameters(net, 0, 1, 20, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 1, 3, 20, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 2, 3, 20, 0.0487, 0.13823, 160, 0.664) + net = create_empty_network(sn_mva=baseMVA) + create_buses(net, 4, baseV) + create_ext_grid(net, 0) + create_line_from_parameters(net, 0, 1, 20, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 1, 3, 20, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 2, 3, 20, 0.0487, 0.13823, 160, 0.664) - pp.create_load(net, 3, 100, 40) + create_load(net, 3, 100, 40) net_ref = copy.deepcopy(net) - pp.create_tcsc(net, 1, 2, xl, xc, -20, 170, "Test", controllable=True, min_angle_degree=90, max_angle_degree=180) + create_tcsc(net, 1, 2, xl, xc, -20, 170, "Test", controllable=True, min_angle_degree=90, max_angle_degree=180) runpp_with_consistency_checks(net, init="dc") - pp.create_impedance(net_ref, 1, 2, 0, net.res_tcsc.x_ohm.at[0] / baseZ, baseMVA) + create_impedance(net_ref, 1, 2, 0, net.res_tcsc.x_ohm.at[0] / baseZ, baseMVA) - pp.runpp(net_ref) + runpp(net_ref) # compare when controllable compare_tcsc_impedance(net, net_ref, 0, 0) @@ -515,17 +521,17 @@ def test_tcsc_case_study(): # plot_z(baseZ, xl, xc) f = net.bus.loc[net.bus.name == "B4"].index.values[0] t = net.bus.loc[net.bus.name == "B6"].index.values[0] - aux = pp.create_bus(net, 230, "aux") + aux = create_bus(net, 230, "aux") l = net.line.loc[(net.line.from_bus == f) & (net.line.to_bus == t)].index.values[0] net.line.loc[l, "from_bus"] = aux net_ref = copy.deepcopy(net) - pp.create_tcsc(net, f, aux, xl, xc, -100, 100, controllable=True) - pp.runpp(net, init="dc") + create_tcsc(net, f, aux, xl, xc, -100, 100, controllable=True) + runpp(net, init="dc") - pp.create_impedance(net_ref, f, aux, 0, net.res_tcsc.at[0, "x_ohm"] / baseZ, baseMVA) - pp.runpp(net_ref) + create_impedance(net_ref, f, aux, 0, net.res_tcsc.at[0, "x_ohm"] / baseZ, baseMVA) + runpp(net_ref) compare_tcsc_impedance(net, net_ref, 0, 0) assert np.allclose(net._ppc["internal"]["Ybus"].toarray(), @@ -544,20 +550,20 @@ def test_multiple_facts(): xl = 0.2 xc = -15 - net = pp.create_empty_network(sn_mva=baseMVA) - pp.create_buses(net, 7, baseV) - pp.create_ext_grid(net, 0) - pp.create_line_from_parameters(net, 0, 1, 20, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 1, 3, 20, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 2, 3, 20, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 4, 3, 20, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 1, 5, 20, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 3, 6, 20, 0.0487, 0.13823, 160, 0.664) + net = create_empty_network(sn_mva=baseMVA) + create_buses(net, 7, baseV) + create_ext_grid(net, 0) + create_line_from_parameters(net, 0, 1, 20, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 1, 3, 20, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 2, 3, 20, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 4, 3, 20, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 1, 5, 20, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 3, 6, 20, 0.0487, 0.13823, 160, 0.664) - pp.create_load(net, 3, 100, 40) + create_load(net, 3, 100, 40) - pp.create_tcsc(net, 5, 2, xl, xc, -10, 140, "Test", controllable=True, min_angle_degree=90, max_angle_degree=180) - pp.create_tcsc(net, 1, 4, xl, xc, -5, 140, "Test", controllable=True, min_angle_degree=90, max_angle_degree=180) + create_tcsc(net, 5, 2, xl, xc, -10, 140, "Test", controllable=True, min_angle_degree=90, max_angle_degree=180) + create_tcsc(net, 1, 4, xl, xc, -5, 140, "Test", controllable=True, min_angle_degree=90, max_angle_degree=180) runpp_with_consistency_checks(net) @@ -567,17 +573,17 @@ def test_multiple_facts(): net.tcsc.loc[1, "controllable"] = False runpp_with_consistency_checks(net) net_ref = copy_with_impedance(net) - pp.runpp(net_ref) + runpp(net_ref) compare_tcsc_impedance(net, net_ref, net.tcsc.index, net_ref.impedance.query("name=='tcsc'").index) - pp.create_svc(net, 3, 1, -10, 1.01, 90) + create_svc(net, 3, 1, -10, 1.01, 90) runpp_with_consistency_checks(net) net.svc.at[0, "thyristor_firing_angle_degree"] = net.res_svc.loc[0, "thyristor_firing_angle_degree"] net.svc.controllable = False runpp_with_consistency_checks(net) net_ref = copy_with_impedance(net) - pp.runpp(net_ref) + runpp(net_ref) compare_tcsc_impedance(net, net_ref, net.tcsc.index, net_ref.impedance.query("name=='tcsc'").index) compare_tcsc_impedance(net, net_ref, net.svc.index, net_ref.impedance.query("name=='svc'").index) @@ -594,27 +600,27 @@ def _many_tcsc_test_net(): xl = 0.2 xc = -15 - net = pp.create_empty_network(sn_mva=baseMVA) - pp.create_buses(net, 7, baseV) - pp.create_ext_grid(net, 0) - pp.create_line_from_parameters(net, 0, 1, 20, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 1, 3, 20, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 2, 3, 20, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 4, 3, 20, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 1, 5, 20, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 3, 6, 20, 0.0487, 0.13823, 160, 0.664) + net = create_empty_network(sn_mva=baseMVA) + create_buses(net, 7, baseV) + create_ext_grid(net, 0) + create_line_from_parameters(net, 0, 1, 20, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 1, 3, 20, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 2, 3, 20, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 4, 3, 20, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 1, 5, 20, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 3, 6, 20, 0.0487, 0.13823, 160, 0.664) - pp.create_load(net, 3, 100, 40) + create_load(net, 3, 100, 40) - pp.create_tcsc(net, 5, 2, xl, xc, -10, 160, "Test", controllable=True, min_angle_degree=90, - max_angle_degree=180) - pp.create_tcsc(net, 1, 4, xl, xc, -5, 160, "Test", controllable=True, min_angle_degree=90, - max_angle_degree=180) + create_tcsc(net, 5, 2, xl, xc, -10, 160, "Test", controllable=True, min_angle_degree=90, + max_angle_degree=180) + create_tcsc(net, 1, 4, xl, xc, -5, 160, "Test", controllable=True, min_angle_degree=90, + max_angle_degree=180) - pp.create_svc(net, 3, 1, -10, 1.01, 144) - pp.create_svc(net, 2, 1, -10, 1., 144) + create_svc(net, 3, 1, -10, 1.01, 144) + create_svc(net, 2, 1, -10, 1., 144) - pp.create_ssc(net, 6, 0, 5, 1, controllable=True, in_service=True) + create_ssc(net, 6, 0, 5, 1, controllable=True, in_service=True) return net @@ -629,7 +635,7 @@ def test_multiple_facts_combinations(svc_status, tcsc_status, ssc_status): net.ssc.in_service = ssc_status runpp_with_consistency_checks(net) net_ref = copy_with_impedance(net) - pp.runpp(net_ref) + runpp(net_ref) compare_tcsc_impedance(net, net_ref, net.tcsc.index, net_ref.impedance.query("name=='tcsc'").index) compare_ssc_impedance_gen(net, net_ref) @@ -638,12 +644,12 @@ def test_multiple_facts_combinations(svc_status, tcsc_status, ssc_status): net.svc.in_service = svc_status net.tcsc.in_service = tcsc_status - # pp.create_ssc(net, 6, 0, 5, 1,controllable=True,in_service=True) + # create_ssc(net, 6, 0, 5, 1,controllable=True,in_service=True) runpp_with_consistency_checks(net) net_ref = copy_with_impedance(net) - pp.runpp(net_ref) + runpp(net_ref) compare_tcsc_impedance(net, net_ref, net.tcsc.index, net_ref.impedance.query("name=='tcsc'").index) compare_ssc_impedance_gen(net, net_ref) @@ -658,36 +664,36 @@ def test_svc_tcsc_case_study(): # plot_z(baseZ, xl, xc) f = net.bus.loc[net.bus.name == "B4"].index.values[0] t = net.bus.loc[net.bus.name == "B6"].index.values[0] - aux = pp.create_bus(net, 230, "aux") + aux = create_bus(net, 230, "aux") l = net.line.loc[(net.line.from_bus == f) & (net.line.to_bus == t)].index.values[0] net.line.loc[l, "from_bus"] = aux - pp.create_tcsc(net, f, aux, xl, xc, -100, 100, controllable=True) + create_tcsc(net, f, aux, xl, xc, -100, 100, controllable=True) - pp.create_svc(net, net.bus.loc[net.bus.name == "B7"].index.values[0], 1, -10, 1., 90) + create_svc(net, net.bus.loc[net.bus.name == "B7"].index.values[0], 1, -10, 1., 90) - pp.runpp(net, init="dc") + runpp(net, init="dc") net_ref = copy_with_impedance(net) - pp.runpp(net_ref) + runpp(net_ref) compare_tcsc_impedance(net, net_ref, net.tcsc.index, net_ref.impedance.index) net.gen.slack_weight = 1 - pp.runpp(net, distributed_slack=True, init="dc") + runpp(net, distributed_slack=True, init="dc") net_ref = copy_with_impedance(net) - pp.runpp(net_ref, distributed_slack=True) + runpp(net_ref, distributed_slack=True) compare_tcsc_impedance(net, net_ref, net.tcsc.index, net_ref.impedance.index) # # def test_tcsc_firing_angle_formula(): -# net = pp.create_empty_network() -# pp.create_buses(net, 2, 110) -# pp.create_ext_grid(net, 0) -# pp.create_line_from_parameters(net, 0, 1, 100, 0.0487, 0.13823, 160, 0.664) -# pp.create_impedance(net, 0, 1, 0, 0.001, 1) -# #pp.create_line_from_parameters(net, 1, 2, 100, 0.0487, 0.13823, 160, 0.664) -# pp.create_load(net, 1, 100, 25) +# net = create_empty_network() +# create_buses(net, 2, 110) +# create_ext_grid(net, 0) +# create_line_from_parameters(net, 0, 1, 100, 0.0487, 0.13823, 160, 0.664) +# create_impedance(net, 0, 1, 0, 0.001, 1) +# #create_line_from_parameters(net, 1, 2, 100, 0.0487, 0.13823, 160, 0.664) +# create_load(net, 1, 100, 25) # # z_base_ohm = np.square(110) / 1 # #y_pu = calc_y_svc_pu(np.deg2rad(134.438395), 0.5 / z_base_ohm, -2 / z_base_ohm) @@ -703,12 +709,12 @@ def test_svc_tcsc_case_study(): # # def test_tcsc_firing_angle_formula(): -# net = pp.create_empty_network() -# pp.create_buses(net, 2, 110) -# pp.create_ext_grid(net, 0) -# pp.create_line_from_parameters(net, 0, 1, 100, 0.0487, 0.13823, 160, 0.664) -# pp.create_line_from_parameters(net, 0, 1, 1, 0, 0.01, 0, 0.664) -# pp.create_load(net, 1, 100, 25) +# net = create_empty_network() +# create_buses(net, 2, 110) +# create_ext_grid(net, 0) +# create_line_from_parameters(net, 0, 1, 100, 0.0487, 0.13823, 160, 0.664) +# create_line_from_parameters(net, 0, 1, 1, 0, 0.01, 0, 0.664) +# create_load(net, 1, 100, 25) # # z_base_ohm = np.square(110) / 1 # #y_pu = calc_y_svc_pu(np.deg2rad(134.438395), 0.5 / z_base_ohm, -2 / z_base_ohm) @@ -718,16 +724,16 @@ def test_svc_tcsc_case_study(): # # net.impedance.rft_pu # #net.line.loc[1, "x_ohm_per_km"] = (1 / y_pu) * z_base_ohm # net.line.loc[1, "x_ohm_per_km"] = -18.9 -# pp.runpp(net, max_iteration=100) +# runpp(net, max_iteration=100) # print(net.res_line) # # # def test_tcsc_firing_angle_formula(): -# net = pp.create_empty_network() -# pp.create_buses(net, 2, 110) -# pp.create_ext_grid(net, 0) -# pp.create_line_from_parameters(net, 0, 1, 100, 0.0487, 0.13823, 160, 0.664) -# pp.create_load(net, 1, 100, 25) +# net = create_empty_network() +# create_buses(net, 2, 110) +# create_ext_grid(net, 0) +# create_line_from_parameters(net, 0, 1, 100, 0.0487, 0.13823, 160, 0.664) +# create_load(net, 1, 100, 25) # # z_base_ohm = np.square(110) / 1 # #y_pu = calc_y_svc_pu(np.deg2rad(134.438395), 0.5 / z_base_ohm, -2 / z_base_ohm) @@ -737,38 +743,38 @@ def test_svc_tcsc_case_study(): # print((1/y_pu) * z_base_ohm) # print(xtcsc(np.deg2rad(141), 1, -10) / z_base_ohm) # # net.impedance.rft_pu -# pp.create_shunt(net, 1, -y_pu, y_pu) +# create_shunt(net, 1, -y_pu, y_pu) # runpp_with_consistency_checks(net) # print(net.res_line.loc[0]) def test_tcsc_simple5(): - net = pp.create_empty_network(sn_mva=100) - pp.create_buses(net, 4, 110) - pp.create_ext_grid(net, 0) - pp.create_line_from_parameters(net, 0, 1, 20, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 1, 2, 20, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 1, 3, 20, 0.0487, 0.13823, 160, 0.664) - pp.create_load(net, 3, 100, 25) + net = create_empty_network(sn_mva=100) + create_buses(net, 4, 110) + create_ext_grid(net, 0) + create_line_from_parameters(net, 0, 1, 20, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 1, 2, 20, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 1, 3, 20, 0.0487, 0.13823, 160, 0.664) + create_load(net, 3, 100, 25) - pp.create_tcsc(net, 2, 3, 1, -10, -20, 90) + create_tcsc(net, 2, 3, 1, -10, -20, 90) runpp_with_consistency_checks(net) net_ref = copy_with_impedance(net) - pp.runpp(net_ref) + runpp(net_ref) compare_tcsc_impedance(net, net_ref, 0, 0) def test_ssc_simple(): - net = pp.create_empty_network() - pp.create_buses(net, 2, 110) - pp.create_ext_grid(net, 0) - pp.create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_load(net, 1, 100, 25) - pp.create_ssc(net, 1, 0, 5, 1) + net = create_empty_network() + create_buses(net, 2, 110) + create_ext_grid(net, 0) + create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) + create_load(net, 1, 100, 25) + create_ssc(net, 1, 0, 5, 1) runpp_with_consistency_checks(net) net_ref = copy_with_impedance(net) - pp.runpp(net_ref) + runpp(net_ref) ### compare (ssc) to bus 1(net) @@ -786,14 +792,14 @@ def test_ssc_simple(): def test_ssc_minimal(): - net = pp.create_empty_network() - pp.create_bus(net, 110) - pp.create_ext_grid(net, 0) - pp.create_ssc(net, 0, 0, 5, 1) + net = create_empty_network() + create_bus(net, 110) + create_ext_grid(net, 0) + create_ssc(net, 0, 0, 5, 1) runpp_with_consistency_checks(net) net_ref = copy_with_impedance(net) - pp.runpp(net_ref) + runpp(net_ref) ### compare (ssc) to bus 1(net) @@ -810,24 +816,24 @@ def test_ssc_minimal(): def test_ssc_controllable(): - net = pp.create_empty_network() - pp.create_buses(net, 3, 110) - pp.create_ext_grid(net, 0) - pp.create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 0, 2, 30, 0.0487, 0.13823, 160, 0.664) + net = create_empty_network() + create_buses(net, 3, 110) + create_ext_grid(net, 0) + create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 0, 2, 30, 0.0487, 0.13823, 160, 0.664) z_base = np.square(110) / net.sn_mva x = 5 # both not controllable net1 = copy.deepcopy(net) - pp.create_ssc(net1, 1, 0, x, 1, controllable=False) - pp.create_ssc(net1, 2, 0, x, 1) + create_ssc(net1, 1, 0, x, 1, controllable=False) + create_ssc(net1, 2, 0, x, 1) runpp_with_consistency_checks(net1) assert np.isclose(net1.res_ssc.vm_internal_pu.at[0], 1, rtol=0, atol=1e-6) assert np.isclose(net1.res_ssc.vm_pu.at[1], 1, rtol=0, atol=1e-6) net2 = copy.deepcopy(net) - pp.create_ssc(net2, 1, 0, x, 1, controllable=False, vm_internal_pu=1.02, va_internal_degree=150) + create_ssc(net2, 1, 0, x, 1, controllable=False, vm_internal_pu=1.02, va_internal_degree=150) runpp_with_consistency_checks(net2) assert np.isclose(net2.res_ssc.vm_internal_pu, 1.02, rtol=0, atol=1e-6) @@ -835,387 +841,387 @@ def test_ssc_controllable(): def test_ssc_case_study(): net = facts_case_study_grid() - pp.create_ssc(net, bus=6, r_ohm=0, x_ohm=5, set_vm_pu=1, controllable=True) - # pp.create_svc(net, 6, 1, -10, 1., 90,controllable=True) + create_ssc(net, bus=6, r_ohm=0, x_ohm=5, set_vm_pu=1, controllable=True) + # create_svc(net, 6, 1, -10, 1., 90,controllable=True) # net.res_ssc.q_mvar = -9.139709 runpp_with_consistency_checks(net) def test_2_sscs(): - net = pp.create_empty_network() - pp.create_buses(net, 3, 110) - pp.create_ext_grid(net, 0) - pp.create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 0, 2, 30, 0.0487, 0.13823, 160, 0.664) + net = create_empty_network() + create_buses(net, 3, 110) + create_ext_grid(net, 0) + create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 0, 2, 30, 0.0487, 0.13823, 160, 0.664) z_base = np.square(110) / net.sn_mva x = 5 # both not controllable net1 = copy.deepcopy(net) - pp.create_ssc(net1, 1, 0, x, 1, controllable=True) - pp.create_ssc(net1, 2, 0, x, 1, controllable=True) + create_ssc(net1, 1, 0, x, 1, controllable=True) + create_ssc(net1, 2, 0, x, 1, controllable=True) runpp_with_consistency_checks(net1) net2 = copy_with_impedance(net1) - pp.runpp(net2) + runpp(net2) compare_ssc_impedance_gen(net1, net2) # first controllable net1 = copy.deepcopy(net) - pp.create_ssc(net1, 1, 0, x, 1, in_service=False, controllable=False) - pp.create_ssc(net1, 2, 0, x, 1, in_service=False, controllable=False) - pp.runpp(net1) + create_ssc(net1, 1, 0, x, 1, in_service=False, controllable=False) + create_ssc(net1, 2, 0, x, 1, in_service=False, controllable=False) + runpp(net1) net2 = copy_with_impedance(net1) - pp.runpp(net2) + runpp(net2) compare_ssc_impedance_gen(net1, net2) return # todo: # # second controllable # net1 = copy.deepcopy(net) - # pp.create_ssc(net1, 1, 0, 121/z_base, 1, controllable=False) - # pp.create_ssc(net1, 2, 0, 121/z_base, 1, controllable=True) + # create_ssc(net1, 1, 0, 121/z_base, 1, controllable=False) + # create_ssc(net1, 2, 0, 121/z_base, 1, controllable=True) # - # pp.runpp(net1) + # runpp(net1) # net2 = copy.deepcopy(net) - # pp.create_load(net2, [1, 2], 100, 25) - # pp.runpp(net2) + # create_load(net2, [1, 2], 100, 25) + # runpp(net2) # assert_frame_equal(net1.res_bus, net2.res_bus) # # # both controllable # net1 = copy.deepcopy(net) - # pp.create_ssc(net1, 1, 0, 121/z_base, 1, controllable=True) - # pp.create_ssc(net1, 2, 0, 121/z_base, 1, controllable=True) - # pp.runpp(net1) + # create_ssc(net1, 1, 0, 121/z_base, 1, controllable=True) + # create_ssc(net1, 2, 0, 121/z_base, 1, controllable=True) + # runpp(net1) # net2 = copy.deepcopy(net) - # pp.create_load(net2, [1, 2], 100, 25) - # pp.runpp(net2) + # create_load(net2, [1, 2], 100, 25) + # runpp(net2) # assert_frame_equal(net1.res_bus, net2.res_bus) def test_vsc_hvdc(): - net = pp.create_empty_network() + net = create_empty_network() # AC part - pp.create_buses(net, 3, 110) - pp.create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 0, 2, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_ext_grid(net, 0) - pp.create_load(net, 2, 10, 5) + create_buses(net, 3, 110) + create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 0, 2, 30, 0.0487, 0.13823, 160, 0.664) + create_ext_grid(net, 0) + create_load(net, 2, 10, 5) # DC part - pp.create_bus_dc(net, 110, 'A') - pp.create_bus_dc(net, 110, 'B') + create_bus_dc(net, 110, 'A') + create_bus_dc(net, 110, 'B') - pp.create_line_dc_from_parameters(net, 0, 1, 100, 0.1, 1) + create_line_dc_from_parameters(net, 0, 1, 100, 0.1, 1) - pp.create_vsc(net, 1, 0, 0.1, 5, 0.15, - control_mode_ac="vm_pu", control_value_ac=1., - control_mode_dc="vm_pu", control_value_dc=1.02) - pp.create_vsc(net, 2, 1, 0.1, 5, 0.15, - control_mode_ac="vm_pu", control_value_ac=1., - control_mode_dc="p_mw", control_value_dc=5) + create_vsc(net, 1, 0, 0.1, 5, 0.15, + control_mode_ac="vm_pu", control_value_ac=1., + control_mode_dc="vm_pu", control_value_dc=1.02) + create_vsc(net, 2, 1, 0.1, 5, 0.15, + control_mode_ac="vm_pu", control_value_ac=1., + control_mode_dc="p_mw", control_value_dc=5) - pp.runpp(net) + runpp(net) runpp_with_consistency_checks(net) def test_vsc_hvdc_control_q(): - net = pp.create_empty_network() + net = create_empty_network() # AC part - pp.create_buses(net, 3, 110) - pp.create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 0, 2, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_ext_grid(net, 0) - pp.create_load(net, 2, 10, 5) + create_buses(net, 3, 110) + create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 0, 2, 30, 0.0487, 0.13823, 160, 0.664) + create_ext_grid(net, 0) + create_load(net, 2, 10, 5) # DC part - pp.create_bus_dc(net, 110, 'A') - pp.create_bus_dc(net, 110, 'B') + create_bus_dc(net, 110, 'A') + create_bus_dc(net, 110, 'B') - pp.create_line_dc_from_parameters(net, 0, 1, 100, 0.1, 1) + create_line_dc_from_parameters(net, 0, 1, 100, 0.1, 1) - pp.create_vsc(net, 1, 0, 0.1, 5, 0.15, - control_mode_ac="q_mvar", control_value_ac=7.5, - control_mode_dc="vm_pu", control_value_dc=1.02) - pp.create_vsc(net, 2, 1, 0.1, 5, 0.15, - control_mode_ac="vm_pu", control_value_ac=1., - control_mode_dc="p_mw", control_value_dc=5) + create_vsc(net, 1, 0, 0.1, 5, 0.15, + control_mode_ac="q_mvar", control_value_ac=7.5, + control_mode_dc="vm_pu", control_value_dc=1.02) + create_vsc(net, 2, 1, 0.1, 5, 0.15, + control_mode_ac="vm_pu", control_value_ac=1., + control_mode_dc="p_mw", control_value_dc=5) runpp_with_consistency_checks(net) def test_vsc_multiterminal_hvdc(): - net = pp.create_empty_network() + net = create_empty_network() # AC part - pp.create_buses(net, 5, 110, geodata=[(0, 50), (50, 100), (200, 100), (50, 0), (200, 0)]) - pp.create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 1, 2, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 0, 3, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 1, 3, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 3, 4, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_ext_grid(net, 0) - pp.create_load(net, 2, 10, 5) + create_buses(net, 5, 110, geodata=[(0, 50), (50, 100), (200, 100), (50, 0), (200, 0)]) + create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 1, 2, 30, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 0, 3, 30, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 1, 3, 30, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 3, 4, 30, 0.0487, 0.13823, 160, 0.664) + create_ext_grid(net, 0) + create_load(net, 2, 10, 5) # DC part - pp.create_bus_dc(net, 320, 'A', geodata=(50, 100)) - pp.create_bus_dc(net, 320, 'B', geodata=(200, 50)) - pp.create_bus_dc(net, 320, 'C', geodata=(200, 100)) - pp.create_bus_dc(net, 320, 'D', geodata=(200, 0)) - pp.create_bus_dc(net, 320, 'E', geodata=(50, 0)) - - pp.create_line_dc_from_parameters(net, 0, 1, 100, 0.1, 1) - pp.create_line_dc_from_parameters(net, 1, 2, 100, 0.1, 1) - pp.create_line_dc_from_parameters(net, 1, 3, 100, 0.1, 1) - pp.create_line_dc_from_parameters(net, 1, 4, 100, 0.1, 1) - - # pp.create_vsc(net, 1, 0, 0.1, 5, control_mode_dc="vm_pu", control_value_dc=1.02) - # pp.create_vsc(net, 2, 2, 0.1, 5, control_value_dc=5) - # pp.create_vsc(net, 4, 3, 0.1, 5, control_value_dc=15) - # pp.create_vsc(net, 3, 4, 0.1, 5, control_mode_dc="vm_pu", control_value_dc=1.02) - - pp.create_vsc(net, 1, 0, 0.1, 5, 0.15, - control_mode_ac="q_mvar", control_value_ac=3, - control_mode_dc="vm_pu", control_value_dc=1) - pp.create_vsc(net, 2, 2, 0.1, 5, 0.15, - control_mode_ac="q_mvar", control_value_ac=10, - control_mode_dc="p_mw", control_value_dc=5) - pp.create_vsc(net, 4, 3, 0.1, 5, 0.15, - control_mode_ac="vm_pu", control_value_ac=1.05, - control_mode_dc="p_mw", control_value_dc=15) - pp.create_vsc(net, 3, 4, 0.1, 5, 0.15, - control_mode_ac="vm_pu", control_value_ac=1.03, - control_mode_dc="vm_pu", control_value_dc=1.02) + create_bus_dc(net, 320, 'A', geodata=(50, 100)) + create_bus_dc(net, 320, 'B', geodata=(200, 50)) + create_bus_dc(net, 320, 'C', geodata=(200, 100)) + create_bus_dc(net, 320, 'D', geodata=(200, 0)) + create_bus_dc(net, 320, 'E', geodata=(50, 0)) + + create_line_dc_from_parameters(net, 0, 1, 100, 0.1, 1) + create_line_dc_from_parameters(net, 1, 2, 100, 0.1, 1) + create_line_dc_from_parameters(net, 1, 3, 100, 0.1, 1) + create_line_dc_from_parameters(net, 1, 4, 100, 0.1, 1) + + # create_vsc(net, 1, 0, 0.1, 5, control_mode_dc="vm_pu", control_value_dc=1.02) + # create_vsc(net, 2, 2, 0.1, 5, control_value_dc=5) + # create_vsc(net, 4, 3, 0.1, 5, control_value_dc=15) + # create_vsc(net, 3, 4, 0.1, 5, control_mode_dc="vm_pu", control_value_dc=1.02) + + create_vsc(net, 1, 0, 0.1, 5, 0.15, + control_mode_ac="q_mvar", control_value_ac=3, + control_mode_dc="vm_pu", control_value_dc=1) + create_vsc(net, 2, 2, 0.1, 5, 0.15, + control_mode_ac="q_mvar", control_value_ac=10, + control_mode_dc="p_mw", control_value_dc=5) + create_vsc(net, 4, 3, 0.1, 5, 0.15, + control_mode_ac="vm_pu", control_value_ac=1.05, + control_mode_dc="p_mw", control_value_dc=15) + create_vsc(net, 3, 4, 0.1, 5, 0.15, + control_mode_ac="vm_pu", control_value_ac=1.03, + control_mode_dc="vm_pu", control_value_dc=1.02) runpp_with_consistency_checks(net) def test_line_dc_bus_dc_structures(): - net = pp.create_empty_network() + net = create_empty_network() # AC part - pp.create_buses(net, 3, 110) - pp.create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 0, 2, 30, 0.0487, 0.13823, 160, 0.664) + create_buses(net, 3, 110) + create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 0, 2, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_ext_grid(net, 0) - pp.create_load(net, 2, 10, 5) + create_ext_grid(net, 0) + create_load(net, 2, 10, 5) - pp.runpp(net) + runpp(net) # DC part ## bus structure 1 - # pp.create_bus_dc(net, 110, 'A') - # pp.create_bus_dc(net, 110, 'B') + # create_bus_dc(net, 110, 'A') + # create_bus_dc(net, 110, 'B') ## bus structure 2 - pp.create_buses_dc(net, 2, 110) + create_buses_dc(net, 2, 110) ## line structure 1 - # pp.create_line_dc_from_parameters(net, 0, 1, 100, 0.1, 1) + # create_line_dc_from_parameters(net, 0, 1, 100, 0.1, 1) ## line structure 2 - pp.create_line_dc(net, 0, 1, 100, std_type="2400-CU") + create_line_dc(net, 0, 1, 100, std_type="2400-CU") - pp.create_vsc(net, 1, 0, 0.1, 5, 0.15, - control_mode_ac="vm_pu", control_value_ac=1., - control_mode_dc="vm_pu", control_value_dc=1.02) - pp.create_vsc(net, 2, 1, 0.1, 5, 0.15, - control_mode_ac="vm_pu", control_value_ac=1., - control_mode_dc="p_mw", control_value_dc=5) + create_vsc(net, 1, 0, 0.1, 5, 0.15, + control_mode_ac="vm_pu", control_value_ac=1., + control_mode_dc="vm_pu", control_value_dc=1.02) + create_vsc(net, 2, 1, 0.1, 5, 0.15, + control_mode_ac="vm_pu", control_value_ac=1., + control_mode_dc="p_mw", control_value_dc=5) runpp_with_consistency_checks(net) def test_line_dc_bus_dc_structures2(): - net = pp.create_empty_network() + net = create_empty_network() # AC part - pp.create_buses(net, 5, 110, geodata=[(0, 50), (50, 100), (200, 100), (50, 0), (200, 0)]) - pp.create_lines_from_parameters(net, [0, 1, 0, 1, 3], [1, 2, 3, 3, 4], 30, 0.0487, 0.13823, 160, 0.664) + create_buses(net, 5, 110, geodata=[(0, 50), (50, 100), (200, 100), (50, 0), (200, 0)]) + create_lines_from_parameters(net, [0, 1, 0, 1, 3], [1, 2, 3, 3, 4], 30, 0.0487, 0.13823, 160, 0.664) - pp.create_ext_grid(net, 0) - pp.create_load(net, 2, 10, 5) + create_ext_grid(net, 0) + create_load(net, 2, 10, 5) # DC part - pp.create_bus_dc(net, 320, 'A', geodata=(50, 100)) - pp.create_bus_dc(net, 320, 'B', geodata=(200, 50)) - pp.create_bus_dc(net, 320, 'C', geodata=(200, 100)) - pp.create_bus_dc(net, 320, 'D', geodata=(200, 0)) - pp.create_bus_dc(net, 320, 'E', geodata=(50, 0)) + create_bus_dc(net, 320, 'A', geodata=(50, 100)) + create_bus_dc(net, 320, 'B', geodata=(200, 50)) + create_bus_dc(net, 320, 'C', geodata=(200, 100)) + create_bus_dc(net, 320, 'D', geodata=(200, 0)) + create_bus_dc(net, 320, 'E', geodata=(50, 0)) ## line structure 3 - # pp.create_lines_dc_from_parameters(net,[0,1,1,1],[1,2,3,4],100,0.01,1) - # pp.create_lines_from_parameters() + # create_lines_dc_from_parameters(net,[0,1,1,1],[1,2,3,4],100,0.01,1) + # create_lines_from_parameters() ## line structure 4 - pp.create_lines_dc(net, [0, 1, 1, 1], [1, 2, 3, 4], 100, std_type="2400-CU") + create_lines_dc(net, [0, 1, 1, 1], [1, 2, 3, 4], 100, std_type="2400-CU") - pp.create_vsc(net, 1, 0, 0.1, 5, 0.15, - control_mode_ac="vm_pu", control_value_ac=1., - control_mode_dc="vm_pu", control_value_dc=1.02) - pp.create_vsc(net, 2, 2, 0.1, 5, 0.15, - control_mode_ac="vm_pu", control_value_ac=1., - control_mode_dc="p_mw", control_value_dc=5) - pp.create_vsc(net, 4, 3, 0.1, 5, 0.15, - control_mode_ac="vm_pu", control_value_ac=1., - control_mode_dc="p_mw", control_value_dc=15) - pp.create_vsc(net, 3, 4, 0.1, 5, 0.15, - control_mode_ac="vm_pu", control_value_ac=1., - control_mode_dc="vm_pu", control_value_dc=1.02) + create_vsc(net, 1, 0, 0.1, 5, 0.15, + control_mode_ac="vm_pu", control_value_ac=1., + control_mode_dc="vm_pu", control_value_dc=1.02) + create_vsc(net, 2, 2, 0.1, 5, 0.15, + control_mode_ac="vm_pu", control_value_ac=1., + control_mode_dc="p_mw", control_value_dc=5) + create_vsc(net, 4, 3, 0.1, 5, 0.15, + control_mode_ac="vm_pu", control_value_ac=1., + control_mode_dc="p_mw", control_value_dc=15) + create_vsc(net, 3, 4, 0.1, 5, 0.15, + control_mode_ac="vm_pu", control_value_ac=1., + control_mode_dc="vm_pu", control_value_dc=1.02) runpp_with_consistency_checks(net) def test_vsc_hvdc_structure1(): - net = pp.create_empty_network() + net = create_empty_network() # AC part - pp.create_buses(net, 3, 110) - pp.create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 1, 2, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_ext_grid(net, 0) - pp.create_load(net, 2, 10, 5) + create_buses(net, 3, 110) + create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 1, 2, 30, 0.0487, 0.13823, 160, 0.664) + create_ext_grid(net, 0) + create_load(net, 2, 10, 5) # DC part - pp.create_bus_dc(net, 110, 'A') - pp.create_bus_dc(net, 110, 'B') + create_bus_dc(net, 110, 'A') + create_bus_dc(net, 110, 'B') - pp.create_line_dc(net, 0, 1, 100, std_type="2400-CU") + create_line_dc(net, 0, 1, 100, std_type="2400-CU") - pp.create_vsc(net, 2, 1, 0.1, 5, 0.15, - control_mode_ac="vm_pu", control_value_ac=1, - control_mode_dc="p_mw", control_value_dc=5) - pp.create_vsc(net, 1, 0, 0.1, 5, 0.15, - control_mode_ac="vm_pu", control_value_ac=1, - control_mode_dc="vm_pu", control_value_dc=1.02) + create_vsc(net, 2, 1, 0.1, 5, 0.15, + control_mode_ac="vm_pu", control_value_ac=1, + control_mode_dc="p_mw", control_value_dc=5) + create_vsc(net, 1, 0, 0.1, 5, 0.15, + control_mode_ac="vm_pu", control_value_ac=1, + control_mode_dc="vm_pu", control_value_dc=1.02) runpp_with_consistency_checks(net) def test_vsc_hvdc_structure1_alternate(): - net = pp.create_empty_network() + net = create_empty_network() # AC part - pp.create_buses(net, 3, 110) - pp.create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 1, 2, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_ext_grid(net, 0) - pp.create_load(net, 2, 10, 5) + create_buses(net, 3, 110) + create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 1, 2, 30, 0.0487, 0.13823, 160, 0.664) + create_ext_grid(net, 0) + create_load(net, 2, 10, 5) # DC part - pp.create_bus_dc(net, 110, 'A') - pp.create_bus_dc(net, 110, 'B') + create_bus_dc(net, 110, 'A') + create_bus_dc(net, 110, 'B') - pp.create_line_dc(net, 0, 1, 100, std_type="2400-CU") + create_line_dc(net, 0, 1, 100, std_type="2400-CU") - pp.create_vsc(net, 1, 0, 0.1, 5, 0.15, - control_mode_ac="vm_pu", control_value_ac=1, - control_mode_dc="p_mw", control_value_dc=5) - pp.create_vsc(net, 2, 1, 0.1, 5, 0.15, - control_mode_ac="vm_pu", control_value_ac=1, - control_mode_dc="vm_pu", control_value_dc=1.02) + create_vsc(net, 1, 0, 0.1, 5, 0.15, + control_mode_ac="vm_pu", control_value_ac=1, + control_mode_dc="p_mw", control_value_dc=5) + create_vsc(net, 2, 1, 0.1, 5, 0.15, + control_mode_ac="vm_pu", control_value_ac=1, + control_mode_dc="vm_pu", control_value_dc=1.02) runpp_with_consistency_checks(net) def test_setting_of_dc_out_of_service(): - net = pp.create_empty_network() + net = create_empty_network() # AC part - pp.create_buses(net, 3, 110) - pp.create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 0, 2, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_ext_grid(net, 0) - pp.create_load(net, 2, 10, 5) + create_buses(net, 3, 110) + create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 0, 2, 30, 0.0487, 0.13823, 160, 0.664) + create_ext_grid(net, 0) + create_load(net, 2, 10, 5) # DC part - pp.create_bus_dc(net, 110, 'A') - pp.create_bus_dc(net, 110, 'B') - pp.create_bus_dc(net, 110, 'T', in_service=False) # todo results for this dc bus must be NaN + create_bus_dc(net, 110, 'A') + create_bus_dc(net, 110, 'B') + create_bus_dc(net, 110, 'T', in_service=False) # todo results for this dc bus must be NaN - pp.create_vsc(net, 1, 0, 0, 5, 0.15, control_mode_dc="vm_pu", control_value_dc=1.02) - pp.create_vsc(net, 2, 1, 0, 5, 0.15, control_value_dc=5) - pp.create_vsc(net, 2, 2, 0, 5, 0.15, control_value_dc=5) + create_vsc(net, 1, 0, 0, 5, 0.15, control_mode_dc="vm_pu", control_value_dc=1.02) + create_vsc(net, 2, 1, 0, 5, 0.15, control_value_dc=5) + create_vsc(net, 2, 2, 0, 5, 0.15, control_value_dc=5) runpp_with_consistency_checks(net) ## does the not in_service dc bus set the vsc out of service? def test_setting_of_dc_vsc_out_of_service(): - net = pp.create_empty_network() + net = create_empty_network() # AC part - pp.create_buses(net, 3, 110) - pp.create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 0, 2, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_ext_grid(net, 0) - pp.create_load(net, 2, 10, 5) + create_buses(net, 3, 110) + create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 0, 2, 30, 0.0487, 0.13823, 160, 0.664) + create_ext_grid(net, 0) + create_load(net, 2, 10, 5) # DC part - pp.create_bus_dc(net, 110, 'A') - pp.create_bus_dc(net, 110, 'B') - pp.create_bus_dc(net, 110, 'T', in_service=False) # todo results for this dc bus must be NaN + create_bus_dc(net, 110, 'A') + create_bus_dc(net, 110, 'B') + create_bus_dc(net, 110, 'T', in_service=False) # todo results for this dc bus must be NaN - pp.create_vsc(net, 1, 0, 0, 5, 0.15, control_mode_dc="vm_pu", control_value_dc=1.02) - pp.create_vsc(net, 2, 1, 0, 5, 0.15, control_value_dc=5) - pp.create_vsc(net, 2, 2, 0, 5, 0.15, control_value_dc=5, in_service=False) + create_vsc(net, 1, 0, 0, 5, 0.15, control_mode_dc="vm_pu", control_value_dc=1.02) + create_vsc(net, 2, 1, 0, 5, 0.15, control_value_dc=5) + create_vsc(net, 2, 2, 0, 5, 0.15, control_value_dc=5, in_service=False) runpp_with_consistency_checks(net) ## does the not in_service dc bus set the vsc out of service? def test_vsc_hvdc_structure2(): - net = pp.create_empty_network() + net = create_empty_network() # AC part - pp.create_buses(net, 5, 110) - pp.create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 1, 2, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 2, 3, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 3, 4, 30, 0.0487, 0.13823, 160, 0.664) + create_buses(net, 5, 110) + create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 1, 2, 30, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 2, 3, 30, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 3, 4, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_ext_grid(net, 0) - pp.create_load(net, 2, 10, 3) - pp.create_load(net, 4, 10, 4) + create_ext_grid(net, 0) + create_load(net, 2, 10, 3) + create_load(net, 4, 10, 4) # DC part - pp.create_bus_dc(net, 110, 'A') - pp.create_bus_dc(net, 110, 'B') + create_bus_dc(net, 110, 'A') + create_bus_dc(net, 110, 'B') - pp.create_bus_dc(net, 110, 'A') - pp.create_bus_dc(net, 110, 'B') + create_bus_dc(net, 110, 'A') + create_bus_dc(net, 110, 'B') - pp.create_line_dc(net, 0, 1, 100, std_type="2400-CU") - pp.create_line_dc(net, 1, 2, 100, std_type="2400-CU") - pp.create_line_dc(net, 2, 3, 100, std_type="2400-CU") + create_line_dc(net, 0, 1, 100, std_type="2400-CU") + create_line_dc(net, 1, 2, 100, std_type="2400-CU") + create_line_dc(net, 2, 3, 100, std_type="2400-CU") - pp.create_vsc(net, 1, 0, 0.1, 5, 0.15, - control_mode_ac="vm_pu", control_value_ac=1, - control_mode_dc="vm_pu", control_value_dc=1.02) - pp.create_vsc(net, 2, 1, 0.1, 5, 0.15, - control_mode_ac="vm_pu", control_value_ac=1, - control_mode_dc="p_mw", control_value_dc=5) + create_vsc(net, 1, 0, 0.1, 5, 0.15, + control_mode_ac="vm_pu", control_value_ac=1, + control_mode_dc="vm_pu", control_value_dc=1.02) + create_vsc(net, 2, 1, 0.1, 5, 0.15, + control_mode_ac="vm_pu", control_value_ac=1, + control_mode_dc="p_mw", control_value_dc=5) - pp.create_vsc(net, 3, 2, 0.1, 5, 0.15, - control_mode_ac="vm_pu", control_value_ac=1, - control_mode_dc="vm_pu", control_value_dc=1.02) - pp.create_vsc(net, 4, 3, 0.1, 5, 0.15, - control_mode_ac="vm_pu", control_value_ac=1, - control_mode_dc="p_mw", control_value_dc=5) + create_vsc(net, 3, 2, 0.1, 5, 0.15, + control_mode_ac="vm_pu", control_value_ac=1, + control_mode_dc="vm_pu", control_value_dc=1.02) + create_vsc(net, 4, 3, 0.1, 5, 0.15, + control_mode_ac="vm_pu", control_value_ac=1, + control_mode_dc="p_mw", control_value_dc=5) runpp_with_consistency_checks(net) def test_vsc_hvdc_mode0_without_dc_line(): - net = pp.create_empty_network() + net = create_empty_network() # AC part - pp.create_buses(net, 3, 110) - pp.create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 1, 2, 30, 0.0487, 0.13823, 160, 0.664) + create_buses(net, 3, 110) + create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 1, 2, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_ext_grid(net, 0) - pp.create_load(net, 2, 10, 5) + create_ext_grid(net, 0) + create_load(net, 2, 10, 5) # DC part - pp.create_bus_dc(net, 110, 'A') - pp.create_bus_dc(net, 110, 'B') + create_bus_dc(net, 110, 'A') + create_bus_dc(net, 110, 'B') - pp.create_vsc(net, 1, 0, 0.1, 5, 0.15, - control_mode_ac="vm_pu", control_value_ac=1, - control_mode_dc="vm_pu", control_value_dc=1) - pp.create_vsc(net, 2, 1, 0.1, 5, 0.15, - control_mode_ac="vm_pu", control_value_ac=1.02, - control_mode_dc="vm_pu", control_value_dc=1.02) + create_vsc(net, 1, 0, 0.1, 5, 0.15, + control_mode_ac="vm_pu", control_value_ac=1, + control_mode_dc="vm_pu", control_value_dc=1) + create_vsc(net, 2, 1, 0.1, 5, 0.15, + control_mode_ac="vm_pu", control_value_ac=1.02, + control_mode_dc="vm_pu", control_value_dc=1.02) runpp_with_consistency_checks(net) @@ -1226,51 +1232,51 @@ def test_vsc_hvdc_mode0_without_dc_line(): def test_vsc_hvdc_dc_line(): - net = pp.create_empty_network() + net = create_empty_network() # AC part - pp.create_buses(net, 2, 110) + create_buses(net, 2, 110) - pp.create_ext_grid(net, 0) - pp.create_load(net, 1, 10, 5) + create_ext_grid(net, 0) + create_load(net, 1, 10, 5) # DC part - pp.create_bus_dc(net, 110, 'A') - pp.create_bus_dc(net, 110, 'B') + create_bus_dc(net, 110, 'A') + create_bus_dc(net, 110, 'B') - pp.create_line_dc(net, 0, 1, 100, std_type="2400-CU") + create_line_dc(net, 0, 1, 100, std_type="2400-CU") - pp.create_vsc(net, 0, 0, 0.1, 5, 0.15, - control_mode_ac="q_mvar", control_value_ac=0, - control_mode_dc="vm_pu", control_value_dc=1.02) - pp.create_vsc(net, 1, 1, 0.1, 5, 0.15, - control_mode_ac="slack", control_value_ac=1.02, - control_mode_dc="p_mw", control_value_dc=0) + create_vsc(net, 0, 0, 0.1, 5, 0.15, + control_mode_ac="q_mvar", control_value_ac=0, + control_mode_dc="vm_pu", control_value_dc=1.02) + create_vsc(net, 1, 1, 0.1, 5, 0.15, + control_mode_ac="slack", control_value_ac=1.02, + control_mode_dc="p_mw", control_value_dc=0) runpp_with_consistency_checks(net) def test_vsc_hvdc_mode1(): - net = pp.create_empty_network() + net = create_empty_network() # AC part - pp.create_buses(net, 3, 110) - pp.create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 1, 2, 30, 0.0487, 0.13823, 160, 0.664) + create_buses(net, 3, 110) + create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 1, 2, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_ext_grid(net, 0) - pp.create_load(net, 2, 10, 5) + create_ext_grid(net, 0) + create_load(net, 2, 10, 5) # DC part - pp.create_bus_dc(net, 110, 'A') - pp.create_bus_dc(net, 110, 'B') + create_bus_dc(net, 110, 'A') + create_bus_dc(net, 110, 'B') - pp.create_line_dc(net, 0, 1, 100, std_type="2400-CU") + create_line_dc(net, 0, 1, 100, std_type="2400-CU") - pp.create_vsc(net, 1, 0, 0.1, 5, 0.15, control_mode_ac="vm_pu", control_value_ac=1, - control_mode_dc="vm_pu", control_value_dc=1.02) - pp.create_vsc(net, 2, 1, 0.1, 5, 0.15, control_mode_ac="vm_pu", control_value_ac=1.02, - control_mode_dc="vm_pu", control_value_dc=1) + create_vsc(net, 1, 0, 0.1, 5, 0.15, control_mode_ac="vm_pu", control_value_ac=1, + control_mode_dc="vm_pu", control_value_dc=1.02) + create_vsc(net, 2, 1, 0.1, 5, 0.15, control_mode_ac="vm_pu", control_value_ac=1.02, + control_mode_dc="vm_pu", control_value_dc=1) - pp.runpp(net) + runpp(net) runpp_with_consistency_checks(net) @@ -1281,29 +1287,29 @@ def test_vsc_hvdc_mode1(): def test_vsc_hvdc_mode2(): - net = pp.create_empty_network() + net = create_empty_network() # AC part - pp.create_buses(net, 3, 110) - pp.create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 1, 2, 30, 0.0487, 0.13823, 160, 0.664) + create_buses(net, 3, 110) + create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 1, 2, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_ext_grid(net, 0) - pp.create_load(net, 2, 10, 5) + create_ext_grid(net, 0) + create_load(net, 2, 10, 5) # DC part - pp.create_bus_dc(net, 110, 'A') - pp.create_bus_dc(net, 110, 'B') + create_bus_dc(net, 110, 'A') + create_bus_dc(net, 110, 'B') - pp.create_line_dc(net, 0, 1, 100, std_type="2400-CU") + create_line_dc(net, 0, 1, 100, std_type="2400-CU") - pp.create_vsc(net, 1, 0, 0.1, 5, 0.15, - control_mode_ac="vm_pu", control_value_ac=1, - control_mode_dc="p_mw", control_value_dc=5) - pp.create_vsc(net, 2, 1, 0.1, 5, 0.15, - control_mode_ac="vm_pu", control_value_ac=1.02, - control_mode_dc="vm_pu", control_value_dc=1) + create_vsc(net, 1, 0, 0.1, 5, 0.15, + control_mode_ac="vm_pu", control_value_ac=1, + control_mode_dc="p_mw", control_value_dc=5) + create_vsc(net, 2, 1, 0.1, 5, 0.15, + control_mode_ac="vm_pu", control_value_ac=1.02, + control_mode_dc="vm_pu", control_value_dc=1) - # pp.runpp(net) + # runpp(net) runpp_with_consistency_checks(net) @@ -1314,23 +1320,23 @@ def test_vsc_hvdc_mode2(): def test_vsc_hvdc_mode2_without_dc_line(): - net = pp.create_empty_network() + net = create_empty_network() # AC part - pp.create_buses(net, 3, 110) - pp.create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 1, 2, 30, 0.0487, 0.13823, 160, 0.664) + create_buses(net, 3, 110) + create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 1, 2, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_ext_grid(net, 0) - pp.create_load(net, 2, 10, 5) + create_ext_grid(net, 0) + create_load(net, 2, 10, 5) # DC part - pp.create_bus_dc(net, 110, 'A') - pp.create_bus_dc(net, 110, 'B') + create_bus_dc(net, 110, 'A') + create_bus_dc(net, 110, 'B') - pp.create_vsc(net, 1, 0, 0.1, 5, 0.15, control_mode_ac="vm_pu", control_value_ac=1, control_mode_dc="p_mw", - control_value_dc=5) - pp.create_vsc(net, 2, 1, 0.1, 5, 0.15, control_mode_ac="vm_pu", control_value_ac=1.02, control_mode_dc="vm_pu", - control_value_dc=1) + create_vsc(net, 1, 0, 0.1, 5, 0.15, control_mode_ac="vm_pu", control_value_ac=1, control_mode_dc="p_mw", + control_value_dc=5) + create_vsc(net, 2, 1, 0.1, 5, 0.15, control_mode_ac="vm_pu", control_value_ac=1.02, control_mode_dc="vm_pu", + control_value_dc=1) runpp_with_consistency_checks(net) @@ -1343,27 +1349,27 @@ def test_vsc_hvdc_mode2_without_dc_line(): def test_vsc_hvdc_mode3(): - net = pp.create_empty_network() + net = create_empty_network() # AC part - pp.create_buses(net, 3, 110) - pp.create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 1, 2, 30, 0.0487, 0.13823, 160, 0.664) + create_buses(net, 3, 110) + create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 1, 2, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_ext_grid(net, 0) - pp.create_load(net, 2, 10, 5) + create_ext_grid(net, 0) + create_load(net, 2, 10, 5) # DC part - pp.create_bus_dc(net, 110, 'A') - pp.create_bus_dc(net, 110, 'B') + create_bus_dc(net, 110, 'A') + create_bus_dc(net, 110, 'B') - pp.create_line_dc(net, 0, 1, 100, std_type="2400-CU") + create_line_dc(net, 0, 1, 100, std_type="2400-CU") - pp.create_vsc(net, 1, 0, 0.1, 5, 0.15, - control_mode_ac="vm_pu", control_value_ac=1, - control_mode_dc="vm_pu", control_value_dc=1) - pp.create_vsc(net, 2, 1, 0.1, 5, 0.15, - control_mode_ac="vm_pu", control_value_ac=1.02, - control_mode_dc="p_mw", control_value_dc=5) + create_vsc(net, 1, 0, 0.1, 5, 0.15, + control_mode_ac="vm_pu", control_value_ac=1, + control_mode_dc="vm_pu", control_value_dc=1) + create_vsc(net, 2, 1, 0.1, 5, 0.15, + control_mode_ac="vm_pu", control_value_ac=1.02, + control_mode_dc="p_mw", control_value_dc=5) runpp_with_consistency_checks(net) @@ -1374,147 +1380,150 @@ def test_vsc_hvdc_mode3(): def test_vsc_hvdc_mode4(): - net = pp.create_empty_network() + net = create_empty_network() # AC part - pp.create_buses(net, 3, 110) - pp.create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 1, 2, 30, 0.0487, 0.13823, 160, 0.664) + create_buses(net, 3, 110) + create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 1, 2, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_ext_grid(net, 0) - pp.create_load(net, 2, 10, 5) + create_ext_grid(net, 0) + create_load(net, 2, 10, 5) # DC part - pp.create_bus_dc(net, 110, 'A') - pp.create_bus_dc(net, 110, 'B') + create_bus_dc(net, 110, 'A') + create_bus_dc(net, 110, 'B') - pp.create_line_dc(net, 0, 1, 100, std_type="2400-CU") + create_line_dc(net, 0, 1, 100, std_type="2400-CU") - pp.create_vsc(net, 1, 0, 0.1, 5, 0.15, control_mode_ac="vm_pu", control_value_ac=1, control_mode_dc="p_mw", - control_value_dc=5) - pp.create_vsc(net, 2, 1, 0.1, 5, 0.15, control_mode_ac="vm_pu", control_value_ac=1.02, control_mode_dc="p_mw", - control_value_dc=5) + create_vsc(net, 1, 0, 0.1, 5, 0.15, control_mode_ac="vm_pu", control_value_ac=1, control_mode_dc="p_mw", + control_value_dc=5) + create_vsc(net, 2, 1, 0.1, 5, 0.15, control_mode_ac="vm_pu", control_value_ac=1.02, control_mode_dc="p_mw", + control_value_dc=5) # all DC buses are set out of service, so there is no error in this case and bus_dc results are NaN # with pytest.raises(UserWarning, match="reference bus for the dc grid"): - # pp.runpp(net) + # runpp(net) runpp_with_consistency_checks(net) def test_vsc_hvdc_mode5(): - net = pp.create_empty_network() + net = create_empty_network() # AC part - pp.create_buses(net, 3, 110) - pp.create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 1, 2, 30, 0.0487, 0.13823, 160, 0.664) + create_buses(net, 3, 110) + create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 1, 2, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_ext_grid(net, 0) - pp.create_load(net, 2, 10, 5) + create_ext_grid(net, 0) + create_load(net, 2, 10, 5) # DC part - pp.create_bus_dc(net, 110, 'A') - pp.create_bus_dc(net, 110, 'B') + create_bus_dc(net, 110, 'A') + create_bus_dc(net, 110, 'B') - pp.create_line_dc(net, 0, 1, 100, std_type="2400-CU") + create_line_dc(net, 0, 1, 100, std_type="2400-CU") - pp.create_vsc(net, 1, 0, 0.1, 5, 0.15, - control_mode_ac="vm_pu", control_value_ac=1, - control_mode_dc="p_mw", control_value_dc=4) - pp.create_vsc(net, 2, 1, 0.1, 5, 0.15, - control_mode_ac="q_mvar", control_value_ac=3, - control_mode_dc="vm_pu", control_value_dc=1) + create_vsc(net, 1, 0, 0.1, 5, 0.15, + control_mode_ac="vm_pu", control_value_ac=1, + control_mode_dc="p_mw", control_value_dc=4) + create_vsc(net, 2, 1, 0.1, 5, 0.15, + control_mode_ac="q_mvar", control_value_ac=3, + control_mode_dc="vm_pu", control_value_dc=1) runpp_with_consistency_checks(net) assert np.isclose(net.res_bus.at[1, 'vm_pu'], net.vsc.at[0, 'control_value_ac'], rtol=0, atol=1e-6) - assert np.isclose(net.res_bus.at[2, 'q_mvar'], net.vsc.at[1, 'control_value_ac'] + net.load.at[0, "q_mvar"], rtol=0, atol=1e-6) + assert np.isclose(net.res_bus.at[2, 'q_mvar'], net.vsc.at[1, 'control_value_ac'] + net.load.at[0, "q_mvar"], rtol=0, + atol=1e-6) assert np.isclose(net.res_bus_dc.at[0, 'p_mw'], net.vsc.at[0, 'control_value_dc'], rtol=0, atol=1e-6) assert np.isclose(net.res_bus_dc.at[1, 'vm_pu'], net.vsc.at[1, 'control_value_dc'], rtol=0, atol=1e-6) def test_vsc_hvdc_mode6(): - net = pp.create_empty_network() + net = create_empty_network() # AC part - pp.create_buses(net, 3, 110) - pp.create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 1, 2, 30, 0.0487, 0.13823, 160, 0.664) + create_buses(net, 3, 110) + create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 1, 2, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_ext_grid(net, 0) - pp.create_load(net, 2, 10, 5) + create_ext_grid(net, 0) + create_load(net, 2, 10, 5) # DC part - pp.create_bus_dc(net, 110, 'A') - pp.create_bus_dc(net, 110, 'B') + create_bus_dc(net, 110, 'A') + create_bus_dc(net, 110, 'B') - pp.create_line_dc(net, 0, 1, 100, std_type="2400-CU") + create_line_dc(net, 0, 1, 100, std_type="2400-CU") - pp.create_vsc(net, 1, 0, 0.1, 5, 0.15, - control_mode_ac="vm_pu", control_value_ac=1, - control_mode_dc="vm_pu", control_value_dc=1.02) - pp.create_vsc(net, 2, 1, 0.1, 5, 0.15, - control_mode_ac="q_mvar", control_value_ac=3, - control_mode_dc="vm_pu", control_value_dc=1) + create_vsc(net, 1, 0, 0.1, 5, 0.15, + control_mode_ac="vm_pu", control_value_ac=1, + control_mode_dc="vm_pu", control_value_dc=1.02) + create_vsc(net, 2, 1, 0.1, 5, 0.15, + control_mode_ac="q_mvar", control_value_ac=3, + control_mode_dc="vm_pu", control_value_dc=1) runpp_with_consistency_checks(net) assert np.isclose(net.res_bus.at[1, 'vm_pu'], net.vsc.at[0, 'control_value_ac'], rtol=0, atol=1e-6) - assert np.isclose(net.res_bus.at[2, 'q_mvar'], net.vsc.at[1, 'control_value_ac'] + net.load.at[0, "q_mvar"], rtol=0, atol=1e-6) + assert np.isclose(net.res_bus.at[2, 'q_mvar'], net.vsc.at[1, 'control_value_ac'] + net.load.at[0, "q_mvar"], rtol=0, + atol=1e-6) assert np.isclose(net.res_bus_dc.at[0, 'vm_pu'], net.vsc.at[0, 'control_value_dc'], rtol=0, atol=1e-6) assert np.isclose(net.res_bus_dc.at[1, 'vm_pu'], net.vsc.at[1, 'control_value_dc'], rtol=0, atol=1e-6) def test_vsc_hvdc_mode7(): - net = pp.create_empty_network() + net = create_empty_network() # AC part - pp.create_buses(net, 3, 110) - pp.create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 1, 2, 30, 0.0487, 0.13823, 160, 0.664) + create_buses(net, 3, 110) + create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 1, 2, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_ext_grid(net, 0) - pp.create_load(net, 2, 10, 5) + create_ext_grid(net, 0) + create_load(net, 2, 10, 5) # DC part - pp.create_bus_dc(net, 110, 'A') - pp.create_bus_dc(net, 110, 'B') + create_bus_dc(net, 110, 'A') + create_bus_dc(net, 110, 'B') - pp.create_line_dc(net, 0, 1, 100, std_type="2400-CU") + create_line_dc(net, 0, 1, 100, std_type="2400-CU") - pp.create_vsc(net, 1, 0, 0.1, 5, 0.15, - control_mode_ac="vm_pu", control_value_ac=1, - control_mode_dc="vm_pu", control_value_dc=1) - pp.create_vsc(net, 2, 1, 0.1, 5, 0.15, - control_mode_ac="q_mvar", control_value_ac=3, - control_mode_dc="p_mw", control_value_dc=4) + create_vsc(net, 1, 0, 0.1, 5, 0.15, + control_mode_ac="vm_pu", control_value_ac=1, + control_mode_dc="vm_pu", control_value_dc=1) + create_vsc(net, 2, 1, 0.1, 5, 0.15, + control_mode_ac="q_mvar", control_value_ac=3, + control_mode_dc="p_mw", control_value_dc=4) runpp_with_consistency_checks(net) assert np.isclose(net.res_bus.at[1, 'vm_pu'], net.vsc.at[0, 'control_value_ac'], rtol=0, atol=1e-6) - assert np.isclose(net.res_bus.at[2, 'q_mvar'], net.vsc.at[1, 'control_value_ac'] + net.load.at[0, "q_mvar"], rtol=0, atol=1e-6) + assert np.isclose(net.res_bus.at[2, 'q_mvar'], net.vsc.at[1, 'control_value_ac'] + net.load.at[0, "q_mvar"], rtol=0, + atol=1e-6) assert np.isclose(net.res_bus_dc.at[0, 'vm_pu'], net.vsc.at[0, 'control_value_dc'], rtol=0, atol=1e-6) assert np.isclose(net.res_bus_dc.at[1, 'p_mw'], net.vsc.at[1, 'control_value_dc'], rtol=0, atol=1e-6) def test_vsc_hvdc_mode9(): - net = pp.create_empty_network() + net = create_empty_network() # AC part - pp.create_buses(net, 3, 110) - pp.create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 1, 2, 30, 0.0487, 0.13823, 160, 0.664) + create_buses(net, 3, 110) + create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 1, 2, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_ext_grid(net, 0) - pp.create_load(net, 2, 10, 4) + create_ext_grid(net, 0) + create_load(net, 2, 10, 4) # DC part - pp.create_bus_dc(net, 110, 'A') - pp.create_bus_dc(net, 110, 'B') + create_bus_dc(net, 110, 'A') + create_bus_dc(net, 110, 'B') - pp.create_line_dc(net, 0, 1, 100, std_type="2400-CU") + create_line_dc(net, 0, 1, 100, std_type="2400-CU") - pp.create_vsc(net, 1, 0, 0.1, 5, 0.15, - control_mode_ac="q_mvar", control_value_ac=5, - control_mode_dc="p_mw", control_value_dc=4) - pp.create_vsc(net, 2, 1, 0.1, 5, 0.15, - control_mode_ac="vm_pu", control_value_ac=1, - control_mode_dc="vm_pu", control_value_dc=1) + create_vsc(net, 1, 0, 0.1, 5, 0.15, + control_mode_ac="q_mvar", control_value_ac=5, + control_mode_dc="p_mw", control_value_dc=4) + create_vsc(net, 2, 1, 0.1, 5, 0.15, + control_mode_ac="vm_pu", control_value_ac=1, + control_mode_dc="vm_pu", control_value_dc=1) runpp_with_consistency_checks(net) @@ -1525,27 +1534,27 @@ def test_vsc_hvdc_mode9(): def test_vsc_hvdc_mode10(): - net = pp.create_empty_network() + net = create_empty_network() # AC part - pp.create_buses(net, 3, 110) - pp.create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 1, 2, 30, 0.0487, 0.13823, 160, 0.664) + create_buses(net, 3, 110) + create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 1, 2, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_ext_grid(net, 0) - pp.create_load(net, 2, 10, 5) + create_ext_grid(net, 0) + create_load(net, 2, 10, 5) # DC part - pp.create_bus_dc(net, 110, 'A') - pp.create_bus_dc(net, 110, 'B') + create_bus_dc(net, 110, 'A') + create_bus_dc(net, 110, 'B') - pp.create_line_dc(net, 0, 1, 100, std_type="2400-CU") + create_line_dc(net, 0, 1, 100, std_type="2400-CU") - pp.create_vsc(net, 1, 0, 0.1, 5, 0.15, - control_mode_ac="q_mvar", control_value_ac=3, - control_mode_dc="vm_pu", control_value_dc=1) - pp.create_vsc(net, 2, 1, 0.1, 5, 0.15, - control_mode_ac="vm_pu", control_value_ac=1, - control_mode_dc="vm_pu", control_value_dc=1) + create_vsc(net, 1, 0, 0.1, 5, 0.15, + control_mode_ac="q_mvar", control_value_ac=3, + control_mode_dc="vm_pu", control_value_dc=1) + create_vsc(net, 2, 1, 0.1, 5, 0.15, + control_mode_ac="vm_pu", control_value_ac=1, + control_mode_dc="vm_pu", control_value_dc=1) runpp_with_consistency_checks(net) @@ -1556,27 +1565,27 @@ def test_vsc_hvdc_mode10(): def test_vsc_hvdc_mode11(): - net = pp.create_empty_network() + net = create_empty_network() # AC part - pp.create_buses(net, 3, 110) - pp.create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 1, 2, 30, 0.0487, 0.13823, 160, 0.664) + create_buses(net, 3, 110) + create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 1, 2, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_ext_grid(net, 0) - pp.create_load(net, 2, 10, 5) + create_ext_grid(net, 0) + create_load(net, 2, 10, 5) # DC part - pp.create_bus_dc(net, 110, 'A') - pp.create_bus_dc(net, 110, 'B') + create_bus_dc(net, 110, 'A') + create_bus_dc(net, 110, 'B') - pp.create_line_dc(net, 0, 1, 100, std_type="2400-CU") + create_line_dc(net, 0, 1, 100, std_type="2400-CU") - pp.create_vsc(net, 1, 0, 0.1, 5, 0.15, - control_mode_ac="q_mvar", control_value_ac=3, - control_mode_dc="vm_pu", control_value_dc=1) - pp.create_vsc(net, 2, 1, 0.1, 5, 0.15, - control_mode_ac="vm_pu", control_value_ac=1, - control_mode_dc="p_mw", control_value_dc=4) + create_vsc(net, 1, 0, 0.1, 5, 0.15, + control_mode_ac="q_mvar", control_value_ac=3, + control_mode_dc="vm_pu", control_value_dc=1) + create_vsc(net, 2, 1, 0.1, 5, 0.15, + control_mode_ac="vm_pu", control_value_ac=1, + control_mode_dc="p_mw", control_value_dc=4) runpp_with_consistency_checks(net) @@ -1587,92 +1596,95 @@ def test_vsc_hvdc_mode11(): def test_vsc_hvdc_mode13(): - net = pp.create_empty_network() + net = create_empty_network() # AC part - pp.create_buses(net, 3, 110) - pp.create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 1, 2, 30, 0.0487, 0.13823, 160, 0.664) + create_buses(net, 3, 110) + create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 1, 2, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_ext_grid(net, 0) - pp.create_load(net, 2, 10, 4) + create_ext_grid(net, 0) + create_load(net, 2, 10, 4) # DC part - pp.create_bus_dc(net, 110, 'A') - pp.create_bus_dc(net, 110, 'B') + create_bus_dc(net, 110, 'A') + create_bus_dc(net, 110, 'B') - pp.create_line_dc(net, 0, 1, 100, std_type="2400-CU") + create_line_dc(net, 0, 1, 100, std_type="2400-CU") - pp.create_vsc(net, 1, 0, 0.1, 5, 0.15, - control_mode_ac="q_mvar", control_value_ac=5, - control_mode_dc="p_mw", control_value_dc=4) - pp.create_vsc(net, 2, 1, 0.1, 5, 0.15, - control_mode_ac="q_mvar", control_value_ac=5, - control_mode_dc="vm_pu", control_value_dc=1) + create_vsc(net, 1, 0, 0.1, 5, 0.15, + control_mode_ac="q_mvar", control_value_ac=5, + control_mode_dc="p_mw", control_value_dc=4) + create_vsc(net, 2, 1, 0.1, 5, 0.15, + control_mode_ac="q_mvar", control_value_ac=5, + control_mode_dc="vm_pu", control_value_dc=1) runpp_with_consistency_checks(net) assert np.isclose(net.res_bus.at[1, 'q_mvar'], net.vsc.at[0, 'control_value_ac'], rtol=0, atol=1e-6) - assert np.isclose(net.res_bus.at[2, 'q_mvar'], net.vsc.at[1, 'control_value_ac'] + net.load.at[0, "q_mvar"], rtol=0, atol=1e-6) + assert np.isclose(net.res_bus.at[2, 'q_mvar'], net.vsc.at[1, 'control_value_ac'] + net.load.at[0, "q_mvar"], rtol=0, + atol=1e-6) assert np.isclose(net.res_bus_dc.at[0, 'p_mw'], net.vsc.at[0, 'control_value_dc'], rtol=0, atol=1e-6) assert np.isclose(net.res_bus_dc.at[1, 'vm_pu'], net.vsc.at[1, 'control_value_dc'], rtol=0, atol=1e-6) def test_vsc_hvdc_mode14(): - net = pp.create_empty_network() + net = create_empty_network() # AC part - pp.create_buses(net, 3, 110) - pp.create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 1, 2, 30, 0.0487, 0.13823, 160, 0.664) + create_buses(net, 3, 110) + create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 1, 2, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_ext_grid(net, 0) - pp.create_load(net, 2, 10, 5) + create_ext_grid(net, 0) + create_load(net, 2, 10, 5) # DC part - pp.create_bus_dc(net, 110, 'A') - pp.create_bus_dc(net, 110, 'B') + create_bus_dc(net, 110, 'A') + create_bus_dc(net, 110, 'B') - pp.create_line_dc(net, 0, 1, 100, std_type="2400-CU") + create_line_dc(net, 0, 1, 100, std_type="2400-CU") - pp.create_vsc(net, 1, 0, 0.1, 5, 0.15, control_mode_ac="q_mvar", control_value_ac=3, control_mode_dc="vm_pu", - control_value_dc=1) - pp.create_vsc(net, 2, 1, 0.1, 5, 0.15, control_mode_ac="q_mvar", control_value_ac=3, control_mode_dc="vm_pu", - control_value_dc=1) + create_vsc(net, 1, 0, 0.1, 5, 0.15, control_mode_ac="q_mvar", control_value_ac=3, control_mode_dc="vm_pu", + control_value_dc=1) + create_vsc(net, 2, 1, 0.1, 5, 0.15, control_mode_ac="q_mvar", control_value_ac=3, control_mode_dc="vm_pu", + control_value_dc=1) runpp_with_consistency_checks(net) assert np.isclose(net.res_bus.at[1, 'q_mvar'], net.vsc.at[0, 'control_value_ac'], rtol=0, atol=1e-6) - assert np.isclose(net.res_bus.at[2, 'q_mvar'], net.vsc.at[1, 'control_value_ac'] + net.load.at[0, "q_mvar"], rtol=0, atol=1e-6) + assert np.isclose(net.res_bus.at[2, 'q_mvar'], net.vsc.at[1, 'control_value_ac'] + net.load.at[0, "q_mvar"], rtol=0, + atol=1e-6) assert np.isclose(net.res_bus_dc.at[0, 'vm_pu'], net.vsc.at[0, 'control_value_dc'], rtol=0, atol=1e-6) assert np.isclose(net.res_bus_dc.at[1, 'vm_pu'], net.vsc.at[1, 'control_value_dc'], rtol=0, atol=1e-6) def test_vsc_hvdc_mode15(): - net = pp.create_empty_network() + net = create_empty_network() # AC part - pp.create_buses(net, 3, 110) - pp.create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 1, 2, 30, 0.0487, 0.13823, 160, 0.664) + create_buses(net, 3, 110) + create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 1, 2, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_ext_grid(net, 0) - pp.create_load(net, 2, 10, 5) + create_ext_grid(net, 0) + create_load(net, 2, 10, 5) # DC part - pp.create_bus_dc(net, 110, 'A', index=1) - pp.create_bus_dc(net, 110, 'B', index=0) + create_bus_dc(net, 110, 'A', index=1) + create_bus_dc(net, 110, 'B', index=0) - pp.create_line_dc(net, 0, 1, 100, std_type="2400-CU", index=6) + create_line_dc(net, 0, 1, 100, std_type="2400-CU", index=6) - pp.create_vsc(net, 1, 1, 0.1, 5, 0.15, - control_mode_ac="q_mvar", control_value_ac=3, - control_mode_dc="vm_pu", control_value_dc=1, index=3) - pp.create_vsc(net, 2, 0, 0.1, 5, 0.15, - control_mode_ac="q_mvar", control_value_ac=4, - control_mode_dc="p_mw", control_value_dc=4, index=2) + create_vsc(net, 1, 1, 0.1, 5, 0.15, + control_mode_ac="q_mvar", control_value_ac=3, + control_mode_dc="vm_pu", control_value_dc=1, index=3) + create_vsc(net, 2, 0, 0.1, 5, 0.15, + control_mode_ac="q_mvar", control_value_ac=4, + control_mode_dc="p_mw", control_value_dc=4, index=2) runpp_with_consistency_checks(net) assert np.isclose(net.res_bus.at[1, 'q_mvar'], net.vsc.at[3, 'control_value_ac'], rtol=0, atol=1e-6) - assert np.isclose(net.res_bus.at[2, 'q_mvar'], net.vsc.at[2, 'control_value_ac'] + net.load.at[0, "q_mvar"], rtol=0, atol=1e-6) + assert np.isclose(net.res_bus.at[2, 'q_mvar'], net.vsc.at[2, 'control_value_ac'] + net.load.at[0, "q_mvar"], rtol=0, + atol=1e-6) assert np.isclose(net.res_bus_dc.at[1, 'vm_pu'], net.vsc.at[3, 'control_value_dc'], rtol=0, atol=1e-6) assert np.isclose(net.res_bus_dc.at[0, 'p_mw'], net.vsc.at[2, 'control_value_dc'], rtol=0, atol=1e-6) @@ -1681,25 +1693,25 @@ def test_vsc_hvdc_mode15(): def test_minimal_ac(): - net = pp.create_empty_network() + net = create_empty_network() # AC part - pp.create_bus(net, 110) - pp.create_ext_grid(net, 0, vm_pu=1.02) + create_bus(net, 110) + create_ext_grid(net, 0, vm_pu=1.02) # DC part - pp.create_bus_dc(net, 110, 'A') + create_bus_dc(net, 110, 'A') - pp.create_vsc(net, 0, 0, 0.1, 6, 0.15, - control_mode_ac="vm_pu", control_value_ac=1.01, - control_mode_dc="vm_pu", control_value_dc=1.02) + create_vsc(net, 0, 0, 0.1, 6, 0.15, + control_mode_ac="vm_pu", control_value_ac=1.01, + control_mode_dc="vm_pu", control_value_dc=1.02) with pytest.raises(UserWarning, match="Voltage controlling elements"): - pp.runpp(net) + runpp(net) net.vsc.at[0, "control_value_ac"] = 1.02 net_copy = copy_with_impedance(net) - pp.runpp(net_copy) + runpp(net_copy) runpp_with_consistency_checks(net) @@ -1710,16 +1722,16 @@ def test_minimal_ac(): def test_minimal_vsc_hvdc(): - net = pp.create_empty_network() + net = create_empty_network() # AC part - pp.create_bus(net, 110) - pp.create_ext_grid(net, 0) + create_bus(net, 110) + create_ext_grid(net, 0) # DC part - pp.create_bus_dc(net, 110, 'A') - pp.create_bus_dc(net, 110, 'B') + create_bus_dc(net, 110, 'A') + create_bus_dc(net, 110, 'B') - pp.create_vsc(net, 0, 0, 0.1, 5, 0.15, control_mode_dc="vm_pu", control_value_dc=1.02) + create_vsc(net, 0, 0, 0.1, 5, 0.15, control_mode_dc="vm_pu", control_value_dc=1.02) runpp_with_consistency_checks(net) @@ -1728,7 +1740,7 @@ def test_minimal_vsc_hvdc(): # assert pd.isnull(net.res_bus_dc.at[1, 'vm_pu']) #todo # assert pd.isnull(net.res_bus_dc.at[1, 'p_mw']) #todo - pp.create_line_dc(net, 0, 1, 100, std_type="2400-CU") + create_line_dc(net, 0, 1, 100, std_type="2400-CU") runpp_with_consistency_checks(net) @@ -1739,137 +1751,137 @@ def test_minimal_vsc_hvdc(): assert np.isclose(net.res_line_dc.at[0, 'vm_to_pu'], net.vsc.at[0, 'control_value_dc'], rtol=0, atol=1e-6) assert np.isclose(net.res_line_dc.at[0, 'loading_percent'], 0, rtol=0, atol=1e-6) - #pp.create_bus(net, 110) - #pp.create_load(net, 2, 10) - #pp.create_vsc(net, 1, 1, 0.1, 5, control_mode_ac="slack", control_value_ac=1.03, control_mode_dc="p_mw", control_value_dc=10) #todo + # create_bus(net, 110) + # create_load(net, 2, 10) + # create_vsc(net, 1, 1, 0.1, 5, control_mode_ac="slack", control_value_ac=1.03, control_mode_dc="p_mw", control_value_dc=10) #todo def test_simple_vsc_hvdc(): - net = pp.create_empty_network() + net = create_empty_network() # AC part - pp.create_buses(net, 3, 110) - pp.create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 0, 2, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_ext_grid(net, 0) - pp.create_load(net, 2, 10, q_mvar=5) + create_buses(net, 3, 110) + create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 0, 2, 30, 0.0487, 0.13823, 160, 0.664) + create_ext_grid(net, 0) + create_load(net, 2, 10, q_mvar=5) # DC part - pp.create_bus_dc(net, 110, 'A') - pp.create_bus_dc(net, 110, 'B') + create_bus_dc(net, 110, 'A') + create_bus_dc(net, 110, 'B') - pp.create_line_dc(net, 0, 1, 100, std_type="2400-CU") + create_line_dc(net, 0, 1, 100, std_type="2400-CU") - pp.create_vsc(net, 1, 0, 0.1, 5, 0.15, - control_mode_ac="vm_pu", control_value_ac=1, - control_mode_dc="vm_pu", control_value_dc=1.02) + create_vsc(net, 1, 0, 0.1, 5, 0.15, + control_mode_ac="vm_pu", control_value_ac=1, + control_mode_dc="vm_pu", control_value_dc=1.02) runpp_with_consistency_checks(net) - pp.create_vsc(net, 2, 1, 0.1, 5, 0.15, - control_mode_ac="vm_pu", control_value_ac=1, - control_mode_dc="p_mw", control_value_dc=1) + create_vsc(net, 2, 1, 0.1, 5, 0.15, + control_mode_ac="vm_pu", control_value_ac=1, + control_mode_dc="p_mw", control_value_dc=1) runpp_with_consistency_checks(net) def test_simple_2vsc_hvdc1(): # np.set_printoptions(linewidth=1000, suppress=True, precision=3) - net = pp.create_empty_network() + net = create_empty_network() # AC part - pp.create_buses(net, 3, 110, geodata=[(0, 0), (100, 0), (200, 0)]) - pp.create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 1, 2, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_ext_grid(net, 0) - pp.create_load(net, 1, 10, q_mvar=5) + create_buses(net, 3, 110, geodata=[(0, 0), (100, 0), (200, 0)]) + create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 1, 2, 30, 0.0487, 0.13823, 160, 0.664) + create_ext_grid(net, 0) + create_load(net, 1, 10, q_mvar=5) # DC part - pp.create_bus_dc(net, 110, 'A', geodata=(100, 10)) - pp.create_bus_dc(net, 110, 'B', geodata=(200, 10)) + create_bus_dc(net, 110, 'A', geodata=(100, 10)) + create_bus_dc(net, 110, 'B', geodata=(200, 10)) - pp.create_bus_dc(net, 110, 'C', geodata=(100, -10)) - pp.create_bus_dc(net, 110, 'D', geodata=(200, -10)) + create_bus_dc(net, 110, 'C', geodata=(100, -10)) + create_bus_dc(net, 110, 'D', geodata=(200, -10)) - pp.create_line_dc(net, 0, 1, 100, std_type="2400-CU") - pp.create_line_dc(net, 2, 3, 100, std_type="2400-CU") + create_line_dc(net, 0, 1, 100, std_type="2400-CU") + create_line_dc(net, 2, 3, 100, std_type="2400-CU") - pp.create_vsc(net, 1, 0, 0.1, 5, 0.15, - control_mode_ac='vm_pu', control_value_ac=1, - control_mode_dc="p_mw", control_value_dc=10) - pp.create_vsc(net, 2, 1, 0.1, 5, 0.15, - control_mode_ac='vm_pu', control_value_ac=1, - control_mode_dc="vm_pu", control_value_dc=1.02) + create_vsc(net, 1, 0, 0.1, 5, 0.15, + control_mode_ac='vm_pu', control_value_ac=1, + control_mode_dc="p_mw", control_value_dc=10) + create_vsc(net, 2, 1, 0.1, 5, 0.15, + control_mode_ac='vm_pu', control_value_ac=1, + control_mode_dc="vm_pu", control_value_dc=1.02) - pp.create_vsc(net, 1, 2, 0.1, 5, 0.15, - control_mode_ac='vm_pu', control_value_ac=1, - control_mode_dc="p_mw", control_value_dc=10) - pp.create_vsc(net, 2, 3, 0.1, 5, 0.15, - control_mode_ac='vm_pu', control_value_ac=1, - control_mode_dc="vm_pu", control_value_dc=1.02) + create_vsc(net, 1, 2, 0.1, 5, 0.15, + control_mode_ac='vm_pu', control_value_ac=1, + control_mode_dc="p_mw", control_value_dc=10) + create_vsc(net, 2, 3, 0.1, 5, 0.15, + control_mode_ac='vm_pu', control_value_ac=1, + control_mode_dc="vm_pu", control_value_dc=1.02) runpp_with_consistency_checks(net) def test_simple_2vsc_hvdc2(): # np.set_printoptions(linewidth=1000, suppress=True, precision=3) - net = pp.create_empty_network() + net = create_empty_network() # AC part - pp.create_buses(net, 3, 110, geodata=[(0, 0), (100, 0), (200, 0)]) - pp.create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 1, 2, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_ext_grid(net, 0) - pp.create_load(net, 1, 10, q_mvar=5) + create_buses(net, 3, 110, geodata=[(0, 0), (100, 0), (200, 0)]) + create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 1, 2, 30, 0.0487, 0.13823, 160, 0.664) + create_ext_grid(net, 0) + create_load(net, 1, 10, q_mvar=5) # DC part - pp.create_bus_dc(net, 110, 'A', geodata=(100, 10)) - pp.create_bus_dc(net, 110, 'B', geodata=(200, 10)) + create_bus_dc(net, 110, 'A', geodata=(100, 10)) + create_bus_dc(net, 110, 'B', geodata=(200, 10)) - pp.create_bus_dc(net, 110, 'C', geodata=(100, -10)) - pp.create_bus_dc(net, 110, 'D', geodata=(200, -10)) + create_bus_dc(net, 110, 'C', geodata=(100, -10)) + create_bus_dc(net, 110, 'D', geodata=(200, -10)) - pp.create_line_dc(net, 0, 1, 100, std_type="2400-CU") - pp.create_line_dc(net, 2, 3, 100, std_type="2400-CU") + create_line_dc(net, 0, 1, 100, std_type="2400-CU") + create_line_dc(net, 2, 3, 100, std_type="2400-CU") - pp.create_vsc(net, 1, 0, 0.1, 5, 0.15, - control_mode_ac='vm_pu', control_value_ac=1, - control_mode_dc="p_mw", control_value_dc=10) - pp.create_vsc(net, 2, 1, 0.1, 5, 0.15, - control_mode_ac='vm_pu', control_value_ac=1, - control_mode_dc="vm_pu", control_value_dc=1.02) + create_vsc(net, 1, 0, 0.1, 5, 0.15, + control_mode_ac='vm_pu', control_value_ac=1, + control_mode_dc="p_mw", control_value_dc=10) + create_vsc(net, 2, 1, 0.1, 5, 0.15, + control_mode_ac='vm_pu', control_value_ac=1, + control_mode_dc="vm_pu", control_value_dc=1.02) - #pp.create_vsc(net, 1, 2, 0.1, 5, control_mode_ac='vm_pu', control_value_ac=1, control_mode_dc="p_mw", control_value_dc=10) - #pp.create_vsc(net, 2, 3, 0.1, 5, control_mode_ac='vm_pu', control_value_ac=1, control_mode_dc="vm_pu", control_value_dc=1.02) + # create_vsc(net, 1, 2, 0.1, 5, control_mode_ac='vm_pu', control_value_ac=1, control_mode_dc="p_mw", control_value_dc=10) + # create_vsc(net, 2, 3, 0.1, 5, control_mode_ac='vm_pu', control_value_ac=1, control_mode_dc="vm_pu", control_value_dc=1.02) - pp.create_buses(net, 2, 110, geodata=[(100, -5), (200, -5)]) - pp.create_line_from_parameters(net, 1, 3, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 2, 4, 30, 0.0487, 0.13823, 160, 0.664) + create_buses(net, 2, 110, geodata=[(100, -5), (200, -5)]) + create_line_from_parameters(net, 1, 3, 30, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 2, 4, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_vsc(net, 3, 2, 0.1, 5, 0.15, - control_mode_ac='vm_pu', control_value_ac=1, - control_mode_dc="p_mw", control_value_dc=10) - pp.create_vsc(net, 4, 3, 0.1, 5, 0.15, - control_mode_ac='vm_pu', control_value_ac=1, - control_mode_dc="vm_pu", control_value_dc=1.02) + create_vsc(net, 3, 2, 0.1, 5, 0.15, + control_mode_ac='vm_pu', control_value_ac=1, + control_mode_dc="p_mw", control_value_dc=10) + create_vsc(net, 4, 3, 0.1, 5, 0.15, + control_mode_ac='vm_pu', control_value_ac=1, + control_mode_dc="vm_pu", control_value_dc=1.02) runpp_with_consistency_checks(net) def test_b2b_vsc_1(): - net = pp.create_empty_network() + net = create_empty_network() # AC part - pp.create_buses(net, 3, 110) - pp.create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 0, 2, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_ext_grid(net, 0) - pp.create_load(net, 2, 10, q_mvar=5) + create_buses(net, 3, 110) + create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 0, 2, 30, 0.0487, 0.13823, 160, 0.664) + create_ext_grid(net, 0) + create_load(net, 2, 10, q_mvar=5) # DC part - pp.create_bus_dc(net, 110, 'A') + create_bus_dc(net, 110, 'A') - pp.create_vsc(net, 1, 0, 0.1, 5, 0.15, - control_mode_ac="vm_pu", control_value_ac=1, - control_mode_dc="vm_pu", control_value_dc=1.02) - pp.create_vsc(net, 2, 0, 0.1, 5, 0.15, - control_mode_ac="vm_pu", control_value_ac=1, - control_mode_dc="p_mw", control_value_dc=2) + create_vsc(net, 1, 0, 0.1, 5, 0.15, + control_mode_ac="vm_pu", control_value_ac=1, + control_mode_dc="vm_pu", control_value_dc=1.02) + create_vsc(net, 2, 0, 0.1, 5, 0.15, + control_mode_ac="vm_pu", control_value_ac=1, + control_mode_dc="p_mw", control_value_dc=2) runpp_with_consistency_checks(net) assert np.isclose(net.res_bus_dc.at[0, 'p_mw'], 0, rtol=0, atol=1e-6) @@ -1878,35 +1890,35 @@ def test_b2b_vsc_1(): def test_multiple_b2b_vsc_1(): - net = pp.create_empty_network() + net = create_empty_network() # AC part - pp.create_buses(net, 5, 110) - pp.create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 0, 2, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 1, 3, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 2, 4, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_ext_grid(net, 0) - pp.create_load(net, 2, 10, q_mvar=5) + create_buses(net, 5, 110) + create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 0, 2, 30, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 1, 3, 30, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 2, 4, 30, 0.0487, 0.13823, 160, 0.664) + create_ext_grid(net, 0) + create_load(net, 2, 10, q_mvar=5) # first B2B converter - pp.create_bus_dc(net, 110, 'A') + create_bus_dc(net, 110, 'A') - pp.create_vsc(net, 1, 0, 0.1, 5, 0.15, - control_mode_ac="vm_pu", control_value_ac=1, - control_mode_dc="vm_pu", control_value_dc=1.02) - pp.create_vsc(net, 2, 0, 0.1, 5, 0.15, - control_mode_ac="vm_pu", control_value_ac=1, - control_mode_dc="p_mw", control_value_dc=2) + create_vsc(net, 1, 0, 0.1, 5, 0.15, + control_mode_ac="vm_pu", control_value_ac=1, + control_mode_dc="vm_pu", control_value_dc=1.02) + create_vsc(net, 2, 0, 0.1, 5, 0.15, + control_mode_ac="vm_pu", control_value_ac=1, + control_mode_dc="p_mw", control_value_dc=2) # second B2B converter - pp.create_bus_dc(net, 110, 'B') + create_bus_dc(net, 110, 'B') - pp.create_vsc(net, 3, 1, 0.1, 5, 0.15, - control_mode_ac="vm_pu", control_value_ac=1, - control_mode_dc="vm_pu", control_value_dc=1.02) - pp.create_vsc(net, 4, 1, 0.1, 5, 0.15, - control_mode_ac="vm_pu", control_value_ac=1, - control_mode_dc="p_mw", control_value_dc=4) + create_vsc(net, 3, 1, 0.1, 5, 0.15, + control_mode_ac="vm_pu", control_value_ac=1, + control_mode_dc="vm_pu", control_value_dc=1.02) + create_vsc(net, 4, 1, 0.1, 5, 0.15, + control_mode_ac="vm_pu", control_value_ac=1, + control_mode_dc="p_mw", control_value_dc=4) runpp_with_consistency_checks(net) assert np.isclose(net.res_bus_dc.at[0, 'p_mw'], 0, rtol=0, atol=1e-6) @@ -1919,28 +1931,28 @@ def test_multiple_b2b_vsc_1(): def test_tres_amigas_b2b_vsc_1(): - net = pp.create_empty_network() + net = create_empty_network() # AC part - pp.create_buses(net, 5, 110) - pp.create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 0, 2, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 0, 3, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 1, 4, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_ext_grid(net, 0) - pp.create_load(net, 2, 10, q_mvar=5) + create_buses(net, 5, 110) + create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 0, 2, 30, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 0, 3, 30, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 1, 4, 30, 0.0487, 0.13823, 160, 0.664) + create_ext_grid(net, 0) + create_load(net, 2, 10, q_mvar=5) # DC system - pp.create_bus_dc(net, 110, 'A') + create_bus_dc(net, 110, 'A') - pp.create_vsc(net, 4, 0, 0.1, 5, 0.15, - control_mode_ac="vm_pu", control_value_ac=1, - control_mode_dc="vm_pu", control_value_dc=1.02) - pp.create_vsc(net, 2, 0, 0.1, 5, 0.15, - control_mode_ac="vm_pu", control_value_ac=1, - control_mode_dc="p_mw", control_value_dc=2) - pp.create_vsc(net, 3, 0, 0.1, 5, 0.15, - control_mode_ac="vm_pu", control_value_ac=1, - control_mode_dc="p_mw", control_value_dc=4) + create_vsc(net, 4, 0, 0.1, 5, 0.15, + control_mode_ac="vm_pu", control_value_ac=1, + control_mode_dc="vm_pu", control_value_dc=1.02) + create_vsc(net, 2, 0, 0.1, 5, 0.15, + control_mode_ac="vm_pu", control_value_ac=1, + control_mode_dc="p_mw", control_value_dc=2) + create_vsc(net, 3, 0, 0.1, 5, 0.15, + control_mode_ac="vm_pu", control_value_ac=1, + control_mode_dc="p_mw", control_value_dc=4) runpp_with_consistency_checks(net) assert net.res_ext_grid.p_mw.at[0] > 10 @@ -1952,28 +1964,28 @@ def test_tres_amigas_b2b_vsc_1(): def test_tres_amigas_b2b_vsc_2(): - net = pp.create_empty_network() + net = create_empty_network() # AC part - pp.create_buses(net, 5, 110) - pp.create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 0, 2, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 0, 3, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 1, 4, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_ext_grid(net, 0) - pp.create_load(net, 2, 10, q_mvar=5) + create_buses(net, 5, 110) + create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 0, 2, 30, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 0, 3, 30, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 1, 4, 30, 0.0487, 0.13823, 160, 0.664) + create_ext_grid(net, 0) + create_load(net, 2, 10, q_mvar=5) # DC system - pp.create_bus_dc(net, 110, 'A') + create_bus_dc(net, 110, 'A') - pp.create_vsc(net, 4, 0, 0.1, 5, 0.15, - control_mode_ac="vm_pu", control_value_ac=1, - control_mode_dc="vm_pu", control_value_dc=1.02) - pp.create_vsc(net, 2, 0, 0.1, 5, 0.15, - control_mode_ac="vm_pu", control_value_ac=1, - control_mode_dc="vm_pu", control_value_dc=1.02) - pp.create_vsc(net, 3, 0, 0.1, 5, 0.15, - control_mode_ac="vm_pu", control_value_ac=1, - control_mode_dc="p_mw", control_value_dc=4) + create_vsc(net, 4, 0, 0.1, 5, 0.15, + control_mode_ac="vm_pu", control_value_ac=1, + control_mode_dc="vm_pu", control_value_dc=1.02) + create_vsc(net, 2, 0, 0.1, 5, 0.15, + control_mode_ac="vm_pu", control_value_ac=1, + control_mode_dc="vm_pu", control_value_dc=1.02) + create_vsc(net, 3, 0, 0.1, 5, 0.15, + control_mode_ac="vm_pu", control_value_ac=1, + control_mode_dc="p_mw", control_value_dc=4) runpp_with_consistency_checks(net) assert net.res_ext_grid.p_mw.at[0] > 10 @@ -1985,70 +1997,70 @@ def test_tres_amigas_b2b_vsc_2(): def test_b2b_vsc_2(): - net = pp.create_empty_network() + net = create_empty_network() # AC part - pp.create_buses(net, 4, 110) - pp.create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 2, 3, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 0, 3, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_ext_grid(net, 0) - pp.create_load(net, 3, 10, q_mvar=5) + create_buses(net, 4, 110) + create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 2, 3, 30, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 0, 3, 30, 0.0487, 0.13823, 160, 0.664) + create_ext_grid(net, 0) + create_load(net, 3, 10, q_mvar=5) # DC part - pp.create_bus_dc(net, 110, 'A') + create_bus_dc(net, 110, 'A') - pp.create_vsc(net, 1, 0, 0.1, 5, 0.15, - control_mode_ac="vm_pu", control_value_ac=1, - control_mode_dc="vm_pu", control_value_dc=1.02) - pp.create_vsc(net, 2, 0, 0.1, 5, 0.15, - control_mode_ac="vm_pu", control_value_ac=1, - control_mode_dc="p_mw", control_value_dc=2) + create_vsc(net, 1, 0, 0.1, 5, 0.15, + control_mode_ac="vm_pu", control_value_ac=1, + control_mode_dc="vm_pu", control_value_dc=1.02) + create_vsc(net, 2, 0, 0.1, 5, 0.15, + control_mode_ac="vm_pu", control_value_ac=1, + control_mode_dc="p_mw", control_value_dc=2) runpp_with_consistency_checks(net) assert net.res_ext_grid.p_mw.at[0] > 10 def test_b2b_vsc_2a(): - net = pp.create_empty_network() + net = create_empty_network() # AC part - pp.create_buses(net, 4, 110) - pp.create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 2, 3, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_ext_grid(net, 0) - pp.create_load(net, 3, 10, q_mvar=5) + create_buses(net, 4, 110) + create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 2, 3, 30, 0.0487, 0.13823, 160, 0.664) + create_ext_grid(net, 0) + create_load(net, 3, 10, q_mvar=5) # DC part - pp.create_bus_dc(net, 110, 'A') + create_bus_dc(net, 110, 'A') - pp.create_vsc(net, 1, 0, 0.1, 5, 0.15, - control_mode_ac="vm_pu", control_value_ac=1, - control_mode_dc="vm_pu", control_value_dc=1.02) - pp.create_vsc(net, 2, 0, 0.1, 5, 0.15, - control_mode_ac="slack", control_value_ac=1, - control_mode_dc="p_mw", control_value_dc=0) + create_vsc(net, 1, 0, 0.1, 5, 0.15, + control_mode_ac="vm_pu", control_value_ac=1, + control_mode_dc="vm_pu", control_value_dc=1.02) + create_vsc(net, 2, 0, 0.1, 5, 0.15, + control_mode_ac="slack", control_value_ac=1, + control_mode_dc="p_mw", control_value_dc=0) runpp_with_consistency_checks(net) assert net.res_ext_grid.p_mw.at[0] > 10 def test_b2b_vsc_3(): - net = pp.create_empty_network() + net = create_empty_network() # AC part - pp.create_buses(net, 4, 110) - pp.create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 2, 3, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_ext_grid(net, 0) - pp.create_load(net, 3, 10, q_mvar=5) + create_buses(net, 4, 110) + create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 2, 3, 30, 0.0487, 0.13823, 160, 0.664) + create_ext_grid(net, 0) + create_load(net, 3, 10, q_mvar=5) # DC part - pp.create_bus_dc(net, 110, 'A') - - pp.create_vsc(net, 1, 0, 0.1, 5, 0.15, - control_mode_ac="vm_pu", control_value_ac=1, - control_mode_dc="vm_pu", control_value_dc=1.01) - pp.create_vsc(net, 2, 0, 0.1, 5, 0.15, - control_mode_ac="slack", control_value_ac=1, - control_mode_dc="vm_pu", control_value_dc=1.01) + create_bus_dc(net, 110, 'A') + + create_vsc(net, 1, 0, 0.1, 5, 0.15, + control_mode_ac="vm_pu", control_value_ac=1, + control_mode_dc="vm_pu", control_value_dc=1.01) + create_vsc(net, 2, 0, 0.1, 5, 0.15, + control_mode_ac="slack", control_value_ac=1, + control_mode_dc="vm_pu", control_value_dc=1.01) # whatever we put in control_mode_dc should actually be ignored runpp_with_consistency_checks(net) @@ -2056,185 +2068,183 @@ def test_b2b_vsc_3(): def test_b2b_vsc_4(): - net = pp.create_empty_network() + net = create_empty_network() # AC part - pp.create_buses(net, 4, 110) - pp.create_line_from_parameters(net, 1, 3, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_load(net, 0, 40, 10) - pp.create_ext_grid(net, 3) - pp.create_load(net, 2, 80, 20) - + create_buses(net, 4, 110) + create_line_from_parameters(net, 1, 3, 30, 0.0487, 0.13823, 160, 0.664) + create_load(net, 0, 40, 10) + create_ext_grid(net, 3) + create_load(net, 2, 80, 20) # DC part - pp.create_bus_dc(net, 150, 'A') + create_bus_dc(net, 150, 'A') - pp.create_vsc(net, 0, 0, 0.1, 5, 0.15, - control_mode_ac="slack", control_value_ac=1., - control_mode_dc="p_mw", control_value_dc=0.) - pp.create_vsc(net, 1, 0, 0.1, 5, 0.15, - control_mode_ac="q_mvar", control_value_ac=10., - control_mode_dc="vm_pu", control_value_dc=1.02) - pp.create_vsc(net, 2, 0, 0.1, 5, 0.15, - control_mode_ac="slack", control_value_ac=1., - control_mode_dc="p_mw", control_value_dc=0.) + create_vsc(net, 0, 0, 0.1, 5, 0.15, + control_mode_ac="slack", control_value_ac=1., + control_mode_dc="p_mw", control_value_dc=0.) + create_vsc(net, 1, 0, 0.1, 5, 0.15, + control_mode_ac="q_mvar", control_value_ac=10., + control_mode_dc="vm_pu", control_value_dc=1.02) + create_vsc(net, 2, 0, 0.1, 5, 0.15, + control_mode_ac="slack", control_value_ac=1., + control_mode_dc="p_mw", control_value_dc=0.) runpp_with_consistency_checks(net) def test_b2b_vsc_5(): - net = pp.create_empty_network() + net = create_empty_network() # AC part - pp.create_buses(net, 5, 110) - pp.create_line_from_parameters(net, 1, 3, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 2, 4, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_ext_grid(net, 3) - pp.create_ext_grid(net, 4) - pp.create_load(net, 0, 40, 10) - pp.create_load(net, 2, 80, 20) - + create_buses(net, 5, 110) + create_line_from_parameters(net, 1, 3, 30, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 2, 4, 30, 0.0487, 0.13823, 160, 0.664) + create_ext_grid(net, 3) + create_ext_grid(net, 4) + create_load(net, 0, 40, 10) + create_load(net, 2, 80, 20) # DC part - pp.create_bus_dc(net, 150, 'A') + create_bus_dc(net, 150, 'A') - pp.create_vsc(net, 0, 0, 0.1, 5, 0.15, - control_mode_ac="slack", control_value_ac=1., - control_mode_dc="p_mw", control_value_dc=0.) - pp.create_vsc(net, 1, 0, 0.1, 5, 0.15, - control_mode_ac="q_mvar", control_value_ac=10., - control_mode_dc="vm_pu", control_value_dc=1.02) - pp.create_vsc(net, 2, 0, 0.1, 5, 0.15, - control_mode_ac="q_mvar", control_value_ac=4., - control_mode_dc="p_mw", control_value_dc=5.) + create_vsc(net, 0, 0, 0.1, 5, 0.15, + control_mode_ac="slack", control_value_ac=1., + control_mode_dc="p_mw", control_value_dc=0.) + create_vsc(net, 1, 0, 0.1, 5, 0.15, + control_mode_ac="q_mvar", control_value_ac=10., + control_mode_dc="vm_pu", control_value_dc=1.02) + create_vsc(net, 2, 0, 0.1, 5, 0.15, + control_mode_ac="q_mvar", control_value_ac=4., + control_mode_dc="p_mw", control_value_dc=5.) runpp_with_consistency_checks(net) def test_b2b_vsc_6(): - net = pp.create_empty_network() + net = create_empty_network() # AC part - pp.create_buses(net, 3, 110) - pp.create_line_from_parameters(net, 1, 2, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_ext_grid(net, 2) - pp.create_load(net, 0, 20, 5) + create_buses(net, 3, 110) + create_line_from_parameters(net, 1, 2, 30, 0.0487, 0.13823, 160, 0.664) + create_ext_grid(net, 2) + create_load(net, 0, 20, 5) # DC part - pp.create_bus_dc(net, 150, 'A') - pp.create_vsc(net, 0, 0, 0.1, 5, 0.15, - control_mode_ac="slack", control_value_ac=1., - control_mode_dc="p_mw", control_value_dc=0.) - pp.create_vsc(net, 1, 0, 0.1, 5, 0.15, - control_mode_ac="q_mvar", control_value_ac=0., - control_mode_dc="vm_pu", control_value_dc=1.) + create_bus_dc(net, 150, 'A') + create_vsc(net, 0, 0, 0.1, 5, 0.15, + control_mode_ac="slack", control_value_ac=1., + control_mode_dc="p_mw", control_value_dc=0.) + create_vsc(net, 1, 0, 0.1, 5, 0.15, + control_mode_ac="q_mvar", control_value_ac=0., + control_mode_dc="vm_pu", control_value_dc=1.) # with pytest.raises(NotImplementedError): - # pp.runpp(net) + # runpp(net) runpp_with_consistency_checks(net) def test_b2b_vsc_7(): - net = pp.create_empty_network() + net = create_empty_network() # AC part - pp.create_buses(net, 2, 110) - pp.create_ext_grid(net, 1) # todo: why is it not working when ext_grid is connected to the VSC AC bus? - pp.create_load(net, 0, 20, 5) + create_buses(net, 2, 110) + create_ext_grid(net, 1) # todo: why is it not working when ext_grid is connected to the VSC AC bus? + create_load(net, 0, 20, 5) # DC part - pp.create_bus_dc(net, 150, 'A') - pp.create_vsc(net, 0, 0, 0.1, 5, 0.15, - control_mode_ac="slack", control_value_ac=1., - control_mode_dc="p_mw", control_value_dc=0.) - pp.create_vsc(net, 1, 0, 0.1, 5, 0.15, - control_mode_ac="q_mvar", control_value_ac=0., - control_mode_dc="vm_pu", control_value_dc=1.) + create_bus_dc(net, 150, 'A') + create_vsc(net, 0, 0, 0.1, 5, 0.15, + control_mode_ac="slack", control_value_ac=1., + control_mode_dc="p_mw", control_value_dc=0.) + create_vsc(net, 1, 0, 0.1, 5, 0.15, + control_mode_ac="q_mvar", control_value_ac=0., + control_mode_dc="vm_pu", control_value_dc=1.) runpp_with_consistency_checks(net) def test_b2b_line_dc_raise(): - net = pp.create_empty_network() + net = create_empty_network() # AC part - pp.create_buses(net, 4, 110) - pp.create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 0, 2, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 2, 3, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_ext_grid(net, 0) - pp.create_load(net, 2, 10, q_mvar=5) + create_buses(net, 4, 110) + create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 0, 2, 30, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 2, 3, 30, 0.0487, 0.13823, 160, 0.664) + create_ext_grid(net, 0) + create_load(net, 2, 10, q_mvar=5) # DC part - pp.create_bus_dc(net, 110, 'A') - pp.create_bus_dc(net, 110, 'B') + create_bus_dc(net, 110, 'A') + create_bus_dc(net, 110, 'B') - pp.create_line_dc(net, 0, 1, 100, std_type="2400-CU") + create_line_dc(net, 0, 1, 100, std_type="2400-CU") - pp.create_vsc(net, 1, 0, 0.1, 5, 0.15, - control_mode_ac="vm_pu", control_value_ac=1, - control_mode_dc="vm_pu", control_value_dc=1.02) - pp.create_vsc(net, 2, 0, 0.1, 5, 0.15, - control_mode_ac="vm_pu", control_value_ac=1, - control_mode_dc="p_mw", control_value_dc=2) - pp.create_vsc(net, 3, 1, 0.1, 5, 0.15, - control_mode_ac="vm_pu", control_value_ac=1, - control_mode_dc="p_mw", control_value_dc=2) + create_vsc(net, 1, 0, 0.1, 5, 0.15, + control_mode_ac="vm_pu", control_value_ac=1, + control_mode_dc="vm_pu", control_value_dc=1.02) + create_vsc(net, 2, 0, 0.1, 5, 0.15, + control_mode_ac="vm_pu", control_value_ac=1, + control_mode_dc="p_mw", control_value_dc=2) + create_vsc(net, 3, 1, 0.1, 5, 0.15, + control_mode_ac="vm_pu", control_value_ac=1, + control_mode_dc="p_mw", control_value_dc=2) runpp_with_consistency_checks(net) # with pytest.raises(NotImplementedError, match="Back-To-Back"): - # pp.runpp(net) + # runpp(net) def test_line_dc_and_2_vsc1(): - net = pp.create_empty_network() + net = create_empty_network() # AC part - pp.create_buses(net, 4, 110) - pp.create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 0, 2, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 2, 3, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_ext_grid(net, 0) - pp.create_load(net, 2, 10, q_mvar=5) + create_buses(net, 4, 110) + create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 0, 2, 30, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 2, 3, 30, 0.0487, 0.13823, 160, 0.664) + create_ext_grid(net, 0) + create_load(net, 2, 10, q_mvar=5) # DC part - pp.create_bus_dc(net, 110, 'A') - pp.create_bus_dc(net, 110, 'B') + create_bus_dc(net, 110, 'A') + create_bus_dc(net, 110, 'B') - pp.create_line_dc(net, 0, 1, 100, std_type="2400-CU") + create_line_dc(net, 0, 1, 100, std_type="2400-CU") - pp.create_vsc(net, 1, 0, 0.1, 5, 0.15, - control_mode_ac="vm_pu", control_value_ac=1, - control_mode_dc="vm_pu", control_value_dc=1.02) - pp.create_vsc(net, 2, 0, 0.1, 5, 0.15, - control_mode_ac="vm_pu", control_value_ac=1, - control_mode_dc="vm_pu", control_value_dc=1.02) - pp.create_vsc(net, 3, 1, 0.1, 5, 0.15, - control_mode_ac="vm_pu", control_value_ac=1, - control_mode_dc="p_mw", control_value_dc=2) + create_vsc(net, 1, 0, 0.1, 5, 0.15, + control_mode_ac="vm_pu", control_value_ac=1, + control_mode_dc="vm_pu", control_value_dc=1.02) + create_vsc(net, 2, 0, 0.1, 5, 0.15, + control_mode_ac="vm_pu", control_value_ac=1, + control_mode_dc="vm_pu", control_value_dc=1.02) + create_vsc(net, 3, 1, 0.1, 5, 0.15, + control_mode_ac="vm_pu", control_value_ac=1, + control_mode_dc="p_mw", control_value_dc=2) runpp_with_consistency_checks(net) def test_line_dc_and_2_vsc2(): - net = pp.create_empty_network() + net = create_empty_network() # AC part - pp.create_buses(net, 4, 110) - pp.create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 0, 2, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 2, 3, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_ext_grid(net, 0) - pp.create_load(net, 3, 10, q_mvar=5) + create_buses(net, 4, 110) + create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 0, 2, 30, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 2, 3, 30, 0.0487, 0.13823, 160, 0.664) + create_ext_grid(net, 0) + create_load(net, 3, 10, q_mvar=5) # DC part - pp.create_bus_dc(net, 110, 'A') - pp.create_bus_dc(net, 110, 'B') + create_bus_dc(net, 110, 'A') + create_bus_dc(net, 110, 'B') - pp.create_line_dc(net, 0, 1, 100, std_type="2400-CU") + create_line_dc(net, 0, 1, 100, std_type="2400-CU") - pp.create_vsc(net, 1, 0, 0.1, 5, 0.15, - control_mode_ac="vm_pu", control_value_ac=1, - control_mode_dc="p_mw", control_value_dc=-2) - pp.create_vsc(net, 2, 0, 0.1, 5, 0.15, - control_mode_ac="vm_pu", control_value_ac=1, - control_mode_dc="p_mw", control_value_dc=-2) - pp.create_vsc(net, 3, 1, 0.1, 5, 0.15, - control_mode_ac="vm_pu", control_value_ac=1, - control_mode_dc="vm_pu", control_value_dc=1.02) + create_vsc(net, 1, 0, 0.1, 5, 0.15, + control_mode_ac="vm_pu", control_value_ac=1, + control_mode_dc="p_mw", control_value_dc=-2) + create_vsc(net, 2, 0, 0.1, 5, 0.15, + control_mode_ac="vm_pu", control_value_ac=1, + control_mode_dc="p_mw", control_value_dc=-2) + create_vsc(net, 3, 1, 0.1, 5, 0.15, + control_mode_ac="vm_pu", control_value_ac=1, + control_mode_dc="vm_pu", control_value_dc=1.02) runpp_with_consistency_checks(net) @@ -2249,31 +2259,31 @@ def test_2vsc_1ac_2dc(control_mode_ac, control_mode_dc): val_ac = {"vm_pu": 1, "q_mvar": -5} val_dc = {"vm_pu": 1, "p_mw": 10} - net = pp.create_empty_network() + net = create_empty_network() # AC part - pp.create_buses(net, 2, 110) - pp.create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_ext_grid(net, 0) - pp.create_load(net, 1, 10, 3) + create_buses(net, 2, 110) + create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) + create_ext_grid(net, 0) + create_load(net, 1, 10, 3) # DC part - pp.create_bus_dc(net, 110, 'A') - pp.create_bus_dc(net, 110, 'B') + create_bus_dc(net, 110, 'A') + create_bus_dc(net, 110, 'B') - pp.create_line_dc(net, 0, 1, 100, std_type="2400-CU") + create_line_dc(net, 0, 1, 100, std_type="2400-CU") - pp.create_vsc(net, 1, 0, 0.1, 5, 0.15, - control_mode_ac=control_mode_ac[0], control_value_ac=val_ac[control_mode_ac[0]], - control_mode_dc=control_mode_dc[0], control_value_dc=val_dc[control_mode_dc[0]]) - pp.create_vsc(net, 1, 1, 0.1, 5, 0.15, - control_mode_ac=control_mode_ac[1], control_value_ac=val_ac[control_mode_ac[1]], - control_mode_dc=control_mode_dc[1], control_value_dc=val_dc[control_mode_dc[1]]) + create_vsc(net, 1, 0, 0.1, 5, 0.15, + control_mode_ac=control_mode_ac[0], control_value_ac=val_ac[control_mode_ac[0]], + control_mode_dc=control_mode_dc[0], control_value_dc=val_dc[control_mode_dc[0]]) + create_vsc(net, 1, 1, 0.1, 5, 0.15, + control_mode_ac=control_mode_ac[1], control_value_ac=val_ac[control_mode_ac[1]], + control_mode_dc=control_mode_dc[1], control_value_dc=val_dc[control_mode_dc[1]]) if control_mode_ac[0] == control_mode_ac[1]: runpp_with_consistency_checks(net) else: with pytest.raises(NotImplementedError, match="share the same AC bus"): - pp.runpp(net) + runpp(net) @pytest.mark.skip(reason="DC line connected to D2B VSC configuration not implemented") @@ -2286,27 +2296,27 @@ def test_2vsc_2ac_1dc(control_mode_ac, control_mode_dc): val_ac = {"vm_pu": 1, "q_mvar": -5} val_dc = {"vm_pu": 1, "p_mw": 10} - net = pp.create_empty_network() + net = create_empty_network() # AC part - pp.create_buses(net, 3, 110) - pp.create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 0, 2, 30, 0.0487, 0.13823, 160, 0.664) + create_buses(net, 3, 110) + create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 0, 2, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_ext_grid(net, 0) - pp.create_load(net, 1, 10, 3) + create_ext_grid(net, 0) + create_load(net, 1, 10, 3) # DC part - pp.create_bus_dc(net, 110, 'A') - pp.create_bus_dc(net, 110, 'A') + create_bus_dc(net, 110, 'A') + create_bus_dc(net, 110, 'A') - pp.create_line_dc(net, 0, 1, 100, std_type="2400-CU") + create_line_dc(net, 0, 1, 100, std_type="2400-CU") - pp.create_vsc(net, 1, 0, 0.1, 5, 0.15, control_mode_ac=control_mode_ac[0], - control_value_ac=val_ac[control_mode_ac[0]], control_mode_dc=control_mode_dc[0], - control_value_dc=val_dc[control_mode_dc[0]]) - pp.create_vsc(net, 2, 0, 0.1, 5, 0.15, control_mode_ac=control_mode_ac[1], - control_value_ac=val_ac[control_mode_ac[1]], control_mode_dc=control_mode_dc[1], - control_value_dc=val_dc[control_mode_dc[1]]) + create_vsc(net, 1, 0, 0.1, 5, 0.15, control_mode_ac=control_mode_ac[0], + control_value_ac=val_ac[control_mode_ac[0]], control_mode_dc=control_mode_dc[0], + control_value_dc=val_dc[control_mode_dc[0]]) + create_vsc(net, 2, 0, 0.1, 5, 0.15, control_mode_ac=control_mode_ac[1], + control_value_ac=val_ac[control_mode_ac[1]], control_mode_dc=control_mode_dc[1], + control_value_dc=val_dc[control_mode_dc[1]]) runpp_with_consistency_checks(net) @@ -2321,203 +2331,203 @@ def test_2vsc_1ac_1dc(control_mode_ac, control_mode_dc): val_ac = {"vm_pu": 1, "q_mvar": -5} val_dc = {"vm_pu": 1, "p_mw": 10} - net = pp.create_empty_network() + net = create_empty_network() # AC part - pp.create_buses(net, 2, 110) - pp.create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) + create_buses(net, 2, 110) + create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_ext_grid(net, 0) - pp.create_load(net, 1, 10, q_mvar=5) + create_ext_grid(net, 0) + create_load(net, 1, 10, q_mvar=5) # DC part - pp.create_bus_dc(net, 110, 'A') - pp.create_bus_dc(net, 110, 'A') + create_bus_dc(net, 110, 'A') + create_bus_dc(net, 110, 'A') - pp.create_line_dc(net, 0, 1, 100, std_type="2400-CU") + create_line_dc(net, 0, 1, 100, std_type="2400-CU") - pp.create_vsc(net, 1, 0, 0.1, 5, 0.15, control_mode_ac=control_mode_ac[0], - control_value_ac=val_ac[control_mode_ac[0]], control_mode_dc=control_mode_dc[0], - control_value_dc=val_dc[control_mode_dc[0]]) - pp.create_vsc(net, 1, 0, 0.1, 5, 0.15, control_mode_ac=control_mode_ac[1], - control_value_ac=val_ac[control_mode_ac[1]], control_mode_dc=control_mode_dc[1], - control_value_dc=val_dc[control_mode_dc[1]]) + create_vsc(net, 1, 0, 0.1, 5, 0.15, control_mode_ac=control_mode_ac[0], + control_value_ac=val_ac[control_mode_ac[0]], control_mode_dc=control_mode_dc[0], + control_value_dc=val_dc[control_mode_dc[0]]) + create_vsc(net, 1, 0, 0.1, 5, 0.15, control_mode_ac=control_mode_ac[1], + control_value_ac=val_ac[control_mode_ac[1]], control_mode_dc=control_mode_dc[1], + control_value_dc=val_dc[control_mode_dc[1]]) if control_mode_ac[0] == control_mode_ac[1]: runpp_with_consistency_checks(net) else: with pytest.raises(NotImplementedError, match="share the same AC bus"): - pp.runpp(net) + runpp(net) def test_vsc_slack_minimal_wrong(): # np.set_printoptions(linewidth=1000, suppress=True, precision=2) # from pandapower.test.loadflow.test_facts import * - net = pp.create_empty_network() + net = create_empty_network() # AC part - pp.create_buses(net, 2, 110, geodata=[(200, 0), (400, 0)]) - pp.create_load(net, 1, 10, 4) - pp.create_gen(net, 0, 0) + create_buses(net, 2, 110, geodata=[(200, 0), (400, 0)]) + create_load(net, 1, 10, 4) + create_gen(net, 0, 0) # DC part - pp.create_bus_dc(net, 110, 'A', geodata=(210, 0)) - pp.create_bus_dc(net, 110, 'B', geodata=(390, 0)) + create_bus_dc(net, 110, 'A', geodata=(210, 0)) + create_bus_dc(net, 110, 'B', geodata=(390, 0)) - pp.create_line_dc(net, 0, 1, 100, std_type="2400-CU") + create_line_dc(net, 0, 1, 100, std_type="2400-CU") - pp.create_vsc(net, 0, 0, 0.1, 5, 0.15, - control_mode_ac="slack", control_value_ac=1, - control_mode_dc="vm_pu", control_value_dc=1.02) - pp.create_vsc(net, 1, 1, 0.1, 5, 0.15, - control_mode_ac="slack", control_value_ac=1, - control_mode_dc="p_mw", control_value_dc=1) + create_vsc(net, 0, 0, 0.1, 5, 0.15, + control_mode_ac="slack", control_value_ac=1, + control_mode_dc="vm_pu", control_value_dc=1.02) + create_vsc(net, 1, 1, 0.1, 5, 0.15, + control_mode_ac="slack", control_value_ac=1, + control_mode_dc="p_mw", control_value_dc=1) # VSC as slack cannot have DC bus as vm_pu, therefore must be excluded from DC slacks # Then the DC buses are set out of service, and the corresponding VSC are also set out of service # Then the corresponding AC buses are changed from type REF to type PQ, which is valid because type PV is set later # Then runpp raises "no slacks" error: with pytest.raises(UserWarning, match="No reference bus is available"): - pp.runpp(net) + runpp(net) def test_vsc_slack_minimal_wrong2(): # np.set_printoptions(linewidth=1000, suppress=True, precision=2) # from pandapower.test.loadflow.test_facts import * - net = pp.create_empty_network() + net = create_empty_network() # AC part - pp.create_buses(net, 2, 110, geodata=[(200, 0), (400, 0)]) - pp.create_load(net, 1, 10, 4) + create_buses(net, 2, 110, geodata=[(200, 0), (400, 0)]) + create_load(net, 1, 10, 4) # DC part - pp.create_bus_dc(net, 110, 'A', geodata=(210, 0)) - pp.create_bus_dc(net, 110, 'B', geodata=(390, 0)) + create_bus_dc(net, 110, 'A', geodata=(210, 0)) + create_bus_dc(net, 110, 'B', geodata=(390, 0)) - pp.create_line_dc(net, 0, 1, 100, std_type="2400-CU") + create_line_dc(net, 0, 1, 100, std_type="2400-CU") - pp.create_vsc(net, 0, 0, 0.1, 5, 0.15, - control_mode_ac="vm_pu", control_value_ac=1, - control_mode_dc="vm_pu", control_value_dc=1.02) - pp.create_vsc(net, 1, 1, 0.1, 5, 0.15, - control_mode_ac="slack", control_value_ac=1, - control_mode_dc="p_mw", control_value_dc=1) + create_vsc(net, 0, 0, 0.1, 5, 0.15, + control_mode_ac="vm_pu", control_value_ac=1, + control_mode_dc="vm_pu", control_value_dc=1.02) + create_vsc(net, 1, 1, 0.1, 5, 0.15, + control_mode_ac="slack", control_value_ac=1, + control_mode_dc="p_mw", control_value_dc=1) # VSC that defines AC slack cannot define DC slack at the same time # DC slack buses that are only connected to VSC AC slacks are converted to type P buses # Then runpp raises "no DC slacks" error: with pytest.raises(UserWarning, match="No reference bus for the dc grid is available"): - pp.runpp(net) + runpp(net) @pytest.mark.xfail(reason="AC bus same as ext_grid bus not implemented") def test_vsc_slack_minimal(): # todo: fix that FACTS elements can be connected to ext_grid buses # np.set_printoptions(linewidth=1000, suppress=True, precision=2) # from pandapower.test.loadflow.test_facts import * - net = pp.create_empty_network() + net = create_empty_network() # AC part - pp.create_buses(net, 2, 110, geodata=[(200, 0), (400, 0)]) - pp.create_load(net, 1, 10, 4) - pp.create_ext_grid(net, 0) + create_buses(net, 2, 110, geodata=[(200, 0), (400, 0)]) + create_load(net, 1, 10, 4) + create_ext_grid(net, 0) # DC part - pp.create_bus_dc(net, 110, 'A', geodata=(210, 0)) - pp.create_bus_dc(net, 110, 'B', geodata=(390, 0)) + create_bus_dc(net, 110, 'A', geodata=(210, 0)) + create_bus_dc(net, 110, 'B', geodata=(390, 0)) - pp.create_line_dc(net, 0, 1, 100, std_type="2400-CU") + create_line_dc(net, 0, 1, 100, std_type="2400-CU") - pp.create_vsc(net, 0, 0, 0.1, 5, 0.15, - control_mode_ac="vm_pu", control_value_ac=1, - control_mode_dc="vm_pu", control_value_dc=1.02) - pp.create_vsc(net, 1, 1, 0.1, 5, 0.15, - control_mode_ac="slack", control_value_ac=1, - control_mode_dc="p_mw", control_value_dc=1) + create_vsc(net, 0, 0, 0.1, 5, 0.15, + control_mode_ac="vm_pu", control_value_ac=1, + control_mode_dc="vm_pu", control_value_dc=1.02) + create_vsc(net, 1, 1, 0.1, 5, 0.15, + control_mode_ac="slack", control_value_ac=1, + control_mode_dc="p_mw", control_value_dc=1) - # pp.runpp(net) + # runpp(net) runpp_with_consistency_checks(net) - # pp.plotting.simple_plot(net, plot_loads=True, load_size=5) + # plotting.simple_plot(net, plot_loads=True, load_size=5) def test_vsc_slack(): # np.set_printoptions(linewidth=1000, suppress=True, precision=3) # from pandapower.test.loadflow.test_facts import * - net = pp.create_empty_network() + net = create_empty_network() # AC part - pp.create_buses(net, 4, 110, geodata=[(0, 0), (200, 0), (400, 0), (600, 0)]) - pp.create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 2, 3, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_ext_grid(net, 0) - pp.create_load(net, 3, 10, 4) + create_buses(net, 4, 110, geodata=[(0, 0), (200, 0), (400, 0), (600, 0)]) + create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 2, 3, 30, 0.0487, 0.13823, 160, 0.664) + create_ext_grid(net, 0) + create_load(net, 3, 10, 4) # DC part - pp.create_bus_dc(net, 110, 'A', geodata=(210, 0)) - pp.create_bus_dc(net, 110, 'B', geodata=(390, 0)) + create_bus_dc(net, 110, 'A', geodata=(210, 0)) + create_bus_dc(net, 110, 'B', geodata=(390, 0)) - pp.create_line_dc(net, 0, 1, 100, std_type="2400-CU") + create_line_dc(net, 0, 1, 100, std_type="2400-CU") - pp.create_vsc(net, 1, 0, 0.1, 5, 0.15, - control_mode_ac="vm_pu", control_value_ac=1, - control_mode_dc="vm_pu", control_value_dc=1.02) - pp.create_vsc(net, 2, 1, 0.1, 5, 0.15, - control_mode_ac="slack", control_value_ac=1, - control_mode_dc="p_mw", control_value_dc=0.) + create_vsc(net, 1, 0, 0.1, 5, 0.15, + control_mode_ac="vm_pu", control_value_ac=1, + control_mode_dc="vm_pu", control_value_dc=1.02) + create_vsc(net, 2, 1, 0.1, 5, 0.15, + control_mode_ac="slack", control_value_ac=1, + control_mode_dc="p_mw", control_value_dc=0.) runpp_with_consistency_checks(net) - # pp.plotting.simple_plot(net, plot_loads=True) + # plotting.simple_plot(net, plot_loads=True) def test_vsc_slack2(): # np.set_printoptions(linewidth=1000, suppress=True, precision=3) # from pandapower.test.loadflow.test_facts import * - net = pp.create_empty_network() + net = create_empty_network() # AC part - pp.create_buses(net, 3, 110, geodata=[(0, 0), (200, 0), (400, 0)]) - pp.create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_ext_grid(net, 0) - pp.create_load(net, 2, 10, 4) + create_buses(net, 3, 110, geodata=[(0, 0), (200, 0), (400, 0)]) + create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) + create_ext_grid(net, 0) + create_load(net, 2, 10, 4) # DC part - pp.create_bus_dc(net, 110, 'A', geodata=(210, 0)) - pp.create_bus_dc(net, 110, 'B', geodata=(390, 0)) + create_bus_dc(net, 110, 'A', geodata=(210, 0)) + create_bus_dc(net, 110, 'B', geodata=(390, 0)) - pp.create_line_dc(net, 0, 1, 100, std_type="2400-CU") + create_line_dc(net, 0, 1, 100, std_type="2400-CU") - pp.create_vsc(net, 1, 0, 0.1, 5, 0.15, - control_mode_ac="vm_pu", control_value_ac=1, - control_mode_dc="vm_pu", control_value_dc=1.02) - pp.create_vsc(net, 2, 1, 0.1, 5, 0.15, - control_mode_ac="slack", control_value_ac=1, - control_mode_dc="p_mw", control_value_dc=10) + create_vsc(net, 1, 0, 0.1, 5, 0.15, + control_mode_ac="vm_pu", control_value_ac=1, + control_mode_dc="vm_pu", control_value_dc=1.02) + create_vsc(net, 2, 1, 0.1, 5, 0.15, + control_mode_ac="slack", control_value_ac=1, + control_mode_dc="p_mw", control_value_dc=10) runpp_with_consistency_checks(net) - # pp.plotting.simple_plot(net, plot_loads=True) + # plotting.simple_plot(net, plot_loads=True) def test_vsc_slack_oos(): # np.set_printoptions(linewidth=1000, suppress=True, precision=3) # from pandapower.test.loadflow.test_facts import * - net = pp.create_empty_network() + net = create_empty_network() # AC part - pp.create_buses(net, 4, 110, geodata=[(0, 0), (200, 0), (400, 0), (600, 0)]) - pp.create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 2, 3, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_ext_grid(net, 0) - pp.create_load(net, 3, 10, 4) + create_buses(net, 4, 110, geodata=[(0, 0), (200, 0), (400, 0), (600, 0)]) + create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 2, 3, 30, 0.0487, 0.13823, 160, 0.664) + create_ext_grid(net, 0) + create_load(net, 3, 10, 4) net.bus.loc[[2, 3], "in_service"] = False # DC part - pp.create_bus_dc(net, 110, 'A', geodata=(210, 0)) - pp.create_bus_dc(net, 110, 'B', geodata=(390, 0)) + create_bus_dc(net, 110, 'A', geodata=(210, 0)) + create_bus_dc(net, 110, 'B', geodata=(390, 0)) - pp.create_line_dc(net, 0, 1, 100, std_type="2400-CU") + create_line_dc(net, 0, 1, 100, std_type="2400-CU") - pp.create_vsc(net, 1, 0, 0.1, 5, 0.15, - control_mode_ac="vm_pu", control_value_ac=1, - control_mode_dc="vm_pu", control_value_dc=1.02) - pp.create_vsc(net, 2, 1, 0.1, 5, 0.15, - control_mode_ac="slack", control_value_ac=1, - control_mode_dc="p_mw", control_value_dc=0.) + create_vsc(net, 1, 0, 0.1, 5, 0.15, + control_mode_ac="vm_pu", control_value_ac=1, + control_mode_dc="vm_pu", control_value_dc=1.02) + create_vsc(net, 2, 1, 0.1, 5, 0.15, + control_mode_ac="slack", control_value_ac=1, + control_mode_dc="p_mw", control_value_dc=0.) runpp_with_consistency_checks(net) @@ -2525,60 +2535,60 @@ def test_vsc_slack_oos(): def test_vsc_dc_r(): # np.set_printoptions(linewidth=1000, suppress=True, precision=3) # from pandapower.test.loadflow.test_facts import * - net = pp.create_empty_network() + net = create_empty_network() # AC part - pp.create_buses(net, 3, 110, geodata=[(0, 0), (200, 0), (400, 0)]) - pp.create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_ext_grid(net, 0) - pp.create_load(net, 2, 10, 4) + create_buses(net, 3, 110, geodata=[(0, 0), (200, 0), (400, 0)]) + create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) + create_ext_grid(net, 0) + create_load(net, 2, 10, 4) # DC part - pp.create_bus_dc(net, 110, 'A', geodata=(210, 0)) - pp.create_bus_dc(net, 110, 'B', geodata=(390, 0)) + create_bus_dc(net, 110, 'A', geodata=(210, 0)) + create_bus_dc(net, 110, 'B', geodata=(390, 0)) - pp.create_line_dc(net, 0, 1, 100, std_type="2400-CU") + create_line_dc(net, 0, 1, 100, std_type="2400-CU") - pp.create_vsc(net, 1, 0, 0.1, 5, 0.15, - control_mode_ac="vm_pu", control_value_ac=1, - control_mode_dc="vm_pu", control_value_dc=1.02) - pp.create_vsc(net, 2, 1, 0.1, 5, 0.15, - control_mode_ac="slack", control_value_ac=1, - control_mode_dc="p_mw", control_value_dc=10) + create_vsc(net, 1, 0, 0.1, 5, 0.15, + control_mode_ac="vm_pu", control_value_ac=1, + control_mode_dc="vm_pu", control_value_dc=1.02) + create_vsc(net, 2, 1, 0.1, 5, 0.15, + control_mode_ac="slack", control_value_ac=1, + control_mode_dc="p_mw", control_value_dc=10) runpp_with_consistency_checks(net) def test_vsc_hvdc_dc_rl(): # from pandapower.test.loadflow.test_facts import * - net = pp.create_empty_network() + net = create_empty_network() # AC part - pp.create_buses(net, 3, 110) - pp.create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_line_from_parameters(net, 0, 2, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_ext_grid(net, 0) - pp.create_load(net, 2, 10, 5) + create_buses(net, 3, 110) + create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 0, 2, 30, 0.0487, 0.13823, 160, 0.664) + create_ext_grid(net, 0) + create_load(net, 2, 10, 5) # DC part - pp.create_bus_dc(net, 110, 'A') - pp.create_bus_dc(net, 110, 'B') + create_bus_dc(net, 110, 'A') + create_bus_dc(net, 110, 'B') - pp.create_line_dc_from_parameters(net, 0, 1, 100, 0.1, 1) + create_line_dc_from_parameters(net, 0, 1, 100, 0.1, 1) - pp.create_vsc(net, 1, 0, 0.1, 5, 0.5, pl_dc_mw=0.5, - control_mode_ac="vm_pu", control_value_ac=1., - control_mode_dc="vm_pu", control_value_dc=1.02) - pp.create_vsc(net, 2, 1, 0.1, 5, 0.5, pl_dc_mw=0.75, - control_mode_ac="vm_pu", control_value_ac=1., - control_mode_dc="p_mw", control_value_dc=5) + create_vsc(net, 1, 0, 0.1, 5, 0.5, pl_dc_mw=0.5, + control_mode_ac="vm_pu", control_value_ac=1., + control_mode_dc="vm_pu", control_value_dc=1.02) + create_vsc(net, 2, 1, 0.1, 5, 0.5, pl_dc_mw=0.75, + control_mode_ac="vm_pu", control_value_ac=1., + control_mode_dc="p_mw", control_value_dc=5) runpp_with_consistency_checks(net) def test_results_pf_grid(): # todo: improve accuracy of DC losses and reduce tolerances - path = os.path.join(pp.pp_dir, "test", "test_files", "test_ac_dc.json") - net = pp.from_json(path) - res = pp.converter.validate_pf_conversion(net) + path = os.path.join(pp_dir, "test", "test_files", "test_ac_dc.json") + net = from_json(path) + res = validate_pf_conversion(net) assert np.max(np.abs(res['diff_vm']['diff'])) < 1e-6 assert np.max(np.abs(res['diff_va']['diff'])) < 1e-3 assert np.max(np.abs(res['bus_dc_diff'])) < 5e-6 diff --git a/pandapower/test/loadflow/test_recycle.py b/pandapower/test/loadflow/test_recycle.py index a6bd3ef7d..d22cce6e3 100644 --- a/pandapower/test/loadflow/test_recycle.py +++ b/pandapower/test/loadflow/test_recycle.py @@ -3,27 +3,29 @@ import numpy as np import pytest -import pandapower as pp -from pandapower.toolbox import nets_equal -from pandapower.test import add_grid_connection +from pandapower.create import create_empty_network, create_bus, create_line_from_parameters, create_load, create_gen, \ + create_transformer, create_ext_grid, create_line, create_transformer_from_parameters +from pandapower.run import set_user_pf_options, runpp, rundcpp from pandapower.test.consistency_checks import runpp_with_consistency_checks, rundcpp_with_consistency_checks +from pandapower.test.helper_functions import add_grid_connection +from pandapower.toolbox.comparison import nets_equal @pytest.fixture def recycle_net(): - net = pp.create_empty_network() + net = create_empty_network() b1, b2, ln = add_grid_connection(net) pl = 1.2 ql = 1.1 ps = 0.5 u_set = 1.0 - b3 = pp.create_bus(net, vn_kv=.4) - pp.create_bus(net, vn_kv=.4, in_service=False) - pp.create_line_from_parameters(net, b2, b3, 12.2, r_ohm_per_km=0.08, x_ohm_per_km=0.12, - c_nf_per_km=300, max_i_ka=.2, df=.8) - pp.create_load(net, b3, p_mw=pl, q_mvar=ql) - pp.create_gen(net, b2, p_mw=ps, vm_pu=u_set) + b3 = create_bus(net, vn_kv=.4) + create_bus(net, vn_kv=.4, in_service=False) + create_line_from_parameters(net, b2, b3, 12.2, r_ohm_per_km=0.08, x_ohm_per_km=0.12, + c_nf_per_km=300, max_i_ka=.2, df=.8) + create_load(net, b3, p_mw=pl, q_mvar=ql) + create_gen(net, b2, p_mw=ps, vm_pu=u_set) return net @@ -71,8 +73,8 @@ def test_recycle_gen(recycle_net): def test_recycle_trafo(recycle_net): # test trafo tap change net = recycle_net - b4 = pp.create_bus(net, vn_kv=20.) - pp.create_transformer(net, 3, b4, std_type="0.4 MVA 10/0.4 kV") + b4 = create_bus(net, vn_kv=20.) + create_transformer(net, 3, b4, std_type="0.4 MVA 10/0.4 kV") net["trafo"].at[0, "tap_pos"] = 0 runpp_with_consistency_checks(net, recycle=dict(trafo=True, bus_pq=False, gen=False)) @@ -86,8 +88,8 @@ def test_recycle_trafo(recycle_net): def test_recycle_trafo_bus_gen(recycle_net): # test trafo tap change net = recycle_net - b4 = pp.create_bus(net, vn_kv=20.) - pp.create_transformer(net, 3, b4, std_type="0.4 MVA 10/0.4 kV") + b4 = create_bus(net, vn_kv=20.) + create_transformer(net, 3, b4, std_type="0.4 MVA 10/0.4 kV") ps = 0.25 u_set = 0.98 @@ -124,23 +126,23 @@ def test_recycle_trafo_bus_gen(recycle_net): def test_result_index_unsorted(): - net = pp.create_empty_network() - pp.set_user_pf_options(net, tolerance_mva=1e-9) + net = create_empty_network() + set_user_pf_options(net, tolerance_mva=1e-9) - b1 = pp.create_bus(net, vn_kv=0.4, index=4) - b2 = pp.create_bus(net, vn_kv=0.4, index=2) - b3 = pp.create_bus(net, vn_kv=0.4, index=3) + b1 = create_bus(net, vn_kv=0.4, index=4) + b2 = create_bus(net, vn_kv=0.4, index=2) + b3 = create_bus(net, vn_kv=0.4, index=3) - pp.create_gen(net, b1, p_mw=0.01, vm_pu=0.4) - pp.create_load(net, b2, p_mw=0.01) - pp.create_ext_grid(net, b3) + create_gen(net, b1, p_mw=0.01, vm_pu=0.4) + create_load(net, b2, p_mw=0.01) + create_ext_grid(net, b3) - pp.create_line(net, from_bus=b1, to_bus=b2, length_km=0.5, std_type="NAYY 4x120 SE") - pp.create_line(net, from_bus=b1, to_bus=b3, length_km=0.5, std_type="NAYY 4x120 SE") + create_line(net, from_bus=b1, to_bus=b2, length_km=0.5, std_type="NAYY 4x120 SE") + create_line(net, from_bus=b1, to_bus=b3, length_km=0.5, std_type="NAYY 4x120 SE") net_recycle = copy.deepcopy(net) - pp.runpp(net_recycle) - pp.runpp(net_recycle, recycle=dict(trafo=True, bus_pq=True, gen=True)) - pp.runpp(net) + runpp(net_recycle) + runpp(net_recycle, recycle=dict(trafo=True, bus_pq=True, gen=True)) + runpp(net) assert nets_equal(net, net_recycle, atol=1e-12) @@ -162,12 +164,12 @@ def test_recycle_dc(recycle_net): def test_recycle_dc_trafo_shift(recycle_net): net = recycle_net - pp.set_user_pf_options(net, calculate_voltage_angles=True) - b4 = pp.create_bus(net, vn_kv=20.) - pp.create_transformer(net, 3, b4, std_type="0.4 MVA 10/0.4 kV") + set_user_pf_options(net, calculate_voltage_angles=True) + b4 = create_bus(net, vn_kv=20.) + create_transformer(net, 3, b4, std_type="0.4 MVA 10/0.4 kV") net["trafo"].at[0, "tap_pos"] = 0 net["trafo"].at[0, "tap_step_percent"] = 1 - #net["trafo"].at[0, "tap_phase_shifter"] = True + # net["trafo"].at[0, "tap_phase_shifter"] = True net["trafo"].at[0, "tap_step_degree"] = 30 net2 = net.deepcopy() pl = 1.2 @@ -186,18 +188,18 @@ def test_recycle_dc_trafo_shift(recycle_net): net2.load.at[0, "p_mw"] = pl net2.load.at[0, "q_mvar"] = ql net2.trafo.at[0, "tap_pos"] = 3 - pp.rundcpp(net2) + rundcpp(net2) assert np.allclose(net.res_bus.va_degree, net2.res_bus.va_degree, rtol=0, atol=1e-9, equal_nan=True) def test_recycle_dc_trafo_ideal(recycle_net): net = recycle_net - pp.set_user_pf_options(net, calculate_voltage_angles=True) + set_user_pf_options(net, calculate_voltage_angles=True) v = net.bus.vn_kv.at[3] - b4 = pp.create_bus(net, vn_kv=v) - pp.create_transformer_from_parameters(net, 3, b4, 10, v, v, 0.5, 12, 10, 0.1, 0, - tap_side='hv', tap_neutral=0, tap_max=10, tap_min=-10, - tap_step_percent=0, tap_step_degree=30, tap_pos=0, tap_phase_shifter=True) + b4 = create_bus(net, vn_kv=v) + create_transformer_from_parameters(net, 3, b4, 10, v, v, 0.5, 12, 10, 0.1, 0, + tap_side='hv', tap_neutral=0, tap_max=10, tap_min=-10, + tap_step_percent=0, tap_step_degree=30, tap_pos=0, tap_phase_shifter=True) net2 = net.deepcopy() pl = 1.2 ql = 0. @@ -215,9 +217,9 @@ def test_recycle_dc_trafo_ideal(recycle_net): net2.load.at[0, "p_mw"] = pl net2.load.at[0, "q_mvar"] = ql net2.trafo.at[0, "tap_pos"] = 3 - pp.rundcpp(net2) + rundcpp(net2) assert np.allclose(net.res_bus.va_degree, net2.res_bus.va_degree, rtol=0, atol=1e-9, equal_nan=True) if __name__ == "__main__": - pytest.main([__file__, "-xs"]) \ No newline at end of file + pytest.main([__file__, "-xs"]) diff --git a/pandapower/test/loadflow/test_results.py b/pandapower/test/loadflow/test_results.py index c20882ab7..7b2f6d914 100644 --- a/pandapower/test/loadflow/test_results.py +++ b/pandapower/test/loadflow/test_results.py @@ -3,29 +3,38 @@ # Copyright (c) 2016-2024 by University of Kassel and Fraunhofer Institute for Energy Economics # and Energy System Technology (IEE), Kassel. All rights reserved. import os + +import numpy as np import pandas as pd import pytest -import numpy as np -from numpy import isin, isnan, isclose, allclose - -import pandapower as pp -import pandapower.control +from numpy import isin, isnan, isclose + +from pandapower import pp_dir +from pandapower.control.controller.trafo.TapDependentImpedance import TapDependentImpedance +from pandapower.control.util.auxiliary import create_trafo_characteristics +from pandapower.control.util.characteristic import Characteristic, SplineCharacteristic +from pandapower.create import create_bus, create_load, create_transformer3w_from_parameters, create_transformer, \ + create_empty_network, create_ext_grid, create_line_from_parameters, create_transformer_from_parameters, \ + create_impedance +from pandapower.file_io import from_json +from pandapower.run import runpp +from pandapower.test.conftest import result_test_network from pandapower.test.consistency_checks import runpp_with_consistency_checks +from pandapower.test.helper_functions import assert_res_equal from pandapower.test.loadflow.result_test_network_generator import add_test_enforce_qlims, \ add_test_gen -from pandapower.test.helper_functions import assert_res_equal -from pandapower.test.conftest import result_test_network + # simple example grid for tap dependent impedance tests: def add_trafo_connection(net, hv_bus, trafotype="2W"): - cb = pp.create_bus(net, vn_kv=0.4) - pp.create_load(net, cb, 0.2, 0.05) + cb = create_bus(net, vn_kv=0.4) + create_load(net, cb, 0.2, 0.05) if trafotype == "3W": - cbm = pp.create_bus(net, vn_kv=0.9) - pp.create_load(net, cbm, 0.1, 0.03) - pp.create_transformer3w_from_parameters( + cbm = create_bus(net, vn_kv=0.9) + create_load(net, cbm, 0.1, 0.03) + create_transformer3w_from_parameters( net, hv_bus=hv_bus, mv_bus=cbm, lv_bus=cb, vn_hv_kv=20., vn_mv_kv=0.9, vn_lv_kv=0.45, sn_hv_mva=0.6, sn_mv_mva=0.5, sn_lv_mva=0.4, vk_hv_percent=1., vk_mv_percent=1., vk_lv_percent=1., @@ -33,17 +42,17 @@ def add_trafo_connection(net, hv_bus, trafotype="2W"): pfe_kw=0.2, i0_percent=0.3, tap_neutral=0., tap_pos=2, tap_step_percent=1., tap_min=-2, tap_max=2) else: - pp.create_transformer(net, hv_bus=hv_bus, lv_bus=cb, std_type="0.25 MVA 20/0.4 kV", tap_pos=2) + create_transformer(net, hv_bus=hv_bus, lv_bus=cb, std_type="0.25 MVA 20/0.4 kV", tap_pos=2) def create_net(): - net = pp.create_empty_network() + net = create_empty_network() vn_kv = 20 - b1 = pp.create_bus(net, vn_kv=vn_kv) - pp.create_ext_grid(net, b1, vm_pu=1.01) - b2 = pp.create_bus(net, vn_kv=vn_kv) - l1 = pp.create_line_from_parameters(net, b1, b2, 12.2, r_ohm_per_km=0.08, x_ohm_per_km=0.12, - c_nf_per_km=300, max_i_ka=.2, df=.8) + b1 = create_bus(net, vn_kv=vn_kv) + create_ext_grid(net, b1, vm_pu=1.01) + b2 = create_bus(net, vn_kv=vn_kv) + l1 = create_line_from_parameters(net, b1, b2, 12.2, r_ohm_per_km=0.08, x_ohm_per_km=0.12, + c_nf_per_km=300, max_i_ka=.2, df=.8) for i in range(2): add_trafo_connection(net, b2) @@ -80,7 +89,6 @@ def test_line(result_test_network, v_tol=1e-6, i_tol=1e-6, s_tol=5e-3, l_tol=1e- v = 1.007389386 - # line 1 assert abs(net.res_line.loading_percent.at[l1] - load1) < l_tol assert abs(net.res_line.i_ka.at[l1] - ika1) < i_tol @@ -242,21 +250,21 @@ def test_trafo(result_test_network, v_tol=1e-6, i_tol=1e-6, s_tol=1e-2, l_tol=1e def test_trafo_2_taps(v_tol=1e-6, i_tol=1e-6, s_tol=1e-2, l_tol=1e-3, va_tol=1e-2): # from pandapower.test.loadflow.test_results import * - net = pp.create_empty_network() - pp.create_bus(net, 110) - pp.create_bus(net, 20) - pp.create_ext_grid(net, 0) - pp.create_transformer_from_parameters(net, 0, 1, 100, 110, 20, 0.5, 12, 14, 0.5, - tap_side="hv", tap_neutral=0, tap_max=10, - tap_min=-10, tap_step_percent=2, tap_step_degree=0, - tap_pos=0, tap_phase_shifter=False, - tap2_side="hv", tap2_neutral=0, tap2_max=10, - tap2_min=-10, tap2_step_percent=2, tap2_step_degree=0, - tap2_pos=0, tap2_phase_shifter=False) - - pp.create_load(net, 1, 10) - - pp.runpp(net) + net = create_empty_network() + create_bus(net, 110) + create_bus(net, 20) + create_ext_grid(net, 0) + create_transformer_from_parameters(net, 0, 1, 100, 110, 20, 0.5, 12, 14, 0.5, + tap_side="hv", tap_neutral=0, tap_max=10, + tap_min=-10, tap_step_percent=2, tap_step_degree=0, + tap_pos=0, tap_phase_shifter=False, + tap2_side="hv", tap2_neutral=0, tap2_max=10, + tap2_min=-10, tap2_step_percent=2, tap2_step_degree=0, + tap2_pos=0, tap2_phase_shifter=False) + + create_load(net, 1, 10) + + runpp(net) net.res_bus @@ -264,12 +272,15 @@ def test_tap_dependent_impedance(result_test_network): net = result_test_network # first, basic example with piecewise linear characteristic - characteristic_vk = pp.control.Characteristic.from_points(net, ((net.trafo.at[0, 'tap_min'], 0.9 * net.trafo.at[0, 'vk_percent']), - (net.trafo.at[0, 'tap_neutral'], net.trafo.at[0, 'vk_percent']), - (net.trafo.at[0, 'tap_max'], 1.1 * net.trafo.at[0, 'vk_percent']))) - characteristic_vkr = pp.control.Characteristic.from_points(net, ((net.trafo.at[0, 'tap_min'], 0.9 * net.trafo.at[0, 'vkr_percent']), - (net.trafo.at[0, 'tap_neutral'], net.trafo.at[0, 'vkr_percent']), - (net.trafo.at[0, 'tap_max'], 1.1 * net.trafo.at[0, 'vkr_percent']))) + characteristic_vk = Characteristic.from_points(net, + ((net.trafo.at[0, 'tap_min'], 0.9 * net.trafo.at[0, 'vk_percent']), + (net.trafo.at[0, 'tap_neutral'], net.trafo.at[0, 'vk_percent']), + (net.trafo.at[0, 'tap_max'], 1.1 * net.trafo.at[0, 'vk_percent']))) + characteristic_vkr = Characteristic.from_points(net, + ((net.trafo.at[0, 'tap_min'], 0.9 * net.trafo.at[0, 'vkr_percent']), + (net.trafo.at[0, 'tap_neutral'], net.trafo.at[0, 'vkr_percent']), + ( + net.trafo.at[0, 'tap_max'], 1.1 * net.trafo.at[0, 'vkr_percent']))) idx_vk = characteristic_vk.index idx_vkr = characteristic_vkr.index @@ -283,21 +294,21 @@ def test_tap_dependent_impedance(result_test_network): # first, make sure there is no change for neutral net.trafo.at[0, "tap_pos"] = net.trafo.tap_neutral.at[0] net0.trafo.at[0, "tap_pos"] = net.trafo.tap_neutral.at[0] - pp.runpp(net) - pp.runpp(net0) + runpp(net) + runpp(net0) assert_res_equal(net, net0) - # now check the min and max positions for pos, factor in (("tap_min", 0.9), ("tap_max", 1.1)): - assert isclose(characteristic_vk(net.trafo[pos].at[0]), net.trafo.vk_percent.at[0]*factor, rtol=0, atol=1e-12) - assert isclose(characteristic_vkr(net.trafo[pos].at[0]), net.trafo.vkr_percent.at[0]*factor, rtol=0, atol=1e-12) - net0.trafo.at[0, "vk_percent"] = net.trafo.vk_percent.at[0]*factor - net0.trafo.at[0, "vkr_percent"] = net.trafo.vkr_percent.at[0]*factor + assert isclose(characteristic_vk(net.trafo[pos].at[0]), net.trafo.vk_percent.at[0] * factor, rtol=0, atol=1e-12) + assert isclose(characteristic_vkr(net.trafo[pos].at[0]), net.trafo.vkr_percent.at[0] * factor, rtol=0, + atol=1e-12) + net0.trafo.at[0, "vk_percent"] = net.trafo.vk_percent.at[0] * factor + net0.trafo.at[0, "vkr_percent"] = net.trafo.vkr_percent.at[0] * factor net0.trafo.at[0, "tap_pos"] = net.trafo[pos].at[0] - pp.runpp(net0) + runpp(net0) net.trafo.at[0, "tap_pos"] = net.trafo[pos].at[0] - pp.runpp(net) + runpp(net) assert_res_equal(net, net0) @@ -305,16 +316,16 @@ def test_tap_dependent_impedance_controller_comparison(): net1 = create_net() net2 = create_net() - pp.control.create_trafo_characteristics(net1, 'trafo', [0], 'vk_percent', [[-2, -1, 0, 1, 2]], [[5, 5.2, 6, 6.8, 7]]) - pp.control.create_trafo_characteristics(net1, 'trafo', [0], 'vkr_percent', [[-2, -1, 0, 1, 2]], [[1.3, 1.4, 1.44, 1.5, 1.6]]) + create_trafo_characteristics(net1, 'trafo', [0], 'vk_percent', [[-2, -1, 0, 1, 2]], [[5, 5.2, 6, 6.8, 7]]) + create_trafo_characteristics(net1, 'trafo', [0], 'vkr_percent', [[-2, -1, 0, 1, 2]], [[1.3, 1.4, 1.44, 1.5, 1.6]]) - pp.control.SplineCharacteristic(net2, [-2, -1, 0, 1, 2], [5, 5.2, 6, 6.8, 7]) - pp.control.SplineCharacteristic(net2, [-2, -1, 0, 1, 2], [1.3, 1.4, 1.44, 1.5, 1.6]) - pp.control.TapDependentImpedance(net2, [0], 0, output_variable="vk_percent") - pp.control.TapDependentImpedance(net2, [0], 1, output_variable="vkr_percent") + SplineCharacteristic(net2, [-2, -1, 0, 1, 2], [5, 5.2, 6, 6.8, 7]) + SplineCharacteristic(net2, [-2, -1, 0, 1, 2], [1.3, 1.4, 1.44, 1.5, 1.6]) + TapDependentImpedance(net2, [0], 0, output_variable="vk_percent") + TapDependentImpedance(net2, [0], 1, output_variable="vkr_percent") - pp.runpp(net1) - pp.runpp(net2, run_control=True) + runpp(net1) + runpp(net2, run_control=True) assert_res_equal(net1, net2) @@ -326,25 +337,31 @@ def test_tap_dependent_impedance_controller_comparison_3w(): add_trafo_connection(net1, net1.trafo.at[0, 'hv_bus'], "3W") add_trafo_connection(net2, net2.trafo.at[0, 'hv_bus'], "3W") - pp.control.create_trafo_characteristics(net1, 'trafo3w', [0], 'vk_hv_percent', [[-2, -1, 0, 1, 2]], [[0.85, 0.9, 1, 1.1, 1.15]]) - pp.control.create_trafo_characteristics(net1, 'trafo3w', [0], 'vkr_hv_percent', [[-2, -1, 0, 1, 2]], [[0.27, 0.28, 0.3, 0.32, 0.33]]) - pp.control.create_trafo_characteristics(net1, 'trafo3w', [0], 'vk_mv_percent', [[-2, -1, 0, 1, 2]], [[0.85, 0.9, 1, 1.1, 1.15]]) - pp.control.create_trafo_characteristics(net1, 'trafo3w', [0], 'vkr_mv_percent', [[-2, -1, 0, 1, 2]], [[0.27, 0.28, 0.3, 0.32, 0.33]]) - pp.control.create_trafo_characteristics(net1, 'trafo3w', [0], 'vk_lv_percent', [[-2, -1, 0, 1, 2]], [[0.85, 0.9, 1, 1.1, 1.15]]) - pp.control.create_trafo_characteristics(net1, 'trafo3w', [0], 'vkr_lv_percent', [[-2, -1, 0, 1, 2]], [[0.27, 0.28, 0.3, 0.32, 0.33]]) - - pp.control.SplineCharacteristic(net2, [-2, -1, 0, 1, 2], [0.85, 0.9, 1, 1.1, 1.15]) - pp.control.SplineCharacteristic(net2, [-2, -1, 0, 1, 2], [0.27, 0.28, 0.3, 0.32, 0.33]) - - pp.control.TapDependentImpedance(net2, [0], 0, element="trafo3w", output_variable="vk_hv_percent") - pp.control.TapDependentImpedance(net2, [0], 1, element="trafo3w", output_variable="vkr_hv_percent") - pp.control.TapDependentImpedance(net2, [0], 0, element="trafo3w", output_variable="vk_mv_percent") - pp.control.TapDependentImpedance(net2, [0], 1, element="trafo3w", output_variable="vkr_mv_percent") - pp.control.TapDependentImpedance(net2, [0], 0, element="trafo3w", output_variable="vk_lv_percent") - pp.control.TapDependentImpedance(net2, [0], 1, element="trafo3w", output_variable="vkr_lv_percent") - - pp.runpp(net1) - pp.runpp(net2, run_control=True) + create_trafo_characteristics(net1, 'trafo3w', [0], 'vk_hv_percent', [[-2, -1, 0, 1, 2]], + [[0.85, 0.9, 1, 1.1, 1.15]]) + create_trafo_characteristics(net1, 'trafo3w', [0], 'vkr_hv_percent', [[-2, -1, 0, 1, 2]], + [[0.27, 0.28, 0.3, 0.32, 0.33]]) + create_trafo_characteristics(net1, 'trafo3w', [0], 'vk_mv_percent', [[-2, -1, 0, 1, 2]], + [[0.85, 0.9, 1, 1.1, 1.15]]) + create_trafo_characteristics(net1, 'trafo3w', [0], 'vkr_mv_percent', [[-2, -1, 0, 1, 2]], + [[0.27, 0.28, 0.3, 0.32, 0.33]]) + create_trafo_characteristics(net1, 'trafo3w', [0], 'vk_lv_percent', [[-2, -1, 0, 1, 2]], + [[0.85, 0.9, 1, 1.1, 1.15]]) + create_trafo_characteristics(net1, 'trafo3w', [0], 'vkr_lv_percent', [[-2, -1, 0, 1, 2]], + [[0.27, 0.28, 0.3, 0.32, 0.33]]) + + SplineCharacteristic(net2, [-2, -1, 0, 1, 2], [0.85, 0.9, 1, 1.1, 1.15]) + SplineCharacteristic(net2, [-2, -1, 0, 1, 2], [0.27, 0.28, 0.3, 0.32, 0.33]) + + TapDependentImpedance(net2, [0], 0, element="trafo3w", output_variable="vk_hv_percent") + TapDependentImpedance(net2, [0], 1, element="trafo3w", output_variable="vkr_hv_percent") + TapDependentImpedance(net2, [0], 0, element="trafo3w", output_variable="vk_mv_percent") + TapDependentImpedance(net2, [0], 1, element="trafo3w", output_variable="vkr_mv_percent") + TapDependentImpedance(net2, [0], 0, element="trafo3w", output_variable="vk_lv_percent") + TapDependentImpedance(net2, [0], 1, element="trafo3w", output_variable="vkr_lv_percent") + + runpp(net1) + runpp(net2, run_control=True) assert_res_equal(net1, net2) @@ -353,17 +370,17 @@ def test_undefined_tap_dependent_impedance_characteristics(): # if some characteristic per 1 trafo are undefined, but at least 1 is defined -> OK # if all characteristic per 1 trafo are undefined -> raise error net = create_net() - pp.control.create_trafo_characteristics(net, 'trafo', [0], 'vk_percent', [[-2, -1, 0, 1, 2]], [[5, 5.2, 6, 6.8, 7]]) - pp.control.create_trafo_characteristics(net, 'trafo', [0], 'vkr_percent', [[-2, -1, 0, 1, 2]], [[1.3, 1.4, 1.44, 1.5, 1.6]]) - pp.control.create_trafo_characteristics(net, 'trafo', [1], 'vk_percent', [[-2, -1, 0, 1, 2]], [[5, 5.2, 6, 6.8, 7]]) + create_trafo_characteristics(net, 'trafo', [0], 'vk_percent', [[-2, -1, 0, 1, 2]], [[5, 5.2, 6, 6.8, 7]]) + create_trafo_characteristics(net, 'trafo', [0], 'vkr_percent', [[-2, -1, 0, 1, 2]], [[1.3, 1.4, 1.44, 1.5, 1.6]]) + create_trafo_characteristics(net, 'trafo', [1], 'vk_percent', [[-2, -1, 0, 1, 2]], [[5, 5.2, 6, 6.8, 7]]) # does not raise error - pp.runpp(net) + runpp(net) # this will raise error net.trafo.at[1, "vk_percent_characteristic"] = None with pytest.raises(UserWarning): - pp.runpp(net) + runpp(net) def test_undefined_tap_dependent_impedance_characteristics_trafo3w(): @@ -376,39 +393,39 @@ def test_undefined_tap_dependent_impedance_characteristics_trafo3w(): add_trafo_connection(net2, 1, "3W") add_trafo_connection(net2, 1, "3W") - pp.control.create_trafo_characteristics( + create_trafo_characteristics( net, 'trafo3w', [0, 1], 'vk_mv_percent', [[-2, -1, 0, 1, 2], [-2, -1, 0, 1, 2]], [[0.7, 0.9, 1, 1.1, 1.3], [0.7, 0.9, 1, 1.1, 1.3]]) - pp.control.create_trafo_characteristics( + create_trafo_characteristics( net, 'trafo3w', [0, 1], 'vkr_mv_percent', [[-2, -1, 0, 1, 2], [-2, -1, 0, 1, 2]], [[0.3, 0.45, 0.5, 0.55, 0.7], [0.3, 0.45, 0.5, 0.55, 0.7]]) - pp.control.Characteristic(net2, [-2, -1, 0, 1, 2], [0.7, 0.9, 1, 1.1, 1.3]) - pp.control.Characteristic(net2, [-2, -1, 0, 1, 2], [0.3, 0.45, 0.5, 0.55, 0.7]) + Characteristic(net2, [-2, -1, 0, 1, 2], [0.7, 0.9, 1, 1.1, 1.3]) + Characteristic(net2, [-2, -1, 0, 1, 2], [0.3, 0.45, 0.5, 0.55, 0.7]) - pp.control.TapDependentImpedance(net2, [0], 0, element="trafo3w", output_variable="vk_mv_percent") - pp.control.TapDependentImpedance(net2, [0], 1, element="trafo3w", output_variable="vkr_mv_percent") - pp.control.TapDependentImpedance(net2, [1], 0, element="trafo3w", output_variable="vk_mv_percent") - pp.control.TapDependentImpedance(net2, [1], 1, element="trafo3w", output_variable="vkr_mv_percent") + TapDependentImpedance(net2, [0], 0, element="trafo3w", output_variable="vk_mv_percent") + TapDependentImpedance(net2, [0], 1, element="trafo3w", output_variable="vkr_mv_percent") + TapDependentImpedance(net2, [1], 0, element="trafo3w", output_variable="vk_mv_percent") + TapDependentImpedance(net2, [1], 1, element="trafo3w", output_variable="vkr_mv_percent") - pp.runpp(net) - pp.runpp(net2, run_control=True) + runpp(net) + runpp(net2, run_control=True) assert_res_equal(net, net2) net.trafo3w.at[0, "vk_mv_percent_characteristic"] = None - pp.runpp(net) + runpp(net) net2.controller.at[0, "in_service"] = False - pp.runpp(net2, run_control=True) + runpp(net2, run_control=True) assert_res_equal(net, net2) net.trafo3w.at[0, "vkr_mv_percent_characteristic"] = None net2.controller.at[1, "in_service"] = False with pytest.raises(UserWarning): - pp.runpp(net) + runpp(net) net.trafo3w.at[0, "tap_dependent_impedance"] = False - pp.runpp(net) - pp.runpp(net2, run_control=True) + runpp(net) + runpp(net2, run_control=True) assert_res_equal(net, net2) @@ -585,7 +602,6 @@ def test_trafo3w(result_test_network, v_tol=1e-6, i_tol=1e-6, s_tol=2e-2, l_tol= pmv = -0.200 plv = -0.100 - assert abs((net.res_bus.vm_pu.at[b2] - uhv)) < v_tol assert abs((net.res_bus.vm_pu.at[b3] - umv)) < v_tol assert abs((net.res_bus.vm_pu.at[b4] - ulv)) < v_tol @@ -604,9 +620,9 @@ def test_trafo3w(result_test_network, v_tol=1e-6, i_tol=1e-6, s_tol=2e-2, l_tol= assert abs((net.res_trafo3w.i_mv_ka.at[t3] - imv)) < i_tol assert abs((net.res_trafo3w.i_lv_ka.at[t3] - ilv)) < i_tol - runpp_with_consistency_checks(net, trafo_model="pi",trafo3w_losses='star') + runpp_with_consistency_checks(net, trafo_model="pi", trafo3w_losses='star') - #Test results Integral: + # Test results Integral: uhv = 1.01011711678 umv = 0.95550024145 ulv = 0.94062989256 @@ -642,18 +658,20 @@ def test_trafo3w(result_test_network, v_tol=1e-6, i_tol=1e-6, s_tol=2e-2, l_tol= assert abs((net.res_trafo3w.i_mv_ka.at[t3] - imv)) < i_tol assert abs((net.res_trafo3w.i_lv_ka.at[t3] - ilv)) < i_tol + @pytest.mark.parametrize("tap_pos", (-1, 2)) @pytest.mark.parametrize("tap_side", ('hv', 'mv', 'lv')) @pytest.mark.parametrize("tap_step_degree", (0, 15, 30)) def test_trafo3w_tap(tap_pos, tap_side, tap_step_degree): - results = pd.read_csv(os.path.join(pp.pp_dir, "test", "test_files", "test_results_files", "trafo_3w_tap_results.csv"), sep=";", decimal=",") + results = pd.read_csv(os.path.join(pp_dir, "test", "test_files", "test_results_files", "trafo_3w_tap_results.csv"), + sep=";", decimal=",") if results.query("tap_side == @tap_side & tap_pos == @tap_pos & tap_step_degree == @tap_step_degree").empty: pytest.skip(f"Skipping combination: tap_side={tap_side}, tap_pos={tap_pos}, tap_step_degree={tap_step_degree}") - net = pp.from_json(os.path.join(pp.pp_dir, "test", "test_files","test_trafo3w_tap.json")) # - net.trafo3w.loc[0, 'tap_at_star_point']= False - net.trafo3w.loc[1, 'tap_at_star_point']= True + net = from_json(os.path.join(pp_dir, "test", "test_files", "test_trafo3w_tap.json")) # + net.trafo3w.loc[0, 'tap_at_star_point'] = False + net.trafo3w.loc[1, 'tap_at_star_point'] = True net.trafo3w.loc[0, "tap_side"] = tap_side net.trafo3w.loc[1, "tap_side"] = tap_side @@ -661,32 +679,36 @@ def test_trafo3w_tap(tap_pos, tap_side, tap_step_degree): net.trafo3w.loc[1, "tap_pos"] = tap_pos net.trafo3w.loc[0, "tap_step_degree"] = tap_step_degree net.trafo3w.loc[1, "tap_step_degree"] = tap_step_degree - pp.runpp(net) + runpp(net) for index in range(8): for variable, tol in zip(("vm_pu", "va_degree"), (1e-6, 1e-3)): assert np.isclose(net.res_bus.at[index, variable], results.query( "tap_side==@tap_side & tap_pos==@tap_pos & tap_step_degree==@tap_step_degree &" "index==@index & element=='bus' & variable==@variable").value, - rtol=0, atol=tol), f"failed for bus {index=}, {variable}, value {net.res_bus.at[index, variable]}" + rtol=0, + atol=tol), f"failed for bus {index=}, {variable}, value {net.res_bus.at[index, variable]}" + @pytest.mark.parametrize("tap_pos", (2, 5)) @pytest.mark.parametrize("tap_side", ('hv', 'mv', 'lv')) @pytest.mark.parametrize("tap_step_degree", (0, 15, 30)) def test_trafo3w_tap_neutral_not_zero(tap_pos, tap_side, tap_step_degree): - results = pd.read_csv(os.path.join(pp.pp_dir, "test", "test_files", "test_results_files", "trafo_3w_tap_results_neutral_not_zero.csv"), sep=";", decimal=",") + results = pd.read_csv( + os.path.join(pp_dir, "test", "test_files", "test_results_files", "trafo_3w_tap_results_neutral_not_zero.csv"), + sep=";", decimal=",") if results.query("tap_side == @tap_side & tap_pos == @tap_pos & tap_step_degree == @tap_step_degree").empty: pytest.skip(f"Skipping combination: tap_side={tap_side}, tap_pos={tap_pos}, tap_step_degree={tap_step_degree}") - net = pp.from_json(os.path.join(pp.pp_dir, "test", "test_files","test_trafo3w_tap.json")) # + net = from_json(os.path.join(pp_dir, "test", "test_files", "test_trafo3w_tap.json")) # net.trafo3w.loc[[0, 1], 'tap_min'] += 3 net.trafo3w.loc[[0, 1], 'tap_max'] += 3 net.trafo3w.loc[[0, 1], 'tap_neutral'] += 3 - net.trafo3w.loc[0, 'tap_at_star_point']= False - net.trafo3w.loc[1, 'tap_at_star_point']= True + net.trafo3w.loc[0, 'tap_at_star_point'] = False + net.trafo3w.loc[1, 'tap_at_star_point'] = True net.trafo3w.loc[0, "tap_side"] = tap_side net.trafo3w.loc[1, "tap_side"] = tap_side @@ -694,15 +716,15 @@ def test_trafo3w_tap_neutral_not_zero(tap_pos, tap_side, tap_step_degree): net.trafo3w.loc[1, "tap_pos"] = tap_pos net.trafo3w.loc[0, "tap_step_degree"] = tap_step_degree net.trafo3w.loc[1, "tap_step_degree"] = tap_step_degree - pp.runpp(net) + runpp(net) for index in range(8): for variable, tol in zip(("vm_pu", "va_degree"), (1e-6, 1e-3)): assert np.isclose(net.res_bus.at[index, variable], results.query( "tap_side==@tap_side & tap_pos==@tap_pos & tap_step_degree==@tap_step_degree &" "index==@index & element=='bus' & variable==@variable").value, - rtol=0, atol=tol), f"failed for bus {index=}, {variable}, value {net.res_bus.at[index, variable]}" - + rtol=0, + atol=tol), f"failed for bus {index=}, {variable}, value {net.res_bus.at[index, variable]}" def test_impedance(result_test_network, v_tol=1e-6, i_tol=1e-6, s_tol=5e-3, l_tol=1e-3): @@ -760,8 +782,8 @@ def test_bus_bus_switch(result_test_network, v_tol=1e-6, i_tol=1e-6, s_tol=5e-3, assert isnan(net.res_switch.p_from_mw).all() # now test with some switches that have non-zero impedance: - net.switch.loc[[2,3], "z_ohm"] = 1e-3 - pp.runpp(net) + net.switch.loc[[2, 3], "z_ohm"] = 1e-3 + runpp(net) p_from_ref = net.res_ext_grid.p_mw[12] p_to_ref = - net.res_line.p_from_mw[28] @@ -775,7 +797,7 @@ def test_bus_bus_switch(result_test_network, v_tol=1e-6, i_tol=1e-6, s_tol=5e-3, # also test with open switch that have non-zero impedance: net.switch.loc[[2], "closed"] = False - pp.runpp(net) + runpp(net) assert isnan(net.res_switch.p_from_mw[2]) @@ -783,9 +805,9 @@ def test_bus_bus_switch(result_test_network, v_tol=1e-6, i_tol=1e-6, s_tol=5e-3, def test_enforce_q_lims(v_tol=1e-6, i_tol=1e-6, s_tol=5e-3, l_tol=1e-3): """ Test for enforce_q_lims loadflow option """ - net = pp.create_empty_network() + net = create_empty_network() net = add_test_gen(net) - pp.runpp(net) + runpp(net) buses = net.bus[net.bus.zone == "test_gen"] gens = [x for x in net.gen.index if net.gen.bus[x] in buses.index] # b1=buses.index[0] @@ -802,7 +824,7 @@ def test_enforce_q_lims(v_tol=1e-6, i_tol=1e-6, s_tol=5e-3, l_tol=1e-3): # test_enforce_qlims net = add_test_enforce_qlims(net) - pp.runpp(net, enforce_q_lims=True) + runpp(net, enforce_q_lims=True) buses = net.bus[net.bus.zone == "test_enforce_qlims"] gens = [x for x in net.gen.index if net.gen.bus[x] in buses.index] b2 = buses.index[1] @@ -856,13 +878,13 @@ def test_open(result_test_network): def test_impedance_g_b(): - net = pp.create_empty_network(sn_mva=100) - pp.create_bus(net, 110) - pp.create_bus(net, 20) - pp.create_ext_grid(net, 0) - pp.create_impedance(net, 0, 1, rft_pu=0.002, xft_pu=0.004, rtf_pu=0.005, xtf_pu=0.008, - gf_pu=0.001, bf_pu=0.003, gt_pu=0.006, bt_pu=0.007, sn_mva=10) - pp.create_load(net, 1, 20, 4) + net = create_empty_network(sn_mva=100) + create_bus(net, 110) + create_bus(net, 20) + create_ext_grid(net, 0) + create_impedance(net, 0, 1, rft_pu=0.002, xft_pu=0.004, rtf_pu=0.005, xtf_pu=0.008, + gf_pu=0.001, bf_pu=0.003, gt_pu=0.006, bt_pu=0.007, sn_mva=10) + create_load(net, 1, 20, 4) runpp_with_consistency_checks(net, tolerance_mva=1e-12) @@ -875,15 +897,15 @@ def test_impedance_g_b(): def test_trafo_unequal_r_x_hv_lv(): - net = pp.create_empty_network(sn_mva=10) - pp.create_bus(net, 110) - pp.create_bus(net, 20) - pp.create_ext_grid(net, 0) - pp.create_transformer_from_parameters(net, 0, 1, 150, 120, 19, - 1, 3, 20, 0.12, tap_side="hv", - tap_neutral=0, tap_max=2, tap_min=-2, tap_step_percent=5, tap_step_degree=30, - tap_pos=-2, leakage_resistance_ratio_hv=0.6, leakage_reactance_ratio_hv=0.2) - pp.create_load(net, 1, 100, 20) + net = create_empty_network(sn_mva=10) + create_bus(net, 110) + create_bus(net, 20) + create_ext_grid(net, 0) + create_transformer_from_parameters(net, 0, 1, 150, 120, 19, + 1, 3, 20, 0.12, tap_side="hv", + tap_neutral=0, tap_max=2, tap_min=-2, tap_step_percent=5, tap_step_degree=30, + tap_pos=-2, leakage_resistance_ratio_hv=0.6, leakage_reactance_ratio_hv=0.2) + create_load(net, 1, 100, 20) runpp_with_consistency_checks(net) assert np.allclose(net.res_bus.vm_pu, [1.000000, 0.941818], rtol=0, atol=1e-6) diff --git a/pandapower/test/loadflow/test_rundcpp.py b/pandapower/test/loadflow/test_rundcpp.py index f84be212b..356714499 100644 --- a/pandapower/test/loadflow/test_rundcpp.py +++ b/pandapower/test/loadflow/test_rundcpp.py @@ -4,41 +4,44 @@ # and Energy System Technology (IEE), Kassel. All rights reserved. +import copy + import numpy as np import pytest -import pandapower as pp -import pandapower.networks as nw -import copy -from pandapower.auxiliary import _check_connectivity, _add_ppc_options +from pandapower.auxiliary import _check_connectivity, _add_ppc_options, LoadflowNotConverged +from pandapower.create import create_empty_network, create_bus, create_transformer, create_transformer3w, create_load, \ + create_xward, create_switch, create_ext_grid +from pandapower.networks.power_system_test_cases import case4gs from pandapower.pd2ppc import _pd2ppc +from pandapower.run import rundcpp, runpp from pandapower.test.consistency_checks import rundcpp_with_consistency_checks -from pandapower.test.loadflow.result_test_network_generator import result_test_network_generator_dcpp from pandapower.test.helper_functions import add_grid_connection, create_test_line, assert_net_equal +from pandapower.test.loadflow.result_test_network_generator import result_test_network_generator_dcpp def test_rundcpp_init(): - net = pp.create_empty_network() + net = create_empty_network() b1, b2, l1 = add_grid_connection(net) - b3 = pp.create_bus(net, vn_kv=0.4) - tidx = pp.create_transformer(net, hv_bus=b2, lv_bus=b3, std_type="0.25 MVA 20/0.4 kV") - pp.rundcpp(net) + b3 = create_bus(net, vn_kv=0.4) + tidx = create_transformer(net, hv_bus=b2, lv_bus=b3, std_type="0.25 MVA 20/0.4 kV") + rundcpp(net) def test_rundcpp_init_auxiliary_buses(): - net = pp.create_empty_network() + net = create_empty_network() b1, b2, l1 = add_grid_connection(net, vn_kv=110.) - b3 = pp.create_bus(net, vn_kv=20.) - b4 = pp.create_bus(net, vn_kv=10.) - tidx = pp.create_transformer3w(net, b2, b3, b4, std_type='63/25/38 MVA 110/20/10 kV') - pp.create_load(net, b3, p_mw=5) - pp.create_load(net, b4, p_mw=5) - pp.create_xward(net, b4, 1, 1, 1, 1, 0.1, 0.1, 1.0) + b3 = create_bus(net, vn_kv=20.) + b4 = create_bus(net, vn_kv=10.) + tidx = create_transformer3w(net, b2, b3, b4, std_type='63/25/38 MVA 110/20/10 kV') + create_load(net, b3, p_mw=5) + create_load(net, b4, p_mw=5) + create_xward(net, b4, 1, 1, 1, 1, 0.1, 0.1, 1.0) net.trafo3w.at[tidx, "shift_lv_degree"] = 120 net.trafo3w.at[tidx, "shift_mv_degree"] = 80 - pp.rundcpp(net) + rundcpp(net) va = net.res_bus.va_degree.at[b2] - pp.rundcpp(net) + rundcpp(net) assert np.allclose(va - net.trafo3w.shift_mv_degree.at[tidx], net.res_bus.va_degree.at[b3], atol=2) assert np.allclose(va - net.trafo3w.shift_lv_degree.at[tidx], net.res_bus.va_degree.at[b4], @@ -52,19 +55,19 @@ def test_result_iter(): rundcpp_with_consistency_checks(net) except (AssertionError): raise UserWarning("Consistency Error after adding %s" % net.last_added_case) - except(pp.LoadflowNotConverged): + except(LoadflowNotConverged): raise UserWarning("Power flow did not converge after adding %s" % net.last_added_case) def test_two_open_switches(): - net = pp.create_empty_network() + net = create_empty_network() b1, b2, l1 = add_grid_connection(net) - b3 = pp.create_bus(net, vn_kv=20.) + b3 = create_bus(net, vn_kv=20.) l2 = create_test_line(net, b2, b3) create_test_line(net, b3, b1) - pp.create_switch(net, b2, l2, et="l", closed=False) - pp.create_switch(net, b3, l2, et="l", closed=False) - pp.rundcpp(net) + create_switch(net, b2, l2, et="l", closed=False) + create_switch(net, b3, l2, et="l", closed=False) + rundcpp(net) assert np.isnan(net.res_line.i_ka.at[l2]) or net.res_line.i_ka.at[l2] == 0 @@ -82,8 +85,8 @@ def test_test_sn_mva(): test_net_gen1 = result_test_network_generator_dcpp(sn_mva=1) test_net_gen2 = result_test_network_generator_dcpp(sn_mva=2) for net1, net2 in zip(test_net_gen1, test_net_gen2): - pp.rundcpp(net1) - pp.rundcpp(net2) + rundcpp(net1) + rundcpp(net2) try: assert_net_equal(net1, net2, exclude_elms=["sn_mva"]) except: @@ -91,34 +94,35 @@ def test_test_sn_mva(): def test_single_bus_network(): - net = pp.create_empty_network() - b = pp.create_bus(net, vn_kv=20.) - pp.create_ext_grid(net, b) + net = create_empty_network() + b = create_bus(net, vn_kv=20.) + create_ext_grid(net, b) - pp.runpp(net) + runpp(net) assert net.converged - pp.rundcpp(net) + rundcpp(net) assert net.converged def test_missing_gen(): - net = nw.case4gs() - pp.rundcpp(net) + net = case4gs() + rundcpp(net) res_gen = copy.deepcopy(net.res_gen.values) net.pop("res_gen") - pp.rundcpp(net) + rundcpp(net) assert np.allclose(net.res_gen.values, res_gen, equal_nan=True) def test_res_bus_vm(): - net = nw.case4gs() + net = case4gs() # run power flow to have bus vm_pu values - pp.runpp(net) + runpp(net) # now run DC pf and check that the vm_pu values are reset to 1 - pp.rundcpp(net) + rundcpp(net) assert np.allclose(net.res_bus.loc[net.line.from_bus.values, "vm_pu"], net.res_line.vm_from_pu, equal_nan=True) - assert np.allclose(net.res_bus.loc[net.line.from_bus.values, "va_degree"], net.res_line.va_from_degree, equal_nan=True) + assert np.allclose(net.res_bus.loc[net.line.from_bus.values, "va_degree"], net.res_line.va_from_degree, + equal_nan=True) assert np.allclose(net.res_bus.loc[net.line.to_bus.values, "vm_pu"], net.res_line.vm_to_pu, equal_nan=True) assert np.allclose(net.res_bus.loc[net.line.to_bus.values, "va_degree"], net.res_line.va_to_degree, equal_nan=True) diff --git a/pandapower/test/loadflow/test_runpp.py b/pandapower/test/loadflow/test_runpp.py index dfc117377..0b125fd60 100644 --- a/pandapower/test/loadflow/test_runpp.py +++ b/pandapower/test/loadflow/test_runpp.py @@ -11,26 +11,33 @@ import pandas as pd import pytest -import pandapower as pp -import pandapower.control +from pandapower import pp_dir from pandapower.auxiliary import _check_connectivity, _add_ppc_options, lightsim2grid_available +from pandapower.control import create_trafo_characteristics, SplineCharacteristic +from pandapower.create import create_bus, create_empty_network, create_ext_grid, create_dcline, create_load, \ + create_sgen, create_switch, create_transformer, create_xward, create_transformer3w, create_gen, create_shunt, \ + create_line_from_parameters, create_line, create_impedance, create_storage, create_buses, \ + create_transformer3w_from_parameters +from pandapower.file_io import from_json from pandapower.networks import create_cigre_network_mv, four_loads_with_branches_out, \ - example_simple, simple_four_bus_system, example_multivoltage + example_simple, simple_four_bus_system, example_multivoltage, case118 from pandapower.pd2ppc import _pd2ppc from pandapower.pf.create_jacobian import _create_J_without_numba from pandapower.pf.run_newton_raphson_pf import _get_pf_variables_from_ppci from pandapower.powerflow import LoadflowNotConverged +from pandapower.pypower.idx_brch import BR_R, BR_X, BR_B, BR_G +from pandapower.pypower.makeYbus import makeYbus as makeYbus_pypower +from pandapower.results import reset_results +from pandapower.run import set_user_pf_options, runpp from pandapower.test.consistency_checks import runpp_with_consistency_checks +from pandapower.test.helper_functions import add_grid_connection, create_test_line, assert_net_equal, assert_res_equal from pandapower.test.loadflow.result_test_network_generator import add_test_xward, add_test_trafo3w, \ add_test_line, add_test_oos_bus_with_is_element, result_test_network_generator, add_test_trafo -from pandapower.test.helper_functions import add_grid_connection, create_test_line, assert_net_equal, assert_res_equal from pandapower.toolbox import nets_equal -from pandapower.pypower.makeYbus import makeYbus as makeYbus_pypower -from pandapower.pypower.idx_brch import BR_R, BR_X, BR_B, BR_G - try: from pandapower.pf.makeYbus_numba import makeYbus as makeYbus_numba + numba_installed = True except ImportError: numba_installed = False @@ -38,53 +45,53 @@ def test_minimal_net(**kwargs): # tests corner-case when the grid only has 1 bus and an ext-grid - net = pp.create_empty_network() - b = pp.create_bus(net, 110) - pp.create_ext_grid(net, b) + net = create_empty_network() + b = create_bus(net, 110) + create_ext_grid(net, b) runpp_with_consistency_checks(net, **kwargs) - pp.create_load(net, b, p_mw=0.1) + create_load(net, b, p_mw=0.1) runpp_with_consistency_checks(net, **kwargs) - b2 = pp.create_bus(net, 110) - pp.create_switch(net, b, b2, 'b') - pp.create_sgen(net, b2, p_mw=0.2) + b2 = create_bus(net, 110) + create_switch(net, b, b2, 'b') + create_sgen(net, b2, p_mw=0.2) runpp_with_consistency_checks(net, **kwargs) def test_set_user_pf_options(): net = example_simple() - pp.runpp(net) + runpp(net) old_options = net._options.copy() test_options = {key: i for i, key in enumerate(old_options.keys())} - pp.set_user_pf_options(net, hello='bye', **test_options) + set_user_pf_options(net, hello='bye', **test_options) test_options.update({'hello': 'bye'}) assert net.user_pf_options == test_options # remove what is in user_pf_options and add hello=world - pp.set_user_pf_options(net, overwrite=True, hello='world') + set_user_pf_options(net, overwrite=True, hello='world') assert net.user_pf_options == {'hello': 'world'} # check if 'hello' is added to net._options, but other options are untouched - pp.runpp(net) + runpp(net) assert 'hello' in net._options.keys() and net._options['hello'] == 'world' net._options.pop('hello') assert net._options == old_options # check if user_pf_options can be deleted and net._options is as it was before - pp.set_user_pf_options(net, overwrite=True, hello='world') - pp.set_user_pf_options(net, overwrite=True) + set_user_pf_options(net, overwrite=True, hello='world') + set_user_pf_options(net, overwrite=True) assert net.user_pf_options == {} - pp.runpp(net) + runpp(net) assert 'hello' not in net._options.keys() # see if user arguments overrule user_pf_options, but other user_pf_options still have the # priority - pp.set_user_pf_options(net, tolerance_mva=1e-6, max_iteration=20) - pp.runpp(net, tolerance_mva=1e-2) + set_user_pf_options(net, tolerance_mva=1e-6, max_iteration=20) + runpp(net, tolerance_mva=1e-2) assert net.user_pf_options['tolerance_mva'] == 1e-6 assert net._options['tolerance_mva'] == 1e-2 assert net._options['max_iteration'] == 20 @@ -92,15 +99,15 @@ def test_set_user_pf_options(): def test_kwargs_with_user_options(): net = example_simple() - pp.runpp(net) + runpp(net) assert net._options["trafo3w_losses"] == "hv" - pp.set_user_pf_options(net, trafo3w_losses="lv") - pp.runpp(net) + set_user_pf_options(net, trafo3w_losses="lv") + runpp(net) assert net._options["trafo3w_losses"] == "lv" # check providing the kwargs options in runpp overrides user_pf_options - pp.set_user_pf_options(net, init_vm_pu="results") - pp.runpp(net, init_vm_pu="flat") + set_user_pf_options(net, init_vm_pu="results") + runpp(net, init_vm_pu="flat") assert net.user_pf_options["init_vm_pu"] == "results" assert net._options["init_vm_pu"] == "flat" @@ -110,49 +117,49 @@ def test_kwargs_with_user_options(): "overwritten with the default values, this is not recognized.") def test_overwrite_default_args_with_user_options(): net = example_simple() - pp.runpp(net) + runpp(net) assert net._options["check_connectivity"] is True - pp.set_user_pf_options(net, check_connectivity=False) - pp.runpp(net) + set_user_pf_options(net, check_connectivity=False) + runpp(net) assert net._options["check_connectivity"] is False - pp.runpp(net, check_connectivity=True) + runpp(net, check_connectivity=True) assert net._options["check_connectivity"] is True def test_runpp_init(): - net = pp.create_empty_network() + net = create_empty_network() b1, b2, l1 = add_grid_connection(net) - b3 = pp.create_bus(net, vn_kv=0.4) - tidx = pp.create_transformer(net, hv_bus=b2, lv_bus=b3, std_type="0.25 MVA 20/0.4 kV") + b3 = create_bus(net, vn_kv=0.4) + tidx = create_transformer(net, hv_bus=b2, lv_bus=b3, std_type="0.25 MVA 20/0.4 kV") net.trafo.at[tidx, "shift_degree"] = 70 - pp.runpp(net, calculate_voltage_angles="auto") + runpp(net, calculate_voltage_angles="auto") va = net.res_bus.va_degree.at[4] - pp.runpp(net, calculate_voltage_angles=True, init_va_degree="dc") + runpp(net, calculate_voltage_angles=True, init_va_degree="dc") assert np.allclose(va - net.trafo.shift_degree.at[tidx], net.res_bus.va_degree.at[4]) - pp.runpp(net, calculate_voltage_angles=True, init_va_degree="results") + runpp(net, calculate_voltage_angles=True, init_va_degree="results") assert np.allclose(va - net.trafo.shift_degree.at[tidx], net.res_bus.va_degree.at[4]) def test_runpp_init_auxiliary_buses(): - net = pp.create_empty_network() + net = create_empty_network() b1, b2, l1 = add_grid_connection(net, vn_kv=110.) - b3 = pp.create_bus(net, vn_kv=20.) - b4 = pp.create_bus(net, vn_kv=10.) - tidx = pp.create_transformer3w(net, b2, b3, b4, std_type='63/25/38 MVA 110/20/10 kV') - pp.create_load(net, b3, p_mw=5) - pp.create_load(net, b4, p_mw=5) - pp.create_xward(net, b4, ps_mw=1, qs_mvar=1, pz_mw=1, qz_mvar=1, r_ohm=0.1, x_ohm=0.1, - vm_pu=1.0) + b3 = create_bus(net, vn_kv=20.) + b4 = create_bus(net, vn_kv=10.) + tidx = create_transformer3w(net, b2, b3, b4, std_type='63/25/38 MVA 110/20/10 kV') + create_load(net, b3, p_mw=5) + create_load(net, b4, p_mw=5) + create_xward(net, b4, ps_mw=1, qs_mvar=1, pz_mw=1, qz_mvar=1, r_ohm=0.1, x_ohm=0.1, + vm_pu=1.0) net.trafo3w.at[tidx, "shift_lv_degree"] = 120 net.trafo3w.at[tidx, "shift_mv_degree"] = 80 - pp.runpp(net) + runpp(net) va = net.res_bus.va_degree.at[b2] - pp.runpp(net, calculate_voltage_angles=True, init_va_degree="dc") + runpp(net, calculate_voltage_angles=True, init_va_degree="dc") assert np.allclose(va - net.trafo3w.shift_mv_degree.at[tidx], net.res_bus.va_degree.at[b3], atol=2) assert np.allclose(va - net.trafo3w.shift_lv_degree.at[tidx], net.res_bus.va_degree.at[b4], atol=2) - pp.runpp(net, calculate_voltage_angles=True, init_va_degree="results") + runpp(net, calculate_voltage_angles=True, init_va_degree="results") assert np.allclose(va - net.trafo3w.shift_mv_degree.at[tidx], net.res_bus.va_degree.at[b3], atol=2) assert np.allclose(va - net.trafo3w.shift_lv_degree.at[tidx], net.res_bus.va_degree.at[b4], @@ -171,29 +178,29 @@ def test_result_iter(): @pytest.fixture def bus_bus_net(): - net = pp.create_empty_network() + net = create_empty_network() add_grid_connection(net) for _u in range(4): - pp.create_bus(net, vn_kv=.4) - pp.create_load(net, 5, p_mw=0.01) - pp.create_switch(net, 3, 6, et="b") - pp.create_switch(net, 4, 5, et="b") - pp.create_switch(net, 6, 5, et="b") - pp.create_switch(net, 0, 7, et="b") + create_bus(net, vn_kv=.4) + create_load(net, 5, p_mw=0.01) + create_switch(net, 3, 6, et="b") + create_switch(net, 4, 5, et="b") + create_switch(net, 6, 5, et="b") + create_switch(net, 0, 7, et="b") create_test_line(net, 4, 7) - pp.create_load(net, 4, p_mw=0.01) + create_load(net, 4, p_mw=0.01) return net def test_bus_bus_switches(bus_bus_net): net = bus_bus_net - pp.runpp(net) + runpp(net) assert net.res_bus.vm_pu.at[3] == net.res_bus.vm_pu.at[4] == net.res_bus.vm_pu.at[5] == \ net.res_bus.vm_pu.at[6] assert net.res_bus.vm_pu.at[0] == net.res_bus.vm_pu.at[7] net.bus.at[5, "in_service"] = False - pp.runpp(net) + runpp(net) assert net.res_bus.vm_pu.at[3] == net.res_bus.vm_pu.at[6] assert net.res_bus.vm_pu.at[0] == net.res_bus.vm_pu.at[7] assert pd.isnull(net.res_bus.vm_pu.at[5]) @@ -204,90 +211,90 @@ def test_bus_bus_switches_merges_two_gens(bus_bus_net): "buses should not be fused if two gens are connected" net = bus_bus_net net.bus.at[5, "in_service"] = False - pp.create_gen(net, 6, 10) - pp.create_gen(net, 4, 10) + create_gen(net, 6, 10) + create_gen(net, 4, 10) net.bus.at[5, "in_service"] = True - pp.runpp(net) + runpp(net) assert net.converged def test_bus_bus_switches_throws_exception_for_two_gen_with_diff_vm(bus_bus_net): "buses should not be fused if two gens are connected" net = bus_bus_net - pp.create_gen(net, 6, 10, 1.) - pp.create_gen(net, 4, 10, 1.1) + create_gen(net, 6, 10, 1.) + create_gen(net, 4, 10, 1.1) with pytest.raises(UserWarning): - pp.runpp(net) + runpp(net) @pytest.fixture def z_switch_net(): - net = pp.create_empty_network() + net = create_empty_network() for i in range(3): - pp.create_bus(net, vn_kv=.4) - pp.create_load(net, i, p_mw=0.1) - pp.create_ext_grid(net, 0, vm_pu=1.0) - pp.create_line_from_parameters(net, 0, 1, 1, r_ohm_per_km=0.1 / np.sqrt(2), - x_ohm_per_km=0.1 / np.sqrt(2), - c_nf_per_km=0, max_i_ka=.2) - pp.create_switch(net, 0, 2, et="b", z_ohm=0.1) + create_bus(net, vn_kv=.4) + create_load(net, i, p_mw=0.1) + create_ext_grid(net, 0, vm_pu=1.0) + create_line_from_parameters(net, 0, 1, 1, r_ohm_per_km=0.1 / np.sqrt(2), + x_ohm_per_km=0.1 / np.sqrt(2), + c_nf_per_km=0, max_i_ka=.2) + create_switch(net, 0, 2, et="b", z_ohm=0.1) return net @pytest.mark.parametrize("numba", [True, False]) def test_z_switch(z_switch_net, numba): net = z_switch_net - pp.runpp(net, numba=numba, switch_rx_ratio=1) + runpp(net, numba=numba, switch_rx_ratio=1) assert pytest.approx(net.res_bus.vm_pu.at[1], abs=1e-9) == net.res_bus.vm_pu.at[2] net_zero_z_switch = copy.deepcopy(net) net_zero_z_switch.switch.z_ohm = 0 - pp.runpp(net_zero_z_switch, numba=numba, switch_rx_ratio=1) + runpp(net_zero_z_switch, numba=numba, switch_rx_ratio=1) assert pytest.approx(net_zero_z_switch.res_bus.vm_pu.at[0], abs=1e-9) == net_zero_z_switch.res_bus.vm_pu.at[2] @pytest.fixture def z_switch_net_4bus_parallel(): - net = pp.create_empty_network() + net = create_empty_network() for i in range(4): - pp.create_bus(net, vn_kv=.4) - pp.create_load(net, i, p_mw=0.1) - pp.create_ext_grid(net, 0, vm_pu=1.0) - pp.create_line_from_parameters(net, 0, 1, 1, r_ohm_per_km=0.1 / np.sqrt(2), - x_ohm_per_km=0.1 / np.sqrt(2), - c_nf_per_km=0, max_i_ka=.2) - pp.create_line_from_parameters(net, 1, 3, 1, r_ohm_per_km=0.1 / np.sqrt(2), - x_ohm_per_km=0.1 / np.sqrt(2), - c_nf_per_km=0, max_i_ka=.2) - pp.create_switch(net, 0, 2, et="b", z_ohm=0.1) - pp.create_switch(net, 0, 2, et="b", z_ohm=0) + create_bus(net, vn_kv=.4) + create_load(net, i, p_mw=0.1) + create_ext_grid(net, 0, vm_pu=1.0) + create_line_from_parameters(net, 0, 1, 1, r_ohm_per_km=0.1 / np.sqrt(2), + x_ohm_per_km=0.1 / np.sqrt(2), + c_nf_per_km=0, max_i_ka=.2) + create_line_from_parameters(net, 1, 3, 1, r_ohm_per_km=0.1 / np.sqrt(2), + x_ohm_per_km=0.1 / np.sqrt(2), + c_nf_per_km=0, max_i_ka=.2) + create_switch(net, 0, 2, et="b", z_ohm=0.1) + create_switch(net, 0, 2, et="b", z_ohm=0) return net @pytest.fixture def z_switch_net_4bus(): - net = pp.create_empty_network() + net = create_empty_network() for i in range(4): - pp.create_bus(net, vn_kv=.4) - pp.create_load(net, i, p_mw=0.01) - pp.create_ext_grid(net, 0, vm_pu=1.0) - pp.create_line_from_parameters(net, 0, 1, 1, r_ohm_per_km=0.1 / np.sqrt(2), - x_ohm_per_km=0.1 / np.sqrt(2), - c_nf_per_km=0, max_i_ka=.2) - pp.create_switch(net, 1, 2, et="b", z_ohm=0.1) - pp.create_switch(net, 2, 3, et="b", z_ohm=0) + create_bus(net, vn_kv=.4) + create_load(net, i, p_mw=0.01) + create_ext_grid(net, 0, vm_pu=1.0) + create_line_from_parameters(net, 0, 1, 1, r_ohm_per_km=0.1 / np.sqrt(2), + x_ohm_per_km=0.1 / np.sqrt(2), + c_nf_per_km=0, max_i_ka=.2) + create_switch(net, 1, 2, et="b", z_ohm=0.1) + create_switch(net, 2, 3, et="b", z_ohm=0) return net @pytest.mark.parametrize("numba", [True, False]) def test_switch_fuse_z_ohm_0(z_switch_net_4bus_parallel, z_switch_net_4bus, numba): net = z_switch_net_4bus_parallel - pp.runpp(net, numba=numba) + runpp(net, numba=numba) assert net.res_bus.vm_pu[0] == net.res_bus.vm_pu[2] assert net.res_switch.i_ka[0] == 0 net = z_switch_net_4bus - pp.runpp(net, numba=numba) + runpp(net, numba=numba) assert net.res_bus.vm_pu[2] == net.res_bus.vm_pu[3] assert net.res_bus.vm_pu[1] != net.res_bus.vm_pu[2] @@ -296,40 +303,40 @@ def test_switch_fuse_z_ohm_0(z_switch_net_4bus_parallel, z_switch_net_4bus, numb def test_switch_z_ohm_different(z_switch_net_4bus_parallel, z_switch_net_4bus, numba): net = z_switch_net_4bus_parallel net.switch.at[1, 'z_ohm'] = 0.2 - pp.runpp(net, numba=numba) + runpp(net, numba=numba) assert net.res_bus.vm_pu[0] != net.res_bus.vm_pu[2] assert np.all(net.res_switch.i_ka > 0) net = z_switch_net_4bus net.switch.at[1, 'z_ohm'] = 0.2 - pp.runpp(net, numba=numba) + runpp(net, numba=numba) assert net.res_bus.vm_pu[2] != net.res_bus.vm_pu[3] assert net.res_bus.vm_pu[1] != net.res_bus.vm_pu[2] def test_two_open_switches(): - net = pp.create_empty_network() + net = create_empty_network() b1, b2, l1 = add_grid_connection(net) - b3 = pp.create_bus(net, vn_kv=20.) + b3 = create_bus(net, vn_kv=20.) l2 = create_test_line(net, b2, b3) create_test_line(net, b3, b1) - pp.create_switch(net, b2, l2, et="l", closed=False) - pp.create_switch(net, b3, l2, et="l", closed=False) - pp.runpp(net) + create_switch(net, b2, l2, et="l", closed=False) + create_switch(net, b3, l2, et="l", closed=False) + runpp(net) assert np.isnan(net.res_line.i_ka.at[l2]) or net.res_line.i_ka.at[l2] == 0 def test_oos_bus(): - net = pp.create_empty_network() + net = create_empty_network() add_test_oos_bus_with_is_element(net) assert runpp_with_consistency_checks(net) # test for pq-node result - pp.create_shunt(net, 6, q_mvar=0.8) + create_shunt(net, 6, q_mvar=0.8) assert runpp_with_consistency_checks(net) # 1test for pv-node result - pp.create_gen(net, 4, p_mw=0.5) + create_gen(net, 4, p_mw=0.5) assert runpp_with_consistency_checks(net) @@ -353,18 +360,18 @@ def test_connectivity_check_island_without_pv_bus(): assert np.isclose(iso_p, 0) assert np.isclose(iso_q, 0) - isolated_bus1 = pp.create_bus(net, vn_kv=20., name="isolated Bus1") - isolated_bus2 = pp.create_bus(net, vn_kv=20., name="isolated Bus2") - pp.create_line(net, isolated_bus2, isolated_bus1, length_km=1, - std_type="N2XS(FL)2Y 1x300 RM/35 64/110 kV", - name="IsolatedLine") + isolated_bus1 = create_bus(net, vn_kv=20., name="isolated Bus1") + isolated_bus2 = create_bus(net, vn_kv=20., name="isolated Bus2") + create_line(net, isolated_bus2, isolated_bus1, length_km=1, + std_type="N2XS(FL)2Y 1x300 RM/35 64/110 kV", + name="IsolatedLine") iso_buses, iso_p, iso_q, *_ = get_isolated(net) assert len(iso_buses) == 2 assert np.isclose(iso_p, 0) assert np.isclose(iso_q, 0) - pp.create_load(net, isolated_bus1, p_mw=0.2, q_mvar=0.02) - pp.create_sgen(net, isolated_bus2, p_mw=0.15, q_mvar=0.01) + create_load(net, isolated_bus1, p_mw=0.2, q_mvar=0.02) + create_sgen(net, isolated_bus2, p_mw=0.15, q_mvar=0.01) # with pytest.warns(UserWarning): iso_buses, iso_p, iso_q, *_ = get_isolated(net) @@ -383,14 +390,14 @@ def test_connectivity_check_island_with_one_pv_bus(): assert np.isclose(iso_p, 0) assert np.isclose(iso_q, 0) - isolated_bus1 = pp.create_bus(net, vn_kv=20., name="isolated Bus1") - isolated_bus2 = pp.create_bus(net, vn_kv=20., name="isolated Bus2") - isolated_gen = pp.create_bus(net, vn_kv=20., name="isolated Gen") - isolated_pv_bus = pp.create_gen(net, isolated_gen, p_mw=0.35, vm_pu=1.0, name="isolated PV bus") - pp.create_line(net, isolated_bus2, isolated_bus1, length_km=1, - std_type="N2XS(FL)2Y 1x300 RM/35 64/110 kV", name="IsolatedLine") - pp.create_line(net, isolated_gen, isolated_bus1, length_km=1, - std_type="N2XS(FL)2Y 1x300 RM/35 64/110 kV", name="IsolatedLineToGen") + isolated_bus1 = create_bus(net, vn_kv=20., name="isolated Bus1") + isolated_bus2 = create_bus(net, vn_kv=20., name="isolated Bus2") + isolated_gen = create_bus(net, vn_kv=20., name="isolated Gen") + isolated_pv_bus = create_gen(net, isolated_gen, p_mw=0.35, vm_pu=1.0, name="isolated PV bus") + create_line(net, isolated_bus2, isolated_bus1, length_km=1, + std_type="N2XS(FL)2Y 1x300 RM/35 64/110 kV", name="IsolatedLine") + create_line(net, isolated_gen, isolated_bus1, length_km=1, + std_type="N2XS(FL)2Y 1x300 RM/35 64/110 kV", name="IsolatedLineToGen") # with pytest.warns(UserWarning): iso_buses, iso_p, iso_q, *_ = get_isolated(net) @@ -398,8 +405,8 @@ def test_connectivity_check_island_with_one_pv_bus(): # assert np.isclose(iso_p, 0) # assert np.isclose(iso_q, 0) # - # pp.create_load(net, isolated_bus1, p_mw=0.200., q_mvar=0.020) - # pp.create_sgen(net, isolated_bus2, p_mw=0.0150., q_mvar=-0.010) + # create_load(net, isolated_bus1, p_mw=0.200., q_mvar=0.020) + # create_sgen(net, isolated_bus2, p_mw=0.0150., q_mvar=-0.010) # # iso_buses, iso_p, iso_q = get_isolated(net) # assert len(iso_buses) == 0 @@ -419,48 +426,48 @@ def test_connectivity_check_island_with_multiple_pv_buses(): assert np.isclose(iso_p, 0) assert np.isclose(iso_q, 0) - isolated_bus1 = pp.create_bus(net, vn_kv=20., name="isolated Bus1") - isolated_bus2 = pp.create_bus(net, vn_kv=20., name="isolated Bus2") - isolated_pv_bus1 = pp.create_bus(net, vn_kv=20., name="isolated PV bus1") - isolated_pv_bus2 = pp.create_bus(net, vn_kv=20., name="isolated PV bus2") - pp.create_gen(net, isolated_pv_bus1, p_mw=0.3, vm_pu=1.0, name="isolated PV bus1") - pp.create_gen(net, isolated_pv_bus2, p_mw=0.05, vm_pu=1.0, name="isolated PV bus2") - - pp.create_line(net, isolated_pv_bus1, isolated_bus1, length_km=1, - std_type="N2XS(FL)2Y 1x300 RM/35 64/110 kV", - name="IsolatedLineToGen1") - pp.create_line(net, isolated_pv_bus2, isolated_bus2, length_km=1, - std_type="N2XS(FL)2Y 1x300 RM/35 64/110 kV", - name="IsolatedLineToGen2") - pp.create_line(net, isolated_bus2, isolated_bus1, length_km=1, - std_type="N2XS(FL)2Y 1x300 RM/35 64/110 kV", - name="IsolatedLine") + isolated_bus1 = create_bus(net, vn_kv=20., name="isolated Bus1") + isolated_bus2 = create_bus(net, vn_kv=20., name="isolated Bus2") + isolated_pv_bus1 = create_bus(net, vn_kv=20., name="isolated PV bus1") + isolated_pv_bus2 = create_bus(net, vn_kv=20., name="isolated PV bus2") + create_gen(net, isolated_pv_bus1, p_mw=0.3, vm_pu=1.0, name="isolated PV bus1") + create_gen(net, isolated_pv_bus2, p_mw=0.05, vm_pu=1.0, name="isolated PV bus2") + + create_line(net, isolated_pv_bus1, isolated_bus1, length_km=1, + std_type="N2XS(FL)2Y 1x300 RM/35 64/110 kV", + name="IsolatedLineToGen1") + create_line(net, isolated_pv_bus2, isolated_bus2, length_km=1, + std_type="N2XS(FL)2Y 1x300 RM/35 64/110 kV", + name="IsolatedLineToGen2") + create_line(net, isolated_bus2, isolated_bus1, length_km=1, + std_type="N2XS(FL)2Y 1x300 RM/35 64/110 kV", + name="IsolatedLine") # ToDo with pytest.warns(UserWarning): iso_buses, iso_p, iso_q, *_ = get_isolated(net) def test_isolated_in_service_bus_at_oos_line(): - net = pp.create_empty_network() + net = create_empty_network() b1, b2, l1 = add_grid_connection(net) - b = pp.create_bus(net, vn_kv=135) - l = pp.create_line(net, b2, b, 0.1, std_type="NAYY 4x150 SE") + b = create_bus(net, vn_kv=135) + l = create_line(net, b2, b, 0.1, std_type="NAYY 4x150 SE") net.line.loc[l, "in_service"] = False assert runpp_with_consistency_checks(net, init="flat") def test_isolated_in_service_line(): # ToDo: Fix this - net = pp.create_empty_network() + net = create_empty_network() _, b2, l1 = add_grid_connection(net) - b = pp.create_bus(net, vn_kv=20.) - pp.create_line(net, b2, b, 0.1, std_type="NAYY 4x150 SE") + b = create_bus(net, vn_kv=20.) + create_line(net, b2, b, 0.1, std_type="NAYY 4x150 SE") net.line.loc[l1, "in_service"] = False assert runpp_with_consistency_checks(net, init="flat") def test_makeYbus(): # tests if makeYbus fails for nets where every bus is connected to each other - net = pp.create_empty_network() + net = create_empty_network() b1, b2, l1 = add_grid_connection(net) # number of buses to create @@ -468,7 +475,7 @@ def test_makeYbus(): bus_list = [] # generate buses and connect them for _ in range(n_bus): - bus_list.append(pp.create_bus(net, vn_kv=20.)) + bus_list.append(create_bus(net, vn_kv=20.)) # connect the first bus to slack node create_test_line(net, bus_list[0], b2) @@ -487,8 +494,8 @@ def test_test_sn_mva(): test_net_gen1 = result_test_network_generator(sn_mva=1) test_net_gen2 = result_test_network_generator(sn_mva=2) for net1, net2 in zip(test_net_gen1, test_net_gen2): - pp.runpp(net1) - pp.runpp(net2) + runpp(net1) + runpp(net2) try: assert_net_equal(net1, net2, exclude_elms=["sn_mva"]) except: @@ -499,11 +506,11 @@ def test_test_sn_mva(): def test_bsfw_algorithm(): net = example_simple() - pp.runpp(net) + runpp(net) vm_nr = copy.copy(net.res_bus.vm_pu) va_nr = copy.copy(net.res_bus.va_degree) - pp.runpp(net, algorithm='bfsw') + runpp(net, algorithm='bfsw') vm_alg = net.res_bus.vm_pu va_alg = net.res_bus.va_degree @@ -516,11 +523,11 @@ def test_bsfw_algorithm_multi_net(): net = example_simple() add_grid_connection(net, vn_kv=110., zone="second") - pp.runpp(net) + runpp(net) vm_nr = copy.copy(net.res_bus.vm_pu) va_nr = copy.copy(net.res_bus.va_degree) - pp.runpp(net, algorithm='bfsw') + runpp(net, algorithm='bfsw') vm_alg = net.res_bus.vm_pu va_alg = net.res_bus.va_degree @@ -532,11 +539,11 @@ def test_bsfw_algorithm_with_trafo_shift_and_voltage_angles(): net = example_simple() net["trafo"].loc[:, "shift_degree"] = 180. - pp.runpp(net, calculate_voltage_angles=True) + runpp(net, calculate_voltage_angles=True) vm_nr = net.res_bus.vm_pu va_nr = net.res_bus.va_degree - pp.runpp(net, algorithm='bfsw', calculate_voltage_angles=True) + runpp(net, algorithm='bfsw', calculate_voltage_angles=True) vm_alg = net.res_bus.vm_pu va_alg = net.res_bus.va_degree assert np.allclose(vm_nr, vm_alg) @@ -550,11 +557,11 @@ def test_bsfw_algorithm_with_enforce_q_lims(): net.gen["max_q_mvar"] = [5.] net.gen["min_q_mvar"] = [4.] - pp.runpp(net, enforce_q_lims=True) + runpp(net, enforce_q_lims=True) vm_nr = net.res_bus.vm_pu va_nr = net.res_bus.va_degree - pp.runpp(net, algorithm='bfsw', enforce_q_lims=True) + runpp(net, algorithm='bfsw', enforce_q_lims=True) vm_alg = net.res_bus.vm_pu va_alg = net.res_bus.va_degree assert np.allclose(vm_nr, vm_alg) @@ -563,15 +570,15 @@ def test_bsfw_algorithm_with_enforce_q_lims(): def test_bsfw_algorithm_with_branch_loops(): net = example_simple() - pp.create_line(net, 0, 6, length_km=2.5, - std_type="NA2XS2Y 1x240 RM/25 12/20 kV", name="Line meshed") + create_line(net, 0, 6, length_km=2.5, + std_type="NA2XS2Y 1x240 RM/25 12/20 kV", name="Line meshed") net.switch.loc[:, "closed"] = True - pp.runpp(net, calculate_voltage_angles="auto") + runpp(net, calculate_voltage_angles="auto") vm_nr = net.res_bus.vm_pu va_nr = net.res_bus.va_degree - pp.runpp(net, algorithm='bfsw', calculate_voltage_angles="auto") + runpp(net, algorithm='bfsw', calculate_voltage_angles="auto") vm_alg = net.res_bus.vm_pu va_alg = net.res_bus.va_degree assert np.allclose(vm_nr, vm_alg) @@ -580,11 +587,11 @@ def test_bsfw_algorithm_with_branch_loops(): def test_disabling_vk_update(): net = example_simple() - pp.runpp(net, calculate_voltage_angles="auto") + runpp(net, calculate_voltage_angles="auto") net.trafo.loc[:, "vk_percent"] = 100. net.trafo.loc[:, "vkr_percent"] = 100. - pp.runpp(net, calculate_voltage_angles="auto", update_vk_values=False) + runpp(net, calculate_voltage_angles="auto", update_vk_values=False) assert net.res_trafo.loc[0, 'loading_percent'] > 70. @@ -688,11 +695,11 @@ def test_zip_loads_gridcal(): losses_gridcal = 4.69773448916 - 2.710430515j - abs_path = os.path.join(pp.pp_dir, 'networks', 'power_system_test_case_jsons', + abs_path = os.path.join(pp_dir, 'networks', 'power_system_test_case_jsons', 'case5_demo_gridcal.json') - net = pp.from_json(abs_path) + net = from_json(abs_path) - pp.runpp(net, voltage_depend_loads=True, recycle=None) + runpp(net, voltage_depend_loads=True, recycle=None) # Test Ybus matrix Ybus_pp = net["_ppc"]['internal']['Ybus'].todense() @@ -710,7 +717,7 @@ def test_zip_loads_gridcal(): assert np.isclose(losses_gridcal, - losses_pp / 1.e3) # Test bfsw algorithm - pp.runpp(net, voltage_depend_loads=True, algorithm='bfsw') + runpp(net, voltage_depend_loads=True, algorithm='bfsw') assert np.allclose(net.res_bus.vm_pu, vm_pu_gridcal) assert np.allclose(net.res_bus.va_degree, va_degree_gridcal) @@ -729,11 +736,11 @@ def test_zip_loads_pf_algorithms(): alg_to_test = ['bfsw'] for alg in alg_to_test: - pp.runpp(net, algorithm='nr') + runpp(net, algorithm='nr') vm_nr = net.res_bus.vm_pu va_nr = net.res_bus.va_degree - pp.runpp(net, algorithm=alg) + runpp(net, algorithm=alg) vm_alg = net.res_bus.vm_pu va_alg = net.res_bus.va_degree @@ -742,22 +749,22 @@ def test_zip_loads_pf_algorithms(): def test_zip_loads_with_voltage_angles(): - net = pp.create_empty_network() - b1 = pp.create_bus(net, vn_kv=1.) - b2 = pp.create_bus(net, vn_kv=1.) - pp.create_ext_grid(net, b1) - pp.create_line_from_parameters(net, b1, b2, length_km=1, r_ohm_per_km=0.3, - x_ohm_per_km=0.3, c_nf_per_km=10, max_i_ka=1) - pp.create_load(net, b2, p_mw=0.002, const_z_percent=0, const_i_percent=100) + net = create_empty_network() + b1 = create_bus(net, vn_kv=1.) + b2 = create_bus(net, vn_kv=1.) + create_ext_grid(net, b1) + create_line_from_parameters(net, b1, b2, length_km=1, r_ohm_per_km=0.3, + x_ohm_per_km=0.3, c_nf_per_km=10, max_i_ka=1) + create_load(net, b2, p_mw=0.002, const_z_percent=0, const_i_percent=100) - pp.set_user_pf_options(net, calculate_voltage_angles=True, init='dc') + set_user_pf_options(net, calculate_voltage_angles=True, init='dc') - pp.runpp(net) + runpp(net) res_load = net.res_load.copy() net.ext_grid.va_degree = 100 - pp.runpp(net) + runpp(net) assert np.allclose(net.res_load.values, res_load.values) @@ -766,29 +773,29 @@ def test_zip_loads_out_of_service(): # example from https://github.com/e2nIEE/pandapower/issues/1504 # test net - net = pp.create_empty_network() - bus1 = pp.create_bus(net, vn_kv=20., name="Bus 1") - bus2 = pp.create_bus(net, vn_kv=0.4, name="Bus 2") - bus3 = pp.create_bus(net, vn_kv=0.4, name="Bus 3") + net = create_empty_network() + bus1 = create_bus(net, vn_kv=20., name="Bus 1") + bus2 = create_bus(net, vn_kv=0.4, name="Bus 2") + bus3 = create_bus(net, vn_kv=0.4, name="Bus 3") # create bus elements - pp.create_ext_grid(net, bus=bus1, vm_pu=1.02, name="Grid Connection") - pp.create_load(net, bus=bus3, p_mw=0.100, q_mvar=0.05, name="Load", - const_i_percent=0, const_z_percent=0) + create_ext_grid(net, bus=bus1, vm_pu=1.02, name="Grid Connection") + create_load(net, bus=bus3, p_mw=0.100, q_mvar=0.05, name="Load", + const_i_percent=0, const_z_percent=0) # create branch elements - pp.create_transformer(net, hv_bus=bus1, lv_bus=bus2, - std_type="0.4 MVA 20/0.4 kV", name="Trafo") - pp.create_line(net, from_bus=bus2, to_bus=bus3, length_km=0.1, - std_type="NAYY 4x50 SE", name="Line") + create_transformer(net, hv_bus=bus1, lv_bus=bus2, + std_type="0.4 MVA 20/0.4 kV", name="Trafo") + create_line(net, from_bus=bus2, to_bus=bus3, length_km=0.1, + std_type="NAYY 4x50 SE", name="Line") net1 = net.deepcopy() - oos_load = pp.create_load( + oos_load = create_load( net1, bus=bus3, p_mw=0.100, q_mvar=0.05, in_service=False, const_i_percent=0, const_z_percent=100) - pp.runpp(net, tolerance_mva=1e-8) - pp.runpp(net1, tolerance_mva=1e-8) + runpp(net, tolerance_mva=1e-8) + runpp(net1, tolerance_mva=1e-8) assert np.allclose(net1.res_load.loc[oos_load].fillna(0), 0) net1.res_load = net1.res_load.drop(oos_load) assert nets_equal(net, net1, check_only_results=True) @@ -800,16 +807,16 @@ def test_xward_buses(): However, if the load flow does not converge, those buses end up staying in the net and don't get removed. This can potentially lead to thousands of dummy buses in net. """ - net = pp.create_empty_network() - bus_sl = pp.create_bus(net, 110, name='ExtGrid') - pp.create_ext_grid(net, bus_sl, vm_pu=1) - bus_x = pp.create_bus(net, 110, name='XWARD') - pp.create_xward(net, bus_x, 0, 0, 0, 0, 0, 10, 1.1) - iid = pp.create_impedance(net, bus_sl, bus_x, 0.2, 0.2, 1e3) + net = create_empty_network() + bus_sl = create_bus(net, 110, name='ExtGrid') + create_ext_grid(net, bus_sl, vm_pu=1) + bus_x = create_bus(net, 110, name='XWARD') + create_xward(net, bus_x, 0, 0, 0, 0, 0, 10, 1.1) + iid = create_impedance(net, bus_sl, bus_x, 0.2, 0.2, 1e3) bus_num1 = len(net.bus) - pp.runpp(net) + runpp(net) bus_num2 = len(net.bus) @@ -817,31 +824,31 @@ def test_xward_buses(): # now - make sure that the loadflow doesn't converge: net.impedance.at[iid, 'rft_pu'] = 1 - pp.create_load(net, bus_x, 1e6, 0) + create_load(net, bus_x, 1e6, 0) with pytest.raises(LoadflowNotConverged): # here the load flow doesn't converge and there is an extra bus in net - pp.runpp(net) + runpp(net) bus_num3 = len(net.bus) assert bus_num3 == bus_num1 def test_pvpq_lookup(): - net = pp.create_empty_network() + net = create_empty_network() - b1 = pp.create_bus(net, vn_kv=0.4, index=4) - b2 = pp.create_bus(net, vn_kv=0.4, index=2) - b3 = pp.create_bus(net, vn_kv=0.4, index=3) + b1 = create_bus(net, vn_kv=0.4, index=4) + b2 = create_bus(net, vn_kv=0.4, index=2) + b3 = create_bus(net, vn_kv=0.4, index=3) - pp.create_gen(net, b1, p_mw=0.01, vm_pu=0.4) - pp.create_load(net, b2, p_mw=0.01) - pp.create_ext_grid(net, b3) + create_gen(net, b1, p_mw=0.01, vm_pu=0.4) + create_load(net, b2, p_mw=0.01) + create_ext_grid(net, b3) - pp.create_line(net, from_bus=b1, to_bus=b2, length_km=0.5, std_type="NAYY 4x120 SE") - pp.create_line(net, from_bus=b1, to_bus=b3, length_km=0.5, std_type="NAYY 4x120 SE") + create_line(net, from_bus=b1, to_bus=b2, length_km=0.5, std_type="NAYY 4x120 SE") + create_line(net, from_bus=b1, to_bus=b3, length_km=0.5, std_type="NAYY 4x120 SE") net_numba = copy.deepcopy(net) - pp.runpp(net_numba, numba=True) - pp.runpp(net, numba=False) + runpp(net_numba, numba=True) + runpp(net, numba=False) assert nets_equal(net, net_numba) @@ -849,7 +856,7 @@ def test_pvpq_lookup(): def test_get_internal(): net = example_simple() # for Newton raphson - pp.runpp(net) + runpp(net) J_intern = net._ppc["internal"]["J"] ppc = net._ppc @@ -876,7 +883,7 @@ def test_get_internal(): def test_Ybus_format(): net = example_simple() - pp.runpp(net) + runpp(net) _, ppci = _pd2ppc(net) Ybus, Yf, Yt = makeYbus_pypower(ppci["baseMVA"], ppci["bus"], ppci["branch"]) @@ -892,20 +899,20 @@ def test_Ybus_format(): def test_storage_pf(): - net = pp.create_empty_network() + net = create_empty_network() - b1 = pp.create_bus(net, vn_kv=0.4) - b2 = pp.create_bus(net, vn_kv=0.4) + b1 = create_bus(net, vn_kv=0.4) + b2 = create_bus(net, vn_kv=0.4) - pp.create_line(net, b1, b2, length_km=5, std_type="NAYY 4x50 SE") + create_line(net, b1, b2, length_km=5, std_type="NAYY 4x50 SE") - pp.create_ext_grid(net, b2) - pp.create_load(net, b1, p_mw=0.010) - pp.create_sgen(net, b1, p_mw=0.010) + create_ext_grid(net, b2) + create_load(net, b1, p_mw=0.010) + create_sgen(net, b1, p_mw=0.010) # test generator behaviour - pp.create_storage(net, b1, p_mw=-0.010, max_e_mwh=0.010) - pp.create_sgen(net, b1, p_mw=0.010, in_service=False) + create_storage(net, b1, p_mw=-0.010, max_e_mwh=0.010) + create_sgen(net, b1, p_mw=0.010, in_service=False) res_gen_beh = runpp_with_consistency_checks(net) res_ll_stor = net["res_line"].loading_percent.iloc[0] @@ -919,7 +926,7 @@ def test_storage_pf(): assert np.isclose(res_ll_stor, res_ll_sgen) # test load behaviour - pp.create_load(net, b1, p_mw=0.01, in_service=False) + create_load(net, b1, p_mw=0.01, in_service=False) net["storage"].loc[0, 'in_service'] = True net["storage"].loc[0, 'p_mw'] = 0.01 net["sgen"].loc[1, 'in_service'] = False @@ -940,83 +947,83 @@ def test_storage_pf(): def test_add_element_and_init_results(): net = simple_four_bus_system() - pp.runpp(net, init="flat", calculate_voltage_angles="auto") - pp.create_bus(net, vn_kv=20.) - pp.create_line(net, from_bus=2, to_bus=3, length_km=1, name="new line" + str(1), - std_type="NAYY 4x150 SE") + runpp(net, init="flat", calculate_voltage_angles="auto") + create_bus(net, vn_kv=20.) + create_line(net, from_bus=2, to_bus=3, length_km=1, name="new line" + str(1), + std_type="NAYY 4x150 SE") try: - pp.runpp(net, init="results", calculate_voltage_angles="auto") + runpp(net, init="results", calculate_voltage_angles="auto") assert False except UserWarning: pass def test_pp_initialization(): - net = pp.create_empty_network() + net = create_empty_network() - b1 = pp.create_bus(net, vn_kv=0.4) - b2 = pp.create_bus(net, vn_kv=0.4) + b1 = create_bus(net, vn_kv=0.4) + b2 = create_bus(net, vn_kv=0.4) - pp.create_ext_grid(net, b1, vm_pu=0.7) - pp.create_line(net, b1, b2, 0.5, std_type="NAYY 4x50 SE", index=4) - pp.create_load(net, b2, p_mw=0.01) + create_ext_grid(net, b1, vm_pu=0.7) + create_line(net, b1, b2, 0.5, std_type="NAYY 4x50 SE", index=4) + create_load(net, b2, p_mw=0.01) - pp.runpp(net, init_va_degree="flat", init_vm_pu=1.02) + runpp(net, init_va_degree="flat", init_vm_pu=1.02) assert net._ppc["iterations"] == 5 - pp.runpp(net, init_va_degree="dc", init_vm_pu=0.8) + runpp(net, init_va_degree="dc", init_vm_pu=0.8) assert net._ppc["iterations"] == 4 - pp.runpp(net, init_va_degree="flat", init_vm_pu=np.array([0.75, 0.7])) + runpp(net, init_va_degree="flat", init_vm_pu=np.array([0.75, 0.7])) assert net._ppc["iterations"] == 3 - pp.runpp(net, init_va_degree="dc", init_vm_pu=[0.75, 0.7]) + runpp(net, init_va_degree="dc", init_vm_pu=[0.75, 0.7]) assert net._ppc["iterations"] == 3 - pp.runpp(net, init_va_degree="flat", init_vm_pu="auto") + runpp(net, init_va_degree="flat", init_vm_pu="auto") assert net._ppc["iterations"] == 3 - pp.runpp(net, init_va_degree="dc") + runpp(net, init_va_degree="dc") assert net._ppc["iterations"] == 3 def test_equal_indices_res(): # tests if res_bus indices of are the same as the ones in bus. # If this is not the case and you init from results, the PF will fail - net = pp.create_empty_network() + net = create_empty_network() - b1 = pp.create_bus(net, vn_kv=10., index=3) - b2 = pp.create_bus(net, vn_kv=0.4, index=1) - b3 = pp.create_bus(net, vn_kv=0.4, index=2) + b1 = create_bus(net, vn_kv=10., index=3) + b2 = create_bus(net, vn_kv=0.4, index=1) + b3 = create_bus(net, vn_kv=0.4, index=2) - pp.create_ext_grid(net, b1) - pp.create_transformer(net, b1, b2, std_type="0.63 MVA 20/0.4 kV") - pp.create_line(net, b2, b3, 0.5, std_type="NAYY 4x50 SE", index=4) - pp.create_load(net, b3, p_mw=0.010) - pp.runpp(net) + create_ext_grid(net, b1) + create_transformer(net, b1, b2, std_type="0.63 MVA 20/0.4 kV") + create_line(net, b2, b3, 0.5, std_type="NAYY 4x50 SE", index=4) + create_load(net, b3, p_mw=0.010) + runpp(net) net["bus"] = net["bus"].sort_index() try: # This should raise a UserWarning since index has changed!! - pp.runpp(net, init_vm_pu="results", init_va_degree="results") + runpp(net, init_vm_pu="results", init_va_degree="results") assert False except UserWarning: pass def test_ext_grid_and_gen_at_one_bus(**kwargs): - net = pp.create_empty_network() - b1 = pp.create_bus(net, vn_kv=110) - b2 = pp.create_bus(net, vn_kv=110) - pp.create_ext_grid(net, b1, vm_pu=1.01) - pp.create_line(net, b1, b2, 1., std_type="305-AL1/39-ST1A 110.0") - pp.create_load(net, bus=b2, p_mw=3.5, q_mvar=1) + net = create_empty_network() + b1 = create_bus(net, vn_kv=110) + b2 = create_bus(net, vn_kv=110) + create_ext_grid(net, b1, vm_pu=1.01) + create_line(net, b1, b2, 1., std_type="305-AL1/39-ST1A 110.0") + create_load(net, bus=b2, p_mw=3.5, q_mvar=1) runpp_with_consistency_checks(net, **kwargs) q = net.res_ext_grid.q_mvar.sum() ##create two gens at the slack bus - g1 = pp.create_gen(net, b1, vm_pu=1.01, p_mw=1) - g2 = pp.create_gen(net, b1, vm_pu=1.01, p_mw=1) + g1 = create_gen(net, b1, vm_pu=1.01, p_mw=1) + g2 = create_gen(net, b1, vm_pu=1.01, p_mw=1) runpp_with_consistency_checks(net, **kwargs) # all the reactive power previously provided by the ext_grid is now provided by the generators @@ -1043,7 +1050,7 @@ def test_ext_grid_and_gen_at_one_bus(**kwargs): assert np.isclose(net.res_gen.q_mvar.sum() + net.res_ext_grid.q_mvar.sum(), q) # second ext_grid at the slack bus - pp.create_ext_grid(net, b1, vm_pu=1.01) + create_ext_grid(net, b1, vm_pu=1.01) runpp_with_consistency_checks(net, enforce_q_lims=False, **kwargs) # gens still have the correct active power assert np.allclose(net.gen.p_mw.values, net.res_gen.p_mw.values) @@ -1059,32 +1066,32 @@ def test_ext_grid_and_gen_at_one_bus(**kwargs): def two_ext_grids_at_one_bus(): - net = pp.create_empty_network() - b1 = pp.create_bus(net, vn_kv=110, index=3) - b2 = pp.create_bus(net, vn_kv=110, index=5) - pp.create_ext_grid(net, b1, vm_pu=1.01, index=2) - pp.create_line(net, b1, b2, 1., std_type="305-AL1/39-ST1A 110.0") - pp.create_load(net, bus=b2, p_mw=3.5, q_mvar=1) - pp.create_gen(net, b1, vm_pu=1.01, p_mw=1) + net = create_empty_network() + b1 = create_bus(net, vn_kv=110, index=3) + b2 = create_bus(net, vn_kv=110, index=5) + create_ext_grid(net, b1, vm_pu=1.01, index=2) + create_line(net, b1, b2, 1., std_type="305-AL1/39-ST1A 110.0") + create_load(net, bus=b2, p_mw=3.5, q_mvar=1) + create_gen(net, b1, vm_pu=1.01, p_mw=1) runpp_with_consistency_checks(net) assert net.converged # connect second ext_grid to b1 with different angle but out of service - eg2 = pp.create_ext_grid(net, b1, vm_pu=1.01, va_degree=20, index=5, in_service=False) + eg2 = create_ext_grid(net, b1, vm_pu=1.01, va_degree=20, index=5, in_service=False) runpp_with_consistency_checks(net) # power flow still converges since eg2 is out of service assert net.converged # error is raised after eg2 is set in service net.ext_grid.at[eg2, "in_service"] = True with pytest.raises(UserWarning): - pp.runpp(net) + runpp(net) # error is also raised when eg2 is connected to first ext_grid through bus-bus switch - b3 = pp.create_bus(net, vn_kv=110) - pp.create_switch(net, b1, b3, et="b") + b3 = create_bus(net, vn_kv=110) + create_switch(net, b1, b3, et="b") net.ext_grid.at[eg2, "bus"] = b3 with pytest.raises(UserWarning): - pp.runpp(net) + runpp(net) # no error is raised when voltage angles are not calculated runpp_with_consistency_checks(net, calculate_voltage_angles=False) @@ -1094,34 +1101,34 @@ def two_ext_grids_at_one_bus(): net.ext_grid.at[eg2, "vm_pu"] = 1.02 net.ext_grid.at[eg2, "va_degree"] = 0 with pytest.raises(UserWarning): - pp.runpp(net) + runpp(net) def test_dc_with_ext_grid_at_one_bus(): - net = pp.create_empty_network() - b1 = pp.create_bus(net, vn_kv=110) - b2 = pp.create_bus(net, vn_kv=110) + net = create_empty_network() + b1 = create_bus(net, vn_kv=110) + b2 = create_bus(net, vn_kv=110) - pp.create_ext_grid(net, b1, vm_pu=1.01) - pp.create_ext_grid(net, b2, vm_pu=1.01) + create_ext_grid(net, b1, vm_pu=1.01) + create_ext_grid(net, b2, vm_pu=1.01) - pp.create_dcline(net, from_bus=b1, to_bus=b2, p_mw=10, - loss_percent=0, loss_mw=0, vm_from_pu=1.01, vm_to_pu=1.01) + create_dcline(net, from_bus=b1, to_bus=b2, p_mw=10, + loss_percent=0, loss_mw=0, vm_from_pu=1.01, vm_to_pu=1.01) - pp.create_sgen(net, b1, p_mw=10) - pp.create_load(net, b2, p_mw=10) + create_sgen(net, b1, p_mw=10) + create_load(net, b2, p_mw=10) runpp_with_consistency_checks(net) assert np.allclose(net.res_ext_grid.p_mw.values, [0, 0]) def test_no_branches(): - net = pp.create_empty_network() - pp.create_buses(net, 3, 110) - pp.create_ext_grid(net, 0) - pp.create_sgen(net, 1, 10) - pp.create_load(net, 2, 10) - pp.runpp(net) + net = create_empty_network() + create_buses(net, 3, 110) + create_ext_grid(net, 0) + create_sgen(net, 1, 10) + create_load(net, 2, 10) + runpp(net) assert net.res_ext_grid.p_mw.at[0] == 0. assert net.res_ext_grid.q_mvar.at[0] == 0. assert net.res_bus.vm_pu.at[0] == 1. @@ -1130,14 +1137,14 @@ def test_no_branches(): def test_only_ref_buses(): - net = pp.create_empty_network() - pp.create_buses(net, nr_buses=2, vn_kv=1) - pp.create_line_from_parameters(net, from_bus=0, to_bus=1, length_km=1, - r_ohm_per_km=1, x_ohm_per_km=1, - c_nf_per_km=0, max_i_ka=1) - pp.create_ext_grid(net, bus=0, vm_pu=1) - pp.create_ext_grid(net, bus=1, vm_pu=1) - pp.runpp(net) + net = create_empty_network() + create_buses(net, nr_buses=2, vn_kv=1) + create_line_from_parameters(net, from_bus=0, to_bus=1, length_km=1, + r_ohm_per_km=1, x_ohm_per_km=1, + c_nf_per_km=0, max_i_ka=1) + create_ext_grid(net, bus=0, vm_pu=1) + create_ext_grid(net, bus=1, vm_pu=1) + runpp(net) assert np.all(net.res_bus.vm_pu == 1.) assert np.all(net.res_bus.va_degree == 0.) assert net.res_line.loading_percent.at[0] == 0. @@ -1145,7 +1152,7 @@ def test_only_ref_buses(): assert np.all(net.res_ext_grid.q_mvar == 0.) net.ext_grid.at[1, "vm_pu"] = 0.5 - pp.runpp(net) + runpp(net) assert np.allclose(net.res_ext_grid.p_mw.values, np.array([0.25, -0.125]), rtol=0, atol=1e-12) assert np.allclose(net.res_ext_grid.q_mvar.values, np.array([0.25, -0.125]), rtol=0, atol=1e-12) assert abs(net.res_line.p_from_mw.at[0] - 0.25) < 1e-12 @@ -1158,22 +1165,22 @@ def test_only_ref_buses(): def test_init_results_without_results(): # should switch to "auto" mode and not fail net = example_multivoltage() - pp.reset_results(net) - pp.runpp(net, init="results") + reset_results(net) + runpp(net, init="results") assert net.converged - pp.reset_results(net) - pp.runpp(net, init_vm_pu="results") + reset_results(net) + runpp(net, init_vm_pu="results") assert net.converged - pp.reset_results(net) - pp.runpp(net, init_va_degree="results") + reset_results(net) + runpp(net, init_va_degree="results") assert net.converged - pp.reset_results(net) - pp.runpp(net, init_va_degree="results", init_vm_pu="results") + reset_results(net) + runpp(net, init_va_degree="results", init_vm_pu="results") assert net.converged def test_init_results(): - net = pp.create_empty_network() + net = create_empty_network() add_test_line(net) # line network with switch at to bus assert_init_results(net) net.switch.at[0, "bus"] = 0 # switch at from bus @@ -1189,8 +1196,8 @@ def test_init_results(): add_test_trafo3w(net) # trafo3w with internal node assert_init_results(net) t3idx = net.trafo3w.index[0] - t3_switch = pp.create_switch(net, bus=net.trafo3w.hv_bus.at[t3idx], - element=t3idx, et="t3", closed=False) # trafo3w switch at hv side + t3_switch = create_switch(net, bus=net.trafo3w.hv_bus.at[t3idx], + element=t3idx, et="t3", closed=False) # trafo3w switch at hv side assert_init_results(net) net.switch.at[t3_switch, "bus"] = net.trafo3w.mv_bus.at[t3idx] # trafo3w switch at mv side assert_init_results(net) @@ -1199,33 +1206,33 @@ def test_init_results(): def assert_init_results(net): - pp.runpp(net, init="auto") + runpp(net, init="auto") assert net._ppc["iterations"] > 0 - pp.runpp(net, init="results") + runpp(net, init="results") assert net._ppc["iterations"] == 0 def test_wye_delta(): - net = pp.create_empty_network() - pp.create_bus(net, vn_kv=110) - pp.create_buses(net, nr_buses=4, vn_kv=20) - trafo = pp.create_transformer(net, hv_bus=0, lv_bus=1, std_type='25 MVA 110/20 kV') - pp.create_line(net, 1, 2, length_km=2.0, std_type="NAYY 4x50 SE") - pp.create_line(net, 2, 3, length_km=6.0, std_type="NAYY 4x50 SE") - pp.create_line(net, 3, 4, length_km=10.0, std_type="NAYY 4x50 SE") - pp.create_ext_grid(net, 0) - pp.create_load(net, 4, p_mw=0.1) - pp.create_sgen(net, 2, p_mw=4.) - pp.create_sgen(net, 3, p_mw=4.) - - pp.runpp(net, trafo_model="pi") + net = create_empty_network() + create_bus(net, vn_kv=110) + create_buses(net, nr_buses=4, vn_kv=20) + trafo = create_transformer(net, hv_bus=0, lv_bus=1, std_type='25 MVA 110/20 kV') + create_line(net, 1, 2, length_km=2.0, std_type="NAYY 4x50 SE") + create_line(net, 2, 3, length_km=6.0, std_type="NAYY 4x50 SE") + create_line(net, 3, 4, length_km=10.0, std_type="NAYY 4x50 SE") + create_ext_grid(net, 0) + create_load(net, 4, p_mw=0.1) + create_sgen(net, 2, p_mw=4.) + create_sgen(net, 3, p_mw=4.) + + runpp(net, trafo_model="pi") f, t = net._pd2ppc_lookups["branch"]["trafo"] assert np.isclose(net.res_trafo.p_hv_mw.at[trafo], -7.560996, rtol=1e-7) assert np.allclose(net._ppc["branch"][f:t, [BR_R, BR_X, BR_B, BR_G]].flatten(), np.array([0.0001640, 0.0047972, -0.0105000, 0.014]), rtol=1e-7) - pp.runpp(net, trafo_model="t") + runpp(net, trafo_model="t") assert np.allclose(net._ppc["branch"][f:t, [BR_R, BR_X, BR_B, BR_G]].flatten(), np.array([0.00016392, 0.00479726, -0.01050009, 0.01399964])) assert np.isclose(net.res_trafo.p_hv_mw.at[trafo], -7.561001, rtol=1e-7) @@ -1236,20 +1243,20 @@ def test_line_temperature(): r_init = net.line.r_ohm_per_km.values.copy() # r_ohm_per_km is not in line results by default - pp.runpp(net) + runpp(net) v_init = net.res_bus.vm_pu.values.copy() va_init = net.res_bus.va_degree.values.copy() assert "r_ohm_per_km" not in net.res_line.columns # no temperature adjustment performed if not explicitly set in options/arguments to runpp net.line["temperature_degree_celsius"] = 20 - pp.runpp(net) + runpp(net) assert "r_ohm_per_km" not in net.res_line.columns assert np.allclose(net.res_bus.vm_pu, v_init, rtol=0, atol=1e-16) assert np.allclose(net.res_bus.va_degree, va_init, rtol=0, atol=1e-16) # argument in runpp is considered - pp.runpp(net, consider_line_temperature=True) + runpp(net, consider_line_temperature=True) assert "r_ohm_per_km" in net.res_line.columns assert np.allclose(net.res_line.r_ohm_per_km, r_init, rtol=0, atol=1e-16) assert np.allclose(net.res_bus.vm_pu, v_init, rtol=0, atol=1e-16) @@ -1258,8 +1265,8 @@ def test_line_temperature(): # check results of r adjustment, check that user_pf_options works, alpha is 4e-3 by default t = np.arange(0, 80, 10) net.line.temperature_degree_celsius = t - pp.set_user_pf_options(net, consider_line_temperature=True) - pp.runpp(net) + set_user_pf_options(net, consider_line_temperature=True) + runpp(net) alpha = 4e-3 r_temp = r_init * (1 + alpha * (t - 20)) assert np.allclose(net.res_line.r_ohm_per_km, r_temp, rtol=0, atol=1e-16) @@ -1269,79 +1276,79 @@ def test_line_temperature(): # check reults with user-defined alpha alpha = np.arange(3e-3, 5e-3, 2.5e-4) net.line['alpha'] = alpha - pp.runpp(net) + runpp(net) r_temp = r_init * (1 + alpha * (t - 20)) assert np.allclose(net.res_line.r_ohm_per_km, r_temp, rtol=0, atol=1e-16) assert not np.allclose(net.res_bus.vm_pu, v_init, rtol=0, atol=1e-4) assert not np.allclose(net.res_bus.va_degree, va_init, rtol=0, atol=1e-2) # not anymore in net if not considered - pp.set_user_pf_options(net, overwrite=True) - pp.runpp(net) + set_user_pf_options(net, overwrite=True) + runpp(net) assert np.allclose(net.res_bus.vm_pu, v_init, rtol=0, atol=1e-16) assert np.allclose(net.res_bus.va_degree, va_init, rtol=0, atol=1e-16) assert "r_ohm_per_km" not in net.res_line.columns def test_results_for_line_temperature(): - net = pp.create_empty_network() - pp.create_bus(net, 0.4) - pp.create_buses(net, 2, 0.4) + net = create_empty_network() + create_bus(net, 0.4) + create_buses(net, 2, 0.4) - pp.create_ext_grid(net, 0) - pp.create_load(net, 1, 5e-3, 10e-3) - pp.create_load(net, 2, 5e-3, 10e-3) + create_ext_grid(net, 0) + create_load(net, 1, 5e-3, 10e-3) + create_load(net, 2, 5e-3, 10e-3) - pp.create_line_from_parameters(net, 0, 1, 0.5, 0.642, 0.083, 210, 1, alpha=0.00403) - pp.create_line_from_parameters(net, 1, 2, 0.5, 0.642, 0.083, 210, 1, alpha=0.00403) + create_line_from_parameters(net, 0, 1, 0.5, 0.642, 0.083, 210, 1, alpha=0.00403) + create_line_from_parameters(net, 1, 2, 0.5, 0.642, 0.083, 210, 1, alpha=0.00403) vm_res_20 = [1, 0.9727288676, 0.95937328755] va_res_20 = [0, 2.2103403814, 3.3622612327] vm_res_80 = [1, 0.96677572771, 0.95062498477] va_res_80 = [0, 2.7993156134, 4.2714451629] - pp.runpp(net) + runpp(net) assert np.allclose(net.res_bus.vm_pu, vm_res_20, rtol=0, atol=1e-6) assert np.allclose(net.res_bus.va_degree, va_res_20, rtol=0, atol=1e-6) net.line["temperature_degree_celsius"] = 80 - pp.set_user_pf_options(net, consider_line_temperature=True) - pp.runpp(net) + set_user_pf_options(net, consider_line_temperature=True) + runpp(net) assert np.allclose(net.res_bus.vm_pu, vm_res_80, rtol=0, atol=1e-6) assert np.allclose(net.res_bus.va_degree, va_res_80, rtol=0, atol=1e-6) def test_tap_dependent_impedance(): - net = pp.create_empty_network() + net = create_empty_network() b1, b2, l1 = add_grid_connection(net) - b3 = pp.create_bus(net, vn_kv=0.4) - pp.create_transformer(net, hv_bus=b2, lv_bus=b3, std_type="0.25 MVA 20/0.4 kV") - pp.create_transformer(net, hv_bus=b2, lv_bus=b3, std_type="0.25 MVA 20/0.4 kV") - - b4 = pp.create_bus(net, vn_kv=0.9) - b5 = pp.create_bus(net, vn_kv=0.4) - pp.create_transformer3w_from_parameters(net, hv_bus=b2, mv_bus=b4, lv_bus=b5, - vn_hv_kv=20., vn_mv_kv=0.9, vn_lv_kv=0.45, sn_hv_mva=0.6, sn_mv_mva=0.5, - sn_lv_mva=0.4, vk_hv_percent=1., vk_mv_percent=1., vk_lv_percent=1., - vkr_hv_percent=0.3, vkr_mv_percent=0.3, vkr_lv_percent=0.3, - pfe_kw=0.2, i0_percent=0.3, tap_neutral=0., - tap_pos=0, tap_step_percent=1., tap_min=-2, tap_max=2) + b3 = create_bus(net, vn_kv=0.4) + create_transformer(net, hv_bus=b2, lv_bus=b3, std_type="0.25 MVA 20/0.4 kV") + create_transformer(net, hv_bus=b2, lv_bus=b3, std_type="0.25 MVA 20/0.4 kV") + + b4 = create_bus(net, vn_kv=0.9) + b5 = create_bus(net, vn_kv=0.4) + create_transformer3w_from_parameters(net, hv_bus=b2, mv_bus=b4, lv_bus=b5, + vn_hv_kv=20., vn_mv_kv=0.9, vn_lv_kv=0.45, sn_hv_mva=0.6, sn_mv_mva=0.5, + sn_lv_mva=0.4, vk_hv_percent=1., vk_mv_percent=1., vk_lv_percent=1., + vkr_hv_percent=0.3, vkr_mv_percent=0.3, vkr_lv_percent=0.3, + pfe_kw=0.2, i0_percent=0.3, tap_neutral=0., + tap_pos=0, tap_step_percent=1., tap_min=-2, tap_max=2) net_backup = net.deepcopy() - pp.control.create_trafo_characteristics(net, 'trafo', [0], "vk_percent", [[-2, -1, 0, 1, 2]], [[5.5, 5.8, 6, 6.2, 6.5]]) - pp.control.create_trafo_characteristics(net, 'trafo', [0], "vkr_percent", [[-2, -1, 0, 1, 2]], [[1.4, 1.42, 1.44, 1.46, 1.48]]) - pp.control.create_trafo_characteristics(net, 'trafo', [1], "vk_percent", [[-2, -1, 0, 1, 2]], [[5.4, 5.7, 6, 6.1, 6.4]]) + create_trafo_characteristics(net, 'trafo', [0], "vk_percent", [[-2, -1, 0, 1, 2]], [[5.5, 5.8, 6, 6.2, 6.5]]) + create_trafo_characteristics(net, 'trafo', [0], "vkr_percent", [[-2, -1, 0, 1, 2]], [[1.4, 1.42, 1.44, 1.46, 1.48]]) + create_trafo_characteristics(net, 'trafo', [1], "vk_percent", [[-2, -1, 0, 1, 2]], [[5.4, 5.7, 6, 6.1, 6.4]]) # test alternative way to set up tap dependence impedance characteristic - pp.control.SplineCharacteristic(net, [-2, -1, 0, 1, 2], [0.95, 0.98, 1, 1.02, 1.05]) + SplineCharacteristic(net, [-2, -1, 0, 1, 2], [0.95, 0.98, 1, 1.02, 1.05]) net.trafo3w['tap_dependent_impedance'] = True net.trafo3w['vk_hv_percent_characteristic'] = 3 - pp.runpp(net) - pp.runpp(net_backup) + runpp(net) + runpp(net_backup) assert_res_equal(net, net_backup) net.trafo.at[0, "tap_pos"] = 2 @@ -1349,24 +1356,24 @@ def test_tap_dependent_impedance(): net_backup.trafo.at[0, "vk_percent"] = 6.5 net_backup.trafo.at[0, "vkr_percent"] = 1.48 - pp.runpp(net) - pp.runpp(net_backup) + runpp(net) + runpp(net_backup) assert_res_equal(net, net_backup) net.trafo.at[1, "tap_pos"] = -2 net_backup.trafo.at[1, "tap_pos"] = -2 net_backup.trafo.at[1, "vk_percent"] = 5.4 - pp.runpp(net) - pp.runpp(net_backup) + runpp(net) + runpp(net_backup) assert_res_equal(net, net_backup) net.trafo3w.at[0, "tap_pos"] = 2 net_backup.trafo3w.at[0, "tap_pos"] = 2 net_backup.trafo3w.at[0, "vk_hv_percent"] = 1.05 - pp.runpp(net) - pp.runpp(net_backup) + runpp(net) + runpp(net_backup) assert_res_equal(net, net_backup) @@ -1376,7 +1383,7 @@ def test_lightsim2grid(): for net in result_test_network_generator(): try: net_ref = copy.deepcopy(net) - pp.runpp(net_ref, lightsim2grid=False) + runpp(net_ref, lightsim2grid=False) runpp_with_consistency_checks(net, lightsim2grid=True) assert_res_equal(net, net_ref) except AssertionError: @@ -1390,9 +1397,9 @@ def test_lightsim2grid(): @pytest.mark.skipif(not lightsim2grid_available, reason="lightsim2grid is not installed") def test_lightsim2grid_case118(): - net = pp.networks.case118() + net = case118() net_ref = copy.deepcopy(net) - pp.runpp(net_ref, lightsim2grid=False) + runpp(net_ref, lightsim2grid=False) runpp_with_consistency_checks(net, lightsim2grid=True) assert_res_equal(net, net_ref) @@ -1419,7 +1426,7 @@ def test_lightsim2grid_extgrid(): @pytest.mark.skipif(lightsim2grid_available, reason="only relevant if lightsim2grid is not installed") def test_lightsim2grid_option_basic(): net = simple_four_bus_system() - pp.runpp(net) + runpp(net) assert not net._options["lightsim2grid"] @@ -1427,63 +1434,63 @@ def test_lightsim2grid_option_basic(): def test_lightsim2grid_option(): # basic usage net = simple_four_bus_system() - pp.runpp(net) + runpp(net) assert net._options["lightsim2grid"] - pp.runpp(net, lightsim2grid=False) + runpp(net, lightsim2grid=False) assert not net._options["lightsim2grid"] # missing algorithm - pp.runpp(net, algorithm="gs") + runpp(net, algorithm="gs") assert not net._options["lightsim2grid"] with pytest.raises(NotImplementedError, match=r"algorithm"): - pp.runpp(net, algorithm="gs", lightsim2grid=True) + runpp(net, algorithm="gs", lightsim2grid=True) # voltage-dependent loads net.load["const_z_percent"] = 100. - pp.runpp(net, voltage_depend_loads=True) + runpp(net, voltage_depend_loads=True) assert not net._options["lightsim2grid"] with pytest.raises(NotImplementedError, match=r"voltage-dependent loads"): - pp.runpp(net, voltage_depend_loads=True, lightsim2grid=True) + runpp(net, voltage_depend_loads=True, lightsim2grid=True) with pytest.raises(NotImplementedError, match=r"voltage-dependent loads"): - pp.runpp(net, lightsim2grid=True) + runpp(net, lightsim2grid=True) net.load.const_z_percent = 0 # multiple slacks - xg = pp.create_ext_grid(net, 1, 1.) - pp.runpp(net) + xg = create_ext_grid(net, 1, 1.) + runpp(net) assert not net._options["lightsim2grid"] with pytest.raises(NotImplementedError, match=r"multiple ext_grids"): - pp.runpp(net, lightsim2grid=True) + runpp(net, lightsim2grid=True) net.ext_grid.at[xg, 'in_service'] = False - pp.runpp(net) + runpp(net) assert net._options["lightsim2grid"] - pp.create_gen(net, 1, 0, 1., slack=True) + create_gen(net, 1, 0, 1., slack=True) with pytest.raises(NotImplementedError, match=r"multiple ext_grids"): - pp.runpp(net, lightsim2grid=True) + runpp(net, lightsim2grid=True) - pp.runpp(net, distributed_slack=True) + runpp(net, distributed_slack=True) assert net._options["lightsim2grid"] def test_at_isolated_bus(): - net = pp.create_empty_network() - pp.create_buses(net, 4, 110) - pp.create_ext_grid(net, 0) + net = create_empty_network() + create_buses(net, 4, 110) + create_ext_grid(net, 0) - pp.create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) + create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) - pp.create_gen(net, 3, 0, vm_pu=0, in_service=False) + create_gen(net, 3, 0, vm_pu=0, in_service=False) - pp.runpp(net) + runpp(net) assert net._options["init_vm_pu"] == 1. if __name__ == "__main__": - pytest.main([__file__, "-xs"]) \ No newline at end of file + pytest.main([__file__, "-xs"]) diff --git a/pandapower/test/loadflow/test_runpp_3ph.py b/pandapower/test/loadflow/test_runpp_3ph.py index 440fc6617..254cb90a0 100644 --- a/pandapower/test/loadflow/test_runpp_3ph.py +++ b/pandapower/test/loadflow/test_runpp_3ph.py @@ -4,34 +4,44 @@ Tests 3 phase power flow algorithm @author: sghosh """ -import pandapower as pp +import os + import numpy as np import pytest -import pandapower.toolbox -from pandapower.test.loadflow.PF_Results import get_PF_Results +from pandapower import pp_dir +from pandapower import replace_line_by_impedance +from pandapower.auxiliary import get_free_id +from pandapower.create import create_empty_network, create_bus, create_ext_grid, create_line, create_asymmetric_load, \ + create_line_from_parameters, create_load, create_transformer_from_parameters, create_sgen, create_asymmetric_sgen, \ + create_shunt +from pandapower.file_io import from_json +from pandapower.pf.runpp_3ph import runpp_3ph +from pandapower.run import runpp +from pandapower.std_types import create_std_type, add_zero_impedance_parameters from pandapower.test.consistency_checks import runpp_3ph_with_consistency_checks, runpp_with_consistency_checks -import os +from pandapower.test.loadflow.PF_Results import get_PF_Results +from pandapower.toolbox import dataframes_equal @pytest.fixture def net(): - v_base = 110 # 110kV Base Voltage - k_va_base = 100 # 100 MVA -# I_base = (kVA_base/V_base) * 1e-3 # in kA - net = pp.create_empty_network(sn_mva=k_va_base) - pp.create_bus(net, vn_kv=v_base, index=1) - pp.create_bus(net, vn_kv=v_base, index=5) - pp.create_ext_grid(net, bus=1, vm_pu=1.0, s_sc_max_mva=5000, rx_max=0.1, - r0x0_max=0.1, x0x_max=1.0) - pp.create_std_type(net, {"r0_ohm_per_km": 0.0848, "x0_ohm_per_km": 0.4649556, - "c0_nf_per_km": 230.6, "g0_us_per_km": 0, "max_i_ka": 0.963, "r_ohm_per_km": 0.0212, - "x_ohm_per_km": 0.1162389, "c_nf_per_km": 230}, - "example_type") - pp.create_line(net, from_bus=1, to_bus=5, length_km=50.0, std_type="example_type") - - pp.create_asymmetric_load(net, 5, p_a_mw=50, q_a_mvar=50, p_b_mw=10, q_b_mvar=15, - p_c_mw=10, q_c_mvar=5) + v_base = 110 # 110kV Base Voltage + k_va_base = 100 # 100 MVA + # I_base = (kVA_base/V_base) * 1e-3 # in kA + net = create_empty_network(sn_mva=k_va_base) + create_bus(net, vn_kv=v_base, index=1) + create_bus(net, vn_kv=v_base, index=5) + create_ext_grid(net, bus=1, vm_pu=1.0, s_sc_max_mva=5000, rx_max=0.1, + r0x0_max=0.1, x0x_max=1.0) + create_std_type(net, {"r0_ohm_per_km": 0.0848, "x0_ohm_per_km": 0.4649556, + "c0_nf_per_km": 230.6, "g0_us_per_km": 0, "max_i_ka": 0.963, "r_ohm_per_km": 0.0212, + "x_ohm_per_km": 0.1162389, "c_nf_per_km": 230}, + "example_type") + create_line(net, from_bus=1, to_bus=5, length_km=50.0, std_type="example_type") + + create_asymmetric_load(net, 5, p_a_mw=50, q_a_mvar=50, p_b_mw=10, q_b_mvar=15, + p_c_mw=10, q_c_mvar=5) return net @@ -39,7 +49,7 @@ def check_it(net): bus_pp = np.abs(net.res_bus_3ph[['vm_a_pu', 'vm_b_pu', 'vm_c_pu']] [~np.isnan(net.res_bus_3ph.vm_a_pu)].values) bus_pf = np.abs(np.array([[0.96742893, 1.01302766, 1.019784], - [0.74957533, 1.09137945, 1.05124282]])) + [0.74957533, 1.09137945, 1.05124282]])) assert np.max(np.abs(bus_pp - bus_pf)) < 1.1e-6 line_pp = np.abs(net.res_line_3ph[~np.isnan(net.res_line_3ph.i_a_from_ka)] [['i_a_from_ka', 'i_a_to_ka', 'i_b_from_ka', 'i_b_to_ka', @@ -51,19 +61,19 @@ def check_it(net): 'loading_percent' ]].values) line_pf = np.abs(np.array( - [[1.34212045, 1.48537916, 0.13715552, 0.26009611, - 0.22838401, 0.1674634, - 55.70772301, (-49.999992954), 60.797262682, (-49.999959283), - 8.7799379802, (-9.9999996625), (-0.88093549983), (-15.000000238), - 9.3739293122, (-10.000000161), (-11.441663679), (-4.9999997418), - 154.2452, 27.00894, 23.71589, - 154.2452]])) + [[1.34212045, 1.48537916, 0.13715552, 0.26009611, + 0.22838401, 0.1674634, + 55.70772301, (-49.999992954), 60.797262682, (-49.999959283), + 8.7799379802, (-9.9999996625), (-0.88093549983), (-15.000000238), + 9.3739293122, (-10.000000161), (-11.441663679), (-4.9999997418), + 154.2452, 27.00894, 23.71589, + 154.2452]])) assert np.max(np.abs(line_pp - line_pf)) < 1.1e-4 def test_2bus_network(net): # -o---o - pp.add_zero_impedance_parameters(net) + add_zero_impedance_parameters(net) runpp_3ph_with_consistency_checks(net) assert net['converged'] check_it(net) @@ -71,9 +81,9 @@ def test_2bus_network(net): def test_2bus_network_single_isolated_busses(net): # -o---o o x - pp.create_bus(net, vn_kv=110) - pp.create_bus(net, vn_kv=110, in_service=False) - pp.add_zero_impedance_parameters(net) + create_bus(net, vn_kv=110) + create_bus(net, vn_kv=110, in_service=False) + add_zero_impedance_parameters(net) runpp_3ph_with_consistency_checks(net) assert net['converged'] check_it(net) @@ -81,12 +91,12 @@ def test_2bus_network_single_isolated_busses(net): def test_2bus_network_isolated_net_part(net): # -o---o o---o - b1 = pp.create_bus(net, vn_kv=110) - b2 = pp.create_bus(net, vn_kv=110) - pp.create_line(net, from_bus=b1, to_bus=b2, length_km=50.0, std_type="example_type") - pp.create_asymmetric_load(net, b2, p_a_mw=50, q_a_mvar=50, p_b_mw=10, q_b_mvar=15, - p_c_mw=10, q_c_mvar=5) - pp.add_zero_impedance_parameters(net) + b1 = create_bus(net, vn_kv=110) + b2 = create_bus(net, vn_kv=110) + create_line(net, from_bus=b1, to_bus=b2, length_km=50.0, std_type="example_type") + create_asymmetric_load(net, b2, p_a_mw=50, q_a_mvar=50, p_b_mw=10, q_b_mvar=15, + p_c_mw=10, q_c_mvar=5) + add_zero_impedance_parameters(net) runpp_3ph_with_consistency_checks(net) assert net['converged'] check_it(net) @@ -94,24 +104,24 @@ def test_2bus_network_isolated_net_part(net): def test_2bus_network_singel_oos_bus(net): # -o---x---o - b1 = pp.create_bus(net, vn_kv=110) + b1 = create_bus(net, vn_kv=110) net.bus.loc[5, "in_service"] = False - pp.create_line(net, from_bus=5, to_bus=b1, length_km=10.0, std_type="example_type") - pp.create_asymmetric_load(net, b1, p_a_mw=-5, q_a_mvar=5, p_b_mw=-1, q_b_mvar=1.5, - p_c_mw=-1, q_c_mvar=.5) - pp.add_zero_impedance_parameters(net) + create_line(net, from_bus=5, to_bus=b1, length_km=10.0, std_type="example_type") + create_asymmetric_load(net, b1, p_a_mw=-5, q_a_mvar=5, p_b_mw=-1, q_b_mvar=1.5, + p_c_mw=-1, q_c_mvar=.5) + add_zero_impedance_parameters(net) runpp_3ph_with_consistency_checks(net) assert net['converged'] def test_out_serv_load(net): # <-x--o------o - pp.add_zero_impedance_parameters(net) + add_zero_impedance_parameters(net) runpp_3ph_with_consistency_checks(net) assert net['converged'] check_it(net) - pp.create_asymmetric_load(net, 5, p_a_mw=50, q_a_mvar=100, p_b_mw=29, q_b_mvar=38, - p_c_mw=10, q_c_mvar=5, in_service=False) + create_asymmetric_load(net, 5, p_a_mw=50, q_a_mvar=100, p_b_mw=29, q_b_mvar=38, + p_c_mw=10, q_c_mvar=5, in_service=False) runpp_3ph_with_consistency_checks(net) assert net['converged'] check_it(net) @@ -119,50 +129,50 @@ def test_out_serv_load(net): def test_2bus_network_one_of_two_ext_grids_oos(net): """ Out of service ext_grids should not affect the unbalanced powerflow""" - pp.create_ext_grid(net, bus=1, vm_pu=1.0, s_sc_max_mva=5000, rx_max=0.1, - r0x0_max=0.1, x0x_max=1.0, in_service=False) - pp.runpp_3ph(net) + create_ext_grid(net, bus=1, vm_pu=1.0, s_sc_max_mva=5000, rx_max=0.1, + r0x0_max=0.1, x0x_max=1.0, in_service=False) + runpp_3ph(net) assert net['converged'] @pytest.mark.parametrize("init", ["auto", "results", "flat", "dc"]) @pytest.mark.parametrize("recycle", [None, {"bus_pq": True, "Ybus": True}, {"bus_pq": True, "Ybus": False}]) def test_4bus_network(init, recycle): - v_base = 110 # 110kV Base Voltage - mva_base = 100 # 100 MVA - net = pp.create_empty_network(sn_mva=mva_base) + v_base = 110 # 110kV Base Voltage + mva_base = 100 # 100 MVA + net = create_empty_network(sn_mva=mva_base) # ============================================================================= # Main Program # ============================================================================= - busn = pp.create_bus(net, vn_kv=v_base, name="busn") - busk = pp.create_bus(net, vn_kv=v_base, name="busk") - busm = pp.create_bus(net, vn_kv=v_base, name="busm") - busp = pp.create_bus(net, vn_kv=v_base, name="busp") - pp.create_ext_grid(net, bus=busn, vm_pu=1.0, name="Grid Connection", s_sc_max_mva=5000, - rx_max=0.1, r0x0_max=0.1, x0x_max=1.0) - pp.create_std_type(net, {"r0_ohm_per_km": .154, "x0_ohm_per_km": 0.5277876, - "c0_nf_per_km": 170.4, "g0_us_per_km": 0, "max_i_ka": 0.741, - "r_ohm_per_km": .0385, "x_ohm_per_km": 0.1319469, - "c_nf_per_km": 170}, "example_type3") - pp.create_line(net, from_bus=busn, to_bus=busm, length_km=1.0, std_type="example_type3") - pp.create_line(net, from_bus=busn, to_bus=busp, length_km=1.0, std_type="example_type3") - pp.create_line_from_parameters(net, from_bus=busn, to_bus=busk, length_km=1.0, r0_ohm_per_km=.1005, - x0_ohm_per_km=0.4900884, c0_nf_per_km=200.5, max_i_ka=0.89, - r_ohm_per_km=.0251, x_ohm_per_km=0.1225221, c_nf_per_km=210) - pp.create_line_from_parameters(net, from_bus=busk, to_bus=busm, length_km=1.0, - r0_ohm_per_km=0.0848, x0_ohm_per_km=0.4649556, c0_nf_per_km=230.6, - max_i_ka=0.963, r_ohm_per_km=0.0212, x_ohm_per_km=0.1162389, c_nf_per_km=230) - pp.create_line_from_parameters(net, from_bus=busk, to_bus=busp, length_km=1.0, r0_ohm_per_km=.3048, - x0_ohm_per_km=0.6031856, c0_nf_per_km=140.3, max_i_ka=0.531, - r_ohm_per_km=.0762, x_ohm_per_km=0.1507964, c_nf_per_km=140) - pp.add_zero_impedance_parameters(net) - - pp.create_asymmetric_load(net, busk, p_a_mw=50, q_a_mvar=20, p_b_mw=80, q_b_mvar=60, - p_c_mw=20, q_c_mvar=5) - pp.create_asymmetric_load(net, busm, p_a_mw=50, q_a_mvar=50, p_b_mw=10, q_b_mvar=15, - p_c_mw=10, q_c_mvar=5) - pp.create_asymmetric_load(net, busp, p_a_mw=50, q_a_mvar=20, p_b_mw=60, q_b_mvar=20, - p_c_mw=10, q_c_mvar=5) + busn = create_bus(net, vn_kv=v_base, name="busn") + busk = create_bus(net, vn_kv=v_base, name="busk") + busm = create_bus(net, vn_kv=v_base, name="busm") + busp = create_bus(net, vn_kv=v_base, name="busp") + create_ext_grid(net, bus=busn, vm_pu=1.0, name="Grid Connection", s_sc_max_mva=5000, + rx_max=0.1, r0x0_max=0.1, x0x_max=1.0) + create_std_type(net, {"r0_ohm_per_km": .154, "x0_ohm_per_km": 0.5277876, + "c0_nf_per_km": 170.4, "g0_us_per_km": 0, "max_i_ka": 0.741, + "r_ohm_per_km": .0385, "x_ohm_per_km": 0.1319469, + "c_nf_per_km": 170}, "example_type3") + create_line(net, from_bus=busn, to_bus=busm, length_km=1.0, std_type="example_type3") + create_line(net, from_bus=busn, to_bus=busp, length_km=1.0, std_type="example_type3") + create_line_from_parameters(net, from_bus=busn, to_bus=busk, length_km=1.0, r0_ohm_per_km=.1005, + x0_ohm_per_km=0.4900884, c0_nf_per_km=200.5, max_i_ka=0.89, + r_ohm_per_km=.0251, x_ohm_per_km=0.1225221, c_nf_per_km=210) + create_line_from_parameters(net, from_bus=busk, to_bus=busm, length_km=1.0, + r0_ohm_per_km=0.0848, x0_ohm_per_km=0.4649556, c0_nf_per_km=230.6, + max_i_ka=0.963, r_ohm_per_km=0.0212, x_ohm_per_km=0.1162389, c_nf_per_km=230) + create_line_from_parameters(net, from_bus=busk, to_bus=busp, length_km=1.0, r0_ohm_per_km=.3048, + x0_ohm_per_km=0.6031856, c0_nf_per_km=140.3, max_i_ka=0.531, + r_ohm_per_km=.0762, x_ohm_per_km=0.1507964, c_nf_per_km=140) + add_zero_impedance_parameters(net) + + create_asymmetric_load(net, busk, p_a_mw=50, q_a_mvar=20, p_b_mw=80, q_b_mvar=60, + p_c_mw=20, q_c_mvar=5) + create_asymmetric_load(net, busm, p_a_mw=50, q_a_mvar=50, p_b_mw=10, q_b_mvar=15, + p_c_mw=10, q_c_mvar=5) + create_asymmetric_load(net, busp, p_a_mw=50, q_a_mvar=20, p_b_mw=60, q_b_mvar=20, + p_c_mw=10, q_c_mvar=5) runpp_3ph_with_consistency_checks(net, init=init, recycle=recycle) runpp_3ph_with_consistency_checks(net, init=init, recycle=recycle) assert net['converged'] @@ -170,84 +180,84 @@ def test_4bus_network(init, recycle): bus_pp = np.abs(net.res_bus_3ph[['vm_a_pu', 'vm_b_pu', 'vm_c_pu']] [~np.isnan(net.res_bus_3ph.vm_a_pu)].values) bus_pf = np.abs(np.array([[0.98085729, 0.97711997, 1.04353786], - [0.97828577, 0.97534651, 1.04470864], - [0.97774307, 0.97648197, 1.04421233], - [0.9780892, 0.97586805, 1.04471106]])) + [0.97828577, 0.97534651, 1.04470864], + [0.97774307, 0.97648197, 1.04421233], + [0.9780892, 0.97586805, 1.04471106]])) assert np.max(np.abs(bus_pp - bus_pf)) < 1e-8 line_pp = np.abs(net.res_line_3ph[ - ['i_a_from_ka', 'i_b_from_ka', 'i_c_from_ka', - 'i_a_to_ka', 'i_b_to_ka', 'i_c_to_ka', - 'p_a_from_mw', 'p_b_from_mw', 'p_c_from_mw', - 'q_a_from_mvar', 'q_b_from_mvar', 'q_c_from_mvar', - 'p_a_to_mw', 'p_b_to_mw', 'p_c_to_mw', - 'q_a_to_mvar', 'q_b_to_mvar', 'q_c_to_mvar', - 'loading_a_percent', 'loading_b_percent', 'loading_c_percent', - 'loading_percent']].values) + ['i_a_from_ka', 'i_b_from_ka', 'i_c_from_ka', + 'i_a_to_ka', 'i_b_to_ka', 'i_c_to_ka', + 'p_a_from_mw', 'p_b_from_mw', 'p_c_from_mw', + 'q_a_from_mvar', 'q_b_from_mvar', 'q_c_from_mvar', + 'p_a_to_mw', 'p_b_to_mw', 'p_c_to_mw', + 'q_a_to_mvar', 'q_b_to_mvar', 'q_c_to_mvar', + 'loading_a_percent', 'loading_b_percent', 'loading_c_percent', + 'loading_percent']].values) line_pf = np.abs(np.array( - [[0.98898804851 , 0.68943734 , 0.19848961 , - 0.99093993 , 0.69146384 , 0.19966503 , - 49.87434308 , 33.86579548 , 12.44659879 , - 36.16562613 , 26.14426519 , 4.25746428 , - -49.75842138 , -33.90236497 , -12.45155362 , - -36.19862688 , -26.25675246 , -4.50384238 , - 133.730100000000 , 93.314960000000 , 26.945350000000 , - 133.730100000000], - [0.87075816277 , 1.03463205 , 0.19072622 , - 0.87210779 , 1.03599167 , 0.19188991 , - 49.59359423 , 58.53676842 , 11.97553941 , - 21.96967200 , 26.37559958 , 4.04458873 , - -49.47110289 , -58.55284705 , -11.98669516 , - -22.07474008 , -26.34476811 , -4.29078447 , - 117.693400000000 , 139.809900000000 , 25.896070000000 , - 139.809900000000], - [0.95760407055 , 1.14786582 , 0.24829126 , - 0.95975383 , 1.15028040 , 0.24975553 , - 50.87938854 , 57.53628873 , 15.54470531 , - 31.13888557 , 41.99378843 , 5.39758513 , - -50.76249094 , -57.56374777 , -15.56099267 , - -31.28560646 , -41.99056453 , -5.69609575 , - 107.837500000000 , 129.245000000000 , 28.062420000000 , - 129.245000000000], - [0.21780921494 , 0.42795803 , 0.03706412 , - 0.22229619 , 0.42603286 , 0.03771703 , - 0.23292404 , -23.88471674 , -2.45255095 , - 13.53037092 , -11.49972060 , 0.17971665 , - -0.24157862 , 23.90236497 , 2.45155361 , - -13.80137312 , 11.25675247 , -0.49615762 , - 23.083720000000 , 44.440090000000 , 3.916618000000 , - 44.440090000000], - [0.03712221482 , 0.10766244 , 0.03093505 , - 0.03446871 , 0.10500386 , 0.03179428 , - 0.52956690 , 1.44846452 , -1.98645639 , - -2.24476446 , -6.50971485 , 0.51637910 , - -0.52889712 , -1.44715295 , 1.98669515 , - 2.07474008 , 6.34476812 , -0.70921554 , - 6.991001000000 , 20.275410000000 , 5.987624000000 , - 20.275410000000]])) + [[0.98898804851, 0.68943734, 0.19848961, + 0.99093993, 0.69146384, 0.19966503, + 49.87434308, 33.86579548, 12.44659879, + 36.16562613, 26.14426519, 4.25746428, + -49.75842138, -33.90236497, -12.45155362, + -36.19862688, -26.25675246, -4.50384238, + 133.730100000000, 93.314960000000, 26.945350000000, + 133.730100000000], + [0.87075816277, 1.03463205, 0.19072622, + 0.87210779, 1.03599167, 0.19188991, + 49.59359423, 58.53676842, 11.97553941, + 21.96967200, 26.37559958, 4.04458873, + -49.47110289, -58.55284705, -11.98669516, + -22.07474008, -26.34476811, -4.29078447, + 117.693400000000, 139.809900000000, 25.896070000000, + 139.809900000000], + [0.95760407055, 1.14786582, 0.24829126, + 0.95975383, 1.15028040, 0.24975553, + 50.87938854, 57.53628873, 15.54470531, + 31.13888557, 41.99378843, 5.39758513, + -50.76249094, -57.56374777, -15.56099267, + -31.28560646, -41.99056453, -5.69609575, + 107.837500000000, 129.245000000000, 28.062420000000, + 129.245000000000], + [0.21780921494, 0.42795803, 0.03706412, + 0.22229619, 0.42603286, 0.03771703, + 0.23292404, -23.88471674, -2.45255095, + 13.53037092, -11.49972060, 0.17971665, + -0.24157862, 23.90236497, 2.45155361, + -13.80137312, 11.25675247, -0.49615762, + 23.083720000000, 44.440090000000, 3.916618000000, + 44.440090000000], + [0.03712221482, 0.10766244, 0.03093505, + 0.03446871, 0.10500386, 0.03179428, + 0.52956690, 1.44846452, -1.98645639, + -2.24476446, -6.50971485, 0.51637910, + -0.52889712, -1.44715295, 1.98669515, + 2.07474008, 6.34476812, -0.70921554, + 6.991001000000, 20.275410000000, 5.987624000000, + 20.275410000000]])) assert np.max(np.abs(line_pp - line_pf)) < 1e-4 def test_3ph_bus_mapping_order(): - net = pp.create_empty_network() - b2 = pp.create_bus(net, vn_kv=0.4, index=4) - pp.create_bus(net, vn_kv=0.4, in_service=False, index=3) - b1 = pp.create_bus(net, vn_kv=0.4, index=7) + net = create_empty_network() + b2 = create_bus(net, vn_kv=0.4, index=4) + create_bus(net, vn_kv=0.4, in_service=False, index=3) + b1 = create_bus(net, vn_kv=0.4, index=7) - pp.create_ext_grid(net, b1, vm_pu=1.0, s_sc_max_mva=10, rx_max=0.1) + create_ext_grid(net, b1, vm_pu=1.0, s_sc_max_mva=10, rx_max=0.1) net.ext_grid["x0x_max"] = 1. net.ext_grid["r0x0_max"] = 0.1 - pp.create_std_type(net, {"r_ohm_per_km": 0.1013, "x_ohm_per_km": 0.06911504, - "c_nf_per_km": 690, "g_us_per_km": 0, "max_i_ka": 0.44, - "c0_nf_per_km": 312.4, "g0_us_per_km": 0, "r0_ohm_per_km": 0.4053, - "x0_ohm_per_km": 0.2764602}, "N2XRY 3x185sm 0.6/1kV") - - pp.create_line(net, b1, b2, 1.0, std_type="N2XRY 3x185sm 0.6/1kV", index=4) - pp.create_line(net, b1, b2, 1.0, std_type="N2XRY 3x185sm 0.6/1kV", index=3, in_service=False) - pp.create_line(net, b1, b2, 1.0, std_type="N2XRY 3x185sm 0.6/1kV", index=7) - pp.add_zero_impedance_parameters(net) - pp.create_load(net, b2, p_mw=0.030, q_mvar=0.030) - pp.runpp(net) + create_std_type(net, {"r_ohm_per_km": 0.1013, "x_ohm_per_km": 0.06911504, + "c_nf_per_km": 690, "g_us_per_km": 0, "max_i_ka": 0.44, + "c0_nf_per_km": 312.4, "g0_us_per_km": 0, "r0_ohm_per_km": 0.4053, + "x0_ohm_per_km": 0.2764602}, "N2XRY 3x185sm 0.6/1kV") + + create_line(net, b1, b2, 1.0, std_type="N2XRY 3x185sm 0.6/1kV", index=4) + create_line(net, b1, b2, 1.0, std_type="N2XRY 3x185sm 0.6/1kV", index=3, in_service=False) + create_line(net, b1, b2, 1.0, std_type="N2XRY 3x185sm 0.6/1kV", index=7) + add_zero_impedance_parameters(net) + create_load(net, b2, p_mw=0.030, q_mvar=0.030) + runpp(net) runpp_3ph_with_consistency_checks(net) assert net['converged'] @@ -262,55 +272,55 @@ def test_3ph_bus_mapping_order(): def test_3ph_two_bus_line_powerfactory(): - net = pp.create_empty_network() + net = create_empty_network() - b1 = pp.create_bus(net, vn_kv=0.4) - b2 = pp.create_bus(net, vn_kv=0.4) + b1 = create_bus(net, vn_kv=0.4) + b2 = create_bus(net, vn_kv=0.4) - pp.create_ext_grid(net, b1, vm_pu=1.0, s_sc_max_mva=10, rx_max=0.1) + create_ext_grid(net, b1, vm_pu=1.0, s_sc_max_mva=10, rx_max=0.1) net.ext_grid["x0x_max"] = 1. net.ext_grid["r0x0_max"] = 0.1 - pp.create_std_type(net, {"r_ohm_per_km": 0.1013, "x_ohm_per_km": 0.06911504, - "c_nf_per_km": 690, "g_us_per_km": 0, "max_i_ka": 0.44, - "c0_nf_per_km": 312.4, "g0_us_per_km": 0, "r0_ohm_per_km": 0.4053, - "x0_ohm_per_km": 0.2764602}, "N2XRY 3x185sm 0.6/1kV") - - pp.create_line(net, b1, b2, 0.4, std_type="N2XRY 3x185sm 0.6/1kV") - pp.add_zero_impedance_parameters(net) - pp.create_load(net, b2, p_mw=0.010, q_mvar=0.010) - pp.create_asymmetric_load(net, b2, p_a_mw=0.020, q_a_mvar=0.010, p_b_mw=0.015, q_b_mvar=0.005, p_c_mw=0.025, - q_c_mvar=0.010) + create_std_type(net, {"r_ohm_per_km": 0.1013, "x_ohm_per_km": 0.06911504, + "c_nf_per_km": 690, "g_us_per_km": 0, "max_i_ka": 0.44, + "c0_nf_per_km": 312.4, "g0_us_per_km": 0, "r0_ohm_per_km": 0.4053, + "x0_ohm_per_km": 0.2764602}, "N2XRY 3x185sm 0.6/1kV") + + create_line(net, b1, b2, 0.4, std_type="N2XRY 3x185sm 0.6/1kV") + add_zero_impedance_parameters(net) + create_load(net, b2, p_mw=0.010, q_mvar=0.010) + create_asymmetric_load(net, b2, p_a_mw=0.020, q_a_mvar=0.010, p_b_mw=0.015, q_b_mvar=0.005, p_c_mw=0.025, + q_c_mvar=0.010) runpp_3ph_with_consistency_checks(net) assert net['converged'] bus_pp = np.abs(net.res_bus_3ph[['vm_a_pu', 'vm_b_pu', 'vm_c_pu']].values) bus_pf = np.abs(np.array([[0.99939853552, 1.0013885141, 0.99921580141], - [0.97401782343, 0.98945593737, 0.96329605983]])) + [0.97401782343, 0.98945593737, 0.96329605983]])) - assert np.max(np.abs(bus_pp-bus_pf)) < 4e-6 + assert np.max(np.abs(bus_pp - bus_pf)) < 4e-6 line_pp = np.abs(net.res_line_3ph[ - ['i_a_from_ka', 'i_b_from_ka', 'i_c_from_ka', - 'i_a_to_ka', 'i_b_to_ka', 'i_c_to_ka', - 'p_a_from_mw', 'p_b_from_mw', 'p_c_from_mw', - 'q_a_from_mvar', 'q_b_from_mvar', 'q_c_from_mvar', - 'p_a_to_mw', 'p_b_to_mw', 'p_c_to_mw', - 'q_a_to_mvar', 'q_b_to_mvar', 'q_c_to_mvar']].values) + ['i_a_from_ka', 'i_b_from_ka', 'i_c_from_ka', + 'i_a_to_ka', 'i_b_to_ka', 'i_c_to_ka', + 'p_a_from_mw', 'p_b_from_mw', 'p_c_from_mw', + 'q_a_from_mvar', 'q_b_from_mvar', 'q_c_from_mvar', + 'p_a_to_mw', 'p_b_to_mw', 'p_c_to_mw', + 'q_a_to_mvar', 'q_b_to_mvar', 'q_c_to_mvar']].values) line_pf = np.abs(np.array( - [[0.11946088987 , 0.08812337783 , 0.14074226065 , - 0.1194708224 , 0.088131567331 , 0.14075063601 , - 0.023810539354 , 0.01855791658 , 0.029375192747 , - 0.013901720672 , 0.008421814704 , 0.013852398586 , - -0.023333142958 , -0.018333405987 , -0.028331643666 , - -0.013332756527 , -0.008333413919 , -0.013332422725 ]])) + [[0.11946088987, 0.08812337783, 0.14074226065, + 0.1194708224, 0.088131567331, 0.14075063601, + 0.023810539354, 0.01855791658, 0.029375192747, + 0.013901720672, 0.008421814704, 0.013852398586, + -0.023333142958, -0.018333405987, -0.028331643666, + -0.013332756527, -0.008333413919, -0.013332422725]])) assert np.max(np.abs(line_pp - line_pf)) < 1e-5 line_load_pp = np.abs(net.res_line_3ph[ - ['loading_a_percent', 'loading_b_percent', 'loading_c_percent', - 'loading_percent']].values) + ['loading_a_percent', 'loading_b_percent', 'loading_c_percent', + 'loading_percent']].values) line_load_pf = np.abs(np.array( - [[27.1525 , 20.0299 , 31.98878 , - 31.98878]])) + [[27.1525, 20.0299, 31.98878, + 31.98878]])) assert np.max(np.abs(line_load_pp - line_load_pf)) < 1e-2 @@ -333,7 +343,8 @@ def check_bus_voltages(net, result, trafo_vector_group): 'Dyn': 1e-05, 'Yzn': 1e-03} - assert np.allclose(result, res_vm_pu, atol=tolerances[trafo_vector_group], rtol=0), f"Incorrect results for {trafo_vector_group}" + assert np.allclose(result, res_vm_pu, atol=tolerances[trafo_vector_group], + rtol=0), f"Incorrect results for {trafo_vector_group}" def check_line_currents(net, result, trafo_vector_group): @@ -397,58 +408,59 @@ def check_results(net, trafo_vector_group, results): def make_nw(net, bushv, tap_ps, case, vector_group): - b1 = pp.create_bus(net, bushv, zone=vector_group, index=pp.get_free_id(net.bus)) - b2 = pp.create_bus(net, 0.4, zone=vector_group) - b3 = pp.create_bus(net, 0.4, zone=vector_group) - pp.create_ext_grid(net, b1, s_sc_max_mva=10000, - rx_max=0.1, r0x0_max=0.1, x0x_max=1.0) - pp.create_transformer_from_parameters(net, hv_bus=b1, lv_bus=b2, - sn_mva=1.6, vn_hv_kv=10, - vn_lv_kv=0.4, vk_percent=6, - vkr_percent=0.78125, pfe_kw=2.7, - i0_percent=0.16875, shift_degree=0, - tap_side='lv', tap_neutral=0, - tap_min=-2, tap_max=2, - tap_step_degree=0, - tap_step_percent=2.5, - tap_phase_shifter=False, - vk0_percent=6, vkr0_percent=0.78125, - mag0_percent=100, mag0_rx=0., - si0_hv_partial=0.9, vector_group=vector_group, - parallel=1, tap_pos=tap_ps, - index=pp.get_free_id(net.trafo)+1) - pp.create_line_from_parameters(net, b2, b3, length_km=0.5, r_ohm_per_km=0.1941, x_ohm_per_km=0.07476991, - c_nf_per_km=1160., max_i_ka=0.421, - endtemp_degree=70.0, r0_ohm_per_km=0.7766, - x0_ohm_per_km=0.2990796, - c0_nf_per_km=496.2, - index=pp.get_free_id(net.line)+1) + b1 = create_bus(net, bushv, zone=vector_group, index=get_free_id(net.bus)) + b2 = create_bus(net, 0.4, zone=vector_group) + b3 = create_bus(net, 0.4, zone=vector_group) + create_ext_grid(net, b1, s_sc_max_mva=10000, + rx_max=0.1, r0x0_max=0.1, x0x_max=1.0) + create_transformer_from_parameters(net, hv_bus=b1, lv_bus=b2, + sn_mva=1.6, vn_hv_kv=10, + vn_lv_kv=0.4, vk_percent=6, + vkr_percent=0.78125, pfe_kw=2.7, + i0_percent=0.16875, shift_degree=0, + tap_side='lv', tap_neutral=0, + tap_min=-2, tap_max=2, + tap_step_degree=0, + tap_step_percent=2.5, + tap_phase_shifter=False, + vk0_percent=6, vkr0_percent=0.78125, + mag0_percent=100, mag0_rx=0., + si0_hv_partial=0.9, vector_group=vector_group, + parallel=1, tap_pos=tap_ps, + index=get_free_id(net.trafo) + 1) + create_line_from_parameters(net, b2, b3, length_km=0.5, r_ohm_per_km=0.1941, x_ohm_per_km=0.07476991, + c_nf_per_km=1160., max_i_ka=0.421, + endtemp_degree=70.0, r0_ohm_per_km=0.7766, + x0_ohm_per_km=0.2990796, + c0_nf_per_km=496.2, + index=get_free_id(net.line) + 1) if case == "bal_wye": # Symmetric Load - pp.create_load(net, b3, 0.08, 0.012, type='wye') + create_load(net, b3, 0.08, 0.012, type='wye') elif case == "delta_wye": # Unsymmetric Light Load - pp.create_asymmetric_load(net, b3, p_a_mw=0.0044, q_a_mvar=0.0013, p_b_mw=0.0044, q_b_mvar=0.0013, - p_c_mw=0.0032, q_c_mvar=0.0013, type='wye') - pp.create_asymmetric_load(net, b3, p_a_mw=0.0300, q_a_mvar=0.0048, p_b_mw=0.0280, q_b_mvar=0.0036, - p_c_mw=0.027, q_c_mvar=0.0043, type='delta') + create_asymmetric_load(net, b3, p_a_mw=0.0044, q_a_mvar=0.0013, p_b_mw=0.0044, q_b_mvar=0.0013, + p_c_mw=0.0032, q_c_mvar=0.0013, type='wye') + create_asymmetric_load(net, b3, p_a_mw=0.0300, q_a_mvar=0.0048, p_b_mw=0.0280, q_b_mvar=0.0036, + p_c_mw=0.027, q_c_mvar=0.0043, type='delta') elif case == "wye": # Unsymmetric Heavy Load - pp.create_asymmetric_load(net, b3, p_a_mw=0.0300, q_a_mvar=0.0048, p_b_mw=0.0280, q_b_mvar=0.0036, - p_c_mw=0.027, q_c_mvar=0.0043, type=case) + create_asymmetric_load(net, b3, p_a_mw=0.0300, q_a_mvar=0.0048, p_b_mw=0.0280, q_b_mvar=0.0036, + p_c_mw=0.027, q_c_mvar=0.0043, type=case) elif case == "delta": - pp.create_asymmetric_load(net, b3, p_a_mw=0.0300, q_a_mvar=0.0048, p_b_mw=0.0280, q_b_mvar=0.0036, - p_c_mw=0.027, q_c_mvar=0.0043, type=case) + create_asymmetric_load(net, b3, p_a_mw=0.0300, q_a_mvar=0.0048, p_b_mw=0.0280, q_b_mvar=0.0036, + p_c_mw=0.027, q_c_mvar=0.0043, type=case) -# pp.add_zero_impedance_parameters(net) Not required here since added through parameters + +# add_zero_impedance_parameters(net) Not required here since added through parameters def test_trafo_asym(): - nw_dir = os.path.abspath(os.path.join(pp.pp_dir, "test/loadflow")) + nw_dir = os.path.abspath(os.path.join(pp_dir, "test/loadflow")) # only 3 vector groups are supported in the 3ph power flow for trafo_vector_group in ["YNyn", "Dyn", "Yzn"]: - net = pp.from_json(nw_dir + '/runpp_3ph Validation.json') + net = from_json(nw_dir + '/runpp_3ph Validation.json') net['trafo'].vector_group = trafo_vector_group runpp_3ph_with_consistency_checks(net) assert net['converged'] @@ -456,7 +468,7 @@ def test_trafo_asym(): def test_2trafos(): - net = pp.create_empty_network() + net = create_empty_network() make_nw(net, 10., 0., "wye", "YNyn") make_nw(net, 10., 0., "wye", "YNyn") runpp_3ph_with_consistency_checks(net) @@ -467,90 +479,91 @@ def test_2trafos(): def test_3ph_isolated_nodes(): v_base = 110 # 110kV Base Voltage mva_base = 100 # 100 MVA - net = pp.create_empty_network(sn_mva=mva_base) + net = create_empty_network(sn_mva=mva_base) - busn = pp.create_bus(net, vn_kv=v_base, name="busn", index=1) - pp.create_bus(net, vn_kv=20., in_service=True, index=2, name="busx") - busk = pp.create_bus(net, vn_kv=v_base, name="busk", index=5) - busl = pp.create_bus(net, vn_kv=v_base, name="busl", index=6) - pp.create_bus(net, vn_kv=20., in_service=False, index=3) - busy = pp.create_bus(net, vn_kv=20., in_service=True, index=0, name="busy") + busn = create_bus(net, vn_kv=v_base, name="busn", index=1) + create_bus(net, vn_kv=20., in_service=True, index=2, name="busx") + busk = create_bus(net, vn_kv=v_base, name="busk", index=5) + busl = create_bus(net, vn_kv=v_base, name="busl", index=6) + create_bus(net, vn_kv=20., in_service=False, index=3) + busy = create_bus(net, vn_kv=20., in_service=True, index=0, name="busy") - pp.create_ext_grid(net, bus=busn, vm_pu=1.0, name="Grid Connection", - s_sc_max_mva=5000, rx_max=0.1) + create_ext_grid(net, bus=busn, vm_pu=1.0, name="Grid Connection", + s_sc_max_mva=5000, rx_max=0.1) net.ext_grid["r0x0_max"] = 0.1 net.ext_grid["x0x_max"] = 1.0 - pp.create_std_type(net, {"r0_ohm_per_km": 0.0848, "x0_ohm_per_km": 0.4649556, - "c0_nf_per_km": 230.6, "g0_us_per_km": 0, "max_i_ka": 0.963, - "r_ohm_per_km": 0.0212, "x_ohm_per_km": 0.1162389, - "c_nf_per_km": 230}, "example_type") + create_std_type(net, {"r0_ohm_per_km": 0.0848, "x0_ohm_per_km": 0.4649556, + "c0_nf_per_km": 230.6, "g0_us_per_km": 0, "max_i_ka": 0.963, + "r_ohm_per_km": 0.0212, "x_ohm_per_km": 0.1162389, + "c_nf_per_km": 230}, "example_type") # Loads on supplied buses - pp.create_asymmetric_load(net, busk, p_a_mw=50, q_a_mvar=50, p_b_mw=10, q_b_mvar=15, - p_c_mw=10, q_c_mvar=5) - pp.create_load(net, bus=busl, p_mw=7, q_mvar=0.070, name="Load 1") + create_asymmetric_load(net, busk, p_a_mw=50, q_a_mvar=50, p_b_mw=10, q_b_mvar=15, + p_c_mw=10, q_c_mvar=5) + create_load(net, bus=busl, p_mw=7, q_mvar=0.070, name="Load 1") # Loads on unsupplied buses - pp.create_load(net, bus=busy, p_mw=70, q_mvar=70, name="Load Y") - pp.create_line(net, from_bus=busn, to_bus=busk, length_km=50.0, std_type="example_type") - pp.create_line(net, from_bus=busl, to_bus=busk, length_km=50.0, std_type="example_type") - pp.add_zero_impedance_parameters(net) + create_load(net, bus=busy, p_mw=70, q_mvar=70, name="Load Y") + create_line(net, from_bus=busn, to_bus=busk, length_km=50.0, std_type="example_type") + create_line(net, from_bus=busl, to_bus=busk, length_km=50.0, std_type="example_type") + add_zero_impedance_parameters(net) runpp_3ph_with_consistency_checks(net) assert net['converged'] assert np.allclose(net.res_bus_3ph.T[[0, 2, 3]].T[["vm_a_pu", "va_a_degree", "vm_b_pu", - "va_b_degree", "vm_c_pu", "va_c_degree"]], np.nan, equal_nan=True) + "va_b_degree", "vm_c_pu", "va_c_degree"]], np.nan, + equal_nan=True) assert np.allclose(net.res_bus_3ph.T[[0, 2, 3]].T[["p_a_mw", "q_a_mvar", "p_b_mw", "q_b_mvar", - "p_c_mw", "q_c_mvar"]], 0.0) + "p_c_mw", "q_c_mvar"]], 0.0) def test_balanced_power_flow_with_unbalanced_loads_and_sgens(): - net = pp.create_empty_network(sn_mva=100) + net = create_empty_network(sn_mva=100) make_nw(net, 10, 0, "wye", "Dyn") - pp.create_asymmetric_sgen(net, 1, p_a_mw=0.01, p_b_mw=0.02, scaling=0.8) + create_asymmetric_sgen(net, 1, p_a_mw=0.01, p_b_mw=0.02, scaling=0.8) runpp_with_consistency_checks(net) vm_pu = net.res_bus.vm_pu net.asymmetric_load.in_service = False - pp.create_load(net, bus=net.asymmetric_load.bus.iloc[0], - scaling=net.asymmetric_load.scaling.iloc[0], - p_mw=net.asymmetric_load.loc[0, ["p_a_mw", "p_b_mw", "p_c_mw"]].sum(), - q_mvar=net.asymmetric_load.loc[0, ["q_a_mvar", "q_b_mvar", "q_c_mvar"]].sum() - ) + create_load(net, bus=net.asymmetric_load.bus.iloc[0], + scaling=net.asymmetric_load.scaling.iloc[0], + p_mw=net.asymmetric_load.loc[0, ["p_a_mw", "p_b_mw", "p_c_mw"]].sum(), + q_mvar=net.asymmetric_load.loc[0, ["q_a_mvar", "q_b_mvar", "q_c_mvar"]].sum() + ) runpp_with_consistency_checks(net) assert net.res_bus.vm_pu.equals(vm_pu) net.asymmetric_sgen.in_service = False - pp.create_sgen(net, bus=net.asymmetric_sgen.bus.iloc[0], - scaling=net.asymmetric_sgen.scaling.iloc[0], - p_mw=net.asymmetric_sgen.loc[0, ["p_a_mw", "p_b_mw", "p_c_mw"]].sum(), - q_mvar=net.asymmetric_sgen.loc[0, ["q_a_mvar", "q_b_mvar", "q_c_mvar"]].sum() - ) + create_sgen(net, bus=net.asymmetric_sgen.bus.iloc[0], + scaling=net.asymmetric_sgen.scaling.iloc[0], + p_mw=net.asymmetric_sgen.loc[0, ["p_a_mw", "p_b_mw", "p_c_mw"]].sum(), + q_mvar=net.asymmetric_sgen.loc[0, ["q_a_mvar", "q_b_mvar", "q_c_mvar"]].sum() + ) runpp_with_consistency_checks(net) assert net.res_bus.vm_pu.equals(vm_pu) def test_3ph_with_impedance(): - nw_dir = os.path.abspath(os.path.join(pp.pp_dir, "test/loadflow")) - net = pp.from_json(nw_dir + '/runpp_3ph Validation.json') + nw_dir = os.path.abspath(os.path.join(pp_dir, "test/loadflow")) + net = from_json(nw_dir + '/runpp_3ph Validation.json') net.line.c_nf_per_km = 0. net.line.g_nf_per_km = 0. net.line["c0_nf_per_km"] = 0. net.line["g0_us_per_km"] = 0. net_imp = net.deepcopy() - pp.replace_line_by_impedance(net_imp, net.line.index, 100) - pp.runpp_3ph(net) - pp.runpp_3ph(net_imp) - assert pandapower.toolbox.dataframes_equal(net.res_bus_3ph, net_imp.res_bus_3ph) + replace_line_by_impedance(net_imp, net.line.index, 100) + runpp_3ph(net) + runpp_3ph(net_imp) + assert dataframes_equal(net.res_bus_3ph, net_imp.res_bus_3ph) def test_shunt_3ph(): - net = pp.create_empty_network() - b1 = pp.create_bus(net, 20.0) - b2 = pp.create_bus(net, 20.0) - pp.create_ext_grid(net, b1, s_sc_max_mva=1000, rx_max=0.1, x0x_max=1.0, r0x0_max=0.1) - pp.create_line_from_parameters(net, b1, b2, length_km=1, r_ohm_per_km=1, x_ohm_per_km=1, c_nf_per_km=1, - r0_ohm_per_km=1, x0_ohm_per_km=1, c0_nf_per_km=1, max_i_ka=1) - pp.create_shunt(net, in_service=True, bus=b2, p_mw=1, q_mvar=1) - pp.runpp_3ph(net) + net = create_empty_network() + b1 = create_bus(net, 20.0) + b2 = create_bus(net, 20.0) + create_ext_grid(net, b1, s_sc_max_mva=1000, rx_max=0.1, x0x_max=1.0, r0x0_max=0.1) + create_line_from_parameters(net, b1, b2, length_km=1, r_ohm_per_km=1, x_ohm_per_km=1, c_nf_per_km=1, + r0_ohm_per_km=1, x0_ohm_per_km=1, c0_nf_per_km=1, max_i_ka=1) + create_shunt(net, in_service=True, bus=b2, p_mw=1, q_mvar=1) + runpp_3ph(net) bus_cols = ["vm_a_pu", "va_a_degree", "vm_b_pu", "va_b_degree", "vm_c_pu", "va_c_degree"] bus_pp = np.abs(net.res_bus_3ph[bus_cols].values) @@ -572,4 +585,3 @@ def test_shunt_3ph(): if __name__ == "__main__": pytest.main([__file__, "-xs"]) - diff --git a/pandapower/test/loadflow/test_runpp_3ph_n_line.py b/pandapower/test/loadflow/test_runpp_3ph_n_line.py index 4641896d7..306831b0c 100644 --- a/pandapower/test/loadflow/test_runpp_3ph_n_line.py +++ b/pandapower/test/loadflow/test_runpp_3ph_n_line.py @@ -4,38 +4,40 @@ Tests 3 phase power flow algorithm @author: gbanerjee """ -import pandapower as pp import numpy as np import pytest +from pandapower import create_empty_network, create_bus, create_ext_grid, create_asymmetric_load, \ + create_line_from_parameters +from pandapower.pf.runpp_3ph import runpp_3ph + + @pytest.fixture def net(): - v_base = 20 # 20kV Base Voltage - mva_base = 100 # 100 MVA - Net = pp.create_empty_network(sn_mva=mva_base) - - bus0 = pp.create_bus(Net, vn_kv=v_base, name="Bus 0") - - pp.create_ext_grid(Net, bus=bus0, vm_pu=1.0, name="Grid Connection", s_sc_max_mva=5000, - rx_max=0.1, r0x0_max=0.1, x0x_max=1.0) - - bus1 = pp.create_bus(Net, name="Bus1", vn_kv=20, type="b") - - #pp.add_zero_impedance_parameters(Net) - - pp.create_asymmetric_load(Net, bus1, p_a_mw=0.3, q_a_mvar=0.003, p_b_mw=0.2, q_b_mvar=0.002, - p_c_mw=0.1, q_c_mvar=0.001, scaling=1.0, in_service=True, type='wye') - - - pp.create_line_from_parameters(Net, from_bus=bus0, to_bus=bus1, length_km=2.0, r0_ohm_per_km=.789, - x0_ohm_per_km=0.306, c0_nf_per_km=272.9, max_i_ka=0.496, - r_ohm_per_km=0.184, x_ohm_per_km=0.1900664, c_nf_per_km=273) + v_base = 20 # 20kV Base Voltage + mva_base = 100 # 100 MVA + Net = create_empty_network(sn_mva=mva_base) + + bus0 = create_bus(Net, vn_kv=v_base, name="Bus 0") + + create_ext_grid(Net, bus=bus0, vm_pu=1.0, name="Grid Connection", s_sc_max_mva=5000, + rx_max=0.1, r0x0_max=0.1, x0x_max=1.0) + + bus1 = create_bus(Net, name="Bus1", vn_kv=20, type="b") + + # add_zero_impedance_parameters(Net) + + create_asymmetric_load(Net, bus1, p_a_mw=0.3, q_a_mvar=0.003, p_b_mw=0.2, q_b_mvar=0.002, + p_c_mw=0.1, q_c_mvar=0.001, scaling=1.0, in_service=True, type='wye') + + create_line_from_parameters(Net, from_bus=bus0, to_bus=bus1, length_km=2.0, r0_ohm_per_km=.789, + x0_ohm_per_km=0.306, c0_nf_per_km=272.9, max_i_ka=0.496, + r_ohm_per_km=0.184, x_ohm_per_km=0.1900664, c_nf_per_km=273) return Net def test_check_it(net): - pp.runpp_3ph(net) - + runpp_3ph(net) line_pp = np.abs(net.res_line_3ph[~np.isnan(net.res_line_3ph.i_a_from_ka)] [['i_a_from_ka', 'i_a_to_ka', 'i_b_from_ka', 'i_b_to_ka', @@ -46,18 +48,14 @@ def test_check_it(net): 'loading_percent' ]].values) line_pf = np.abs(np.array( - [[0.0260710, 0.0260123, 0.0174208, 0.0173288, - 0.0088636, 0.0086592, 0.0150228, 0.0150217, - 0.3003988, (-0.3), (-0.0196415), (-0.003), - 0.2000966, (-0.2), (-0.0206405), (-0.002), - 0.0999835, (-0.1), (-0.0218763), (-0.001), - 5.25625]])) + [[0.0260710, 0.0260123, 0.0174208, 0.0173288, + 0.0088636, 0.0086592, 0.0150228, 0.0150217, + 0.3003988, (-0.3), (-0.0196415), (-0.003), + 0.2000966, (-0.2), (-0.0206405), (-0.002), + 0.0999835, (-0.1), (-0.0218763), (-0.001), + 5.25625]])) assert np.max(np.abs(line_pp - line_pf)) < 1.1e-5 - - - - if __name__ == "__main__": pytest.main([__file__, "-xs"]) diff --git a/pandapower/test/loadflow/test_runpp_pgm.py b/pandapower/test/loadflow/test_runpp_pgm.py index 088dc0ccb..c90070543 100644 --- a/pandapower/test/loadflow/test_runpp_pgm.py +++ b/pandapower/test/loadflow/test_runpp_pgm.py @@ -3,53 +3,56 @@ import pytest -import pandapower as pp +from pandapower.create import create_empty_network, create_bus, create_ext_grid, create_load, create_switch, \ + create_sgen, create_line +from pandapower.run import runpp_pgm from pandapower.test.consistency_checks import runpp_pgm_with_consistency_checks, runpp_pgm_3ph_with_consistency_checks try: import power_grid_model + PGM_IMPORTED = True except ImportError: PGM_IMPORTED = False -@pytest.mark.parametrize("consistency_fn" , [runpp_pgm_with_consistency_checks, runpp_pgm_3ph_with_consistency_checks]) +@pytest.mark.parametrize("consistency_fn", [runpp_pgm_with_consistency_checks, runpp_pgm_3ph_with_consistency_checks]) @pytest.mark.skipif(not PGM_IMPORTED, reason="requires power_grid_model") def test_minimal_net_pgm(consistency_fn): # tests corner-case when the grid only has 1 bus and an ext-grid - net = pp.create_empty_network() - b = pp.create_bus(net, 110) - pp.create_ext_grid(net, b) + net = create_empty_network() + b = create_bus(net, 110) + create_ext_grid(net, b) consistency_fn(net) - pp.create_load(net, b, p_mw=0.1) + create_load(net, b, p_mw=0.1) consistency_fn(net) - b2 = pp.create_bus(net, 110) - pp.create_switch(net, b, b2, "b") - pp.create_sgen(net, b2, p_mw=0.2, q_mvar=0.1) + b2 = create_bus(net, 110) + create_switch(net, b, b2, "b") + create_sgen(net, b2, p_mw=0.2, q_mvar=0.1) consistency_fn(net) @pytest.mark.skipif(not PGM_IMPORTED, reason="requires power_grid_model") def test_runpp_pgm__invalid_algorithm(): - net = pp.create_empty_network() + net = create_empty_network() with pytest.raises( - KeyError, - match="Invalid algorithm 'foo'", + KeyError, + match="Invalid algorithm 'foo'", ): - pp.runpp_pgm(net, algorithm="foo") + runpp_pgm(net, algorithm="foo") @patch("pandapower.run.logger") @pytest.mark.skipif(not PGM_IMPORTED, reason="requires power_grid_model") def test_runpp_pgm__internal_pgm_error(mock_logger: MagicMock): - net = pp.create_empty_network() - b1 = pp.create_bus(net, 110) - pp.create_ext_grid(net, b1, vm_pu=1) - b2 = pp.create_bus(net, 50) - pp.create_line(net, b1, b2, 1, std_type="NAYY 4x50 SE") - pp.runpp_pgm(net) + net = create_empty_network() + b1 = create_bus(net, 110) + create_ext_grid(net, b1, vm_pu=1) + b2 = create_bus(net, 50) + create_line(net, b1, b2, 1, std_type="NAYY 4x50 SE") + runpp_pgm(net) assert net["converged"] is False @@ -65,9 +68,9 @@ def test_runpp_pgm__internal_pgm_error(mock_logger: MagicMock): @patch("pandapower.run.logger") @pytest.mark.skipif(not PGM_IMPORTED, reason="requires power_grid_model") def test_runpp_pgm__validation_fail(mock_logger: MagicMock): - net = pp.create_empty_network() - pp.create_bus(net, -110, index=123) - pp.runpp_pgm(net, validate_input=True) + net = create_empty_network() + create_bus(net, -110, index=123) + runpp_pgm(net, validate_input=True) mock_logger.error.assert_called_once_with("1. Power Grid Model validation error: Check bus-123") mock_logger.debug.assert_called_once() diff --git a/pandapower/test/loadflow/test_scenarios.py b/pandapower/test/loadflow/test_scenarios.py index bb0c8b85d..fe8ddcf32 100644 --- a/pandapower/test/loadflow/test_scenarios.py +++ b/pandapower/test/loadflow/test_scenarios.py @@ -7,23 +7,27 @@ import numpy as np import pytest -import pandapower as pp +from pandapower.auxiliary import get_free_id +from pandapower.create import create_gen, create_ext_grid, create_bus, create_line, create_empty_network, \ + create_switch, create_xward, create_transformer_from_parameters, create_transformer3w_from_parameters, \ + create_load, create_transformer, create_transformer3w, create_motor +from pandapower.networks.simple_pandapower_test_networks import simple_mv_open_ring_net +from pandapower.run import runpp, rundcpp +from pandapower.shortcircuit.calc_sc import calc_sc +from pandapower.std_types import create_std_type from pandapower.test.consistency_checks import runpp_with_consistency_checks -from pandapower.test.loadflow.result_test_network_generator import add_test_bus_bus_switch, \ - add_test_trafo from pandapower.test.helper_functions import create_test_network2, add_grid_connection -import pandapower.networks as nw -import pandapower.shortcircuit as sc - -#TODO: 2 gen 2 ext_grid missing +from pandapower.test.loadflow.result_test_network_generator import add_test_bus_bus_switch, \ + add_test_trafo +# TODO: 2 gen 2 ext_grid missing def test_2gen_1ext_grid(): net = create_test_network2() net.shunt.q_mvar *= -1 - pp.create_gen(net, 2, p_mw=0.100) + create_gen(net, 2, p_mw=0.100) net.trafo.shift_degree = 150 - pp.runpp(net, init='dc', calculate_voltage_angles=True) + runpp(net, init='dc', calculate_voltage_angles=True) assert np.allclose(net.res_gen.p_mw.values, [0.100, 0.100]) assert np.allclose(net.res_gen.q_mvar.values, [-0.447397232056, -0.0518152713776], atol=1e-2) @@ -44,20 +48,20 @@ def test_0gen_2ext_grid(): # testing 2 ext grid and 0 gen, both EG on same trafo side net = create_test_network2() net.shunt.q_mvar *= -1 - pp.create_ext_grid(net, 1) + create_ext_grid(net, 1) net.gen = net.gen.drop(0) net.trafo.shift_degree = 150 net.ext_grid.at[1, "in_service"] = False - pp.create_ext_grid(net, 3) + create_ext_grid(net, 3) - pp.runpp(net, init='dc', calculate_voltage_angles=True) + runpp(net, init='dc', calculate_voltage_angles=True) assert np.allclose(net.res_bus.p_mw.values, [-0.000000, 0.03000000, 0.000000, -0.032993015]) assert np.allclose(net.res_bus.q_mvar.values, [0.00408411026001, 0.002000000, -0.0286340014753, 0.027437210083]) assert np.allclose(net.res_bus.va_degree.values, [0.000000, -155.719283, -153.641832, 0.000000]) - assert np.allclose(net.res_bus.vm_pu.values, [1.000000, 0.932225, - 0.976965, 1.000000]) + assert np.allclose(net.res_bus.vm_pu.values, [1.000000, 0.932225, + 0.976965, 1.000000]) assert np.allclose(net.res_ext_grid.p_mw.values, [-0.000000, 0.000000, 0.132993015]) assert np.allclose(net.res_ext_grid.q_mvar, [-0.00408411026001, 0.000000, -0.027437210083]) @@ -67,159 +71,159 @@ def test_0gen_2ext_grid_decoupled(): net = create_test_network2() net.gen = net.gen.drop(0) net.shunt.q_mvar *= -1 - pp.create_ext_grid(net, 1) + create_ext_grid(net, 1) net.ext_grid.at[1, "in_service"] = False - pp.create_ext_grid(net, 3) + create_ext_grid(net, 3) net.ext_grid.at[2, "in_service"] = False - auxbus = pp.create_bus(net, name="bus1", vn_kv=10.) + auxbus = create_bus(net, name="bus1", vn_kv=10.) net.trafo.shift_degree = 150 - pp.create_std_type(net, {"type": "cs", "r_ohm_per_km": 0.876, "q_mm2": 35.0, - "endtmp_deg": 160.0, "c_nf_per_km": 260.0, - "max_i_ka": 0.123, "x_ohm_per_km": 0.1159876}, - name="NAYSEY 3x35rm/16 6/10kV", element="line") - pp.create_line(net, 0, auxbus, 1, name="line_to_decoupled_grid", - std_type="NAYSEY 3x35rm/16 6/10kV") # NAYSEY 3x35rm/16 6/10kV - pp.create_ext_grid(net, auxbus) - pp.create_switch(net, auxbus, 2, et="l", closed=0, type="LS") - pp.runpp(net, init='dc', calculate_voltage_angles=True) - - assert np.allclose(net.res_bus.p_mw.values*1e3, [-133.158732, 30.000000, - 0.000000, 100.000000, 0.000000]) - assert np.allclose(net.res_bus.q_mvar.values*1e3, [39.5843982697, 2.000000, - -28.5636406913, 0.000000, 0.000000]) + create_std_type(net, {"type": "cs", "r_ohm_per_km": 0.876, "q_mm2": 35.0, + "endtmp_deg": 160.0, "c_nf_per_km": 260.0, + "max_i_ka": 0.123, "x_ohm_per_km": 0.1159876}, + name="NAYSEY 3x35rm/16 6/10kV", element="line") + create_line(net, 0, auxbus, 1, name="line_to_decoupled_grid", + std_type="NAYSEY 3x35rm/16 6/10kV") # NAYSEY 3x35rm/16 6/10kV + create_ext_grid(net, auxbus) + create_switch(net, auxbus, 2, et="l", closed=0, type="LS") + runpp(net, init='dc', calculate_voltage_angles=True) + + assert np.allclose(net.res_bus.p_mw.values * 1e3, [-133.158732, 30.000000, + 0.000000, 100.000000, 0.000000]) + assert np.allclose(net.res_bus.q_mvar.values * 1e3, [39.5843982697, 2.000000, + -28.5636406913, 0.000000, 0.000000]) assert np.allclose(net.res_bus.va_degree.values, [0.000000, -155.752225311, -153.669395244, -0.0225931152895, 0.0]) - assert np.allclose(net.res_bus.vm_pu.values, [1.000000, 0.930961, - 0.975764, 0.998865, 1.0]) + assert np.allclose(net.res_bus.vm_pu.values, [1.000000, 0.930961, + 0.975764, 0.998865, 1.0]) - assert np.allclose(net.res_ext_grid.p_mw.values*1e3, [133.158732, 0.000000, 0.000000, - -0.000000]) - assert np.allclose(net.res_ext_grid.q_mvar*1e3, [-39.5843982697, 0.000000, 0.000000, - -0.000000]) + assert np.allclose(net.res_ext_grid.p_mw.values * 1e3, [133.158732, 0.000000, 0.000000, + -0.000000]) + assert np.allclose(net.res_ext_grid.q_mvar * 1e3, [-39.5843982697, 0.000000, 0.000000, + -0.000000]) def test_bus_bus_switch_at_eg(): - net = pp.create_empty_network() - b1 = pp.create_bus(net, name="bus1", vn_kv=.4) - b2 = pp.create_bus(net, name="bus2", vn_kv=.4) - b3 = pp.create_bus(net, name="bus3", vn_kv=.4) + net = create_empty_network() + b1 = create_bus(net, name="bus1", vn_kv=.4) + b2 = create_bus(net, name="bus2", vn_kv=.4) + b3 = create_bus(net, name="bus3", vn_kv=.4) - pp.create_ext_grid(net, b1) + create_ext_grid(net, b1) - pp.create_switch(net, b1, et="b", element=1) - pp.create_line(net, b2, b3, 1, name="line1", - std_type="NAYY 4x150 SE") + create_switch(net, b1, et="b", element=1) + create_line(net, b2, b3, 1, name="line1", + std_type="NAYY 4x150 SE") - pp.create_load(net, b3, p_mw=0.01, q_mvar=0, name="load1") + create_load(net, b3, p_mw=0.01, q_mvar=0, name="load1") runpp_with_consistency_checks(net) def test_bb_switch(): - net = pp.create_empty_network() + net = create_empty_network() net = add_test_bus_bus_switch(net) runpp_with_consistency_checks(net) def test_two_gens_at_one_bus(): - net = pp.create_empty_network() + net = create_empty_network() - b1 = pp.create_bus(net, 380) - b2 = pp.create_bus(net, 380) - b3 = pp.create_bus(net, 380) + b1 = create_bus(net, 380) + b2 = create_bus(net, 380) + b3 = create_bus(net, 380) - pp.create_ext_grid(net, b1, 1.02, max_p_mw=0.) + create_ext_grid(net, b1, 1.02, max_p_mw=0.) p1 = 800 p2 = 500 - g1 = pp.create_gen(net, b3, vm_pu=1.018, p_mw=p1) - g2 = pp.create_gen(net, b3, vm_pu=1.018, p_mw=p2) - pp.create_line(net, b1, b2, 30, "490-AL1/64-ST1A 380.0") - pp.create_line(net, b2, b3, 20, "490-AL1/64-ST1A 380.0") + g1 = create_gen(net, b3, vm_pu=1.018, p_mw=p1) + g2 = create_gen(net, b3, vm_pu=1.018, p_mw=p2) + create_line(net, b1, b2, 30, "490-AL1/64-ST1A 380.0") + create_line(net, b2, b3, 20, "490-AL1/64-ST1A 380.0") - pp.runpp(net) + runpp(net) assert net.res_gen.p_mw.at[g1] == p1 assert net.res_gen.p_mw.at[g2] == p2 def test_ext_grid_gen_order_in_ppc(): - net = pp.create_empty_network() + net = create_empty_network() for b in range(6): - pp.create_bus(net, vn_kv=1., name=b) + create_bus(net, vn_kv=1., name=b) for l_bus in range(0, 5, 2): - pp.create_line(net, from_bus=l_bus, to_bus=l_bus+1, length_km=1, - std_type="48-AL1/8-ST1A 10.0") + create_line(net, from_bus=l_bus, to_bus=l_bus + 1, length_km=1, + std_type="48-AL1/8-ST1A 10.0") for slack_bus in [0, 2, 5]: - pp.create_ext_grid(net, bus=slack_bus, vm_pu=1.) + create_ext_grid(net, bus=slack_bus, vm_pu=1.) for gen_bus in [0, 1, 2, 3, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5]: - pp.create_gen(net, bus=gen_bus, p_mw=1, vm_pu=1.) + create_gen(net, bus=gen_bus, p_mw=1, vm_pu=1.) - pp.rundcpp(net) + rundcpp(net) assert all(net.res_gen.p_mw == net.gen.p_mw) assert all(net.res_ext_grid.p_mw < 0) - pp.runpp(net) + runpp(net) assert all(net.res_gen.p_mw == net.gen.p_mw) assert all(net.res_ext_grid.p_mw < 0) def test_isolated_gen_lookup(): - net = pp.create_empty_network() + net = create_empty_network() - gen_bus = pp.create_bus(net, vn_kv=1., name='gen_bus') - slack_bus = pp.create_bus(net, vn_kv=1., name='slack_bus') - gen_iso_bus = pp.create_bus(net, vn_kv=1., name='iso_bus') + gen_bus = create_bus(net, vn_kv=1., name='gen_bus') + slack_bus = create_bus(net, vn_kv=1., name='slack_bus') + gen_iso_bus = create_bus(net, vn_kv=1., name='iso_bus') - pp.create_line(net, from_bus=slack_bus, to_bus=gen_bus, length_km=1, - std_type="48-AL1/8-ST1A 10.0") + create_line(net, from_bus=slack_bus, to_bus=gen_bus, length_km=1, + std_type="48-AL1/8-ST1A 10.0") - pp.create_ext_grid(net, bus=slack_bus, vm_pu=1.) + create_ext_grid(net, bus=slack_bus, vm_pu=1.) - pp.create_gen(net, bus=gen_iso_bus, p_mw=1, vm_pu=1., name='iso_gen') - pp.create_gen(net, bus=gen_bus, p_mw=1, vm_pu=1., name='oos_gen', in_service=False) - pp.create_gen(net, bus=gen_bus, p_mw=2, vm_pu=1., name='gen') + create_gen(net, bus=gen_iso_bus, p_mw=1, vm_pu=1., name='iso_gen') + create_gen(net, bus=gen_bus, p_mw=1, vm_pu=1., name='oos_gen', in_service=False) + create_gen(net, bus=gen_bus, p_mw=2, vm_pu=1., name='gen') - pp.rundcpp(net) + rundcpp(net) assert np.allclose(net.res_gen.p_mw.values, [0, 0, 2]) - pp.runpp(net) + runpp(net) assert np.allclose(net.res_gen.p_mw.values, [0, 0, 2]) - pp.create_xward(net, bus=gen_iso_bus, pz_mw=1., qz_mvar=1., ps_mw=1., qs_mvar=1., - vm_pu=1., x_ohm=1., r_ohm=.1) - pp.create_xward(net, bus=gen_bus, pz_mw=1., qz_mvar=1., ps_mw=1., qs_mvar=1., - vm_pu=1., x_ohm=1., r_ohm=.1) - pp.create_xward(net, bus=gen_iso_bus, pz_mw=1., qz_mvar=1., ps_mw=1., qs_mvar=1., - vm_pu=1., x_ohm=1., r_ohm=.1, in_service=False) + create_xward(net, bus=gen_iso_bus, pz_mw=1., qz_mvar=1., ps_mw=1., qs_mvar=1., + vm_pu=1., x_ohm=1., r_ohm=.1) + create_xward(net, bus=gen_bus, pz_mw=1., qz_mvar=1., ps_mw=1., qs_mvar=1., + vm_pu=1., x_ohm=1., r_ohm=.1) + create_xward(net, bus=gen_iso_bus, pz_mw=1., qz_mvar=1., ps_mw=1., qs_mvar=1., + vm_pu=1., x_ohm=1., r_ohm=.1, in_service=False) - pp.rundcpp(net) + rundcpp(net) assert np.allclose(net.res_gen.p_mw.values, [0, 0, 2]) assert np.allclose(net.res_xward.p_mw.values, [0, 2, 0]) - pp.runpp(net) + runpp(net) assert np.allclose(net.res_gen.p_mw.values, [0, 0, 2]) assert np.allclose(net.res_xward.p_mw.values, [0, 2, 0]) def test_transformer_phase_shift(): - net = pp.create_empty_network() + net = create_empty_network() for side in ["hv", "lv"]: - b1 = pp.create_bus(net, vn_kv=110.) - b2 = pp.create_bus(net, vn_kv=20.) - b3 = pp.create_bus(net, vn_kv=0.4) - pp.create_ext_grid(net, b1) - pp.create_transformer_from_parameters( + b1 = create_bus(net, vn_kv=110.) + b2 = create_bus(net, vn_kv=20.) + b3 = create_bus(net, vn_kv=0.4) + create_ext_grid(net, b1) + create_transformer_from_parameters( net, b1, b2, 40000, 110, 20, 0.1, 5, 0, 0.1, 30, side, # 0, 2, -2, 1.25, 10, 0) 0, 2, -2, 0, 10, 0, True) - pp.create_transformer_from_parameters( + create_transformer_from_parameters( net, b2, b3, 630, 20, 0.4, 0.1, 5, 0, 0.1, 20, tap_phase_shifter=True) - pp.runpp(net, init="dc", calculate_voltage_angles=True) + runpp(net, init="dc", calculate_voltage_angles=True) b2a_angle = net.res_bus.va_degree.at[1] b3a_angle = net.res_bus.va_degree.at[2] b2b_angle = net.res_bus.va_degree.at[4] @@ -227,7 +231,7 @@ def test_transformer_phase_shift(): net.trafo.at[0, "tap_pos"] = 1 net.trafo.at[2, "tap_pos"] = 1 - pp.runpp(net, init="dc", calculate_voltage_angles=True) + runpp(net, init="dc", calculate_voltage_angles=True) assert np.isclose(b2a_angle - net.res_bus.va_degree.at[1], 10) assert np.isclose(b3a_angle - net.res_bus.va_degree.at[2], 10) assert np.isclose(b2b_angle - net.res_bus.va_degree.at[4], -10) @@ -245,27 +249,27 @@ def test_transformer_phase_shift_complex(): 'lv': (0.9603, -31.1306) } for side in ["hv", "lv"]: - net = pp.create_empty_network() - b1 = pp.create_bus(net, vn_kv=110.) - pp.create_ext_grid(net, b1) - b2 = pp.create_bus(net, vn_kv=20.) - pp.create_load(net, b2, p_mw=10) - pp.create_transformer_from_parameters(net, hv_bus=b1, lv_bus=b2, sn_mva=40, vn_hv_kv=110, - vn_lv_kv=20, vkr_percent=0.1, vk_percent=5, - pfe_kw=0, i0_percent=0.1, shift_degree=30, - tap_side=side, tap_neutral=0, tap_max=2, tap_min=-2, - tap_step_percent=2, tap_step_degree=10, tap_pos=0) - pp.runpp(net, init="dc", calculate_voltage_angles=True) + net = create_empty_network() + b1 = create_bus(net, vn_kv=110.) + create_ext_grid(net, b1) + b2 = create_bus(net, vn_kv=20.) + create_load(net, b2, p_mw=10) + create_transformer_from_parameters(net, hv_bus=b1, lv_bus=b2, sn_mva=40, vn_hv_kv=110, + vn_lv_kv=20, vkr_percent=0.1, vk_percent=5, + pfe_kw=0, i0_percent=0.1, shift_degree=30, + tap_side=side, tap_neutral=0, tap_max=2, tap_min=-2, + tap_step_percent=2, tap_step_degree=10, tap_pos=0) + runpp(net, init="dc", calculate_voltage_angles=True) assert np.isclose(net.res_bus.vm_pu.at[b2], test_ref[0], rtol=1e-4) assert np.isclose(net.res_bus.va_degree.at[b2], test_ref[1], rtol=1e-4) net.trafo.at[0, "tap_pos"] = 2 - pp.runpp(net, init="dc", calculate_voltage_angles=True) + runpp(net, init="dc", calculate_voltage_angles=True) assert np.isclose(net.res_bus.vm_pu.at[b2], test_tap_pos[side][0], rtol=1e-4) assert np.isclose(net.res_bus.va_degree.at[b2], test_tap_pos[side][1], rtol=1e-4) net.trafo.at[0, "tap_pos"] = -2 - pp.runpp(net, init="dc", calculate_voltage_angles=True) + runpp(net, init="dc", calculate_voltage_angles=True) assert np.isclose(net.res_bus.vm_pu.at[b2], test_tap_neg[side][0], rtol=1e-4) assert np.isclose(net.res_bus.va_degree.at[b2], test_tap_neg[side][1], rtol=1e-4) @@ -283,39 +287,39 @@ def test_transformer3w_phase_shift(): 'lv': ((0.9995, -31.003), (0.9603, -61.178)) } for side in ["hv", "mv", "lv"]: - net = pp.create_empty_network() - b1 = pp.create_bus(net, vn_kv=110.) - pp.create_ext_grid(net, b1) - b2 = pp.create_bus(net, vn_kv=20.) - pp.create_load(net, b2, p_mw=10) - b3 = pp.create_bus(net, vn_kv=0.4) - pp.create_load(net, b3, p_mw=1) - pp.create_transformer3w_from_parameters(net, hv_bus=b1, mv_bus=b2, lv_bus=b3, vn_hv_kv=110, - vn_mv_kv=20, vn_lv_kv=0.4, sn_hv_mva=40, - sn_mv_mva=30, sn_lv_mva=10, - vk_hv_percent=5, vk_mv_percent=5, - vk_lv_percent=5, vkr_hv_percent=0.1, - vkr_mv_percent=0.1, vkr_lv_percent=0.1, pfe_kw=0, - i0_percent=0.1, shift_mv_degree=30, - shift_lv_degree=60, tap_side=side, - tap_step_percent=2, tap_step_degree=10, tap_pos=0, - tap_neutral=0, tap_min=-2, - tap_max=2) - pp.runpp(net, init="dc", calculate_voltage_angles=True) + net = create_empty_network() + b1 = create_bus(net, vn_kv=110.) + create_ext_grid(net, b1) + b2 = create_bus(net, vn_kv=20.) + create_load(net, b2, p_mw=10) + b3 = create_bus(net, vn_kv=0.4) + create_load(net, b3, p_mw=1) + create_transformer3w_from_parameters(net, hv_bus=b1, mv_bus=b2, lv_bus=b3, vn_hv_kv=110, + vn_mv_kv=20, vn_lv_kv=0.4, sn_hv_mva=40, + sn_mv_mva=30, sn_lv_mva=10, + vk_hv_percent=5, vk_mv_percent=5, + vk_lv_percent=5, vkr_hv_percent=0.1, + vkr_mv_percent=0.1, vkr_lv_percent=0.1, pfe_kw=0, + i0_percent=0.1, shift_mv_degree=30, + shift_lv_degree=60, tap_side=side, + tap_step_percent=2, tap_step_degree=10, tap_pos=0, + tap_neutral=0, tap_min=-2, + tap_max=2) + runpp(net, init="dc", calculate_voltage_angles=True) assert np.isclose(net.res_bus.vm_pu.at[b2], test_ref[0][0], rtol=1e-4) assert np.isclose(net.res_bus.va_degree.at[b2], test_ref[0][1], rtol=1e-4) assert np.isclose(net.res_bus.vm_pu.at[b3], test_ref[1][0], rtol=1e-4) assert np.isclose(net.res_bus.va_degree.at[b3], test_ref[1][1], rtol=1e-4) net.trafo3w.at[0, "tap_pos"] = 2 - pp.runpp(net, init="dc", calculate_voltage_angles=True) + runpp(net, init="dc", calculate_voltage_angles=True) assert np.isclose(net.res_bus.vm_pu.at[b2], test_tap_pos[side][0][0], rtol=1e-4) assert np.isclose(net.res_bus.va_degree.at[b2], test_tap_pos[side][0][1], rtol=1e-4) assert np.isclose(net.res_bus.vm_pu.at[b3], test_tap_pos[side][1][0], rtol=1e-4) assert np.isclose(net.res_bus.va_degree.at[b3], test_tap_pos[side][1][1], rtol=1e-4) net.trafo3w.at[0, "tap_pos"] = -2 - pp.runpp(net, init="dc", calculate_voltage_angles=True) + runpp(net, init="dc", calculate_voltage_angles=True) assert np.isclose(net.res_bus.vm_pu.at[b2], test_tap_neg[side][0][0], rtol=1e-4) assert np.isclose(net.res_bus.va_degree.at[b2], test_tap_neg[side][0][1], rtol=1e-4) assert np.isclose(net.res_bus.vm_pu.at[b3], test_tap_neg[side][1][0], rtol=1e-4) @@ -324,77 +328,77 @@ def test_transformer3w_phase_shift(): def test_volt_dep_load_at_inactive_bus(): # create empty net - net = pp.create_empty_network() + net = create_empty_network() # create buses - bus1 = pp.create_bus(net, index=0, vn_kv=20., name="Bus 1") - bus2 = pp.create_bus(net, index=1, vn_kv=0.4, name="Bus 2") - bus3 = pp.create_bus(net, index=3, in_service=False, vn_kv=0.4, name="Bus 3") - bus4 = pp.create_bus(net, index=4, vn_kv=0.4, name="Bus 4") - bus4 = pp.create_bus(net, index=5, vn_kv=0.4, name="Bus 4") + bus1 = create_bus(net, index=0, vn_kv=20., name="Bus 1") + bus2 = create_bus(net, index=1, vn_kv=0.4, name="Bus 2") + bus3 = create_bus(net, index=3, in_service=False, vn_kv=0.4, name="Bus 3") + bus4 = create_bus(net, index=4, vn_kv=0.4, name="Bus 4") + bus4 = create_bus(net, index=5, vn_kv=0.4, name="Bus 4") # create bus elements - pp.create_ext_grid(net, bus=bus1, vm_pu=1.02, name="Grid Connection") - pp.create_load(net, bus=4, p_mw=0.1, q_mvar=0.05, name="Load3", const_i_percent=100) - pp.create_load(net, bus=5, p_mw=0.1, q_mvar=0.05, name="Load4") + create_ext_grid(net, bus=bus1, vm_pu=1.02, name="Grid Connection") + create_load(net, bus=4, p_mw=0.1, q_mvar=0.05, name="Load3", const_i_percent=100) + create_load(net, bus=5, p_mw=0.1, q_mvar=0.05, name="Load4") # create branch elements - trafo = pp.create_transformer(net, hv_bus=bus1, lv_bus=bus2, std_type="0.4 MVA 20/0.4 kV", - name="Trafo") - line1 = pp.create_line(net, from_bus=1, to_bus=3, length_km=0.1, std_type="NAYY 4x50 SE", - name="Line") - line2 = pp.create_line(net, from_bus=1, to_bus=4, length_km=0.1, std_type="NAYY 4x50 SE", - name="Line") - line3 = pp.create_line(net, from_bus=1, to_bus=5, length_km=0.1, std_type="NAYY 4x50 SE", - name="Line") - - pp.runpp(net) + trafo = create_transformer(net, hv_bus=bus1, lv_bus=bus2, std_type="0.4 MVA 20/0.4 kV", + name="Trafo") + line1 = create_line(net, from_bus=1, to_bus=3, length_km=0.1, std_type="NAYY 4x50 SE", + name="Line") + line2 = create_line(net, from_bus=1, to_bus=4, length_km=0.1, std_type="NAYY 4x50 SE", + name="Line") + line3 = create_line(net, from_bus=1, to_bus=5, length_km=0.1, std_type="NAYY 4x50 SE", + name="Line") + + runpp(net) assert not np.isnan(net.res_load.p_mw.at[1]) assert not np.isnan(net.res_bus.p_mw.at[5]) assert net.res_bus.p_mw.at[3] == 0 def test_two_oos_buses(): - net = pp.create_empty_network() + net = create_empty_network() - b1 = pp.create_bus(net, vn_kv=0.4) - b2 = pp.create_bus(net, vn_kv=0.4) - b3 = pp.create_bus(net, vn_kv=0.4, in_service=False) - b4 = pp.create_bus(net, vn_kv=0.4, in_service=False) + b1 = create_bus(net, vn_kv=0.4) + b2 = create_bus(net, vn_kv=0.4) + b3 = create_bus(net, vn_kv=0.4, in_service=False) + b4 = create_bus(net, vn_kv=0.4, in_service=False) - pp.create_ext_grid(net, b1) - l1 = pp.create_line(net, b1, b2, 0.5, std_type="NAYY 4x50 SE", index=4) - l2 = pp.create_line(net, b2, b3, 0.5, std_type="NAYY 4x50 SE", index=2) - l3 = pp.create_line(net, b3, b4, 0.5, std_type="NAYY 4x50 SE", index=7) + create_ext_grid(net, b1) + l1 = create_line(net, b1, b2, 0.5, std_type="NAYY 4x50 SE", index=4) + l2 = create_line(net, b2, b3, 0.5, std_type="NAYY 4x50 SE", index=2) + l3 = create_line(net, b3, b4, 0.5, std_type="NAYY 4x50 SE", index=7) - pp.runpp(net) + runpp(net) assert net.res_line.loading_percent.at[l1] > 0 assert net.res_line.loading_percent.at[l2] > 0 assert np.isnan(net.res_line.loading_percent.at[l3]) net.line = net.line.drop(l2) - pp.runpp(net) + runpp(net) assert net.res_line.loading_percent.at[l1] > 0 assert np.isnan(net.res_line.loading_percent.at[l3]) def test_oos_buses_at_trafo3w(): - net = pp.create_empty_network() + net = create_empty_network() - b1 = pp.create_bus(net, vn_kv=110.) - b2 = pp.create_bus(net, vn_kv=110.) - b3 = pp.create_bus(net, vn_kv=110., in_service=False) - b4 = pp.create_bus(net, vn_kv=20., in_service=False) - b5 = pp.create_bus(net, vn_kv=10., in_service=False) + b1 = create_bus(net, vn_kv=110.) + b2 = create_bus(net, vn_kv=110.) + b3 = create_bus(net, vn_kv=110., in_service=False) + b4 = create_bus(net, vn_kv=20., in_service=False) + b5 = create_bus(net, vn_kv=10., in_service=False) - pp.create_ext_grid(net, b1) - l1 = pp.create_line(net, b1, b2, 0.5, std_type="NAYY 4x50 SE", in_service=True) - l2 = pp.create_line(net, b2, b3, 0.5, std_type="NAYY 4x50 SE", in_service=False) + create_ext_grid(net, b1) + l1 = create_line(net, b1, b2, 0.5, std_type="NAYY 4x50 SE", in_service=True) + l2 = create_line(net, b2, b3, 0.5, std_type="NAYY 4x50 SE", in_service=False) - tidx = pp.create_transformer3w( + tidx = create_transformer3w( net, b3, b4, b5, std_type='63/25/38 MVA 110/20/10 kV', in_service=True) - pp.runpp(net, trafo3w_losses = 'star', trafo_model= 'pi', init='flat') + runpp(net, trafo3w_losses='star', trafo_model='pi', init='flat') assert net.res_line.loading_percent.at[l1] > 0 assert np.isnan(net.res_trafo3w.i_hv_ka.at[tidx]) @@ -402,22 +406,22 @@ def test_oos_buses_at_trafo3w(): @pytest.fixture def network_with_trafo3ws(): - net = pp.create_empty_network() + net = create_empty_network() add_test_trafo(net) slack, hv, ln = add_grid_connection(net, zone="test_trafo3w") for _ in range(2): - mv = pp.create_bus(net, vn_kv=0.6, zone="test_trafo3w") - pp.create_load(net, mv, p_mw=0.8, q_mvar=0) - lv = pp.create_bus(net, vn_kv=0.4, zone="test_trafo3w") - pp.create_load(net, lv, p_mw=0.5, q_mvar=0) - t3 = pp.create_transformer3w_from_parameters( + mv = create_bus(net, vn_kv=0.6, zone="test_trafo3w") + create_load(net, mv, p_mw=0.8, q_mvar=0) + lv = create_bus(net, vn_kv=0.4, zone="test_trafo3w") + create_load(net, lv, p_mw=0.5, q_mvar=0) + t3 = create_transformer3w_from_parameters( net, hv_bus=hv, mv_bus=mv, lv_bus=lv, vn_hv_kv=22, vn_mv_kv=.64, vn_lv_kv=.42, sn_hv_mva=1, sn_mv_mva=0.7, sn_lv_mva=0.3, vk_hv_percent=1., vkr_hv_percent=.03, vk_mv_percent=.5, vkr_mv_percent=.02, vk_lv_percent=.25, vkr_lv_percent=.01, pfe_kw=.5, i0_percent=0.1, - name="test", index=pp.get_free_id(net.trafo3w) + 1, + name="test", index=get_free_id(net.trafo3w) + 1, tap_side="hv", tap_pos=2, tap_step_percent=1.25, tap_min=-5, tap_neutral=0, tap_max=5) return (net, t3, hv, mv, lv) @@ -427,7 +431,7 @@ def test_trafo3w_switches(network_with_trafo3ws): net, t3, hv, mv, lv = network_with_trafo3ws # open switch at hv side - t3 is disconnected - s1 = pp.create_switch(net, bus=hv, element=t3, et="t3", closed=False) + s1 = create_switch(net, bus=hv, element=t3, et="t3", closed=False) runpp_with_consistency_checks(net) assert np.isnan(net.res_bus.vm_pu.at[mv]) assert np.isnan(net.res_bus.vm_pu.at[lv]) @@ -454,7 +458,7 @@ def test_trafo3w_switches(network_with_trafo3ws): assert 0.790 < net.res_trafo3w.p_hv_mw.at[t3] < 0.810 # open switch at lv and mv side - lv and mv is disconnected, t3 in open loop - pp.create_switch(net, bus=mv, element=t3, et="t3", closed=False) + create_switch(net, bus=mv, element=t3, et="t3", closed=False) runpp_with_consistency_checks(net) assert np.isnan(net.res_bus.vm_pu.at[lv]) @@ -465,104 +469,103 @@ def test_trafo3w_switches(network_with_trafo3ws): def test_generator_as_slack(): - net = pp.create_empty_network() - b1 = pp.create_bus(net, 110.) - pp.create_ext_grid(net, b1, vm_pu=1.02) - b2 = pp.create_bus(net, 110.) - pp.create_line(net, b1, b2, length_km=70., std_type='149-AL1/24-ST1A 110.0') - pp.create_load(net, b2, p_mw=2) - pp.runpp(net) + net = create_empty_network() + b1 = create_bus(net, 110.) + create_ext_grid(net, b1, vm_pu=1.02) + b2 = create_bus(net, 110.) + create_line(net, b1, b2, length_km=70., std_type='149-AL1/24-ST1A 110.0') + create_load(net, b2, p_mw=2) + runpp(net) res_bus = net.res_bus.vm_pu.values - pp.create_gen(net, b1, p_mw=0.1, vm_pu=1.02, slack=True) + create_gen(net, b1, p_mw=0.1, vm_pu=1.02, slack=True) net.ext_grid.loc[0, 'in_service'] = False - pp.runpp(net) + runpp(net) assert np.allclose(res_bus, net.res_bus.vm_pu.values) net.gen.loc[0, 'slack'] = False with pytest.raises(UserWarning): - pp.runpp(net) + runpp(net) def test_transformer_with_two_open_switches(): - net = pp.create_empty_network() - b1 = pp.create_bus(net, 110.) - pp.create_ext_grid(net, b1, vm_pu=1.02) - b2 = pp.create_bus(net, 20.) - t = pp.create_transformer(net, b1, b2, std_type='63 MVA 110/20 kV') - b3 = pp.create_bus(net, 20.) - pp.create_line(net, b2, b3, length_km=7., std_type='149-AL1/24-ST1A 110.0') - pp.create_load(net, b2, p_mw=2) - pp.runpp(net) + net = create_empty_network() + b1 = create_bus(net, 110.) + create_ext_grid(net, b1, vm_pu=1.02) + b2 = create_bus(net, 20.) + t = create_transformer(net, b1, b2, std_type='63 MVA 110/20 kV') + b3 = create_bus(net, 20.) + create_line(net, b2, b3, length_km=7., std_type='149-AL1/24-ST1A 110.0') + create_load(net, b2, p_mw=2) + runpp(net) assert net.res_trafo.vm_hv_pu.at[t] == net.res_bus.vm_pu.at[b1] assert net.res_trafo.vm_lv_pu.at[t] == net.res_bus.vm_pu.at[b2] - pp.create_switch(net, b2, element=t, et="t", closed=False) - pp.runpp(net) + create_switch(net, b2, element=t, et="t", closed=False) + runpp(net) assert net.res_trafo.vm_hv_pu.at[t] == net.res_bus.vm_pu.at[b1] assert net.res_trafo.vm_lv_pu.at[t] != net.res_bus.vm_pu.at[b2] - pp.create_switch(net, b1, element=t, et="t", closed=False) - pp.runpp(net) + create_switch(net, b1, element=t, et="t", closed=False) + runpp(net) assert net.res_trafo.vm_hv_pu.at[t] != net.res_bus.vm_pu.at[b1] assert net.res_trafo.vm_lv_pu.at[t] != net.res_bus.vm_pu.at[b2] def test_motor(): - net = pp.create_empty_network() - b1 = pp.create_bus(net, 0.4) - b2 = pp.create_bus(net, 0.4) - pp.create_line(net, b1, b2, length_km=0.1, std_type="NAYY 4x50 SE") - pp.create_ext_grid(net, b1) + net = create_empty_network() + b1 = create_bus(net, 0.4) + b2 = create_bus(net, 0.4) + create_line(net, b1, b2, length_km=0.1, std_type="NAYY 4x50 SE") + create_ext_grid(net, b1) p_mech = 0.1 cos_phi = 0.98 efficiency = 95 - pp.create_motor(net, b2, pn_mech_mw=0.1, cos_phi=cos_phi, - efficiency_percent=efficiency) + create_motor(net, b2, pn_mech_mw=0.1, cos_phi=cos_phi, + efficiency_percent=efficiency) - pp.runpp(net) + runpp(net) p = net.res_motor.p_mw.iloc[0] q = net.res_motor.q_mvar.iloc[0] - s = np.sqrt(p**2+q**2) + s = np.sqrt(p ** 2 + q ** 2) assert p == p_mech / efficiency * 100 - assert p/s == cos_phi + assert p / s == cos_phi res_bus_motor = net.res_bus.copy() - pp.create_load(net, b2, p_mw=net.res_motor.p_mw.values[0], - q_mvar=net.res_motor.q_mvar.values[0]) + create_load(net, b2, p_mw=net.res_motor.p_mw.values[0], + q_mvar=net.res_motor.q_mvar.values[0]) net.motor.in_service = False - pp.runpp(net) + runpp(net) assert net.res_bus.equals(res_bus_motor) def test_switch_results(): - net = nw.simple_mv_open_ring_net() + net = simple_mv_open_ring_net() net.ext_grid["s_sc_max_mva"] = 1000 net.ext_grid['rx_max'] = 0.1 - switch_trafo_hv = pp.create_switch(net, bus=0, element=0, et="t") - switch_trafo_lv = pp.create_switch(net, bus=1, element=0, et="t") + switch_trafo_hv = create_switch(net, bus=0, element=0, et="t") + switch_trafo_lv = create_switch(net, bus=1, element=0, et="t") closed_line_switch = 1 open_line_switch = 6 - new_bus = pp.create_bus(net, vn_kv=20.0) - pp.create_load(net, new_bus, p_mw=1.5) - closed_bb_switch = pp.create_switch(net, bus=new_bus, element=6, et="b") + new_bus = create_bus(net, vn_kv=20.0) + create_load(net, new_bus, p_mw=1.5) + closed_bb_switch = create_switch(net, bus=new_bus, element=6, et="b") - new_bus = pp.create_bus(net, vn_kv=20.0) + new_bus = create_bus(net, vn_kv=20.0) in_ka = 0.1 - pp.create_load(net, new_bus, p_mw=1.5) - closed_bb_switch_impedance = pp.create_switch(net, bus=new_bus, element=4, et="b", z_ohm=0.1, in_ka=in_ka) + create_load(net, new_bus, p_mw=1.5) + closed_bb_switch_impedance = create_switch(net, bus=new_bus, element=4, et="b", z_ohm=0.1, in_ka=in_ka) - new_bus = pp.create_bus(net, vn_kv=20.0) - pp.create_load(net, new_bus, p_mw=1.5) - open_bb_switch = pp.create_switch(net, bus=new_bus, element=6, et="b", closed=False) + new_bus = create_bus(net, vn_kv=20.0) + create_load(net, new_bus, p_mw=1.5) + open_bb_switch = create_switch(net, bus=new_bus, element=6, et="b", closed=False) - - pp.runpp(net) + runpp(net) assert np.isclose(net.res_switch.i_ka.at[open_line_switch], 0) assert np.isclose(net.res_switch.i_ka.at[open_bb_switch], 0) @@ -579,8 +582,7 @@ def test_switch_results(): assert np.isclose(net.res_switch.i_ka.at[switch_trafo_hv], abs(net.res_trafo.i_hv_ka.at[trafo])) assert np.isclose(net.res_switch.i_ka.at[switch_trafo_lv], abs(net.res_trafo.i_lv_ka.at[trafo])) - - sc.calc_sc(net, branch_results=True) + calc_sc(net, branch_results=True) assert np.isclose(net.res_switch_sc.ikss_ka.at[open_line_switch], 0) assert np.isclose(net.res_switch_sc.ikss_ka.at[open_bb_switch], 0) diff --git a/pandapower/test/loadflow/test_tdpf.py b/pandapower/test/loadflow/test_tdpf.py index 4c437e041..9423d8053 100644 --- a/pandapower/test/loadflow/test_tdpf.py +++ b/pandapower/test/loadflow/test_tdpf.py @@ -5,17 +5,19 @@ import os import numpy as np +import pandas as pd import pytest +from pandapower import pp_dir +from pandapower.create import create_empty_network, create_bus, create_line, create_load, create_ext_grid, \ + create_buses, create_sgen, create_gen, create_gens, create_line_from_parameters +from pandapower.networks.power_system_test_cases import case9, case30 from pandapower.pf.create_jacobian_tdpf import calc_r_theta_from_t_rise, calc_i_square_p_loss, calc_g_b, \ calc_a0_a1_a2_tau, calc_T_ngoko, calc_r_theta, calc_T_frank -from pandapower.test.helper_functions import assert_res_equal - -import pandas as pd -import pandapower as pp -import pandapower.networks - from pandapower.pypower.idx_brch import BR_R, BR_X +from pandapower.run import set_user_pf_options, runpp +from pandapower.std_types import parameter_from_std_type +from pandapower.test.helper_functions import assert_res_equal # pd.set_option("display.max_columns", 1000) @@ -36,14 +38,14 @@ def en_net(request): def create_single_line_net(std_type): - net = pp.create_empty_network() - pp.set_user_pf_options(net, init="dc", max_iteration=100) + net = create_empty_network() + set_user_pf_options(net, init="dc", max_iteration=100) vn_kv = float(std_type.split(" ")[-1]) - b1 = pp.create_bus(net, vn_kv=vn_kv, name='b1_hv', type='n') - b2 = pp.create_bus(net, vn_kv=vn_kv, name='b10', type='n') + b1 = create_bus(net, vn_kv=vn_kv, name='b1_hv', type='n') + b2 = create_bus(net, vn_kv=vn_kv, name='b10', type='n') - pp.create_line(net, from_bus=b1, to_bus=b2, length_km=vn_kv / 4, std_type=std_type, name='l3') + create_line(net, from_bus=b1, to_bus=b2, length_km=vn_kv / 4, std_type=std_type, name='l3') max_i_ka = net.line.at[0, 'max_i_ka'] # Initial standard Value @@ -51,13 +53,13 @@ def create_single_line_net(std_type): # Chose the load to match nominal current p_ac = vn_kv * max_i_ka * np.sqrt(3) # Q=0 - pp.create_load(net, b2, sn_mva=p_ac, p_mw=p_ac, name="load_b8", const_i_percent=100) + create_load(net, b2, sn_mva=p_ac, p_mw=p_ac, name="load_b8", const_i_percent=100) - pp.create_ext_grid(net, b1) + create_ext_grid(net, b1) # Declaration of overhead and cable systems ol_index = net.line.loc[net.line.type == "ol"].index.values - pp.parameter_from_std_type(net, 'q_mm2') + parameter_from_std_type(net, 'q_mm2') q_mm2 = net.line.loc[ol_index, "q_mm2"].values.astype(np.float64) # e.g. 0.0218 for 243-AL1/39-ST1A 110.0 d_m = (np.sqrt(q_mm2 * 4 * (1 / np.pi))) * 1e-3 * 1.2 # 1.2 because not perfect circle @@ -79,7 +81,7 @@ def create_single_line_net(std_type): def prepare_case_30(): - net = pp.networks.case30() + net = case30() for i in net.line.index.values: net.line.at[i, 'name'] = f"{net.line.at[i, 'from_bus'] + 1} - {net.line.at[i, 'to_bus'] + 1}" @@ -105,7 +107,7 @@ def prepare_case_30(): def simple_test_grid(load_scaling=1., sgen_scaling=1., with_gen=False, distributed_slack=False): s_base = 100 - net = pp.create_empty_network(sn_mva=s_base) + net = create_empty_network(sn_mva=s_base) std_type = "490-AL1/64-ST1A 110.0" # r = 0.1188 # std_type = "490-AL1/64-ST1A 220.0" @@ -113,14 +115,14 @@ def simple_test_grid(load_scaling=1., sgen_scaling=1., with_gen=False, distribut v_base = 132 z_base = v_base ** 2 / s_base - pp.create_buses(net, 5, v_base, geodata=[(0, 1), (-1, 0.5), (0, 0), (1, 0.5), (0, 0.5)]) + create_buses(net, 5, v_base, geodata=[(0, 1), (-1, 0.5), (0, 0), (1, 0.5), (0, 0.5)]) - pp.create_line(net, 0, 1, 0.84e-2 * z_base / r, std_type, name="1-2") - pp.create_line(net, 0, 3, 0.84e-2 * z_base / r, std_type, name="1-4") - pp.create_line(net, 1, 2, 0.67e-2 * z_base / r, std_type, name="2-3") - pp.create_line(net, 1, 4, 0.42e-2 * z_base / r, std_type, name="2-5") - pp.create_line(net, 2, 3, 0.67e-2 * z_base / r, std_type, name="3-4") - pp.create_line(net, 3, 4, 0.42e-2 * z_base / r, std_type, name="4-5") + create_line(net, 0, 1, 0.84e-2 * z_base / r, std_type, name="1-2") + create_line(net, 0, 3, 0.84e-2 * z_base / r, std_type, name="1-4") + create_line(net, 1, 2, 0.67e-2 * z_base / r, std_type, name="2-3") + create_line(net, 1, 4, 0.42e-2 * z_base / r, std_type, name="2-5") + create_line(net, 2, 3, 0.67e-2 * z_base / r, std_type, name="3-4") + create_line(net, 3, 4, 0.42e-2 * z_base / r, std_type, name="4-5") net.line.c_nf_per_km = 0 net.line["temperature_degree_celsius"] = 20 @@ -136,24 +138,24 @@ def simple_test_grid(load_scaling=1., sgen_scaling=1., with_gen=False, distribut net.line["emissivity"] = 0.5 net.line["tdpf"] = True - pp.create_ext_grid(net, 3, 1.05, name="G1") - pp.create_sgen(net, 0, 200, scaling=sgen_scaling, name="R1") - pp.create_sgen(net, 1, 250, scaling=sgen_scaling, name="R2") + create_ext_grid(net, 3, 1.05, name="G1") + create_sgen(net, 0, 200, scaling=sgen_scaling, name="R1") + create_sgen(net, 1, 250, scaling=sgen_scaling, name="R2") if with_gen: - idx = pp.create_gen(net, 2, 600, 1., scaling=sgen_scaling, name="G3") - pp.create_gen(net, 4, 300, 1., scaling=sgen_scaling, name="G5") + idx = create_gen(net, 2, 600, 1., scaling=sgen_scaling, name="G3") + create_gen(net, 4, 300, 1., scaling=sgen_scaling, name="G5") else: - idx = pp.create_sgen(net, 2, 600, scaling=sgen_scaling, name="G3") - pp.create_sgen(net, 4, 300, scaling=sgen_scaling, name="G5") + idx = create_sgen(net, 2, 600, scaling=sgen_scaling, name="G3") + create_sgen(net, 4, 300, scaling=sgen_scaling, name="G5") if distributed_slack: net["gen" if with_gen else "sgen"].at[idx, 'slack_weight'] = 1 - pp.set_user_pf_options(net, distributed_slack=True) + set_user_pf_options(net, distributed_slack=True) net.sn_mva = 1000 # otherwise numerical issues - pp.create_load(net, 1, 600, 240, scaling=load_scaling) - pp.create_load(net, 3, 1000, 400, scaling=load_scaling) - pp.create_load(net, 4, 400, 160, scaling=load_scaling) + create_load(net, 1, 600, 240, scaling=load_scaling) + create_load(net, 3, 1000, 400, scaling=load_scaling) + create_load(net, 4, 400, 160, scaling=load_scaling) return net @@ -161,7 +163,7 @@ def simple_test_grid(load_scaling=1., sgen_scaling=1., with_gen=False, distribut def test_tdpf_frank_current(): net = prepare_case_30() net.line["c_nf_per_km"] = 0 # otherwise i_square_pu will not match net.res_line.i_ka - pp.runpp(net, tdpf=True, tdpf_update_r_theta=False) + runpp(net, tdpf=True, tdpf_update_r_theta=False) branch = net._ppc["branch"] V = net._ppc["internal"]["V"] @@ -178,7 +180,7 @@ def test_tdpf_frank_current(): def test_tdpf_frank(): net = prepare_case_30() - pp.runpp(net, tdpf=True, tdpf_update_r_theta=False) + runpp(net, tdpf=True, tdpf_update_r_theta=False) v_base_kv = net.bus.loc[net.line.from_bus].vn_kv.values z_base_ohm = np.square(v_base_kv) / net.sn_mva @@ -194,7 +196,7 @@ def test_tdpf_frank(): line_max_mva = net.line.max_i_ka.loc[sorted_index] * 135 * np.sqrt(3) line_loading = line_mva / line_max_mva - ref2 = pd.read_csv(os.path.join(pp.pp_dir, "test", "test_files", "tdpf", "case30_branch_details.csv")) + ref2 = pd.read_csv(os.path.join(pp_dir, "test", "test_files", "tdpf", "case30_branch_details.csv")) ref2 = ref2.sort_values(by="R_THETA", ascending=False) # compare p_loss @@ -216,7 +218,7 @@ def test_temperature_r(): for distributed_slack in (False, True): net = simple_test_grid(load_scaling=0.25, sgen_scaling=0.5, with_gen=with_gen, distributed_slack=distributed_slack) - pp.runpp(net, tdpf=True, max_iteration=100) + runpp(net, tdpf=True, max_iteration=100) T = calc_T_ngoko(np.square(net.res_line.i_ka.values * 1e3), a0, a1, a2, None, None, None) assert np.allclose(net.res_line.temperature_degree_celsius, T, rtol=0, atol=1e-6) @@ -224,16 +226,16 @@ def test_temperature_r(): net2 = simple_test_grid(load_scaling=0.25, sgen_scaling=0.5, with_gen=with_gen, distributed_slack=distributed_slack) net2.line["temperature_degree_celsius"] = net.res_line.temperature_degree_celsius - pp.runpp(net2, consider_line_temperature=True) + runpp(net2, consider_line_temperature=True) net.res_line = net.res_line.drop(["temperature_degree_celsius", "r_theta_kelvin_per_mw"], axis=1) assert_res_equal(net, net2) # now test transient results -> after 5 min - pp.runpp(net, tdpf=True, tdpf_delay_s=5 * 60, max_iteration=100) + runpp(net, tdpf=True, tdpf_delay_s=5 * 60, max_iteration=100) net2.line["temperature_degree_celsius"] = net.res_line.temperature_degree_celsius - pp.runpp(net2, consider_line_temperature=True) + runpp(net2, consider_line_temperature=True) net.res_line = net.res_line.drop(["temperature_degree_celsius", "r_theta_kelvin_per_mw"], axis=1) assert_res_equal(net, net2) @@ -241,7 +243,7 @@ def test_temperature_r(): def test_ngoko_vs_frank(): net = simple_test_grid(load_scaling=0.25, sgen_scaling=0.5) - pp.runpp(net) + runpp(net) t_air_pu = 35 alpha_pu = 4e-3 @@ -279,64 +281,64 @@ def test_tdpf_delay(): net = simple_test_grid(load_scaling=0.25, sgen_scaling=0.5, with_gen=with_gen, distributed_slack=distributed_slack) # no delay - pp.runpp(net, tdpf=True, max_iteration=100, tdpf_delay_s=0) + runpp(net, tdpf=True, max_iteration=100, tdpf_delay_s=0) assert np.allclose(net.res_line.temperature_degree_celsius, 20, rtol=0, atol=1e-6) # infinite delay (steady state) - pp.runpp(net, tdpf=True, max_iteration=100, tdpf_delay_s=np.inf) + runpp(net, tdpf=True, max_iteration=100, tdpf_delay_s=np.inf) temp = net.res_line.temperature_degree_celsius.values.copy() - pp.runpp(net, tdpf=True, max_iteration=100, tdpf_delay_s=None) + runpp(net, tdpf=True, max_iteration=100, tdpf_delay_s=None) assert np.allclose(net.res_line.temperature_degree_celsius, temp, rtol=0, atol=1e-6) # check tau: time to "charge" to approx. 63.2 %; we cannot match it very accurately though - pp.runpp(net, tdpf=True, max_iteration=100, tdpf_delay_s=tau) + runpp(net, tdpf=True, max_iteration=100, tdpf_delay_s=tau) assert np.allclose(net.res_line.temperature_degree_celsius, 20 + (temp - 20) * 0.632, rtol=0, atol=0.6) def test_only_pv(): net = simple_test_grid(load_scaling=0.25, sgen_scaling=0.5, with_gen=True) pq = net.bus.loc[~net.bus.index.isin(np.union1d(net.gen.bus, net.ext_grid.bus))].index - pp.create_gens(net, pq, 0) + create_gens(net, pq, 0) - pp.runpp(net, init="flat") + runpp(net, init="flat") - pp.runpp(net, tdpf=True) + runpp(net, tdpf=True) def test_default_parameters(): # length_km is important in the formulas - net = pp.networks.case9() + net = case9() net.line.length_km = net.line.x_ohm_per_km / 4 net.line.x_ohm_per_km /= net.line.length_km net.line.r_ohm_per_km /= net.line.length_km net.line.c_nf_per_km /= net.line.length_km net_backup = net.deepcopy() - pp.runpp(net_backup) + runpp(net_backup) # test error is raised when 'tdpf' column is missng with pytest.raises(UserWarning, match="required columns .* are missing"): - pp.runpp(net, tdpf=True) + runpp(net, tdpf=True) net.line["tdpf"] = np.nan with pytest.raises(UserWarning, match="required columns .*'conductor_outer_diameter_m'.* are missing"): - pp.runpp(net, tdpf=True) + runpp(net, tdpf=True) # with TDPF algorithm but no relevant tdpf lines the results must match with normal runpp: net.line["conductor_outer_diameter_m"] = np.nan - pp.runpp(net, tdpf=True) + runpp(net, tdpf=True) net.res_line = net.res_line.drop(["r_ohm_per_km", "temperature_degree_celsius", "r_theta_kelvin_per_mw"], axis=1) assert_res_equal(net, net_backup) with pytest.raises(UserWarning, match="required columns .*'mc_joule_per_m_k'.* are missing"): - pp.runpp(net, tdpf=True, tdpf_delay_s=120) + runpp(net, tdpf=True, tdpf_delay_s=120) # check for simplified method net = net_backup.deepcopy() net.line["tdpf"] = np.nan with pytest.raises(UserWarning, match="required columns .* are missing"): - pp.runpp(net, tdpf=True, tdpf_update_r_theta=False) + runpp(net, tdpf=True, tdpf_update_r_theta=False) net.line["r_theta_kelvin_per_mw"] = np.nan - pp.runpp(net, tdpf=True, tdpf_update_r_theta=False) + runpp(net, tdpf=True, tdpf_update_r_theta=False) net.res_line = net.res_line.drop(["r_ohm_per_km", "temperature_degree_celsius", "r_theta_kelvin_per_mw"], axis=1) assert_res_equal(net, net_backup) @@ -345,16 +347,16 @@ def test_default_parameters(): net.line.loc[1, 'alpha'] = 4.03e-3 net.line["r_theta_kelvin_per_mw"] = calc_r_theta_from_t_rise(net, 25) with pytest.raises(UserWarning, match="required columns .* are missing"): - pp.runpp(net, tdpf=True, tdpf_update_r_theta=False) + runpp(net, tdpf=True, tdpf_update_r_theta=False) net.line['alpha'] = 4.03e-3 net.line["r_theta_kelvin_per_mw"] = calc_r_theta_from_t_rise(net, 25) - pp.runpp(net, tdpf=True, tdpf_update_r_theta=False) + runpp(net, tdpf=True, tdpf_update_r_theta=False) # now test with "normal" TDPF net = net_backup.deepcopy() net.line.loc[net.line.r_ohm_per_km != 0, "tdpf"] = True net.line["conductor_outer_diameter_m"] = 2.5e-2 # 2.5 cm? - pp.runpp(net, tdpf=True) + runpp(net, tdpf=True) # here all the standard assumptions are filled # now we check that user-defined assumptions are preserved net = net_backup.deepcopy() @@ -363,50 +365,50 @@ def test_default_parameters(): net.line.loc[[2, 4], 'temperature_degree_celsius'] = 40 net.line.loc[[2, 4], 'alpha'] = 3e-3 net.line.loc[[2, 4], 'wind_speed_m_per_s'] = 0 - pp.runpp(net, tdpf=True) + runpp(net, tdpf=True) assert np.array_equal(net.line.loc[[2, 4], 'temperature_degree_celsius'].values, np.array([40, 40])) assert np.array_equal(net.line.loc[[2, 4], 'alpha'].values, np.array([3e-3, 3e-3])) assert np.array_equal(net.line.loc[[2, 4], 'wind_speed_m_per_s'].values, np.array([0, 0])) net.line["mc_joule_per_m_k"] = 500 - pp.runpp(net, tdpf=True, tdpf_delay_s=10 * 60) + runpp(net, tdpf=True, tdpf_delay_s=10 * 60) def test_with_user_pf_options(): net = simple_test_grid(0.5, 0.5) net2 = net.deepcopy() - pp.set_user_pf_options(net, tdpf=True) - pp.runpp(net) + set_user_pf_options(net, tdpf=True) + runpp(net) assert "r_ohm_per_km" in net.res_line assert "temperature_degree_celsius" in net.res_line assert len(net.res_line.loc[net.res_line.r_ohm_per_km.isnull()]) == 0 assert len(net.res_line.loc[net.res_line.temperature_degree_celsius.isnull()]) == 0 - pp.runpp(net2, tdpf=True) + runpp(net2, tdpf=True) assert_res_equal(net, net2) with pytest.raises(NotImplementedError): - pp.runpp(net, algorithm="bfsw") + runpp(net, algorithm="bfsw") # Testing with a given Example from "IEEE Standard for Calculating the Current-Temperature # Relationship of Bare Overhead Conductors" Basic Example with Calculation, Page 23 and following def test_IEEE_example_1(): # 60Hz according to USA - net = pp.create_empty_network(f_hz=60.0) + net = create_empty_network(f_hz=60.0) - b1 = pp.create_bus(net, vn_kv=380, name='b1_hv', type='n') - b2 = pp.create_bus(net, vn_kv=380, name='b10', type='n') + b1 = create_bus(net, vn_kv=380, name='b1_hv', type='n') + b2 = create_bus(net, vn_kv=380, name='b10', type='n') # 795 kcmil 26/7 Drake ACSR - pp.create_line_from_parameters(net, from_bus=b1, to_bus=b2, length_km=1, r_ohm_per_km=0.07283, x_ohm_per_km=0.341, - c_nf_per_km=7.7827795, max_i_ka=1.024, type='ol') + create_line_from_parameters(net, from_bus=b1, to_bus=b2, length_km=1, r_ohm_per_km=0.07283, x_ohm_per_km=0.341, + c_nf_per_km=7.7827795, max_i_ka=1.024, type='ol') # Chose the load to match nominal current p_ac = 380 * 1.024 * np.sqrt(3) - pp.create_load(net, b2, p_mw=p_ac, q_mvar=0, name="load_b8", const_i_percent=100) + create_load(net, b2, p_mw=p_ac, q_mvar=0, name="load_b8", const_i_percent=100) - pp.create_ext_grid(net, b1, vm_pu=1, va_degree=0, s_sc_max_mva=20 * 110 * np.sqrt(3), rx_max=0.1) + create_ext_grid(net, b1, vm_pu=1, va_degree=0, s_sc_max_mva=20 * 110 * np.sqrt(3), rx_max=0.1) # Defining Overhead-Lines ol_index = net.line.loc[net.line.type == "ol"].index.values @@ -428,7 +430,7 @@ def test_IEEE_example_1(): net.line.loc[ol_index, 'emissivity'] = 0.8 # Starting Control Loop - pp.runpp(net, tdpf=True, init="dc") + runpp(net, tdpf=True, init="dc") # calculating current max_cond_temp = 100 @@ -442,23 +444,23 @@ def test_IEEE_example_1(): # Relationship of Bare Overhead Conductors", Annex B, Numerical example 1, Page 44 def test_IEEE_example_2(): # 60Hz according to USA - net = pp.create_empty_network(f_hz=60.0) + net = create_empty_network(f_hz=60.0) - b1 = pp.create_bus(net, vn_kv=380, name='b1_hv', type='n') - b2 = pp.create_bus(net, vn_kv=380, name='b10', type='n') + b1 = create_bus(net, vn_kv=380, name='b1_hv', type='n') + b2 = create_bus(net, vn_kv=380, name='b10', type='n') # 400 MM2 26/7 Drake ACSR - pp.create_line_from_parameters(net, from_bus=b1, to_bus=b2, length_km=1, r_ohm_per_km=0.07284, x_ohm_per_km=0.341, - c_nf_per_km=7.7827795, max_i_ka=1.0, type='ol') + create_line_from_parameters(net, from_bus=b1, to_bus=b2, length_km=1, r_ohm_per_km=0.07284, x_ohm_per_km=0.341, + c_nf_per_km=7.7827795, max_i_ka=1.0, type='ol') # Initial standard Value net.line['max_loading_percent'] = 100 # Chose the load to match nominal current p_ac = 380 * 1.0 * np.sqrt(3) # Q=0 - pp.create_load(net, b2, p_mw=p_ac, q_mvar=0, name="load_b8", const_i_percent=100) + create_load(net, b2, p_mw=p_ac, q_mvar=0, name="load_b8", const_i_percent=100) - pp.create_ext_grid(net, b1, vm_pu=1, va_degree=0, s_sc_max_mva=20 * 110 * np.sqrt(3), rx_max=0.1) + create_ext_grid(net, b1, vm_pu=1, va_degree=0, s_sc_max_mva=20 * 110 * np.sqrt(3), rx_max=0.1) # Defining Overhead-Lines ol_index = net.line.loc[net.line.type == "ol"].index.values @@ -477,7 +479,7 @@ def test_IEEE_example_2(): net.line.loc[ol_index, 'emissivity'] = 0.5 # Starting Control Loop - pp.runpp(net, tdpf=True, init="dc") + runpp(net, tdpf=True, init="dc") # calculating current max_cond_temp = 100.7 @@ -490,23 +492,23 @@ def test_IEEE_example_2(): # Relationship of Bare Overhead Conductors", Annex B, Numerical example 2, Page 45 def test_IEEE_example_3(): # 60Hz according to USA - net = pp.create_empty_network(f_hz=60.0) + net = create_empty_network(f_hz=60.0) - b1 = pp.create_bus(net, vn_kv=380, name='b1_hv', type='n') - b2 = pp.create_bus(net, vn_kv=380, name='b10', type='n') + b1 = create_bus(net, vn_kv=380, name='b1_hv', type='n') + b2 = create_bus(net, vn_kv=380, name='b10', type='n') # 400 MM2 26/7 Drake ACSR - pp.create_line_from_parameters(net, from_bus=b1, to_bus=b2, length_km=1, r_ohm_per_km=0.07284, x_ohm_per_km=0.341, - c_nf_per_km=7.7827795, max_i_ka=1.003, type='ol') + create_line_from_parameters(net, from_bus=b1, to_bus=b2, length_km=1, r_ohm_per_km=0.07284, x_ohm_per_km=0.341, + c_nf_per_km=7.7827795, max_i_ka=1.003, type='ol') # Initial standard Value net.line['max_loading_percent'] = 100 # Chose the load to match nominal current p_ac = 380 * 1.003 * np.sqrt(3) # Q=0 - pp.create_load(net, b2, p_mw=p_ac, q_mvar=0, name="load_b8", const_i_percent=100) + create_load(net, b2, p_mw=p_ac, q_mvar=0, name="load_b8", const_i_percent=100) - pp.create_ext_grid(net, b1, vm_pu=1, va_degree=0, s_sc_max_mva=20 * 110 * np.sqrt(3), rx_max=0.1) + create_ext_grid(net, b1, vm_pu=1, va_degree=0, s_sc_max_mva=20 * 110 * np.sqrt(3), rx_max=0.1) # Defining Overhead-Lines ol_index = net.line.loc[net.line.type == "ol"].index.values @@ -525,7 +527,7 @@ def test_IEEE_example_3(): net.line.loc[ol_index, 'emissivity'] = 0.5 # Starting Control Loop - pp.runpp(net, tdpf=True, init="dc") + runpp(net, tdpf=True, init="dc") # calculating current max_cond_temp = 101.1 @@ -540,7 +542,7 @@ def test_EN_standard(en_net): more than 0.1 below absorptivity, this combination can be considered safe for thermal rating calculations without field measurements. """ - pp.runpp(en_net, tdpf=True) + runpp(en_net, tdpf=True) max_cond_temp = 80 diff --git a/pandapower/test/networks/test_cigre_networks.py b/pandapower/test/networks/test_cigre_networks.py index ebbea5581..9ae03ee42 100644 --- a/pandapower/test/networks/test_cigre_networks.py +++ b/pandapower/test/networks/test_cigre_networks.py @@ -7,13 +7,13 @@ import pandas as pd import pytest -import pandapower as pp -import pandapower.networks as pn +from pandapower.networks.cigre_networks import create_cigre_network_hv, create_cigre_network_mv, create_cigre_network_lv +from pandapower.run import runpp def test_cigre_hv(): - net = pn.create_cigre_network_hv() # length_km_6a_6b=0.1 - pp.runpp(net) + net = create_cigre_network_hv() # length_km_6a_6b=0.1 + runpp(net) all_vn_kv = pd.Series([22, 220, 380]) assert net.bus.vn_kv.isin(all_vn_kv).all() @@ -29,13 +29,13 @@ def test_cigre_hv(): assert len(net.ext_grid) == 1 assert net.converged - net = pn.create_cigre_network_hv(length_km_6a_6b=80) + net = create_cigre_network_hv(length_km_6a_6b=80) assert net.line.length_km[8] == 80 def test_cigre_mv(): - net = pn.create_cigre_network_mv() # with_der=False - pp.runpp(net) + net = create_cigre_network_mv() # with_der=False + runpp(net) all_vn_kv = pd.Series([110, 20]) assert net.bus.vn_kv.isin(all_vn_kv).all() @@ -50,8 +50,8 @@ def test_cigre_mv(): assert len(net.switch) == 8 assert net.converged - net = pn.create_cigre_network_mv(with_der="pv_wind") - pp.runpp(net) + net = create_cigre_network_mv(with_der="pv_wind") + runpp(net) all_vn_kv = pd.Series([110, 20]) assert net.bus.vn_kv.isin(all_vn_kv).all() @@ -66,8 +66,8 @@ def test_cigre_mv(): assert len(net.switch) == 8 assert net.converged - net = pn.create_cigre_network_mv(with_der="all") - pp.runpp(net) + net = create_cigre_network_mv(with_der="all") + runpp(net) all_vn_kv = pd.Series([110, 20]) assert net.bus.vn_kv.isin(all_vn_kv).all() @@ -85,8 +85,8 @@ def test_cigre_mv(): def test_cigre_lv(): - net = pn.create_cigre_network_lv() - pp.runpp(net) + net = create_cigre_network_lv() + runpp(net) all_vn_kv = pd.Series([20, 0.4]) assert net.bus.vn_kv.isin(all_vn_kv).all() @@ -101,5 +101,6 @@ def test_cigre_lv(): assert len(net.switch) == 3 assert net.converged + if __name__ == '__main__': pytest.main([__file__, "-xs"]) diff --git a/pandapower/test/networks/test_create_example.py b/pandapower/test/networks/test_create_example.py index 780065147..7af100b01 100644 --- a/pandapower/test/networks/test_create_example.py +++ b/pandapower/test/networks/test_create_example.py @@ -7,13 +7,13 @@ import pandas as pd import pytest -import pandapower as pp -import pandapower.networks as pn +from pandapower.networks.create_examples import example_simple, example_multivoltage +from pandapower.run import runpp def test_create_simple(): - net = pn.example_simple() - pp.runpp(net) + net = example_simple() + runpp(net) assert net.converged for element in ["bus", "line", "gen", "sgen", "shunt", "trafo", "load", "ext_grid"]: assert len(net[element]) >= 1 @@ -22,8 +22,8 @@ def test_create_simple(): def test_create_realistic(): - net = pn.example_multivoltage() - pp.runpp(net) + net = example_multivoltage() + runpp(net) assert net.converged for element in ["bus", "line", "gen", "sgen", "shunt", "trafo", "trafo3w", "load", "ext_grid", "impedance", "xward"]: diff --git a/pandapower/test/networks/test_dickert_lv_networks.py b/pandapower/test/networks/test_dickert_lv_networks.py index a728ec5d8..17a4d8162 100644 --- a/pandapower/test/networks/test_dickert_lv_networks.py +++ b/pandapower/test/networks/test_dickert_lv_networks.py @@ -6,33 +6,34 @@ import pytest -import pandapower as pp -import pandapower.networks as pn +from pandapower.networks.dickert_lv_networks import create_dickert_lv_network +from pandapower.run import runpp + @pytest.mark.slow def test_dickert_lv_networks(): net_data = [('short', 'cable', 'single', 'good', 1), ('short', 'cable', 'single', 'average', 1), ('short', 'cable', 'single', 'bad', 2), - ('short', 'cable', 'multiple', 'good', 2*3), - ('short', 'cable', 'multiple', 'average', 2*6), - ('short', 'cable', 'multiple', 'bad', 2*10), - ('middle', 'cable', 'multiple', 'good', 3*15), - ('middle', 'cable', 'multiple', 'average', 3*20), - ('middle', 'cable', 'multiple', 'bad', 3*25), - ('middle', 'C&OHL', 'multiple', 'good', 3*10), - ('middle', 'C&OHL', 'multiple', 'average', 3*13), - ('middle', 'C&OHL', 'multiple', 'bad', 3*16), - ('long', 'cable', 'multiple', 'good', 3*30), - ('long', 'cable', 'multiple', 'average', 3*40), - ('long', 'cable', 'multiple', 'bad', 3*50), - ('long', 'C&OHL', 'multiple', 'good', 3*20), - ('long', 'C&OHL', 'multiple', 'average', 3*30), - ('long', 'C&OHL', 'multiple', 'bad', 3*40)] + ('short', 'cable', 'multiple', 'good', 2 * 3), + ('short', 'cable', 'multiple', 'average', 2 * 6), + ('short', 'cable', 'multiple', 'bad', 2 * 10), + ('middle', 'cable', 'multiple', 'good', 3 * 15), + ('middle', 'cable', 'multiple', 'average', 3 * 20), + ('middle', 'cable', 'multiple', 'bad', 3 * 25), + ('middle', 'C&OHL', 'multiple', 'good', 3 * 10), + ('middle', 'C&OHL', 'multiple', 'average', 3 * 13), + ('middle', 'C&OHL', 'multiple', 'bad', 3 * 16), + ('long', 'cable', 'multiple', 'good', 3 * 30), + ('long', 'cable', 'multiple', 'average', 3 * 40), + ('long', 'cable', 'multiple', 'bad', 3 * 50), + ('long', 'C&OHL', 'multiple', 'good', 3 * 20), + ('long', 'C&OHL', 'multiple', 'average', 3 * 30), + ('long', 'C&OHL', 'multiple', 'bad', 3 * 40)] for i in net_data: - net = pn.create_dickert_lv_network(i[0], i[1], i[2], i[3]) + net = create_dickert_lv_network(i[0], i[1], i[2], i[3]) assert net.bus.shape[0] == i[4] + 2 - pp.runpp(net) + runpp(net) assert net.converged diff --git a/pandapower/test/networks/test_kerber_extreme_networks.py b/pandapower/test/networks/test_kerber_extreme_networks.py index c12dd0b4d..8e36d38f3 100644 --- a/pandapower/test/networks/test_kerber_extreme_networks.py +++ b/pandapower/test/networks/test_kerber_extreme_networks.py @@ -6,128 +6,129 @@ import pytest -import pandapower as pp -import pandapower.networks as pn +from pandapower.networks.kerber_extreme_networks import * +from pandapower.run import runpp def test_kb_extrem_landnetz_freileitung(): - pd_net = pn.kb_extrem_landnetz_freileitung(p_load_mw=0.002, q_load_mvar=0.001) + pd_net = kb_extrem_landnetz_freileitung(p_load_mw=0.002, q_load_mvar=0.001) assert abs(pd_net.line.length_km.sum() - 0.312) < 0.00000001 assert abs(pd_net.load.p_mw.sum() - 0.052) < 0.00000001 assert abs(pd_net.load.q_mvar.sum() - 0.026) < 0.00000001 assert len(pd_net.bus.index) == 28 assert len(pd_net.line.index) == 26 assert len(pd_net.trafo.index) == 1 - pp.runpp(pd_net) + runpp(pd_net) assert pd_net.converged def test_kb_extrem_landnetz_kabel(): - pd_net = pn.kb_extrem_landnetz_kabel(p_load_mw=0.002, q_load_mvar=0.001) + pd_net = kb_extrem_landnetz_kabel(p_load_mw=0.002, q_load_mvar=0.001) assert abs(pd_net.line.length_km.sum() - 1.339) < 0.00000001 assert abs(pd_net.load.p_mw.sum() - 0.052) < 0.00000001 assert abs(pd_net.load.q_mvar.sum() - 0.026) < 0.00000001 assert len(pd_net.bus.index) == 54 assert len(pd_net.line.index) == 52 assert len(pd_net.trafo.index) == 1 - pp.runpp(pd_net) + runpp(pd_net) assert pd_net.converged def test_kb_extrem_landnetz_freileitung_trafo(): - pd_net = pn.kb_extrem_landnetz_freileitung_trafo(p_load_mw=0.002, q_load_mvar=0.001) + pd_net = kb_extrem_landnetz_freileitung_trafo(p_load_mw=0.002, q_load_mvar=0.001) assert abs(pd_net.line.length_km.sum() - 0.348) < 0.00000001 assert abs(pd_net.load.p_mw.sum() - 0.054) < 0.00000001 assert abs(pd_net.load.q_mvar.sum() - 0.027) < 0.00000001 assert len(pd_net.bus.index) == 29 assert len(pd_net.line.index) == 27 assert len(pd_net.trafo.index) == 1 - pp.runpp(pd_net) + runpp(pd_net) assert pd_net.converged def test_kb_extrem_landnetz_kabel_trafo(): - pd_net = pn.kb_extrem_landnetz_kabel_trafo(p_load_mw=0.002, q_load_mvar=.001) + pd_net = kb_extrem_landnetz_kabel_trafo(p_load_mw=0.002, q_load_mvar=.001) assert abs(pd_net.line.length_km.sum() - 1.435) < 0.00000001 assert abs(pd_net.load.p_mw.sum() - 0.054) < 0.00000001 assert abs(pd_net.load.q_mvar.sum() - 0.027) < 0.00000001 assert len(pd_net.bus.index) == 56 assert len(pd_net.line.index) == 54 assert len(pd_net.trafo.index) == 1 - pp.runpp(pd_net) + runpp(pd_net) assert pd_net.converged def test_kb_extrem_dorfnetz(): - pd_net = pn.kb_extrem_dorfnetz(p_load_mw=.002, q_load_mvar=.001) + pd_net = kb_extrem_dorfnetz(p_load_mw=.002, q_load_mvar=.001) assert abs(pd_net.line.length_km.sum() - 3.088) < 0.00000001 assert abs(pd_net.load.p_mw.sum() - .116) < 0.00000001 assert abs(pd_net.load.q_mvar.sum() - 0.058) < 0.00000001 assert len(pd_net.bus.index) == 118 assert len(pd_net.line.index) == 116 assert len(pd_net.trafo.index) == 1 - pp.runpp(pd_net) + runpp(pd_net) assert pd_net.converged def test_kb_extrem_dorfnetz_trafo(): - pd_net = pn.kb_extrem_dorfnetz_trafo(p_load_mw=0.002, q_load_mvar=0.001) + pd_net = kb_extrem_dorfnetz_trafo(p_load_mw=0.002, q_load_mvar=0.001) assert abs(pd_net.line.length_km.sum() - 6.094) < 0.00000001 assert abs(pd_net.load.p_mw.sum() - .234) < 0.00000001 assert abs(pd_net.load.q_mvar.sum() - .117) < 0.00000001 assert len(pd_net.bus.index) == 236 assert len(pd_net.line.index) == 234 assert len(pd_net.trafo.index) == 1 - pp.runpp(pd_net) + runpp(pd_net) assert pd_net.converged def test_kb_extrem_vorstadtnetz_1(): - pd_net = pn.kb_extrem_vorstadtnetz_1(p_load_mw=.002, q_load_mvar=0.001) + pd_net = kb_extrem_vorstadtnetz_1(p_load_mw=.002, q_load_mvar=0.001) assert abs(pd_net.line.length_km.sum() - 3.296) < 0.00000001 assert abs(pd_net.load.p_mw.sum() - 0.290) < 0.00000001 assert abs(pd_net.load.q_mvar.sum() - 0.145) < 0.00000001 assert len(pd_net.bus.index) == 292 assert len(pd_net.line.index) == 290 assert len(pd_net.trafo.index) == 1 - pp.runpp(pd_net) + runpp(pd_net) assert pd_net.converged def test_kb_extrem_vorstadtnetz_2(): - pd_net = pn.kb_extrem_vorstadtnetz_2(p_load_mw=.002, q_load_mvar=0.001) + pd_net = kb_extrem_vorstadtnetz_2(p_load_mw=.002, q_load_mvar=0.001) assert abs(pd_net.line.length_km.sum() - 4.019) < 0.00000001 assert abs(pd_net.load.p_mw.sum() - 0.290) < 0.00000001 assert abs(pd_net.load.q_mvar.sum() - .145) < 0.00000001 assert len(pd_net.bus.index) == 292 assert len(pd_net.line.index) == 290 assert len(pd_net.trafo.index) == 1 - pp.runpp(pd_net) + runpp(pd_net) assert pd_net.converged def test_kb_extrem_vorstadtnetz_trafo_1(): - pd_net = pn.kb_extrem_vorstadtnetz_trafo_1(p_load_mw=.002, q_load_mvar=0.001) + pd_net = kb_extrem_vorstadtnetz_trafo_1(p_load_mw=.002, q_load_mvar=0.001) assert abs(pd_net.line.length_km.sum() - 5.256) < 0.00000001 assert abs(pd_net.load.p_mw.sum() - .382) < 0.00000001 assert abs(pd_net.load.q_mvar.sum() - .191) < 0.00000001 assert len(pd_net.bus.index) == 384 assert len(pd_net.line.index) == 382 assert len(pd_net.trafo.index) == 1 - pp.runpp(pd_net) + runpp(pd_net) assert pd_net.converged def test_kb_extrem_vorstadtnetz_trafo_2(): - pd_net = pn.kb_extrem_vorstadtnetz_trafo_2(p_load_mw=.002, q_load_mvar=0.001) + pd_net = kb_extrem_vorstadtnetz_trafo_2(p_load_mw=.002, q_load_mvar=0.001) assert abs(pd_net.line.length_km.sum() - 5.329) < 0.00000001 assert abs(pd_net.load.p_mw.sum() - .384) < 0.00000001 assert abs(pd_net.load.q_mvar.sum() - .192) < 0.00000001 assert len(pd_net.bus.index) == 386 assert len(pd_net.line.index) == 384 assert len(pd_net.trafo.index) == 1 - pp.runpp(pd_net) + runpp(pd_net) assert pd_net.converged + if __name__ == '__main__': pytest.main([__file__, "-xs"]) diff --git a/pandapower/test/networks/test_kerber_networks.py b/pandapower/test/networks/test_kerber_networks.py index 88db050a1..8c2f4d16e 100644 --- a/pandapower/test/networks/test_kerber_networks.py +++ b/pandapower/test/networks/test_kerber_networks.py @@ -8,10 +8,12 @@ import pytest -import pandapower as pp -import pandapower.networks as pn +from pandapower.create import create_empty_network, create_bus from pandapower.networks.kerber_networks import _create_empty_network_with_transformer, \ - _add_lines_and_loads, _add_lines_with_branched_loads + _add_lines_and_loads, _add_lines_with_branched_loads, create_kerber_landnetz_freileitung_1, \ + create_kerber_landnetz_freileitung_2, create_kerber_dorfnetz, create_kerber_landnetz_kabel_1, \ + create_kerber_vorstadtnetz_kabel_2, create_kerber_vorstadtnetz_kabel_1, create_kerber_landnetz_kabel_2 +from pandapower.run import runpp def test_create_empty_network_with_transformer(): @@ -31,8 +33,8 @@ def test_create_empty_network_with_transformer(): def test_add_lines_and_loads(): # BUILD: - pd_net = pp.create_empty_network() - busnr1 = pp.create_bus(pd_net, name="startbus", vn_kv=.4) + pd_net = create_empty_network() + busnr1 = create_bus(pd_net, name="startbus", vn_kv=.4) n_lines_add = int(10. * rd.random() + 1) l_per_line = 0.10 * rd.random() # OPERATE: @@ -48,8 +50,8 @@ def test_add_lines_and_loads(): def test_add_lines_with_branched_loads(): # BUILD: - pd_net = pp.create_empty_network() - busnr1 = pp.create_bus(pd_net, name="startbus", vn_kv=.4) + pd_net = create_empty_network() + busnr1 = create_bus(pd_net, name="startbus", vn_kv=.4) n_lines_add = int(10. * rd.random() + 1) l_per_line = 0.10 * rd.random() l_branchout_line = 0.022 @@ -68,92 +70,92 @@ def test_add_lines_with_branched_loads(): @pytest.mark.slow def test_kerber_landnetz_freileitung_1(): - pd_net = pn.create_kerber_landnetz_freileitung_1(p_load_mw=.002, q_load_mvar=0.001) + pd_net = create_kerber_landnetz_freileitung_1(p_load_mw=.002, q_load_mvar=0.001) assert abs(pd_net.line.length_km.sum() - 0.273) < 0.00000001 assert abs(pd_net.load.p_mw.sum() - 0.026) < 0.00000001 assert abs(pd_net.load.q_mvar.sum() - 0.013) < 0.00000001 assert len(pd_net.bus.index) == 15 assert len(pd_net.line.index) == 13 assert len(pd_net.trafo.index) == 1 - pp.runpp(pd_net) + runpp(pd_net) assert pd_net.converged @pytest.mark.slow def test_kerber_landnetz_freileitung_2(): - pd_net = pn.create_kerber_landnetz_freileitung_2(p_load_mw=.002, q_load_mvar=.001) + pd_net = create_kerber_landnetz_freileitung_2(p_load_mw=.002, q_load_mvar=.001) assert abs(pd_net.line.length_km.sum() - 0.390) < 0.00000001 assert abs(pd_net.load.p_mw.sum() - 0.016) < 0.00000001 assert abs(pd_net.load.q_mvar.sum() - 0.008) < 0.00000001 assert len(pd_net.bus.index) == 10 assert len(pd_net.line.index) == 8 assert len(pd_net.trafo.index) == 1 - pp.runpp(pd_net) + runpp(pd_net) assert pd_net.converged @pytest.mark.slow def test_create_kerber_landnetz_kabel_1(): - pd_net = pn.create_kerber_landnetz_kabel_1(p_load_mw=.002, q_load_mvar=.001) + pd_net = create_kerber_landnetz_kabel_1(p_load_mw=.002, q_load_mvar=.001) assert abs(pd_net.line.length_km.sum() - 1.046) < 0.00000001 assert abs(pd_net.load.p_mw.sum() - 0.016) < 0.00000001 assert abs(pd_net.load.q_mvar.sum() - 0.008) < 0.00000001 assert len(pd_net.bus.index) == 18 assert len(pd_net.line.index) == 16 assert len(pd_net.trafo.index) == 1 - pp.runpp(pd_net) + runpp(pd_net) assert pd_net.converged @pytest.mark.slow def test_create_kerber_landnetz_kabel_2(): - pd_net = pn.create_kerber_landnetz_kabel_2(p_load_mw=.002, q_load_mvar=.001) + pd_net = create_kerber_landnetz_kabel_2(p_load_mw=.002, q_load_mvar=.001) assert abs(pd_net.line.length_km.sum() - 1.343) < 0.00000001 assert abs(pd_net.load.p_mw.sum() - 0.028) < 0.00000001 assert abs(pd_net.load.q_mvar.sum() - 0.014) < 0.00000001 assert len(pd_net.bus.index) == 30 assert len(pd_net.line.index) == 28 assert len(pd_net.trafo.index) == 1 - pp.runpp(pd_net) + runpp(pd_net) assert pd_net.converged @pytest.mark.slow def test_create_kerber_dorfnetz(): - pd_net = pn.create_kerber_dorfnetz(p_load_mw=.002, q_load_mvar=.001) + pd_net = create_kerber_dorfnetz(p_load_mw=.002, q_load_mvar=.001) assert abs(pd_net.line.length_km.sum() - 3.412) < 0.00000001 assert abs(pd_net.load.p_mw.sum() - .114) < 0.00000001 assert abs(pd_net.load.q_mvar.sum() - 0.057) < 0.00000001 assert len(pd_net.bus.index) == 116 assert len(pd_net.line.index) == 114 assert len(pd_net.trafo.index) == 1 - pp.runpp(pd_net) + runpp(pd_net) assert pd_net.converged @pytest.mark.slow def test_create_kerber_vorstadtnetz_kabel_1(): - pd_net = pn.create_kerber_vorstadtnetz_kabel_1(p_load_mw=.002, q_load_mvar=0.001) + pd_net = create_kerber_vorstadtnetz_kabel_1(p_load_mw=.002, q_load_mvar=0.001) assert abs(pd_net.line.length_km.sum() - 4.476) < 0.00000001 assert abs(pd_net.load.p_mw.sum() - .292) < 0.00000001 assert abs(pd_net.load.q_mvar.sum() - .146) < 0.00000001 assert len(pd_net.bus.index) == 294 assert len(pd_net.line.index) == 292 assert len(pd_net.trafo.index) == 1 - pp.runpp(pd_net) + runpp(pd_net) assert pd_net.converged @pytest.mark.slow def test_create_kerber_vorstadtnetz_kabel_2(): - pd_net = pn.create_kerber_vorstadtnetz_kabel_2(p_load_mw=.002, q_load_mvar=.001) + pd_net = create_kerber_vorstadtnetz_kabel_2(p_load_mw=.002, q_load_mvar=.001) assert abs(pd_net.line.length_km.sum() - 4.689) < 0.00000001 assert abs(pd_net.load.p_mw.sum() - .288) < 0.00000001 assert abs(pd_net.load.q_mvar.sum() - .144) < 0.00000001 assert len(pd_net.bus.index) == 290 assert len(pd_net.line.index) == 288 assert len(pd_net.trafo.index) == 1 - pp.runpp(pd_net) + runpp(pd_net) assert pd_net.converged diff --git a/pandapower/test/networks/test_lv_schutterwald.py b/pandapower/test/networks/test_lv_schutterwald.py index f201d037b..c3a5c503e 100644 --- a/pandapower/test/networks/test_lv_schutterwald.py +++ b/pandapower/test/networks/test_lv_schutterwald.py @@ -6,8 +6,8 @@ import pytest -import pandapower as pp -import pandapower.networks as pn +from pandapower.networks import lv_schutterwald +from pandapower.run import runpp def test_lv_schutterwald(): @@ -16,8 +16,8 @@ def test_lv_schutterwald(): for j in include_heat_pumps: for k in separation_by_sub: - net = pn.lv_schutterwald(include_heat_pumps=j) - pp.runpp(net) + net = lv_schutterwald(include_heat_pumps=j) + runpp(net) if j is False: assert len(net.load.bus) == 1506 @@ -29,7 +29,7 @@ def test_lv_schutterwald(): assert net.converged if k is True: - subnets = pn.lv_schutterwald(include_heat_pumps=j, separation_by_sub=k) + subnets = lv_schutterwald(include_heat_pumps=j, separation_by_sub=k) assert all(len(subnets[0].keys()) == len(subnet.keys()) for subnet in subnets[1:]) assert len(net.bus) == sum(len(subnet.bus) for subnet in subnets) assert all(subnet.converged for subnet in subnets) diff --git a/pandapower/test/networks/test_mv_oberrhein.py b/pandapower/test/networks/test_mv_oberrhein.py index 19c030704..a6a75dd33 100644 --- a/pandapower/test/networks/test_mv_oberrhein.py +++ b/pandapower/test/networks/test_mv_oberrhein.py @@ -6,45 +6,46 @@ import pytest -import pandapower as pp -import pandapower.networks as pn +from pandapower.networks.mv_oberrhein import mv_oberrhein +from pandapower.run import runpp def test_mv_oberrhein(): scenarios = ["load", "generation"] include_substations = [False, True] separation_by_sub = [False, True] - + for i in scenarios: for j in include_substations: for k in separation_by_sub: - net = pn.mv_oberrhein(scenario=i, include_substations=j) - pp.runpp(net) - + net = mv_oberrhein(scenario=i, include_substations=j) + runpp(net) + if i == "load": assert net.sgen.scaling.mean() < 0.2 assert net.load.scaling.mean() > 0.5 elif i == "generation": net.sgen.scaling.mean() > 0.6 net.load.scaling.mean() < 0.2 - + if j is False: assert len(net.bus) == 179 assert len(net.trafo) == 2 elif j is True: assert len(net.bus) == 320 assert len(net.trafo) == 143 - + assert len(net.line) == 181 assert len(net.switch) == 322 assert net.converged - + if k is True: - net0, net1 = pn.mv_oberrhein(scenario=i, include_substations=j, separation_by_sub=k) + net0, net1 = mv_oberrhein(scenario=i, include_substations=j, separation_by_sub=k) assert len(net1.keys()) == len(net0.keys()) == len(net.keys()) assert net1.res_ext_grid.loc[1].all() == net.res_ext_grid.loc[1].all() - assert net0.res_ext_grid.loc[0].all() == net.res_ext_grid.loc[0].all() + assert net0.res_ext_grid.loc[0].all() == net.res_ext_grid.loc[0].all() assert len(net.bus) == len(net0.bus) + len(net1.bus) + if __name__ == '__main__': pytest.main([__file__, "-xs"]) diff --git a/pandapower/test/networks/test_power_system_test_cases.py b/pandapower/test/networks/test_power_system_test_cases.py index 7eb4721b1..c1760ef54 100644 --- a/pandapower/test/networks/test_power_system_test_cases.py +++ b/pandapower/test/networks/test_power_system_test_cases.py @@ -6,12 +6,15 @@ import pytest -import pandapower as pp -import pandapower.networks as pn +from pandapower.networks.power_system_test_cases import case4gs, case5, case6ww, case9, case14, case24_ieee_rts, \ + case30, case_ieee30, case33bw, case39, case57, case89pegase, case118, case145, case_illinois200, case300, \ + case1354pegase, case1888rte, case2848rte, case2869pegase, case3120sp, case6470rte, case6495rte, case6515rte, \ + case9241pegase, GBnetwork, GBreducednetwork, iceland # missing test for case11_iwamoto +from pandapower.run import runpp def _ppc_element_test(net, n_bus=None, n_branch=None, n_gen=None, gencost=False): - pp.runpp(net, trafo_model="pi") + runpp(net, trafo_model="pi") if n_bus: assert len(net.bus) == n_bus if n_branch: @@ -27,212 +30,212 @@ def _ppc_element_test(net, n_bus=None, n_branch=None, n_gen=None, gencost=False) def test_case4gs(): - net = pn.case4gs() - pp.runpp(net) + net = case4gs() + runpp(net) assert net.converged _ppc_element_test(net, 4, 4, 2, False) def test_case5(): - net = pn.case5() - pp.runpp(net) + net = case5() + runpp(net) assert net.converged _ppc_element_test(net, 5, 6, 5, False) def test_case6ww(): - net = pn.case6ww() - pp.runpp(net) + net = case6ww() + runpp(net) assert net.converged _ppc_element_test(net, 6, 11, 3, True) def test_case9(): - net = pn.case9() - pp.runpp(net) + net = case9() + runpp(net) assert net.converged _ppc_element_test(net, 9, 9, 3, True) def test_case14(): - net = pn.case14() - pp.runpp(net) + net = case14() + runpp(net) assert net.converged _ppc_element_test(net, 14, 20, 5, True) def test_case24_ieee_rts(): - net = pn.case24_ieee_rts() - pp.runpp(net) + net = case24_ieee_rts() + runpp(net) assert net.converged _ppc_element_test(net, 24) def test_case30(): - net = pn.case30() - pp.runpp(net) + net = case30() + runpp(net) assert net.converged _ppc_element_test(net, 30, 41, 6, True) def test_case_ieee30(): - net = pn.case_ieee30() - pp.runpp(net) + net = case_ieee30() + runpp(net) assert net.converged _ppc_element_test(net, 30, 41, 6, False) def test_case33bw(): - net = pn.case33bw() - pp.runpp(net, trafo_mode="pi") + net = case33bw() + runpp(net, trafo_mode="pi") assert net.converged _ppc_element_test(net, 33, 37, 1, True) def test_case39(): - net = pn.case39() - pp.runpp(net) + net = case39() + runpp(net) assert net.converged _ppc_element_test(net, 39, 46, 10, True) def test_case57(): - net = pn.case57() - pp.runpp(net) + net = case57() + runpp(net) assert net.converged _ppc_element_test(net, 57, 80, 7, True) def test_case89pegase(): - net = pn.case89pegase() - pp.runpp(net) + net = case89pegase() + runpp(net) assert net.converged - _ppc_element_test(net, 89, 210, 12+6, 12) + _ppc_element_test(net, 89, 210, 12 + 6, 12) def test_case118(): - net = pn.case118() - pp.runpp(net) + net = case118() + runpp(net) assert net.converged _ppc_element_test(net, 118, 186, 54, True) def test_case145(): - net = pn.case145() - pp.runpp(net) + net = case145() + runpp(net) assert net.converged - _ppc_element_test(net, 145, 453, 50+9, 50) + _ppc_element_test(net, 145, 453, 50 + 9, 50) def test_case_illinois200(): - net = pn.case_illinois200() - pp.runpp(net) + net = case_illinois200() + runpp(net) assert net.converged _ppc_element_test(net, 200, 245, 49, False) def test_case300(): - net = pn.case300() - pp.runpp(net) + net = case300() + runpp(net) assert net.converged - _ppc_element_test(net, 300, 411, 69+8, 69) + _ppc_element_test(net, 300, 411, 69 + 8, 69) def test_case1354pegase(): - net = pn.case1354pegase() - pp.runpp(net) + net = case1354pegase() + runpp(net) assert net.converged - _ppc_element_test(net, 1354, 1991, 260+52, 260) + _ppc_element_test(net, 1354, 1991, 260 + 52, 260) def test_case1888rte(): - net = pn.case1888rte() - pp.runpp(net) + net = case1888rte() + runpp(net) assert net.converged _ppc_element_test(net, 1888, 2531, 354, 297) def test_case1888rte_changed_slack(): ref_bus_idx = 1233 - net = pn.case1888rte(ref_bus_idx=ref_bus_idx) - pp.runpp(net) + net = case1888rte(ref_bus_idx=ref_bus_idx) + runpp(net) assert net.converged _ppc_element_test(net, 1888, 2531, 354, 297) assert net.ext_grid.bus.at[0] == ref_bus_idx ref_bus_idx = [1233, 1854] - net = pn.case1888rte(ref_bus_idx=ref_bus_idx) - pp.runpp(net, trafo_model='pi') + net = case1888rte(ref_bus_idx=ref_bus_idx) + runpp(net, trafo_model='pi') assert list(net.ext_grid.bus.sort_values()) == ref_bus_idx assert net.converged def test_case2848rte(): - net = pn.case2848rte() - pp.runpp(net) + net = case2848rte() + runpp(net) assert net.converged _ppc_element_test(net, 2848, 3776, 670, 547) def test_case2869pegase(): - net = pn.case2869pegase() - pp.runpp(net) + net = case2869pegase() + runpp(net) assert net.converged _ppc_element_test(net, 2869, 4582, 690, 510) def test_case3120sp(): - net = pn.case3120sp() - pp.runpp(net) + net = case3120sp() + runpp(net) assert net.converged _ppc_element_test(net, 3120, 3693, 505, True) def test_case6470rte(): - net = pn.case6470rte() - pp.runpp(net) + net = case6470rte() + runpp(net) assert net.converged _ppc_element_test(net, 6470, 9005, 1578, 1330) def test_case6495rte(): - net = pn.case6495rte() - pp.runpp(net) + net = case6495rte() + runpp(net) assert net.converged _ppc_element_test(net, 6495, 9019, 1650, 1372) def test_case6515rte(): - net = pn.case6515rte() - pp.runpp(net) + net = case6515rte() + runpp(net) assert net.converged _ppc_element_test(net, 6515, 9037, 1651, 1388) def test_case9241pegase(): - net = pn.case9241pegase() - pp.runpp(net) + net = case9241pegase() + runpp(net) assert net.converged _ppc_element_test(net, 9241, 16049, 1879, 1445) def test_GBreducednetwork(): - net = pn.GBreducednetwork() - pp.runpp(net) + net = GBreducednetwork() + runpp(net) assert net.converged _ppc_element_test(net, 29, 99, 66, True) def test_GBnetwork(): - net = pn.GBnetwork() - pp.runpp(net) + net = GBnetwork() + runpp(net) assert net.converged - _ppc_element_test(net, 2224, 3207, 394+37, 394) + _ppc_element_test(net, 2224, 3207, 394 + 37, 394) def test_iceland(): - net = pn.iceland() - pp.runpp(net) + net = iceland() + runpp(net) assert net.converged _ppc_element_test(net, 189, 206, 35, True) diff --git a/pandapower/test/networks/test_simple_pandapower_test_networks.py b/pandapower/test/networks/test_simple_pandapower_test_networks.py index 75d176010..9279d6bdb 100644 --- a/pandapower/test/networks/test_simple_pandapower_test_networks.py +++ b/pandapower/test/networks/test_simple_pandapower_test_networks.py @@ -6,52 +6,53 @@ import pytest -import pandapower as pp -import pandapower.networks as pn +from pandapower.networks.simple_pandapower_test_networks import panda_four_load_branch, four_loads_with_branches_out, \ + simple_four_bus_system, simple_mv_open_ring_net +from pandapower.run import runpp def test_panda_four_load_branch(): - pd_net = pn.panda_four_load_branch() + pd_net = panda_four_load_branch() assert len(pd_net.bus) == 6 assert len(pd_net.ext_grid) == 1 assert len(pd_net.trafo) == 1 assert len(pd_net.line) == 4 assert len(pd_net.load) == 4 - pp.runpp(pd_net) + runpp(pd_net) assert pd_net.converged def test_four_loads_with_branches_out(): - pd_net = pn.four_loads_with_branches_out() + pd_net = four_loads_with_branches_out() assert len(pd_net.bus) == 10 assert len(pd_net.ext_grid) == 1 assert len(pd_net.trafo) == 1 assert len(pd_net.line) == 8 assert len(pd_net.load) == 4 - pp.runpp(pd_net) + runpp(pd_net) assert pd_net.converged def test_simple_four_bus_system(): - net = pn.simple_four_bus_system() + net = simple_four_bus_system() assert len(net.bus) == 4 assert len(net.ext_grid) == 1 assert len(net.trafo) == 1 assert len(net.line) == 2 assert len(net.sgen) == 2 assert len(net.load) == 2 - pp.runpp(net) + runpp(net) assert net.converged def test_simple_mv_open_ring_net(): - net = pn.simple_mv_open_ring_net() + net = simple_mv_open_ring_net() assert len(net.bus) == 7 assert len(net.ext_grid) == 1 assert len(net.trafo) == 1 assert len(net.line) == 6 assert len(net.load) == 5 - pp.runpp(net) + runpp(net) assert net.converged diff --git a/pandapower/test/networks/test_synthetic_voltage_control_lv_networks.py b/pandapower/test/networks/test_synthetic_voltage_control_lv_networks.py index 7c6d88d7f..cb2695df3 100644 --- a/pandapower/test/networks/test_synthetic_voltage_control_lv_networks.py +++ b/pandapower/test/networks/test_synthetic_voltage_control_lv_networks.py @@ -6,62 +6,62 @@ import pytest -import pandapower as pp -import pandapower.networks as pn +from pandapower.networks.synthetic_voltage_control_lv_networks import create_synthetic_voltage_control_lv_network +from pandapower.run import runpp def test_rural_1(): - net = pn.create_synthetic_voltage_control_lv_network('rural_1') + net = create_synthetic_voltage_control_lv_network('rural_1') assert abs(net.line.length_km.sum() - 1.616) < 1e-6 assert abs(net.load.p_mw.sum() - 77e-3) < 1e-6 assert len(net.bus.index) == 26 assert len(net.line.index) == 24 assert len(net.trafo.index) == 1 - pp.runpp(net) + runpp(net) assert net.converged def test_rural_2(): - net = pn.create_synthetic_voltage_control_lv_network('rural_2') + net = create_synthetic_voltage_control_lv_network('rural_2') assert abs(net.line.length_km.sum() - 0.567) < 1e-6 assert abs(net.load.p_mw.sum() - 64.5e-3) < 1e-6 assert len(net.bus.index) == 18 assert len(net.line.index) == 16 assert len(net.trafo.index) == 1 - pp.runpp(net) + runpp(net) assert net.converged def test_village_1(): - net = pn.create_synthetic_voltage_control_lv_network('village_1') + net = create_synthetic_voltage_control_lv_network('village_1') assert abs(net.line.length_km.sum() - 2.6) < 1e-6 assert abs(net.load.p_mw.sum() - 262.1e-3) < 1e-6 assert len(net.bus.index) == 80 assert len(net.line.index) == 78 assert len(net.trafo.index) == 1 - pp.runpp(net) + runpp(net) assert net.converged def test_village_2(): - net = pn.create_synthetic_voltage_control_lv_network('village_2') + net = create_synthetic_voltage_control_lv_network('village_2') assert abs(net.line.length_km.sum() - 1.832) < 1e-6 assert abs(net.load.p_mw.sum() - 183.6e-3) < 1e-6 assert len(net.bus.index) == 74 assert len(net.line.index) == 72 assert len(net.trafo.index) == 1 - pp.runpp(net) + runpp(net) assert net.converged def test_suburb_1(): - net = pn.create_synthetic_voltage_control_lv_network('suburb_1') + net = create_synthetic_voltage_control_lv_network('suburb_1') assert abs(net.line.length_km.sum() - 4.897) < 1e-6 assert abs(net.load.p_mw.sum() - 578.3e-3) < 1e-6 assert len(net.bus.index) == 204 assert len(net.line.index) == 202 assert len(net.trafo.index) == 1 - pp.runpp(net) + runpp(net) assert net.converged diff --git a/pandapower/test/opf/test_TNEP.py b/pandapower/test/opf/test_TNEP.py index 38bdc955b..cd1a4be04 100644 --- a/pandapower/test/opf/test_TNEP.py +++ b/pandapower/test/opf/test_TNEP.py @@ -1,10 +1,17 @@ -import pytest -import pandapower.networks as nw -from pandapower.converter.pandamodels.to_pm import init_ne_line -import pandas as pd +# -*- coding: utf-8 -*- + +# Copyright (c) 2016-2024 by University of Kassel and Fraunhofer Institute for Energy Economics +# and Energy System Technology (IEE), Kassel. All rights reserved. + import numpy as np -import pandapower as pp -from pandapower.converter import convert_pp_to_pm +import pandas as pd +import pytest + +from pandapower.converter.pandamodels.to_pm import init_ne_line, convert_pp_to_pm +from pandapower.create import create_poly_cost +from pandapower.networks.cigre_networks import create_cigre_network_mv +from pandapower.run import runpp +from pandapower.runpm import runpm_tnep try: from julia.core import UnsupportedPythonError @@ -12,17 +19,18 @@ UnsupportedPythonError = Exception try: from julia.api import Julia + Julia(compiled_modules=False) from julia import Main julia_installed = True except (ImportError, RuntimeError, UnsupportedPythonError) as e: julia_installed = False - #print(e) + # print(e) def cigre_grid(): - net = nw.create_cigre_network_mv() + net = create_cigre_network_mv() net["bus"].loc[:, "min_vm_pu"] = 0.95 net["bus"].loc[:, "max_vm_pu"] = 1.05 @@ -34,7 +42,7 @@ def cigre_grid(): def define_possible_new_lines(net): # Here the possible new lines are a copy of all the lines which are already in the grid max_idx = max(net["line"].index) - net["line"] = pd.concat([net["line"]] * 2, ignore_index=True) # duplicate + net["line"] = pd.concat([net["line"]] * 2, ignore_index=True) # duplicate # they must be set out of service in the line DataFrame (otherwise they are already "built") net["line"].loc[max_idx + 1:, "in_service"] = False # get the index of the new lines @@ -55,31 +63,31 @@ def test_pm_tnep_cigre_dc(): # add the possible new lines define_possible_new_lines(net) # check if max line loading percent is violated (should be) - pp.runpp(net) - #print("Max line loading prior to optimization:") - #print(net.res_line.loading_percent.max()) + runpp(net) + # print("Max line loading prior to optimization:") + # print(net.res_line.loading_percent.max()) assert np.any(net["res_line"].loc[:, "loading_percent"] > net["line"].loc[:, "max_loading_percent"]) # run power models tnep optimization - pp.runpm_tnep(net, pm_solver= "juniper", pm_model="DCMPPowerModel") # gurobi is a better option, but not for travis - + runpm_tnep(net, pm_solver="juniper", pm_model="DCMPPowerModel") # gurobi is a better option, but not for travis + # print the information about the newly built lines - #print("These lines are to be built:") - #print(net["res_ne_line"]) + # print("These lines are to be built:") + # print(net["res_ne_line"]) # set lines to be built in service lines_to_built = net["res_ne_line"].loc[net["res_ne_line"].loc[:, "built"], "built"].index net["line"].loc[lines_to_built, "in_service"] = True # run a power flow calculation again and check if max_loading percent is still violated - pp.runpp(net) + runpp(net) # check max line loading results assert not np.any(net["res_line"].loc[:, "loading_percent"] > net["line"].loc[:, "max_loading_percent"]) - #print("Max line loading after the optimization:") - #print(net.res_line.loading_percent.max()) + # print("Max line loading after the optimization:") + # print(net.res_line.loading_percent.max()) def define_ext_grid_limits(net): @@ -90,7 +98,7 @@ def define_ext_grid_limits(net): net["ext_grid"].loc[:, "max_q_mvar"] = 9999. # define costs for i in net.ext_grid.index: - pp.create_poly_cost(net, i, 'ext_grid', cp1_eur_per_mw=1) + create_poly_cost(net, i, 'ext_grid', cp1_eur_per_mw=1) def test_pm_tnep_cigre_only_conversion(): @@ -99,9 +107,9 @@ def test_pm_tnep_cigre_only_conversion(): # add the possible new lines define_possible_new_lines(net) # check if max line loading percent is violated (should be) - pp.runpp(net) - #print("Max line loading prior to optimization:") - #print(net.res_line.loading_percent.max()) + runpp(net) + # print("Max line loading prior to optimization:") + # print(net.res_line.loading_percent.max()) assert np.any(net["res_line"].loc[:, "loading_percent"] > net["line"].loc[:, "max_loading_percent"]) # run power models tnep optimization @@ -116,29 +124,30 @@ def test_pm_tnep_cigre_ac_S(): # add the possible new lines define_possible_new_lines(net) # check if max line loading percent is violated (should be) - pp.runpp(net) - #print("Max line loading prior to optimization:") - #print(net.res_line.loading_percent.max()) + runpp(net) + # print("Max line loading prior to optimization:") + # print(net.res_line.loading_percent.max()) assert np.any(net["res_line"].loc[:, "loading_percent"] > net["line"].loc[:, "max_loading_percent"]) # run power models tnep optimization - pp.runpm_tnep(net, pm_solver= "juniper", pm_model="ACPPowerModel", opf_flow_lim="S") # gurobi is a better option, but not for travis + runpm_tnep(net, pm_solver="juniper", pm_model="ACPPowerModel", + opf_flow_lim="S") # gurobi is a better option, but not for travis # print the information about the newly built lines - #print("These lines are to be built:") - #print(net["res_ne_line"]) + # print("These lines are to be built:") + # print(net["res_ne_line"]) # set lines to be built in service lines_to_built = net["res_ne_line"].loc[net["res_ne_line"].loc[:, "built"], "built"].index net["line"].loc[lines_to_built, "in_service"] = True # run a power flow calculation again and check if max_loading percent is still violated - pp.runpp(net) + runpp(net) # check max line loading results assert not np.any(net["res_line"].loc[:, "loading_percent"] > net["line"].loc[:, "max_loading_percent"]) - #print("Max line loading after the optimization:") - #print(net.res_line.loading_percent.max()) + # print("Max line loading after the optimization:") + # print(net.res_line.loading_percent.max()) @pytest.mark.slow @@ -150,29 +159,30 @@ def test_pm_tnep_cigre_ac_I(): # add the possible new lines define_possible_new_lines(net) # check if max line loading percent is violated (should be) - pp.runpp(net) - #print("Max line loading prior to optimization:") - #print(net.res_line.loading_percent.max()) + runpp(net) + # print("Max line loading prior to optimization:") + # print(net.res_line.loading_percent.max()) assert np.any(net["res_line"].loc[:, "loading_percent"] > net["line"].loc[:, "max_loading_percent"]) # run power models tnep optimization - pp.runpm_tnep(net, pm_solver= "juniper", pm_model="ACPPowerModel", opf_flow_lim="I") # gurobi is a better option, but not for travis + runpm_tnep(net, pm_solver="juniper", pm_model="ACPPowerModel", + opf_flow_lim="I") # gurobi is a better option, but not for travis # print the information about the newly built lines - #print("These lines are to be built:") - #print(net["res_ne_line"]) + # print("These lines are to be built:") + # print(net["res_ne_line"]) # set lines to be built in service lines_to_built = net["res_ne_line"].loc[net["res_ne_line"].loc[:, "built"], "built"].index net["line"].loc[lines_to_built, "in_service"] = True # run a power flow calculation again and check if max_loading percent is still violated - pp.runpp(net) + runpp(net) # check max line loading results assert not np.any(net["res_line"].loc[:, "loading_percent"] > net["line"].loc[:, "max_loading_percent"]) - #print("Max line loading after the optimization:") - #print(net.res_line.loading_percent.max()) + # print("Max line loading after the optimization:") + # print(net.res_line.loading_percent.max()) if __name__ == '__main__': diff --git a/pandapower/test/opf/test_basic.py b/pandapower/test/opf/test_basic.py index ec63d061e..a80acaa85 100644 --- a/pandapower/test/opf/test_basic.py +++ b/pandapower/test/opf/test_basic.py @@ -7,9 +7,13 @@ import numpy as np import pytest -import pandapower as pp +from pandapower.auxiliary import OPFNotConverged from pandapower.convert_format import convert_format +from pandapower.create import create_empty_network, create_bus, create_gen, create_ext_grid, create_load, \ + create_poly_cost, create_line_from_parameters, create_transformer3w_from_parameters, create_line, create_sgen, \ + create_transformer_from_parameters, create_transformer3w, create_pwl_cost, create_storage from pandapower.networks import simple_four_bus_system +from pandapower.run import runopp, rundcopp, runpp from pandapower.test.helper_functions import add_grid_connection try: @@ -26,73 +30,73 @@ def simplest_grid(): vm_min = 0.95 # create net - net = pp.create_empty_network() - pp.create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=10.) - pp.create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=.4) - pp.create_gen(net, 1, p_mw=0.1, controllable=True, min_p_mw=0.005, max_p_mw=0.15, - max_q_mvar=0.005, min_q_mvar=-0.005) - pp.create_ext_grid(net, 0) - pp.create_load(net, 1, p_mw=0.02, controllable=False) - pp.create_line_from_parameters(net, 0, 1, 50, name="line2", r_ohm_per_km=0.876, - c_nf_per_km=260.0, max_i_ka=0.123, x_ohm_per_km=0.1159876, - max_loading_percent=100) - pp.create_poly_cost(net, 0, "gen", cp1_eur_per_mw=0.1) + net = create_empty_network() + create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=10.) + create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=.4) + create_gen(net, 1, p_mw=0.1, controllable=True, min_p_mw=0.005, max_p_mw=0.15, + max_q_mvar=0.005, min_q_mvar=-0.005) + create_ext_grid(net, 0) + create_load(net, 1, p_mw=0.02, controllable=False) + create_line_from_parameters(net, 0, 1, 50, name="line2", r_ohm_per_km=0.876, + c_nf_per_km=260.0, max_i_ka=0.123, x_ohm_per_km=0.1159876, + max_loading_percent=100) + create_poly_cost(net, 0, "gen", cp1_eur_per_mw=0.1) return net @pytest.fixture def net_3w_trafo_opf(): - net = pp.create_empty_network() + net = create_empty_network() # create buses - bus1 = pp.create_bus(net, vn_kv=220.) - bus2 = pp.create_bus(net, vn_kv=110.) - bus3 = pp.create_bus(net, vn_kv=110.) - bus4 = pp.create_bus(net, vn_kv=110.) - bus5 = pp.create_bus(net, vn_kv=110.) + bus1 = create_bus(net, vn_kv=220.) + bus2 = create_bus(net, vn_kv=110.) + bus3 = create_bus(net, vn_kv=110.) + bus4 = create_bus(net, vn_kv=110.) + bus5 = create_bus(net, vn_kv=110.) - pp.create_bus(net, vn_kv=110., in_service=False) + create_bus(net, vn_kv=110., in_service=False) # create 220/110 kV transformer - pp.create_transformer3w_from_parameters(net, bus1, bus2, bus5, vn_hv_kv=220, vn_mv_kv=110, - vn_lv_kv=110, vk_hv_percent=10., vk_mv_percent=10., - vk_lv_percent=10., vkr_hv_percent=0.5, - vkr_mv_percent=0.5, vkr_lv_percent=0.5, pfe_kw=100, - i0_percent=0.1, shift_mv_degree=0, shift_lv_degree=0, - sn_hv_mva=100, sn_mv_mva=50, sn_lv_mva=50) + create_transformer3w_from_parameters(net, bus1, bus2, bus5, vn_hv_kv=220, vn_mv_kv=110, + vn_lv_kv=110, vk_hv_percent=10., vk_mv_percent=10., + vk_lv_percent=10., vkr_hv_percent=0.5, + vkr_mv_percent=0.5, vkr_lv_percent=0.5, pfe_kw=100, + i0_percent=0.1, shift_mv_degree=0, shift_lv_degree=0, + sn_hv_mva=100, sn_mv_mva=50, sn_lv_mva=50) # create 110 kV lines - pp.create_line(net, bus2, bus3, length_km=70., std_type='149-AL1/24-ST1A 110.0') - pp.create_line(net, bus3, bus4, length_km=50., std_type='149-AL1/24-ST1A 110.0') - pp.create_line(net, bus4, bus2, length_km=40., std_type='149-AL1/24-ST1A 110.0') - pp.create_line(net, bus4, bus5, length_km=30., std_type='149-AL1/24-ST1A 110.0') + create_line(net, bus2, bus3, length_km=70., std_type='149-AL1/24-ST1A 110.0') + create_line(net, bus3, bus4, length_km=50., std_type='149-AL1/24-ST1A 110.0') + create_line(net, bus4, bus2, length_km=40., std_type='149-AL1/24-ST1A 110.0') + create_line(net, bus4, bus5, length_km=30., std_type='149-AL1/24-ST1A 110.0') # create loads - pp.create_load(net, bus2, p_mw=60, controllable=False) - pp.create_load(net, bus3, p_mw=70, controllable=False) - pp.create_sgen(net, bus3, p_mw=10, controllable=False) + create_load(net, bus2, p_mw=60, controllable=False) + create_load(net, bus3, p_mw=70, controllable=False) + create_sgen(net, bus3, p_mw=10, controllable=False) # create generators - pp.create_ext_grid(net, bus1, min_p_mw=0, max_p_mw=1000, max_q_mvar=0.01, min_q_mvar=0) - pp.create_gen(net, bus3, p_mw=80, min_p_mw=0, max_p_mw=80, vm_pu=1.01) - pp.create_gen(net, bus4, p_mw=80, min_p_mw=0, max_p_mw=80, vm_pu=1.01) + create_ext_grid(net, bus1, min_p_mw=0, max_p_mw=1000, max_q_mvar=0.01, min_q_mvar=0) + create_gen(net, bus3, p_mw=80, min_p_mw=0, max_p_mw=80, vm_pu=1.01) + create_gen(net, bus4, p_mw=80, min_p_mw=0, max_p_mw=80, vm_pu=1.01) net.gen["controllable"] = False return net @pytest.fixture def simple_opf_test_net(): - net = pp.create_empty_network() - pp.create_bus(net, vn_kv=10.) - pp.create_bus(net, vn_kv=.4) - pp.create_gen(net, 1, p_mw=0.1, controllable=True, min_p_mw=0.005, max_p_mw=0.15, - max_q_mvar=0.05, min_q_mvar=-.005) - pp.create_ext_grid(net, 0) - pp.create_load(net, 1, p_mw=0.020, controllable=False) - pp.create_line_from_parameters(net, 0, 1, 50, name="line2", r_ohm_per_km=0.876, - c_nf_per_km=260.0, max_i_ka=0.123, x_ohm_per_km=0.1159876, - max_loading_percent=100) + net = create_empty_network() + create_bus(net, vn_kv=10.) + create_bus(net, vn_kv=.4) + create_gen(net, 1, p_mw=0.1, controllable=True, min_p_mw=0.005, max_p_mw=0.15, + max_q_mvar=0.05, min_q_mvar=-.005) + create_ext_grid(net, 0) + create_load(net, 1, p_mw=0.020, controllable=False) + create_line_from_parameters(net, 0, 1, 50, name="line2", r_ohm_per_km=0.876, + c_nf_per_km=260.0, max_i_ka=0.123, x_ohm_per_km=0.1159876, + max_loading_percent=100) return net @@ -105,22 +109,22 @@ def test_convert_format(): vm_min = 0.95 # create net - net = pp.create_empty_network() - pp.create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=10.) - pp.create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=.4) - pp.create_gen(net, 1, p_mw=0.1, controllable=True, min_p_mw=0.005, max_p_mw=0.15, - max_q_mvar=0.05, min_q_mvar=-0.005) + net = create_empty_network() + create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=10.) + create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=.4) + create_gen(net, 1, p_mw=0.1, controllable=True, min_p_mw=0.005, max_p_mw=0.15, + max_q_mvar=0.05, min_q_mvar=-0.005) net.gen["cost_per_mw"] = 100 - pp.create_ext_grid(net, 0) - pp.create_load(net, 1, p_mw=0.02, controllable=False) - pp.create_line_from_parameters(net, 0, 1, 50, name="line2", r_ohm_per_km=0.876, - c_nf_per_km=260.0, max_i_ka=0.123, x_ohm_per_km=0.1159876, - max_loading_percent=100 * 690) + create_ext_grid(net, 0) + create_load(net, 1, p_mw=0.02, controllable=False) + create_line_from_parameters(net, 0, 1, 50, name="line2", r_ohm_per_km=0.876, + c_nf_per_km=260.0, max_i_ka=0.123, x_ohm_per_km=0.1159876, + max_loading_percent=100 * 690) # run OPF convert_format(net) for init in ["pf", "flat"]: - pp.runopp(net, init=init) + runopp(net, init=init) assert net["OPF_converged"] # check and assert result @@ -143,7 +147,7 @@ def test_simplest_voltage(): net = simplest_grid() # run OPF for init in ["pf", "flat"]: - pp.runopp(net, init=init) + runopp(net, init=init) assert net["OPF_converged"] # check and assert result @@ -154,7 +158,7 @@ def test_simplest_voltage(): assert max(net.res_bus.vm_pu) < vm_max assert min(net.res_bus.vm_pu) > vm_min - pp.runopp(net, check_connectivity=True) + runopp(net, check_connectivity=True) assert net["OPF_converged"] # check and assert result @@ -175,19 +179,19 @@ def test_simplest_voltage(): # vm_min = 0.95 # # # create net -# net = pp.create_empty_network() -# pp.create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=10.) -# pp.create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=.4) -# pp.create_gen(net, 1, p_mw=0.1, controllable=True, min_p_mw=0.005, max_p_mw=0.150, +# net = create_empty_network() +# create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=10.) +# create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=.4) +# create_gen(net, 1, p_mw=0.1, controllable=True, min_p_mw=0.005, max_p_mw=0.150, # max_q_mvar=0.05, min_q_mvar=-0.05) -# pp.create_ext_grid(net, 0, vm_pu=1.01) -# pp.create_load(net, 1, p_mw=0.02, controllable=False) -# pp.create_line_from_parameters(net, 0, 1, 50, name="line2", r_ohm_per_km=0.876, +# create_ext_grid(net, 0, vm_pu=1.01) +# create_load(net, 1, p_mw=0.02, controllable=False) +# create_line_from_parameters(net, 0, 1, 50, name="line2", r_ohm_per_km=0.876, # c_nf_per_km=260.0, max_i_ka=0.123, x_ohm_per_km=0.1159876, # max_loading_percent=100) # # run OPF # for init in ["pf", "flat"]: -# pp.runopp(net, init=init) +# runopp(net, init=init) # assert net["OPF_converged"] # # # check and assert result @@ -207,21 +211,21 @@ def test_simplest_dispatch(): vm_min = 0.95 # create net - net = pp.create_empty_network() - pp.create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=10.) - pp.create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=.4) - pp.create_gen(net, 1, p_mw=0.1, controllable=True, min_p_mw=0.005, max_p_mw=0.150, - max_q_mvar=0.05, min_q_mvar=-0.05) - pp.create_poly_cost(net, 0, "gen", cp1_eur_per_mw=100) - pp.create_ext_grid(net, 0) - pp.create_poly_cost(net, 0, "ext_grid", cp1_eur_per_mw=101) - pp.create_load(net, 1, p_mw=0.02, controllable=False) - pp.create_line_from_parameters(net, 0, 1, 50, name="line2", r_ohm_per_km=0.876, - c_nf_per_km=260.0, max_i_ka=0.123, x_ohm_per_km=0.1159876, - max_loading_percent=100 * 690) + net = create_empty_network() + create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=10.) + create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=.4) + create_gen(net, 1, p_mw=0.1, controllable=True, min_p_mw=0.005, max_p_mw=0.150, + max_q_mvar=0.05, min_q_mvar=-0.05) + create_poly_cost(net, 0, "gen", cp1_eur_per_mw=100) + create_ext_grid(net, 0) + create_poly_cost(net, 0, "ext_grid", cp1_eur_per_mw=101) + create_load(net, 1, p_mw=0.02, controllable=False) + create_line_from_parameters(net, 0, 1, 50, name="line2", r_ohm_per_km=0.876, + c_nf_per_km=260.0, max_i_ka=0.123, x_ohm_per_km=0.1159876, + max_loading_percent=100 * 690) # run OPF for init in ["pf", "flat"]: - pp.runopp(net, cost_function="linear", init=init) + runopp(net, cost_function="linear", init=init) assert net["OPF_converged"] # check and assert result @@ -242,33 +246,33 @@ def test_opf_gen_voltage(): vm_min = 0.95 # ceate net - net = pp.create_empty_network() - pp.create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=10.) - pp.create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=.4) - pp.create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=.4) - pp.create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=.4) - pp.create_transformer_from_parameters(net, 0, 1, vk_percent=3.75, - tap_max=2, vn_lv_kv=0.4, - shift_degree=150, tap_neutral=0, - vn_hv_kv=10.0, vkr_percent=2.8125, - tap_pos=0, tap_side="hv", tap_min=-2, - tap_step_percent=2.5, i0_percent=0.68751, - sn_mva=0.016, pfe_kw=0.11, name=None, - in_service=True, index=None, max_loading_percent=200) - pp.create_gen(net, 3, p_mw=0.01, controllable=True, min_p_mw=0, max_p_mw=0.025, max_q_mvar=0.5, - min_q_mvar=-0.5) - pp.create_poly_cost(net, 0, "gen", cp1_eur_per_mw=10) - pp.create_ext_grid(net, 0) - pp.create_line_from_parameters(net, 1, 2, 1, name="line2", r_ohm_per_km=0.876, - c_nf_per_km=260.0, max_i_ka=0.123, x_ohm_per_km=0.1159876, - max_loading_percent=100000) - pp.create_line_from_parameters(net, 2, 3, 1, name="line2", r_ohm_per_km=0.876, - c_nf_per_km=260.0, max_i_ka=0.123, x_ohm_per_km=0.1159876, - max_loading_percent=100000) + net = create_empty_network() + create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=10.) + create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=.4) + create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=.4) + create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=.4) + create_transformer_from_parameters(net, 0, 1, vk_percent=3.75, + tap_max=2, vn_lv_kv=0.4, + shift_degree=150, tap_neutral=0, + vn_hv_kv=10.0, vkr_percent=2.8125, + tap_pos=0, tap_side="hv", tap_min=-2, + tap_step_percent=2.5, i0_percent=0.68751, + sn_mva=0.016, pfe_kw=0.11, name=None, + in_service=True, index=None, max_loading_percent=200) + create_gen(net, 3, p_mw=0.01, controllable=True, min_p_mw=0, max_p_mw=0.025, max_q_mvar=0.5, + min_q_mvar=-0.5) + create_poly_cost(net, 0, "gen", cp1_eur_per_mw=10) + create_ext_grid(net, 0) + create_line_from_parameters(net, 1, 2, 1, name="line2", r_ohm_per_km=0.876, + c_nf_per_km=260.0, max_i_ka=0.123, x_ohm_per_km=0.1159876, + max_loading_percent=100000) + create_line_from_parameters(net, 2, 3, 1, name="line2", r_ohm_per_km=0.876, + c_nf_per_km=260.0, max_i_ka=0.123, x_ohm_per_km=0.1159876, + max_loading_percent=100000) # run OPF for init in ["pf", "flat"]: - pp.runopp(net, init=init, calculate_voltage_angles=False) + runopp(net, init=init, calculate_voltage_angles=False) assert net["OPF_converged"] # check and assert result @@ -288,33 +292,33 @@ def test_opf_sgen_voltage(): vm_min = 0.96 # create net - net = pp.create_empty_network() - pp.create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=10.) - pp.create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=.4) - pp.create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=.4) - pp.create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=.4) - pp.create_transformer_from_parameters(net, 0, 1, vk_percent=3.75, - tap_max=2, vn_lv_kv=0.4, - shift_degree=150, tap_neutral=0, - vn_hv_kv=10.0, vkr_percent=2.8125, - tap_pos=0, tap_side="hv", tap_min=-2, - tap_step_percent=2.5, i0_percent=0.68751, - sn_mva=0.016, pfe_kw=0.11, name=None, - in_service=True, index=None, max_loading_percent=1000000) - pp.create_sgen(net, 3, p_mw=0.01, controllable=True, min_p_mw=-0.005, max_p_mw=0.015, - max_q_mvar=0.025, min_q_mvar=-0.025) - pp.create_poly_cost(net, 0, "sgen", cp1_eur_per_mw=0.1) - pp.create_ext_grid(net, 0) - pp.create_line_from_parameters(net, 1, 2, 1, name="line2", r_ohm_per_km=0.876, - c_nf_per_km=260.0, max_i_ka=0.123, x_ohm_per_km=0.1159876, - max_loading_percent=1000000) - pp.create_line_from_parameters(net, 2, 3, 1, name="line2", r_ohm_per_km=0.876, - c_nf_per_km=260.0, max_i_ka=0.123, x_ohm_per_km=0.1159876, - max_loading_percent=1000000) + net = create_empty_network() + create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=10.) + create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=.4) + create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=.4) + create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=.4) + create_transformer_from_parameters(net, 0, 1, vk_percent=3.75, + tap_max=2, vn_lv_kv=0.4, + shift_degree=150, tap_neutral=0, + vn_hv_kv=10.0, vkr_percent=2.8125, + tap_pos=0, tap_side="hv", tap_min=-2, + tap_step_percent=2.5, i0_percent=0.68751, + sn_mva=0.016, pfe_kw=0.11, name=None, + in_service=True, index=None, max_loading_percent=1000000) + create_sgen(net, 3, p_mw=0.01, controllable=True, min_p_mw=-0.005, max_p_mw=0.015, + max_q_mvar=0.025, min_q_mvar=-0.025) + create_poly_cost(net, 0, "sgen", cp1_eur_per_mw=0.1) + create_ext_grid(net, 0) + create_line_from_parameters(net, 1, 2, 1, name="line2", r_ohm_per_km=0.876, + c_nf_per_km=260.0, max_i_ka=0.123, x_ohm_per_km=0.1159876, + max_loading_percent=1000000) + create_line_from_parameters(net, 2, 3, 1, name="line2", r_ohm_per_km=0.876, + c_nf_per_km=260.0, max_i_ka=0.123, x_ohm_per_km=0.1159876, + max_loading_percent=1000000) # run OPF for init in ["pf", "flat"]: - pp.runopp(net, init=init, calculate_voltage_angles=False) + runopp(net, init=init, calculate_voltage_angles=False) assert net["OPF_converged"] # assert and check result @@ -335,36 +339,36 @@ def test_opf_gen_loading(): max_line_loading = 11 # create net - net = pp.create_empty_network() - pp.create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=10.) - pp.create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=.4) - pp.create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=.4) - pp.create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=.4) - pp.create_transformer_from_parameters(net, 0, 1, vk_percent=3.75, - tap_max=2, vn_lv_kv=0.4, - shift_degree=150, tap_neutral=0, - vn_hv_kv=10.0, vkr_percent=2.8125, - tap_pos=0, tap_side="hv", tap_min=-2, - tap_step_percent=2.5, i0_percent=0.68751, - sn_mva=0.016, pfe_kw=0.11, name=None, - in_service=True, index=None, max_loading_percent=145) - pp.create_gen(net, 3, p_mw=0.01, controllable=True, min_p_mw=0.005, max_p_mw=0.015, - max_q_mvar=0.05, min_q_mvar=-0.05) - pp.create_poly_cost(net, 0, "gen", cp1_eur_per_mw=-10) - pp.create_ext_grid(net, 0) - pp.create_poly_cost(net, 0, "ext_grid", cp1_eur_per_mw=.1) - pp.create_line_from_parameters(net, 1, 2, 1, name="line2", r_ohm_per_km=0.876, - c_nf_per_km=260.0, max_i_ka=0.123, x_ohm_per_km=0.1159876, - max_loading_percent=max_line_loading) - pp.create_line_from_parameters(net, 2, 3, 1, name="line2", r_ohm_per_km=0.876, - c_nf_per_km=260.0, max_i_ka=0.123, x_ohm_per_km=0.1159876, - max_loading_percent=max_line_loading) + net = create_empty_network() + create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=10.) + create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=.4) + create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=.4) + create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=.4) + create_transformer_from_parameters(net, 0, 1, vk_percent=3.75, + tap_max=2, vn_lv_kv=0.4, + shift_degree=150, tap_neutral=0, + vn_hv_kv=10.0, vkr_percent=2.8125, + tap_pos=0, tap_side="hv", tap_min=-2, + tap_step_percent=2.5, i0_percent=0.68751, + sn_mva=0.016, pfe_kw=0.11, name=None, + in_service=True, index=None, max_loading_percent=145) + create_gen(net, 3, p_mw=0.01, controllable=True, min_p_mw=0.005, max_p_mw=0.015, + max_q_mvar=0.05, min_q_mvar=-0.05) + create_poly_cost(net, 0, "gen", cp1_eur_per_mw=-10) + create_ext_grid(net, 0) + create_poly_cost(net, 0, "ext_grid", cp1_eur_per_mw=.1) + create_line_from_parameters(net, 1, 2, 1, name="line2", r_ohm_per_km=0.876, + c_nf_per_km=260.0, max_i_ka=0.123, x_ohm_per_km=0.1159876, + max_loading_percent=max_line_loading) + create_line_from_parameters(net, 2, 3, 1, name="line2", r_ohm_per_km=0.876, + c_nf_per_km=260.0, max_i_ka=0.123, x_ohm_per_km=0.1159876, + max_loading_percent=max_line_loading) # run OPF - pp.runopp(net, OPF_VIOLATION=1e-1, OUT_LIM_LINE=2, - PDIPM_GRADTOL=1e-10, PDIPM_COMPTOL=1e-10, PDIPM_COSTTOL=1e-10, - calculate_voltage_angles=False) + runopp(net, OPF_VIOLATION=1e-1, OUT_LIM_LINE=2, + PDIPM_GRADTOL=1e-10, PDIPM_COMPTOL=1e-10, PDIPM_COSTTOL=1e-10, + calculate_voltage_angles=False) assert net["OPF_converged"] # assert and check result @@ -389,32 +393,32 @@ def test_opf_sgen_loading(): max_line_loading = 13 # create net - net = pp.create_empty_network() - pp.create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=10.) - pp.create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=.4) - pp.create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=.4) - pp.create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=.4) - pp.create_transformer_from_parameters(net, 0, 1, vk_percent=3.75, tap_max=2, vn_lv_kv=0.4, - shift_degree=150, tap_neutral=0, vn_hv_kv=10.0, - vkr_percent=2.8125, tap_pos=0, tap_side="hv", tap_min=-2, - tap_step_percent=2.5, i0_percent=0.68751, sn_mva=0.016, - pfe_kw=0.11, name=None, in_service=True, index=None, - max_loading_percent=max_trafo_loading) - pp.create_sgen(net, 3, p_mw=0.01, controllable=True, min_p_mw=0.005, max_p_mw=.015, - max_q_mvar=0.025, min_q_mvar=-0.025) - pp.create_poly_cost(net, 0, "sgen", cp1_eur_per_mw=-10) - pp.create_ext_grid(net, 0) - pp.create_poly_cost(net, 0, "ext_grid", cp1_eur_per_mw=.1) - pp.create_line_from_parameters(net, 1, 2, 1, name="line2", r_ohm_per_km=0.876, - c_nf_per_km=260.0, max_i_ka=0.123, x_ohm_per_km=0.1159876, - max_loading_percent=max_line_loading) - pp.create_line_from_parameters(net, 2, 3, 1, name="line2", r_ohm_per_km=0.876, - c_nf_per_km=260.0, max_i_ka=0.123, x_ohm_per_km=0.1159876, - max_loading_percent=max_line_loading) + net = create_empty_network() + create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=10.) + create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=.4) + create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=.4) + create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=.4) + create_transformer_from_parameters(net, 0, 1, vk_percent=3.75, tap_max=2, vn_lv_kv=0.4, + shift_degree=150, tap_neutral=0, vn_hv_kv=10.0, + vkr_percent=2.8125, tap_pos=0, tap_side="hv", tap_min=-2, + tap_step_percent=2.5, i0_percent=0.68751, sn_mva=0.016, + pfe_kw=0.11, name=None, in_service=True, index=None, + max_loading_percent=max_trafo_loading) + create_sgen(net, 3, p_mw=0.01, controllable=True, min_p_mw=0.005, max_p_mw=.015, + max_q_mvar=0.025, min_q_mvar=-0.025) + create_poly_cost(net, 0, "sgen", cp1_eur_per_mw=-10) + create_ext_grid(net, 0) + create_poly_cost(net, 0, "ext_grid", cp1_eur_per_mw=.1) + create_line_from_parameters(net, 1, 2, 1, name="line2", r_ohm_per_km=0.876, + c_nf_per_km=260.0, max_i_ka=0.123, x_ohm_per_km=0.1159876, + max_loading_percent=max_line_loading) + create_line_from_parameters(net, 2, 3, 1, name="line2", r_ohm_per_km=0.876, + c_nf_per_km=260.0, max_i_ka=0.123, x_ohm_per_km=0.1159876, + max_loading_percent=max_line_loading) # run OPF for init in ["pf", "flat"]: - pp.runopp(net, init=init, calculate_voltage_angles=False) + runopp(net, init=init, calculate_voltage_angles=False) assert net["OPF_converged"] # assert and check result @@ -427,7 +431,7 @@ def test_opf_sgen_loading(): assert max(net.res_bus.vm_pu) < vm_max assert min(net.res_bus.vm_pu) > vm_min # check connectivity check - pp.runopp(net, check_connectivity=True, calculate_voltage_angles=False) + runopp(net, check_connectivity=True, calculate_voltage_angles=False) def test_unconstrained_line(): @@ -439,19 +443,19 @@ def test_unconstrained_line(): vm_min = 0.95 # create net - net = pp.create_empty_network() - pp.create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=10.) - pp.create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=.4) - pp.create_gen(net, 1, p_mw=0.1, controllable=True, min_p_mw=0.005, max_p_mw=0.15, - max_q_mvar=0.05, min_q_mvar=-0.05) - pp.create_ext_grid(net, 0) - pp.create_load(net, 1, p_mw=0.02, controllable=False) - pp.create_line_from_parameters(net, 0, 1, 50, name="line2", r_ohm_per_km=0.876, - c_nf_per_km=260.0, max_i_ka=0.123, x_ohm_per_km=0.1159876) - pp.create_poly_cost(net, 0, "gen", cp1_eur_per_mw=1) + net = create_empty_network() + create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=10.) + create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=.4) + create_gen(net, 1, p_mw=0.1, controllable=True, min_p_mw=0.005, max_p_mw=0.15, + max_q_mvar=0.05, min_q_mvar=-0.05) + create_ext_grid(net, 0) + create_load(net, 1, p_mw=0.02, controllable=False) + create_line_from_parameters(net, 0, 1, 50, name="line2", r_ohm_per_km=0.876, + c_nf_per_km=260.0, max_i_ka=0.123, x_ohm_per_km=0.1159876) + create_poly_cost(net, 0, "gen", cp1_eur_per_mw=1) # run OPF for init in ["pf", "flat"]: - pp.runopp(net, init=init, calculate_voltage_angles=False) + runopp(net, init=init, calculate_voltage_angles=False) assert net["OPF_converged"] # check and assert result @@ -464,32 +468,32 @@ def test_unconstrained_line(): def test_trafo3w_loading(): - net = pp.create_empty_network() + net = create_empty_network() b1, b2, l1 = add_grid_connection(net, vn_kv=110.) - b3 = pp.create_bus(net, vn_kv=20.) - b4 = pp.create_bus(net, vn_kv=10.) - tidx = pp.create_transformer3w(net, b2, b3, b4, std_type='63/25/38 MVA 110/20/10 kV', - max_loading_percent=120) - pp.create_load(net, b3, p_mw=5, controllable=False) - load_id = pp.create_load(net, b4, p_mw=5, controllable=True, max_p_mw=50, min_p_mw=0, - min_q_mvar=-1e6, max_q_mvar=1e6) - pp.create_poly_cost(net, load_id, "load", cp1_eur_per_mw=-1000) - # pp.create_xward(net, b4, 1000, 1000, 1000, 1000, 0.1, 0.1, 1.0) + b3 = create_bus(net, vn_kv=20.) + b4 = create_bus(net, vn_kv=10.) + tidx = create_transformer3w(net, b2, b3, b4, std_type='63/25/38 MVA 110/20/10 kV', + max_loading_percent=120) + create_load(net, b3, p_mw=5, controllable=False) + load_id = create_load(net, b4, p_mw=5, controllable=True, max_p_mw=50, min_p_mw=0, + min_q_mvar=-1e6, max_q_mvar=1e6) + create_poly_cost(net, load_id, "load", cp1_eur_per_mw=-1000) + # create_xward(net, b4, 1000, 1000, 1000, 1000, 0.1, 0.1, 1.0) net.trafo3w.at[tidx, "shift_lv_degree"] = 120 net.trafo3w.at[tidx, "shift_mv_degree"] = 80 - # pp.runopp(net, calculate_voltage_angles = True) >> Doesn't converge + # runopp(net, calculate_voltage_angles = True) >> Doesn't converge for init in ["pf", "flat"]: - pp.runopp(net, calculate_voltage_angles=False, init=init) + runopp(net, calculate_voltage_angles=False, init=init) assert net["OPF_converged"] assert abs(net.res_trafo3w.loading_percent.values - 120) < 1e-3 def test_dcopf_poly(simple_opf_test_net): net = simple_opf_test_net - pp.create_poly_cost(net, 0, "gen", cp1_eur_per_mw=100) + create_poly_cost(net, 0, "gen", cp1_eur_per_mw=100) # run OPF - pp.rundcopp(net) + rundcopp(net) # check and assert result logger.debug("test_simplest_voltage") @@ -501,10 +505,10 @@ def test_dcopf_poly(simple_opf_test_net): def test_opf_poly(simple_opf_test_net): net = simple_opf_test_net - pp.create_poly_cost(net, 0, "gen", cp1_eur_per_mw=100) + create_poly_cost(net, 0, "gen", cp1_eur_per_mw=100) # run OPF for init in ["pf", "flat"]: - pp.runopp(net, init=init) + runopp(net, init=init) assert net["OPF_converged"] # check and assert result logger.debug("test_simplest_voltage") @@ -517,10 +521,10 @@ def test_opf_poly(simple_opf_test_net): def test_opf_pwl(simple_opf_test_net): # create net net = simple_opf_test_net - pp.create_pwl_cost(net, 0, "gen", [[0, 100, 100], [100, 200, 100]]) + create_pwl_cost(net, 0, "gen", [[0, 100, 100], [100, 200, 100]]) # run OPF for init in ["pf", "flat"]: - pp.runopp(net, init=init) + runopp(net, init=init) assert net["OPF_converged"] # check and assert result @@ -534,10 +538,10 @@ def test_opf_pwl(simple_opf_test_net): def test_dcopf_pwl(simple_opf_test_net): # create net net = simple_opf_test_net - pp.create_pwl_cost(net, 0, "gen", [[0, 100, 100], [100, 200, 100]]) - pp.create_pwl_cost(net, 0, "ext_grid", [[0, 100, 0], [100, 200, 0]]) + create_pwl_cost(net, 0, "gen", [[0, 100, 100], [100, 200, 100]]) + create_pwl_cost(net, 0, "ext_grid", [[0, 100, 0], [100, 200, 0]]) # run OPF - pp.rundcopp(net) + rundcopp(net) assert net["OPF_converged"] # check and assert result @@ -559,35 +563,35 @@ def test_opf_varying_max_line_loading(): max_line_loading = 13 # create net - net = pp.create_empty_network() - pp.create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=10.) - pp.create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=.4) - pp.create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=.4) - pp.create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=.4) - pp.create_transformer_from_parameters(net, 0, 1, vk_percent=3.75, tap_max=2, vn_lv_kv=0.4, - shift_degree=150, tap_neutral=0, vn_hv_kv=10.0, - vkr_percent=2.8125, tap_pos=0, tap_side="hv", tap_min=-2, - tap_step_percent=2.5, i0_percent=0.68751, sn_mva=0.016, - pfe_kw=0.11, name=None, in_service=True, index=None, - max_loading_percent=max_trafo_loading) - - pp.create_sgen(net, 3, p_mw=0.1, controllable=True, min_p_mw=0.005, max_p_mw=0.15, - max_q_mvar=0.025, min_q_mvar=-0.025) - pp.create_sgen(net, 2, p_mw=0.1, controllable=True, min_p_mw=0.005, max_p_mw=0.15, - max_q_mvar=0.025, min_q_mvar=-0.025) - pp.create_poly_cost(net, 0, "sgen", cp1_eur_per_mw=10) - pp.create_poly_cost(net, 1, "sgen", cp1_eur_per_mw=10) - pp.create_ext_grid(net, 0) - pp.create_poly_cost(net, 0, "ext_grid", cp1_eur_per_mw=.1) - pp.create_line_from_parameters(net, 1, 2, 1, name="line1", r_ohm_per_km=0.876, - c_nf_per_km=260.0, max_i_ka=0.200, x_ohm_per_km=0.1159876, - max_loading_percent=20) - pp.create_line_from_parameters(net, 1, 3, 1, name="line2", r_ohm_per_km=0.876, - c_nf_per_km=260.0, max_i_ka=0.100, x_ohm_per_km=0.1159876, - max_loading_percent=10) + net = create_empty_network() + create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=10.) + create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=.4) + create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=.4) + create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=.4) + create_transformer_from_parameters(net, 0, 1, vk_percent=3.75, tap_max=2, vn_lv_kv=0.4, + shift_degree=150, tap_neutral=0, vn_hv_kv=10.0, + vkr_percent=2.8125, tap_pos=0, tap_side="hv", tap_min=-2, + tap_step_percent=2.5, i0_percent=0.68751, sn_mva=0.016, + pfe_kw=0.11, name=None, in_service=True, index=None, + max_loading_percent=max_trafo_loading) + + create_sgen(net, 3, p_mw=0.1, controllable=True, min_p_mw=0.005, max_p_mw=0.15, + max_q_mvar=0.025, min_q_mvar=-0.025) + create_sgen(net, 2, p_mw=0.1, controllable=True, min_p_mw=0.005, max_p_mw=0.15, + max_q_mvar=0.025, min_q_mvar=-0.025) + create_poly_cost(net, 0, "sgen", cp1_eur_per_mw=10) + create_poly_cost(net, 1, "sgen", cp1_eur_per_mw=10) + create_ext_grid(net, 0) + create_poly_cost(net, 0, "ext_grid", cp1_eur_per_mw=.1) + create_line_from_parameters(net, 1, 2, 1, name="line1", r_ohm_per_km=0.876, + c_nf_per_km=260.0, max_i_ka=0.200, x_ohm_per_km=0.1159876, + max_loading_percent=20) + create_line_from_parameters(net, 1, 3, 1, name="line2", r_ohm_per_km=0.876, + c_nf_per_km=260.0, max_i_ka=0.100, x_ohm_per_km=0.1159876, + max_loading_percent=10) # run OPF - pp.runopp(net, init="flat", calculate_voltage_angles=False) + runopp(net, init="flat", calculate_voltage_angles=False) assert net["OPF_converged"] assert np.allclose(net["_ppc"]["branch"][:, 5], np.array([0.02771281 + 0.j, 0.00692820 + 0.j, @@ -612,35 +616,35 @@ def test_storage_opf(): max_line_loading_percent = 100 # create network - net = pp.create_empty_network() + net = create_empty_network() - b1 = pp.create_bus(net, vn_kv=0.4, max_vm_pu=vm_max, min_vm_pu=vm_min) - b2 = pp.create_bus(net, vn_kv=0.4, max_vm_pu=vm_max, min_vm_pu=vm_min) + b1 = create_bus(net, vn_kv=0.4, max_vm_pu=vm_max, min_vm_pu=vm_min) + b2 = create_bus(net, vn_kv=0.4, max_vm_pu=vm_max, min_vm_pu=vm_min) - pp.create_line(net, b1, b2, length_km=5, std_type="NAYY 4x50 SE", - max_loading_percent=max_line_loading_percent) + create_line(net, b1, b2, length_km=5, std_type="NAYY 4x50 SE", + max_loading_percent=max_line_loading_percent) # test elements static - pp.create_ext_grid(net, b2) - pp.create_load(net, b1, p_mw=0.0075, controllable=False) - pp.create_sgen(net, b1, p_mw=0.025, controllable=True, min_p_mw=0.01, max_p_mw=0.025, - max_q_mvar=0.025, min_q_mvar=-0.025) + create_ext_grid(net, b2) + create_load(net, b1, p_mw=0.0075, controllable=False) + create_sgen(net, b1, p_mw=0.025, controllable=True, min_p_mw=0.01, max_p_mw=0.025, + max_q_mvar=0.025, min_q_mvar=-0.025) # test elements - pp.create_storage(net, b1, p_mw=-.0025, max_e_mwh=50, controllable=True, max_p_mw=0, - min_p_mw=-0.025, max_q_mvar=0.025, min_q_mvar=-0.025) - pp.create_sgen(net, b1, p_mw=0.025, controllable=True, min_p_mw=0, max_p_mw=0.025, - max_q_mvar=0.025, min_q_mvar=-0.025) - pp.create_load(net, b1, p_mw=0.025, controllable=True, max_p_mw=0.025, min_p_mw=0, - max_q_mvar=0.025, min_q_mvar=-0.025) + create_storage(net, b1, p_mw=-.0025, max_e_mwh=50, controllable=True, max_p_mw=0, + min_p_mw=-0.025, max_q_mvar=0.025, min_q_mvar=-0.025) + create_sgen(net, b1, p_mw=0.025, controllable=True, min_p_mw=0, max_p_mw=0.025, + max_q_mvar=0.025, min_q_mvar=-0.025) + create_load(net, b1, p_mw=0.025, controllable=True, max_p_mw=0.025, min_p_mw=0, + max_q_mvar=0.025, min_q_mvar=-0.025) # costs - pp.create_poly_cost(net, 0, "ext_grid", cp1_eur_per_mw=3) - pp.create_poly_cost(net, 0, "sgen", cp1_eur_per_mw=2) - pp.create_poly_cost(net, 0, "storage", cp1_eur_per_mw=-1) - pp.create_poly_cost(net, 1, "sgen", cp1_eur_per_mw=1) + create_poly_cost(net, 0, "ext_grid", cp1_eur_per_mw=3) + create_poly_cost(net, 0, "sgen", cp1_eur_per_mw=2) + create_poly_cost(net, 0, "storage", cp1_eur_per_mw=-1) + create_poly_cost(net, 1, "sgen", cp1_eur_per_mw=1) - pp.create_poly_cost(net, 1, "load", cp1_eur_per_mw=-3) + create_poly_cost(net, 1, "load", cp1_eur_per_mw=-3) # test storage generator behaviour net["storage"].loc[0, 'in_service'] = True @@ -648,7 +652,7 @@ def test_storage_opf(): net["sgen"].loc[1, 'in_service'] = False net["load"].loc[1, 'in_service'] = False - pp.runopp(net) + runopp(net) assert net["OPF_converged"] res_stor_p_mw = net["res_storage"].p_mw.iloc[0] @@ -660,7 +664,7 @@ def test_storage_opf(): net["sgen"].loc[1, 'in_service'] = True net["load"].loc[1, 'in_service'] = False - pp.runopp(net) + runopp(net) assert net["OPF_converged"] res_sgen_p_mw = net["res_sgen"].p_mw.iloc[1] @@ -685,7 +689,7 @@ def test_storage_opf(): net["sgen"].loc[1, 'in_service'] = False net["load"].loc[1, 'in_service'] = False - pp.runopp(net) + runopp(net) assert net["OPF_converged"] res_stor_p_mw = net["res_storage"].p_mw.iloc[0] @@ -697,7 +701,7 @@ def test_storage_opf(): net["sgen"].loc[1, 'in_service'] = False net["load"].loc[1, 'in_service'] = True - pp.runopp(net) + runopp(net) assert net["OPF_converged"] res_load_p_mw = net["res_load"].p_mw.iloc[1] @@ -718,37 +722,37 @@ def test_in_service_controllables(): max_line_loading_percent = 100 # create network - net = pp.create_empty_network() - b1 = pp.create_bus(net, vn_kv=0.4, max_vm_pu=vm_max, min_vm_pu=vm_min) - b2 = pp.create_bus(net, vn_kv=0.4, max_vm_pu=vm_max, min_vm_pu=vm_min) + net = create_empty_network() + b1 = create_bus(net, vn_kv=0.4, max_vm_pu=vm_max, min_vm_pu=vm_min) + b2 = create_bus(net, vn_kv=0.4, max_vm_pu=vm_max, min_vm_pu=vm_min) - pp.create_line(net, b1, b2, length_km=5, std_type="NAYY 4x50 SE", - max_loading_percent=max_line_loading_percent) + create_line(net, b1, b2, length_km=5, std_type="NAYY 4x50 SE", + max_loading_percent=max_line_loading_percent) # test elements static - pp.create_ext_grid(net, b2) - pp.create_load(net, b1, p_mw=7.5, controllable=True, max_p_mw=0.010, min_p_mw=0, - max_q_mvar=2.5, min_q_mvar=-2.5) - pp.create_sgen(net, b1, p_mw=0.025, controllable=True, min_p_mw=0.01, max_p_mw=0.025, - max_q_mvar=0.025, min_q_mvar=-0.025) + create_ext_grid(net, b2) + create_load(net, b1, p_mw=7.5, controllable=True, max_p_mw=0.010, min_p_mw=0, + max_q_mvar=2.5, min_q_mvar=-2.5) + create_sgen(net, b1, p_mw=0.025, controllable=True, min_p_mw=0.01, max_p_mw=0.025, + max_q_mvar=0.025, min_q_mvar=-0.025) # test elements - pp.create_sgen(net, b1, p_mw=0.025, controllable=True, min_p_mw=0, max_p_mw=0.025, - max_q_mvar=0.025, min_q_mvar=-0.025) - pp.create_load(net, b1, p_mw=0.025, controllable=True, max_p_mw=0.0025, min_p_mw=0, - max_q_mvar=2.5, min_q_mvar=-2.5) + create_sgen(net, b1, p_mw=0.025, controllable=True, min_p_mw=0, max_p_mw=0.025, + max_q_mvar=0.025, min_q_mvar=-0.025) + create_load(net, b1, p_mw=0.025, controllable=True, max_p_mw=0.0025, min_p_mw=0, + max_q_mvar=2.5, min_q_mvar=-2.5) # costs - pp.create_poly_cost(net, 0, "ext_grid", cp1_eur_per_mw=3) - pp.create_poly_cost(net, 0, "load", cp1_eur_per_mw=-1) - pp.create_poly_cost(net, 0, "sgen", cp1_eur_per_mw=2) - pp.create_poly_cost(net, 1, "sgen", cp1_eur_per_mw=1) - pp.create_poly_cost(net, 1, "load", cp1_eur_per_mw=-1) + create_poly_cost(net, 0, "ext_grid", cp1_eur_per_mw=3) + create_poly_cost(net, 0, "load", cp1_eur_per_mw=-1) + create_poly_cost(net, 0, "sgen", cp1_eur_per_mw=2) + create_poly_cost(net, 1, "sgen", cp1_eur_per_mw=1) + create_poly_cost(net, 1, "load", cp1_eur_per_mw=-1) net["sgen"].loc[1, 'in_service'] = False net["load"].loc[1, 'in_service'] = False - pp.runopp(net) + runopp(net) assert net["OPF_converged"] @@ -756,17 +760,17 @@ def test_no_controllables(simple_opf_test_net): # was ist das problwem an diesem fall und wie fange ich es ab? net = simple_opf_test_net net.gen.controllable = False - pp.create_poly_cost(net, 0, "gen", cp1_eur_per_mw=-2) - pp.create_poly_cost(net, 0, "load", cp1_eur_per_mw=1) + create_poly_cost(net, 0, "gen", cp1_eur_per_mw=-2) + create_poly_cost(net, 0, "load", cp1_eur_per_mw=1) try: - pp.runopp(net) - except pp.OPFNotConverged: + runopp(net) + except OPFNotConverged: # opf will fail if not bus limits are set and vm_pu is the default value of 1.0 ( # it is enforced) assert True net.gen.loc[:, "vm_pu"] = 1.062 # vm_pu setpoint is mandatory if controllable=False net.gen.loc[:, "p_mw"] = 0.149 - pp.runopp(net) + runopp(net) assert np.allclose(net.res_gen.at[0, "vm_pu"], 1.062) assert np.allclose(net.res_gen.at[0, "p_mw"], 0.149) @@ -781,33 +785,33 @@ def test_opf_no_controllables_vs_pf(): max_line_loading_percent = 100 # create network - net = pp.create_empty_network() + net = create_empty_network() - b1 = pp.create_bus(net, vn_kv=0.4, max_vm_pu=vm_max, min_vm_pu=vm_min) - b2 = pp.create_bus(net, vn_kv=0.4, max_vm_pu=vm_max, min_vm_pu=vm_min) + b1 = create_bus(net, vn_kv=0.4, max_vm_pu=vm_max, min_vm_pu=vm_min) + b2 = create_bus(net, vn_kv=0.4, max_vm_pu=vm_max, min_vm_pu=vm_min) - pp.create_line(net, b1, b2, length_km=5, std_type="NAYY 4x50 SE", - max_loading_percent=max_line_loading_percent) + create_line(net, b1, b2, length_km=5, std_type="NAYY 4x50 SE", + max_loading_percent=max_line_loading_percent) # test elements static - pp.create_ext_grid(net, b2) - pp.create_load(net, b1, p_mw=.0075, controllable=False) - pp.create_sgen(net, b1, p_mw=0.025, controllable=False, min_p_mw=0.01, max_p_mw=0.025, - max_q_mvar=0.025, min_q_mvar=-0.025) + create_ext_grid(net, b2) + create_load(net, b1, p_mw=.0075, controllable=False) + create_sgen(net, b1, p_mw=0.025, controllable=False, min_p_mw=0.01, max_p_mw=0.025, + max_q_mvar=0.025, min_q_mvar=-0.025) # testing cost assignment (for non-controllable elements - see Gitlab Issue #27) - pp.create_poly_cost(net, 0, "ext_grid", cp1_eur_per_mw=3) - pp.create_poly_cost(net, 0, "load", cp1_eur_per_mw=-3) - pp.create_poly_cost(net, 0, "sgen", cp1_eur_per_mw=2) + create_poly_cost(net, 0, "ext_grid", cp1_eur_per_mw=3) + create_poly_cost(net, 0, "load", cp1_eur_per_mw=-3) + create_poly_cost(net, 0, "sgen", cp1_eur_per_mw=2) # do calculations - pp.runopp(net) + runopp(net) assert net["OPF_converged"] res_opf_line_loading = net.res_line.loading_percent res_opf_bus_voltages = net.res_bus.vm_pu - pp.runpp(net) + runpp(net) assert net["converged"] res_pf_line_loading = net.res_line.loading_percent @@ -823,7 +827,7 @@ def test_line_temperature(): r_init = net.line.r_ohm_per_km.copy() # run OPF - pp.runopp(net, verbose=False) + runopp(net, verbose=False) va_init = net.res_bus.va_degree assert "r_ohm_per_km" not in net.res_line.columns @@ -831,12 +835,12 @@ def test_line_temperature(): net.line["temperature_degree_celsius"] = 80 alpha = 4.03e-3 net.line['alpha'] = alpha - pp.runopp(net, verbose=False, consider_line_temperature=True) + runopp(net, verbose=False, consider_line_temperature=True) r_temp = r_init * (1 + alpha * (80 - 20)) assert np.allclose(net.res_line.r_ohm_per_km, r_temp, rtol=0, atol=1e-16) assert not np.allclose(net.res_bus.va_degree, va_init, rtol=0, atol=1e-2) - pp.runopp(net, verbose=False, consider_line_temperature=False) + runopp(net, verbose=False, consider_line_temperature=False) assert np.allclose(net.res_bus.va_degree, va_init, rtol=0, atol=1e-16) assert "r_ohm_per_km" not in net.res_line.columns @@ -854,12 +858,12 @@ def test_three_slacks_vm_setpoint(four_bus_net): # only one is allowed per area. The others should have vmin / vmax set as their vm_pu setpoint net = four_bus_net # create two additional slacks with different voltage setpoints - pp.create_ext_grid(net, 1, vm_pu=1.01, max_p_mw=1., min_p_mw=-1., min_q_mvar=-1, max_q_mvar=1.) - pp.create_ext_grid(net, 3, vm_pu=1.02, max_p_mw=1., min_p_mw=-1., min_q_mvar=-1, max_q_mvar=1.) - pp.runpp(net) + create_ext_grid(net, 1, vm_pu=1.01, max_p_mw=1., min_p_mw=-1., min_q_mvar=-1, max_q_mvar=1.) + create_ext_grid(net, 3, vm_pu=1.02, max_p_mw=1., min_p_mw=-1., min_q_mvar=-1, max_q_mvar=1.) + runpp(net) # assert if voltage limits are correct in result in pf an opf assert np.allclose(net.res_bus.loc[[0, 1, 3], "vm_pu"], [1., 1.01, 1.02]) - pp.runopp(net, calculate_voltage_angles=False) + runopp(net, calculate_voltage_angles=False) assert np.allclose(net.res_bus.loc[[0, 1, 3], "vm_pu"], [1., 1.01, 1.02]) @@ -871,17 +875,17 @@ def test_only_gen_slack_vm_setpoint(four_bus_net): net.bus.loc[:, "min_vm_pu"] = 0.9 net.bus.loc[:, "max_vm_pu"] = 1.1 # create two additional slacks with different voltage setpoints - pp.create_gen(net, 0, p_mw=0., vm_pu=1., max_p_mw=1., min_p_mw=-1., min_q_mvar=-1, - max_q_mvar=1., slack=True) - pp.create_gen(net, 1, p_mw=0.02, vm_pu=1.01, max_p_mw=1., min_p_mw=-1., min_q_mvar=-1, - max_q_mvar=1., controllable=False) # controllable == False -> vm_pu enforced - pp.create_gen(net, 3, p_mw=0.01, vm_pu=1.02, max_p_mw=1., min_p_mw=-1., - min_q_mvar=-1, max_q_mvar=1.) # controllable == True -> vm_pu between + create_gen(net, 0, p_mw=0., vm_pu=1., max_p_mw=1., min_p_mw=-1., min_q_mvar=-1, + max_q_mvar=1., slack=True) + create_gen(net, 1, p_mw=0.02, vm_pu=1.01, max_p_mw=1., min_p_mw=-1., min_q_mvar=-1, + max_q_mvar=1., controllable=False) # controllable == False -> vm_pu enforced + create_gen(net, 3, p_mw=0.01, vm_pu=1.02, max_p_mw=1., min_p_mw=-1., + min_q_mvar=-1, max_q_mvar=1.) # controllable == True -> vm_pu between # bus voltages - pp.runpp(net) + runpp(net) # assert if voltage limits are correct in result in pf an opf assert np.allclose(net.res_bus.loc[[0, 1, 3], "vm_pu"], [1., 1.01, 1.02]) - pp.runopp(net, calculate_voltage_angles=False) + runopp(net, calculate_voltage_angles=False) # controllable == True is more important than slack == True -> vm_pu is between bus limits assert not np.allclose(net.res_bus.at[0, "vm_pu"], 1.) @@ -905,9 +909,9 @@ def test_gen_p_vm_fixed(four_bus_net): bus = 1 # controllable == False -> limits are ignored and p_mw / vm_pu values are enforced - pp.create_gen(net, bus, p_mw=p_mw, vm_pu=vm_pu, controllable=False, - min_vm_pu=min_vm_pu, max_vm_pu=max_vm_pu, min_p_mw=min_p_mw, max_p_mw=max_p_mw) - pp.runopp(net, calculate_voltage_angles=False) + create_gen(net, bus, p_mw=p_mw, vm_pu=vm_pu, controllable=False, + min_vm_pu=min_vm_pu, max_vm_pu=max_vm_pu, min_p_mw=min_p_mw, max_p_mw=max_p_mw) + runopp(net, calculate_voltage_angles=False) assert np.allclose(net.res_bus.at[bus, "vm_pu"], vm_pu) assert np.allclose(net.res_bus.at[bus, "p_mw"], -p_mw) @@ -921,9 +925,9 @@ def test_gen_p_vm_limits(four_bus_net): min_p_mw, max_p_mw = 0., 1. bus = 1 # controllable == False -> limits are ignored and p_mw / vm_pu values are enforced - pp.create_gen(net, bus, p_mw=0.02, vm_pu=1.01, controllable=True, - min_vm_pu=min_vm_pu, max_vm_pu=max_vm_pu, min_p_mw=min_p_mw, max_p_mw=max_p_mw) - pp.runopp(net, calculate_voltage_angles=False) + create_gen(net, bus, p_mw=0.02, vm_pu=1.01, controllable=True, + min_vm_pu=min_vm_pu, max_vm_pu=max_vm_pu, min_p_mw=min_p_mw, max_p_mw=max_p_mw) + runopp(net, calculate_voltage_angles=False) assert not np.allclose(net.res_bus.at[bus, "vm_pu"], 1.01) assert not np.allclose(net.res_bus.at[bus, "p_mw"], 0.02) assert min_vm_pu < net.res_bus.at[bus, "vm_pu"] < max_vm_pu @@ -940,15 +944,15 @@ def test_gen_violated_p_vm_limits(four_bus_net): min_p_mw, max_p_mw = 0., 1. bus = 1 # controllable == False -> limits are ignored and p_mw / vm_pu values are enforced - g = pp.create_gen(net, bus, p_mw=0.02, vm_pu=1.01, controllable=True, - min_vm_pu=.9, max_vm_pu=1.1, min_p_mw=min_p_mw, max_p_mw=max_p_mw) - pp.runopp(net, calculate_voltage_angles=False) + g = create_gen(net, bus, p_mw=0.02, vm_pu=1.01, controllable=True, + min_vm_pu=.9, max_vm_pu=1.1, min_p_mw=min_p_mw, max_p_mw=max_p_mw) + runopp(net, calculate_voltage_angles=False) assert not np.allclose(net.res_bus.at[bus, "vm_pu"], 1.01) assert not np.allclose(net.res_bus.at[bus, "p_mw"], 0.02) assert min_vm_pu < net.res_bus.at[bus, "vm_pu"] < max_vm_pu assert min_p_mw <= -net.res_bus.at[bus, "p_mw"] < max_p_mw net.gen.at[g, "vm_pu"] = 0.9 # lower bus vm_pu limit violation - pp.runopp(net, calculate_voltage_angles=False) + runopp(net, calculate_voltage_angles=False) assert min_vm_pu < net.res_bus.at[bus, "vm_pu"] < max_vm_pu diff --git a/pandapower/test/opf/test_check_opf_data.py b/pandapower/test/opf/test_check_opf_data.py index 07d48585b..1bf5de5da 100644 --- a/pandapower/test/opf/test_check_opf_data.py +++ b/pandapower/test/opf/test_check_opf_data.py @@ -1,8 +1,10 @@ -from numpy import nan import pytest +from numpy import nan -import pandapower as pp +from pandapower.create import create_bus, create_empty_network, create_buses, create_transformer, create_line, \ + create_ext_grid, create_dcline, create_load, create_gen, create_sgen from pandapower.opf.validate_opf_input import _check_necessary_opf_parameters + try: import pandaplan.core.pplog as logging except ImportError: @@ -12,20 +14,20 @@ def _opf_net(): - net = pp.create_empty_network() - pp.create_bus(net, 20, min_vm_pu=0.85, max_vm_pu=1.15) - pp.create_buses(net, 3, 0.4, min_vm_pu=0.85, max_vm_pu=1.15) - pp.create_transformer(net, 0, 1, "0.25 MVA 20/0.4 kV") - pp.create_line(net, 1, 2, 1, "48-AL1/8-ST1A 0.4") - pp.create_ext_grid(net, 0) - pp.create_dcline(net, 1, 3, -5, 1, 1, 1, 1.02, max_p_mw=0.01, min_q_from_mvar=-.005, - min_q_to_mvar=-0.005, max_q_from_mvar=.005, max_q_to_mvar=.005) - pp.create_load(net, bus=2, p_mw=0.015, controllable=True, max_p_mw=0.025, min_p_mw=0, - max_q_mvar=0.005, min_q_mvar=-0.005) - pp.create_gen(net, bus=1, p_mw=0.002, vm_pu=1.002, controllable=True, max_p_mw=0, min_p_mw=-0.025, - max_q_mvar=0.025, min_q_mvar=-0.025) - pp.create_sgen(net, bus=2, p_mw=0.001, controllable=True, max_p_mw=0.003, min_p_mw=0, - max_q_mvar=.001, min_q_mvar=-.001) + net = create_empty_network() + create_bus(net, 20, min_vm_pu=0.85, max_vm_pu=1.15) + create_buses(net, 3, 0.4, min_vm_pu=0.85, max_vm_pu=1.15) + create_transformer(net, 0, 1, "0.25 MVA 20/0.4 kV") + create_line(net, 1, 2, 1, "48-AL1/8-ST1A 0.4") + create_ext_grid(net, 0) + create_dcline(net, 1, 3, -5, 1, 1, 1, 1.02, max_p_mw=0.01, min_q_from_mvar=-.005, + min_q_to_mvar=-0.005, max_q_from_mvar=.005, max_q_to_mvar=.005) + create_load(net, bus=2, p_mw=0.015, controllable=True, max_p_mw=0.025, min_p_mw=0, + max_q_mvar=0.005, min_q_mvar=-0.005) + create_gen(net, bus=1, p_mw=0.002, vm_pu=1.002, controllable=True, max_p_mw=0, min_p_mw=-0.025, + max_q_mvar=0.025, min_q_mvar=-0.025) + create_sgen(net, bus=2, p_mw=0.001, controllable=True, max_p_mw=0.003, min_p_mw=0, + max_q_mvar=.001, min_q_mvar=-.001) return net diff --git a/pandapower/test/opf/test_cost_consistency.py b/pandapower/test/opf/test_cost_consistency.py index c7d1e12fa..1a22ba013 100644 --- a/pandapower/test/opf/test_cost_consistency.py +++ b/pandapower/test/opf/test_cost_consistency.py @@ -1,26 +1,30 @@ -import pandapower as pp import pytest -from numpy import array, isclose -import pandas as pd +from numpy import isclose + +from pandapower.create import create_empty_network, create_bus, create_ext_grid, create_line_from_parameters, \ + create_load, create_sgen, create_pwl_cost, create_poly_cost, create_gen +from pandapower.run import runpp, runopp + @pytest.fixture() def base_net(): - net = pp.create_empty_network() - pp.create_bus(net, vn_kv=10) - pp.create_bus(net, vn_kv=10) - pp.create_ext_grid(net, 0) - pp.create_load(net, 1, p_mw=0.2, controllable=False) - pp.create_line_from_parameters(net, 0, 1, 50, name="line", r_ohm_per_km=0.876, - c_nf_per_km=260.0, max_i_ka=0.123, x_ohm_per_km=0.1159876, - max_loading_percent=100 * 690) - - pp.runpp(net) + net = create_empty_network() + create_bus(net, vn_kv=10) + create_bus(net, vn_kv=10) + create_ext_grid(net, 0) + create_load(net, 1, p_mw=0.2, controllable=False) + create_line_from_parameters(net, 0, 1, 50, name="line", r_ohm_per_km=0.876, + c_nf_per_km=260.0, max_i_ka=0.123, x_ohm_per_km=0.1159876, + max_loading_percent=100 * 690) + + runpp(net) return net + def test_contingency_sgen(base_net): net = base_net - pp.create_sgen(net, 1, p_mw=0.1, q_mvar=0, controllable=True, min_p_mw=0.005, max_p_mw=0.150, - max_q_mvar=0.05, min_q_mvar=-0.05) + create_sgen(net, 1, p_mw=0.1, q_mvar=0, controllable=True, min_p_mw=0.005, max_p_mw=0.150, + max_q_mvar=0.05, min_q_mvar=-0.05) # pwl costs # maximize the sgen feed in by using a positive cost slope # using a slope of 1 @@ -28,14 +32,13 @@ def test_contingency_sgen(base_net): # | / # | / # |/ - #------------------------------------------- + # ------------------------------------------- # p_min_mw /| # / | # / | - pwl = pp.create_pwl_cost(net, 0, "sgen", [[0, net.sgen.max_p_mw.at[0], 1]]) - pp.runopp(net) - + pwl = create_pwl_cost(net, 0, "sgen", [[0, net.sgen.max_p_mw.at[0], 1]]) + runopp(net) assert isclose(net.res_cost, net.res_sgen.p_mw.at[0], atol=1e-3) # minimize the sgen feed in by using a positive cost slope @@ -44,34 +47,34 @@ def test_contingency_sgen(base_net): # \ | # \ | # \| - #------------------------------------------- + # ------------------------------------------- # p_min_mw |\ # | \ # | \ net.pwl_cost.at[pwl, 'points'] = [(0, net.sgen.max_p_mw.at[0], -1)] - pp.runopp(net) + runopp(net) assert isclose(net.res_cost, -net.res_sgen.p_mw.at[0], atol=1e-4) net.pwl_cost = net.pwl_cost.drop(0) # first using a positive slope as in the case above - pp.create_poly_cost(net, 0, "sgen", cp1_eur_per_mw=1.) - pp.runopp(net) + create_poly_cost(net, 0, "sgen", cp1_eur_per_mw=1.) + runopp(net) assert isclose(net.res_cost, net.res_sgen.p_mw.at[0], atol=1e-3) # negative slope as in the case above net.poly_cost.cp1_eur_per_mw.at[0] *= -1 - pp.runopp(net) + runopp(net) assert isclose(net.res_cost, -net.res_sgen.p_mw.at[0], atol=1e-4) def test_contingency_load(base_net): net = base_net - pp.create_gen(net, 1, p_mw=0.1, vm_pu = 1.05, controllable=True, min_p_mw=0.005, max_p_mw=0.150, - max_q_mvar=0.05, min_q_mvar=-0.05) + create_gen(net, 1, p_mw=0.1, vm_pu=1.05, controllable=True, min_p_mw=0.005, max_p_mw=0.150, + max_q_mvar=0.05, min_q_mvar=-0.05) # pwl costs # maximize the sgen feed in by using a positive cost slope # using a slope of 1 @@ -79,14 +82,13 @@ def test_contingency_load(base_net): # | / # | / # |/ - #------------------------------------------- + # ------------------------------------------- # p_min_mw /| # / | # / | - pp.create_pwl_cost(net, 0, "gen",[[0, net.gen.max_p_mw.at[0], 1]]) - pp.runopp(net) - + create_pwl_cost(net, 0, "gen", [[0, net.gen.max_p_mw.at[0], 1]]) + runopp(net) assert isclose(net.res_cost, net.res_gen.p_mw.at[0], atol=1e-3) # minimize the sgen feed in by using a positive cost slope @@ -95,33 +97,33 @@ def test_contingency_load(base_net): # \ | # \ | # \| - #------------------------------------------- + # ------------------------------------------- # p_min_mw |\ # | \ # | \ net.pwl_cost.at[0, 'points'] = [(0, net.gen.max_p_mw.at[0], -1)] - pp.runopp(net) + runopp(net) assert isclose(net.res_cost, -net.res_gen.p_mw.at[0], atol=1e-3) net.pwl_cost = net.pwl_cost.drop(0) # first using a positive slope as in the case above - pp.create_poly_cost(net, 0, "gen", cp1_eur_per_mw=1) - pp.runopp(net) + create_poly_cost(net, 0, "gen", cp1_eur_per_mw=1) + runopp(net) assert isclose(net.res_cost, net.res_gen.p_mw.at[0], atol=1e-3) # negative slope as in the case above net.poly_cost.cp1_eur_per_mw.at[0] *= -1 - pp.runopp(net) + runopp(net) assert isclose(net.res_cost, -net.res_gen.p_mw.at[0], atol=1e-3) def test_contingency_gen(base_net): net = base_net - pp.create_gen(net, 1, p_mw=0.1, vm_pu = 1.05, controllable=True, min_p_mw=0.005, max_p_mw=0.150, - max_q_mvar=0.05, min_q_mvar=-0.05) + create_gen(net, 1, p_mw=0.1, vm_pu=1.05, controllable=True, min_p_mw=0.005, max_p_mw=0.150, + max_q_mvar=0.05, min_q_mvar=-0.05) # pwl costs # maximize the sgen feed in by using a positive cost slope # using a slope of 1 @@ -129,14 +131,13 @@ def test_contingency_gen(base_net): # | / # | / # |/ - #------------------------------------------- + # ------------------------------------------- # p_min_mw /| # / | # / | - pp.create_pwl_cost(net, 0, "gen", [[0, net.gen.max_p_mw.at[0], 1]]) - pp.runopp(net) - + create_pwl_cost(net, 0, "gen", [[0, net.gen.max_p_mw.at[0], 1]]) + runopp(net) assert isclose(net.res_cost, net.res_gen.p_mw.at[0], atol=1e-3) # minimize the sgen feed in by using a positive cost slope @@ -145,26 +146,26 @@ def test_contingency_gen(base_net): # \ | # \ | # \| - #------------------------------------------- + # ------------------------------------------- # p_min_mw |\ # | \ # | \ - net.pwl_cost.at[0, 'points'] = [(0, net.gen.max_p_mw.at[0], -1)] - pp.runopp(net) + net.pwl_cost.at[0, 'points'] = [(0, net.gen.max_p_mw.at[0], -1)] + runopp(net) assert isclose(net.res_cost, -net.res_gen.p_mw.at[0], atol=1e-3) net.pwl_cost = net.pwl_cost.drop(0) # first using a positive slope as in the case above -# pp.create_pwl_cost(net, 0, "gen", array([1, 0])) - pp.create_poly_cost(net, 0, "gen", cp1_eur_per_mw=1) - pp.runopp(net) + # create_pwl_cost(net, 0, "gen", array([1, 0])) + create_poly_cost(net, 0, "gen", cp1_eur_per_mw=1) + runopp(net) assert isclose(net.res_cost, net.res_gen.p_mw.at[0], atol=1e-3) # negative slope as in the case above net.poly_cost.cp1_eur_per_mw *= -1 - pp.runopp(net) + runopp(net) assert isclose(net.res_cost, -net.res_gen.p_mw.at[0], atol=1e-3) diff --git a/pandapower/test/opf/test_costs_mixed.py b/pandapower/test/opf/test_costs_mixed.py index d9bd4d357..af59ead0b 100644 --- a/pandapower/test/opf/test_costs_mixed.py +++ b/pandapower/test/opf/test_costs_mixed.py @@ -3,11 +3,12 @@ # Copyright (c) 2016-2024 by University of Kassel and Fraunhofer Institute for Energy Economics # and Energy System Technology (IEE), Kassel. All rights reserved. - import numpy as np import pytest -import pandapower as pp +from pandapower.create import create_empty_network, create_bus, create_ext_grid, create_line_from_parameters, \ + create_gen, create_load, create_pwl_cost, create_poly_cost +from pandapower.run import runopp try: import pandaplan.core.pplog as logging @@ -22,48 +23,48 @@ def test_cost_mixed(): vm_min = 0.95 # create net - net = pp.create_empty_network() - pp.create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=10.) - pp.create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=.4) - pp.create_gen(net, 1, p_mw=-0.1, controllable=True, min_p_mw=0.005, max_p_mw=0.15, max_q_mvar=.05, - min_q_mvar=-.05) - pp.create_ext_grid(net, 0) - pp.create_load(net, 1, p_mw=0.02, controllable=False, max_q_mvar=.05, max_p_mw=0.1, min_p_mw=0.0050, - min_q_mvar=-.05) - pp.create_line_from_parameters(net, 0, 1, 50, name="line2", r_ohm_per_km=0.876, - c_nf_per_km=260.0, max_i_ka=0.123, x_ohm_per_km=0.1159876, - max_loading_percent=100 * 690) + net = create_empty_network() + create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=10.) + create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=.4) + create_gen(net, 1, p_mw=-0.1, controllable=True, min_p_mw=0.005, max_p_mw=0.15, max_q_mvar=.05, + min_q_mvar=-.05) + create_ext_grid(net, 0) + create_load(net, 1, p_mw=0.02, controllable=False, max_q_mvar=.05, max_p_mw=0.1, min_p_mw=0.0050, + min_q_mvar=-.05) + create_line_from_parameters(net, 0, 1, 50, name="line2", r_ohm_per_km=0.876, + c_nf_per_km=260.0, max_i_ka=0.123, x_ohm_per_km=0.1159876, + max_loading_percent=100 * 690) # testing some combinations - pp.create_poly_cost(net, 0, "gen", cp1_eur_per_mw=1) - pp.runopp(net) + create_poly_cost(net, 0, "gen", cp1_eur_per_mw=1) + runopp(net) assert net["OPF_converged"] assert np.isclose(net.res_cost, net.res_gen.p_mw.values[0]) net.poly_cost.cp1_eur_per_mw.at[0] = 0 net.poly_cost.cp2_eur_per_mw2.at[0] = 1 - pp.runopp(net) + runopp(net) assert net["OPF_converged"] - assert np.isclose(net.res_cost, net.res_gen.p_mw.values**2) + assert np.isclose(net.res_cost, net.res_gen.p_mw.values ** 2) net.poly_cost.cp0_eur.at[0] = 1 - pp.runopp(net) + runopp(net) assert net["OPF_converged"] - assert np.isclose(net.res_cost, net.res_gen.p_mw.values**2 + 1) + assert np.isclose(net.res_cost, net.res_gen.p_mw.values ** 2 + 1) net.load.at[0, "controllable"] = True - pp.runopp(net) + runopp(net) assert np.isclose(net.res_cost, net.res_gen.p_mw.values ** 2 + 1) net.load.at[0, "controllable"] = False net.pwl_cost = net.pwl_cost.drop(net.pwl_cost.index) - pp.create_pwl_cost(net, 0, "ext_grid", [[-1000, 0, -2000], [0, 1000, 2000]], power_type="p") + create_pwl_cost(net, 0, "ext_grid", [[-1000, 0, -2000], [0, 1000, 2000]], power_type="p") net.poly_cost.cp1_eur_per_mw.at[0] = 1000 net.poly_cost.cp2_eur_per_mw2.at[0] = 0 - pp.runopp(net) + runopp(net) assert np.isclose(net.res_ext_grid.p_mw.values[0], 0, atol=1e-4) - assert np.isclose(net.res_cost, net.res_gen.p_mw.values[0]*1000, atol=1e-3) + assert np.isclose(net.res_cost, net.res_gen.p_mw.values[0] * 1000, atol=1e-3) def test_mixed_p_q_pol(): @@ -71,21 +72,21 @@ def test_mixed_p_q_pol(): vm_min = 0.95 # create net - net = pp.create_empty_network() - pp.create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=10.) - pp.create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=.4) - pp.create_gen(net, 1, p_mw=0.1, controllable=True, min_p_mw=0.005, max_p_mw=0.15, max_q_mvar=.05, - min_q_mvar=-.05) - pp.create_ext_grid(net, 0) - pp.create_load(net, 1, p_mw=0.02, controllable=False, max_q_mvar=.05, max_p_mw=0.1, min_p_mw=0.0050, - min_q_mvar=-.05) - pp.create_line_from_parameters(net, 0, 1, 50, name="line2", r_ohm_per_km=0.876, - c_nf_per_km=260.0, max_i_ka=0.123, x_ohm_per_km=0.1159876, - max_loading_percent=100 * 690) + net = create_empty_network() + create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=10.) + create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=.4) + create_gen(net, 1, p_mw=0.1, controllable=True, min_p_mw=0.005, max_p_mw=0.15, max_q_mvar=.05, + min_q_mvar=-.05) + create_ext_grid(net, 0) + create_load(net, 1, p_mw=0.02, controllable=False, max_q_mvar=.05, max_p_mw=0.1, min_p_mw=0.0050, + min_q_mvar=-.05) + create_line_from_parameters(net, 0, 1, 50, name="line2", r_ohm_per_km=0.876, + c_nf_per_km=260.0, max_i_ka=0.123, x_ohm_per_km=0.1159876, + max_loading_percent=100 * 690) # testing some combinations - pp.create_poly_cost(net, 0, "gen", cp1_eur_per_mw=1, cq1_eur_per_mvar=1) - pp.runopp(net) + create_poly_cost(net, 0, "gen", cp1_eur_per_mw=1, cq1_eur_per_mvar=1) + runopp(net) assert net["OPF_converged"] assert np.isclose(net.res_cost, (net.res_gen.p_mw.values + net.res_gen.q_mvar.values)) @@ -95,22 +96,22 @@ def test_mixed_p_q_pwl(): vm_min = 0.95 # create net - net = pp.create_empty_network() - pp.create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=10.) - pp.create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=.4) - pp.create_gen(net, 1, p_mw=0.1, controllable=True, min_p_mw=0.005, max_p_mw=0.15, - max_q_mvar=.05, min_q_mvar=-.05) - pp.create_ext_grid(net, 0) - pp.create_load(net, 1, p_mw=0.02, controllable=False, min_p_mw=0.005, max_p_mw=0.1, - max_q_mvar=.05, min_q_mvar=-.05) - pp.create_line_from_parameters(net, 0, 1, 50, name="line2", r_ohm_per_km=0.876, - c_nf_per_km=260.0, max_i_ka=0.123, x_ohm_per_km=0.1159876, - max_loading_percent=100 * 690) + net = create_empty_network() + create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=10.) + create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=.4) + create_gen(net, 1, p_mw=0.1, controllable=True, min_p_mw=0.005, max_p_mw=0.15, + max_q_mvar=.05, min_q_mvar=-.05) + create_ext_grid(net, 0) + create_load(net, 1, p_mw=0.02, controllable=False, min_p_mw=0.005, max_p_mw=0.1, + max_q_mvar=.05, min_q_mvar=-.05) + create_line_from_parameters(net, 0, 1, 50, name="line2", r_ohm_per_km=0.876, + c_nf_per_km=260.0, max_i_ka=0.123, x_ohm_per_km=0.1159876, + max_loading_percent=100 * 690) # testing some combinations - pp.create_pwl_cost(net, 0, "gen", [[-150, 150, 1]]) - pp.create_pwl_cost(net, 0, "gen", [[-150, 150, 1]], power_type="q") - pp.runopp(net) + create_pwl_cost(net, 0, "gen", [[-150, 150, 1]]) + create_pwl_cost(net, 0, "gen", [[-150, 150, 1]], power_type="q") + runopp(net) assert net["OPF_converged"] assert np.allclose(net.res_cost, net.res_gen.p_mw.values + net.res_gen.q_mvar.values) diff --git a/pandapower/test/opf/test_costs_pol.py b/pandapower/test/opf/test_costs_pol.py index 7342ea17f..ba14eaf72 100644 --- a/pandapower/test/opf/test_costs_pol.py +++ b/pandapower/test/opf/test_costs_pol.py @@ -3,11 +3,12 @@ # Copyright (c) 2016-2024 by University of Kassel and Fraunhofer Institute for Energy Economics # and Energy System Technology (IEE), Kassel. All rights reserved. - import numpy as np import pytest -import pandapower as pp +from pandapower.create import create_empty_network, create_bus, create_gen, create_ext_grid, create_load, \ + create_line_from_parameters, create_poly_cost, create_sgen +from pandapower.run import runopp try: import pandaplan.core.pplog as logging @@ -23,20 +24,20 @@ def test_cost_pol_gen(): vm_min = 0.95 # create net - net = pp.create_empty_network() - pp.create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=10.) - pp.create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=.4) - pp.create_gen(net, 1, p_mw=0.1, controllable=True, min_p_mw=0.005, max_p_mw=0.15, max_q_mvar=0.05, - min_q_mvar=-0.05) - pp.create_ext_grid(net, 0) - pp.create_load(net, 1, p_mw=0.02, controllable=False) - pp.create_line_from_parameters(net, 0, 1, 50, name="line2", r_ohm_per_km=0.876, - c_nf_per_km=260.0, max_i_ka=0.123, x_ohm_per_km=0.1159876, - max_loading_percent=100 * 690) + net = create_empty_network() + create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=10.) + create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=.4) + create_gen(net, 1, p_mw=0.1, controllable=True, min_p_mw=0.005, max_p_mw=0.15, max_q_mvar=0.05, + min_q_mvar=-0.05) + create_ext_grid(net, 0) + create_load(net, 1, p_mw=0.02, controllable=False) + create_line_from_parameters(net, 0, 1, 50, name="line2", r_ohm_per_km=0.876, + c_nf_per_km=260.0, max_i_ka=0.123, x_ohm_per_km=0.1159876, + max_loading_percent=100 * 690) - pp.create_poly_cost(net, 0, "gen", cp1_eur_per_mw=1) + create_poly_cost(net, 0, "gen", cp1_eur_per_mw=1) - pp.runopp(net) + runopp(net) assert net["OPF_converged"] assert np.isclose(net.res_cost, net.res_gen.p_mw.values) @@ -44,10 +45,10 @@ def test_cost_pol_gen(): net.poly_cost.cp1_eur_per_mw.at[0] = 0 net.poly_cost.cp2_eur_per_mw2.at[0] = 1 # run OPF - pp.runopp(net) + runopp(net) assert net["OPF_converged"] - assert np.isclose(net.res_cost, net.res_gen.p_mw.values**2) + assert np.isclose(net.res_cost, net.res_gen.p_mw.values ** 2) def test_cost_pol_all_elements(): @@ -58,23 +59,23 @@ def test_cost_pol_all_elements(): vm_min = 0.95 # create net - net = pp.create_empty_network() - pp.create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=10.) - pp.create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=.4) - pp.create_gen(net, 1, p_mw=0.1, controllable=True, min_p_mw=0.005, max_p_mw=0.15, max_q_mvar=0.05, - min_q_mvar=-0.05) - pp.create_sgen(net, 1, p_mw=0.1, controllable=True, min_p_mw=0.005, max_p_mw=0.15, max_q_mvar=0.05, - min_q_mvar=-0.05) - pp.create_ext_grid(net, 0) - pp.create_load(net, 1, p_mw=0.02, controllable=False) - pp.create_line_from_parameters(net, 0, 1, 50, name="line2", r_ohm_per_km=0.876, - c_nf_per_km=260.0, max_i_ka=0.123, x_ohm_per_km=0.1159876, - max_loading_percent=100 * 690) - - pp.create_poly_cost(net, 0, "gen", cp1_eur_per_mw=1) - pp.create_poly_cost(net, 0, "sgen", cp1_eur_per_mw=1) + net = create_empty_network() + create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=10.) + create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=.4) + create_gen(net, 1, p_mw=0.1, controllable=True, min_p_mw=0.005, max_p_mw=0.15, max_q_mvar=0.05, + min_q_mvar=-0.05) + create_sgen(net, 1, p_mw=0.1, controllable=True, min_p_mw=0.005, max_p_mw=0.15, max_q_mvar=0.05, + min_q_mvar=-0.05) + create_ext_grid(net, 0) + create_load(net, 1, p_mw=0.02, controllable=False) + create_line_from_parameters(net, 0, 1, 50, name="line2", r_ohm_per_km=0.876, + c_nf_per_km=260.0, max_i_ka=0.123, x_ohm_per_km=0.1159876, + max_loading_percent=100 * 690) + + create_poly_cost(net, 0, "gen", cp1_eur_per_mw=1) + create_poly_cost(net, 0, "sgen", cp1_eur_per_mw=1) # run OPF - pp.runopp(net) + runopp(net) assert net["OPF_converged"] assert abs(net.res_cost - (net.res_gen.p_mw.values + net.res_sgen.p_mw.values)) < 1e-2 @@ -82,10 +83,11 @@ def test_cost_pol_all_elements(): net.poly_cost.cp1_eur_per_mw.at[0] = 0 net.poly_cost.cp2_eur_per_mw2.at[0] = 1 - pp.runopp(net) + runopp(net) assert net["OPF_converged"] - assert np.isclose(net.res_cost, net.res_gen.p_mw.values**2 + net.res_sgen.p_mw.values) + assert np.isclose(net.res_cost, net.res_gen.p_mw.values ** 2 + net.res_sgen.p_mw.values) + def test_cost_pol_q(): """ Testing a very simple network for the resulting cost value @@ -95,33 +97,32 @@ def test_cost_pol_q(): vm_min = 0.95 # create net - net = pp.create_empty_network() - pp.create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=10.) - pp.create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=.4) - pp.create_sgen(net, 1, p_mw=0.1, controllable=True, min_p_mw=0.005, max_p_mw=0.15, max_q_mvar=0.05, - min_q_mvar=-0.05) - pp.create_ext_grid(net, 0) - pp.create_load(net, 1, p_mw=0.02, controllable=False) - pp.create_line_from_parameters(net, 0, 1, 50, name="line2", r_ohm_per_km=0.876, - c_nf_per_km=260.0, max_i_ka=0.123, x_ohm_per_km=0.1159876, - max_loading_percent=100 * 690) - - pp.create_poly_cost(net, 0, "sgen", cp1_eur_per_mw=0, cq1_eur_per_mvar=-1) + net = create_empty_network() + create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=10.) + create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=.4) + create_sgen(net, 1, p_mw=0.1, controllable=True, min_p_mw=0.005, max_p_mw=0.15, max_q_mvar=0.05, + min_q_mvar=-0.05) + create_ext_grid(net, 0) + create_load(net, 1, p_mw=0.02, controllable=False) + create_line_from_parameters(net, 0, 1, 50, name="line2", r_ohm_per_km=0.876, + c_nf_per_km=260.0, max_i_ka=0.123, x_ohm_per_km=0.1159876, + max_loading_percent=100 * 690) + + create_poly_cost(net, 0, "sgen", cp1_eur_per_mw=0, cq1_eur_per_mvar=-1) # run OPF - pp.runopp(net) + runopp(net) assert net["OPF_converged"] - assert abs(net.res_cost + (net.res_sgen.q_mvar.values)) < 1e-2 + assert abs(net.res_cost + net.res_sgen.q_mvar.values) < 1e-2 net.poly_cost.cq1_eur_per_mvar.at[0] = 0 net.poly_cost.cq2_eur_per_mvar2.at[0] = 1 -# net.poly_cost.at[0, "c"] = np.array([[1, 0, 0]]) + # net.poly_cost.at[0, "c"] = np.array([[1, 0, 0]]) # run OPF - pp.runopp(net) + runopp(net) assert net["OPF_converged"] - assert np.isclose(net.res_cost, net.res_sgen.q_mvar.values**2) - + assert np.isclose(net.res_cost, net.res_sgen.q_mvar.values ** 2) if __name__ == "__main__": diff --git a/pandapower/test/opf/test_costs_pwl.py b/pandapower/test/opf/test_costs_pwl.py index a0da9530b..78301afef 100644 --- a/pandapower/test/opf/test_costs_pwl.py +++ b/pandapower/test/opf/test_costs_pwl.py @@ -7,7 +7,9 @@ import numpy as np import pytest -import pandapower as pp +from pandapower.create import create_empty_network, create_bus, create_gen, create_ext_grid, create_load, \ + create_line_from_parameters, create_pwl_cost, create_sgen +from pandapower.run import runopp try: import pandaplan.core.pplog as logging @@ -23,20 +25,20 @@ def test_cost_piecewise_linear_gen(): vm_min = 0.95 # create net - net = pp.create_empty_network() - pp.create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=10.) - pp.create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=.4) - pp.create_gen(net, 1, p_mw=0.1, controllable=True, min_p_mw=0.05, max_p_mw=0.15, max_q_mvar=0.05, - min_q_mvar=-0.05) - pp.create_ext_grid(net, 0) - pp.create_load(net, 1, p_mw=0.02, controllable=False) - pp.create_line_from_parameters(net, 0, 1, 50, name="line2", r_ohm_per_km=0.876, - c_nf_per_km=260.0, max_i_ka=0.123, x_ohm_per_km=0.1159876, - max_loading_percent=100 * 690) + net = create_empty_network() + create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=10.) + create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=.4) + create_gen(net, 1, p_mw=0.1, controllable=True, min_p_mw=0.05, max_p_mw=0.15, max_q_mvar=0.05, + min_q_mvar=-0.05) + create_ext_grid(net, 0) + create_load(net, 1, p_mw=0.02, controllable=False) + create_line_from_parameters(net, 0, 1, 50, name="line2", r_ohm_per_km=0.876, + c_nf_per_km=260.0, max_i_ka=0.123, x_ohm_per_km=0.1159876, + max_loading_percent=100 * 690) - pp.create_pwl_cost(net, 0, "gen", [[0, 75, 1.5], [75, 150, 1.5]]) + create_pwl_cost(net, 0, "gen", [[0, 75, 1.5], [75, 150, 1.5]]) - pp.runopp(net) + runopp(net) assert net["OPF_converged"] assert np.isclose(net.res_cost, net.res_gen.p_mw.values * 1.5, atol=1e-3) @@ -51,23 +53,23 @@ def test_cost_piecewise_linear_eg(): vm_min = 0.95 # create net - net = pp.create_empty_network() - pp.create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=10.) - pp.create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=10) - pp.create_ext_grid(net, 0, min_p_mw=0, max_p_mw=0.050) - pp.create_gen(net, 1, p_mw=0.01, min_p_mw=0, max_p_mw=0.050, controllable=True) - # pp.create_ext_grid(net, 0) - pp.create_load(net, 1, p_mw=0.02, controllable=False) - pp.create_line_from_parameters(net, 0, 1, 50, name="line2", r_ohm_per_km=0.876, - c_nf_per_km=260.0, max_i_ka=0.123, x_ohm_per_km=0.1159876, - max_loading_percent=100 * 690) - - pp.create_pwl_cost(net, 0, "ext_grid", [[0, 50, -10]]) + net = create_empty_network() + create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=10.) + create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=10) + create_ext_grid(net, 0, min_p_mw=0, max_p_mw=0.050) + create_gen(net, 1, p_mw=0.01, min_p_mw=0, max_p_mw=0.050, controllable=True) + # create_ext_grid(net, 0) + create_load(net, 1, p_mw=0.02, controllable=False) + create_line_from_parameters(net, 0, 1, 50, name="line2", r_ohm_per_km=0.876, + c_nf_per_km=260.0, max_i_ka=0.123, x_ohm_per_km=0.1159876, + max_loading_percent=100 * 690) + + create_pwl_cost(net, 0, "ext_grid", [[0, 50, -10]]) # run OPF - pp.runopp(net) + runopp(net) assert net["OPF_converged"] - assert np.isclose(net.res_cost, -10*net.res_ext_grid.p_mw.values) + assert np.isclose(net.res_cost, -10 * net.res_ext_grid.p_mw.values) def test_get_costs(): @@ -79,20 +81,20 @@ def test_get_costs(): vm_min = 0.95 # create net - net = pp.create_empty_network() - pp.create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=10.) - pp.create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=.4) - pp.create_gen(net, 1, p_mw=0.1, controllable=True, min_p_mw=0.05, max_p_mw=0.15, max_q_mvar=0.05, - min_q_mvar=-0.05) - pp.create_ext_grid(net, 0) - pp.create_load(net, 1, p_mw=0.02, controllable=False) - pp.create_line_from_parameters(net, 0, 1, 50, name="line2", r_ohm_per_km=0.876, - c_nf_per_km=260.0, max_i_ka=0.123, x_ohm_per_km=0.1159876, - max_loading_percent=100 * 690) - - pp.create_pwl_cost(net, 0, "gen", [[0, 150, 2]]) + net = create_empty_network() + create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=10.) + create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=.4) + create_gen(net, 1, p_mw=0.1, controllable=True, min_p_mw=0.05, max_p_mw=0.15, max_q_mvar=0.05, + min_q_mvar=-0.05) + create_ext_grid(net, 0) + create_load(net, 1, p_mw=0.02, controllable=False) + create_line_from_parameters(net, 0, 1, 50, name="line2", r_ohm_per_km=0.876, + c_nf_per_km=260.0, max_i_ka=0.123, x_ohm_per_km=0.1159876, + max_loading_percent=100 * 690) + + create_pwl_cost(net, 0, "gen", [[0, 150, 2]]) # run OPF - pp.runopp(net) + runopp(net) assert net["OPF_converged"] assert net.res_gen.p_mw.values[0] - net.gen.min_p_mw.values[0] < 1e-2 @@ -109,20 +111,20 @@ def test_cost_piecewise_linear_sgen(): vm_min = 0.95 # create net - net = pp.create_empty_network() - pp.create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=10.) - pp.create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=.4) - pp.create_sgen(net, 1, p_mw=0.1, controllable=True, min_p_mw=0.05, max_p_mw=0.15, max_q_mvar=0.05, - min_q_mvar=-0.05) - pp.create_ext_grid(net, 0) - pp.create_load(net, 1, p_mw=0.02, controllable=False) - pp.create_line_from_parameters(net, 0, 1, 50, name="line2", r_ohm_per_km=0.876, - c_nf_per_km=260.0, max_i_ka=0.123, x_ohm_per_km=0.1159876, - max_loading_percent=100 * 690) - - pp.create_pwl_cost(net, 0, "sgen", [[0, 150, 2]]) + net = create_empty_network() + create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=10.) + create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=.4) + create_sgen(net, 1, p_mw=0.1, controllable=True, min_p_mw=0.05, max_p_mw=0.15, max_q_mvar=0.05, + min_q_mvar=-0.05) + create_ext_grid(net, 0) + create_load(net, 1, p_mw=0.02, controllable=False) + create_line_from_parameters(net, 0, 1, 50, name="line2", r_ohm_per_km=0.876, + c_nf_per_km=260.0, max_i_ka=0.123, x_ohm_per_km=0.1159876, + max_loading_percent=100 * 690) + + create_pwl_cost(net, 0, "sgen", [[0, 150, 2]]) # run OPF - pp.runopp(net) + runopp(net) assert net["OPF_converged"] assert net.res_sgen.p_mw.values[0] - net.sgen.min_p_mw.values[0] < 1e-2 @@ -138,23 +140,24 @@ def test_cost_piecewise_linear_load(): vm_min = 0.95 # create net - net = pp.create_empty_network() - pp.create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=10.) - pp.create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=.4) - pp.create_load(net, 1, p_mw=0.1, controllable=True, max_p_mw=0.15, min_p_mw=0.050, max_q_mvar=0, - min_q_mvar=0) - pp.create_ext_grid(net, 0) - pp.create_line_from_parameters(net, 0, 1, 50, name="line2", r_ohm_per_km=0.876, - c_nf_per_km=260.0, max_i_ka=0.123, x_ohm_per_km=0.1159876, - max_loading_percent=100 * 690) + net = create_empty_network() + create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=10.) + create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=.4) + create_load(net, 1, p_mw=0.1, controllable=True, max_p_mw=0.15, min_p_mw=0.050, max_q_mvar=0, + min_q_mvar=0) + create_ext_grid(net, 0) + create_line_from_parameters(net, 0, 1, 50, name="line2", r_ohm_per_km=0.876, + c_nf_per_km=260.0, max_i_ka=0.123, x_ohm_per_km=0.1159876, + max_loading_percent=100 * 690) - pp.create_pwl_cost(net, 0, "load", [[0, 75, 1.5], [75, 150, 1.5]]) + create_pwl_cost(net, 0, "load", [[0, 75, 1.5], [75, 150, 1.5]]) - pp.runopp(net) + runopp(net) assert net["OPF_converged"] assert abs(net.res_cost - net.res_load.p_mw.values * 1.5) < 1e-3 + def test_cost_piecewise_linear_sgen_uneven_slopes(): """ Testing a very simple network for the resulting cost value constraints with OPF """ @@ -164,20 +167,20 @@ def test_cost_piecewise_linear_sgen_uneven_slopes(): vm_min = 0.95 # create net - net = pp.create_empty_network() - pp.create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=10.) - pp.create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=.4) - pp.create_sgen(net, 1, p_mw=0.1, controllable=True, min_p_mw=0.05, max_p_mw=0.15, max_q_mvar=0.05, - min_q_mvar=-0.05) - pp.create_ext_grid(net, 0) - pp.create_load(net, 1, p_mw=0.02, controllable=False) - pp.create_line_from_parameters(net, 0, 1, 50, name="line2", r_ohm_per_km=0.876, - c_nf_per_km=260.0, max_i_ka=0.123, x_ohm_per_km=0.1159876, - max_loading_percent=100 * 690) - - pp.create_pwl_cost(net, 0, "sgen", [[0, 75, 1.5], [75, 150, 1.5]]) + net = create_empty_network() + create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=10.) + create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=.4) + create_sgen(net, 1, p_mw=0.1, controllable=True, min_p_mw=0.05, max_p_mw=0.15, max_q_mvar=0.05, + min_q_mvar=-0.05) + create_ext_grid(net, 0) + create_load(net, 1, p_mw=0.02, controllable=False) + create_line_from_parameters(net, 0, 1, 50, name="line2", r_ohm_per_km=0.876, + c_nf_per_km=260.0, max_i_ka=0.123, x_ohm_per_km=0.1159876, + max_loading_percent=100 * 690) + + create_pwl_cost(net, 0, "sgen", [[0, 75, 1.5], [75, 150, 1.5]]) # run OPF - pp.runopp(net) + runopp(net) assert net["OPF_converged"] assert net.res_cost - net.res_sgen.p_mw.values * 1.5 < 1e-3 @@ -192,25 +195,25 @@ def test_cost_piecewise_linear_load_uneven_slopes(): vm_min = 0.95 # create net - net = pp.create_empty_network() - pp.create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=10.) - pp.create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=.4) - pp.create_load(net, 1, p_mw=0.050) - pp.create_ext_grid(net, 0) - pp.create_line_from_parameters(net, 0, 1, 50, name="line2", r_ohm_per_km=0.876, - c_nf_per_km=260.0, max_i_ka=0.123, x_ohm_per_km=0.1159876, - max_loading_percent=100 * 690) - - - pp.create_pwl_cost(net, 0, "ext_grid", [(0, 0.075, 1), (0.075, 150, 2)]) - - pp.runopp(net) + net = create_empty_network() + create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=10.) + create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=.4) + create_load(net, 1, p_mw=0.050) + create_ext_grid(net, 0) + create_line_from_parameters(net, 0, 1, 50, name="line2", r_ohm_per_km=0.876, + c_nf_per_km=260.0, max_i_ka=0.123, x_ohm_per_km=0.1159876, + max_loading_percent=100 * 690) + + create_pwl_cost(net, 0, "ext_grid", [(0, 0.075, 1), (0.075, 150, 2)]) + + runopp(net) assert net["OPF_converged"] assert np.isclose(net.res_cost, net.res_ext_grid.p_mw.values[0]) net.load.p_mw = 0.1 - pp.runopp(net) - assert np.isclose(net.res_cost, (0.075 + 2*(net.res_ext_grid.p_mw.values[0] - 0.075)), rtol=1e-2) + runopp(net) + assert np.isclose(net.res_cost, (0.075 + 2 * (net.res_ext_grid.p_mw.values[0] - 0.075)), rtol=1e-2) + def test_cost_piecewise_linear_sgen_very_unsteady_slopes(): """ Testing a very simple network for the resulting cost value @@ -221,20 +224,20 @@ def test_cost_piecewise_linear_sgen_very_unsteady_slopes(): vm_min = 0.5 # create net - net = pp.create_empty_network() - pp.create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=10.) - pp.create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=.4) - pp.create_sgen(net, 1, p_mw=0.10, controllable=True, min_p_mw=0, max_p_mw=1.50, - max_q_mvar=0.05, min_q_mvar=-0.05) - pp.create_ext_grid(net, 0) - pp.create_load(net, 1, p_mw=0.02, controllable=False) - pp.create_line_from_parameters(net, 0, 1, 50, name="line2", r_ohm_per_km=0.876, - c_nf_per_km=260.0, max_i_ka=0.123, x_ohm_per_km=0.1159876, - max_loading_percent=100 * 690) - - pp.create_pwl_cost(net, 0, "sgen", [[0, 0.75, -1], [0.75, 1500, 2]]) + net = create_empty_network() + create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=10.) + create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=.4) + create_sgen(net, 1, p_mw=0.10, controllable=True, min_p_mw=0, max_p_mw=1.50, + max_q_mvar=0.05, min_q_mvar=-0.05) + create_ext_grid(net, 0) + create_load(net, 1, p_mw=0.02, controllable=False) + create_line_from_parameters(net, 0, 1, 50, name="line2", r_ohm_per_km=0.876, + c_nf_per_km=260.0, max_i_ka=0.123, x_ohm_per_km=0.1159876, + max_loading_percent=100 * 690) + + create_pwl_cost(net, 0, "sgen", [[0, 0.75, -1], [0.75, 1500, 2]]) # run OPF - pp.runopp(net) + runopp(net) assert net["OPF_converged"] assert np.isclose(net.res_sgen.p_mw.values[0], .75, rtol=1e-2) diff --git a/pandapower/test/opf/test_costs_pwl_q.py b/pandapower/test/opf/test_costs_pwl_q.py index ae5733667..edbb27ff0 100644 --- a/pandapower/test/opf/test_costs_pwl_q.py +++ b/pandapower/test/opf/test_costs_pwl_q.py @@ -1,7 +1,12 @@ -import pytest +# TODO: include head -import pandapower as pp import numpy as np +import pytest + +from pandapower.create import create_empty_network, create_bus, create_sgen, create_ext_grid, create_load, \ + create_line_from_parameters, create_pwl_cost +from pandapower.run import runopp + @pytest.mark.xfail def test_3point_pwl(): @@ -9,33 +14,34 @@ def test_3point_pwl(): vm_min = 0.95 # create net - net = pp.create_empty_network() - pp.create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=10.) - pp.create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=.4) - pp.create_sgen(net, 1, p_mw=0.1, q_mvar=0, controllable=True, min_p_mw=0.1, max_p_mw=0.15, - max_q_mvar=0.05, min_q_mvar=-0.05) - pp.create_ext_grid(net, 0) - pp.create_load(net, 1, p_mw=0.02, controllable=False) - pp.create_line_from_parameters(net, 0, 1, 50, name="line2", r_ohm_per_km=0.876, - c_nf_per_km=260.0, max_i_ka=0.123, x_ohm_per_km=0.1159876, - max_loading_percent=100 * 690) + net = create_empty_network() + create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=10.) + create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=.4) + create_sgen(net, 1, p_mw=0.1, q_mvar=0, controllable=True, min_p_mw=0.1, max_p_mw=0.15, + max_q_mvar=0.05, min_q_mvar=-0.05) + create_ext_grid(net, 0) + create_load(net, 1, p_mw=0.02, controllable=False) + create_line_from_parameters(net, 0, 1, 50, name="line2", r_ohm_per_km=0.876, + c_nf_per_km=260.0, max_i_ka=0.123, x_ohm_per_km=0.1159876, + max_loading_percent=100 * 690) # creating a pwl cost function that actually is realistic: The absolute value of the reactive power has costs. - pp.create_pwl_cost(net, 0, "sgen", [[-50, 0, -1.5], [0, 50, 1.5]], power_type="q") + create_pwl_cost(net, 0, "sgen", [[-50, 0, -1.5], [0, 50, 1.5]], power_type="q") - pp.runopp(net) + runopp(net) - # The reactive power should be at zero to minimze the costs. + # The reactive power should be at zero to minimize the costs. assert np.isclose(net.res_sgen.q_mvar.values, 0, atol=1e-4) - assert np.isclose(net.res_cost, abs(net.res_sgen.q_mvar.values)*1.5, atol=1e-4) - #TODO costs seem to be assigned to ext_grid, not to sgen (net.res_ext_grid.q_mvar*1.5=net.res_cost) - # They are however correctly assigned in the gencost array, this seems to be a bug in PYPOWER + assert np.isclose(net.res_cost, abs(net.res_sgen.q_mvar.values) * 1.5, atol=1e-4) + # TODO costs seem to be assigned to ext_grid, not to sgen (net.res_ext_grid.q_mvar*1.5=net.res_cost) + # They are however correctly assigned in the gen cost array, this seems to be a bug in PYPOWER net.sgen.min_q_mvar = 0.05 net.sgen.max_q_mvar = 0.1 - pp.runopp(net) + runopp(net) assert np.isclose(net.res_sgen.q_mvar.values, 0.05, atol=1e-4) - assert np.isclose(net.res_cost, abs(net.res_sgen.q_mvar.values)*1.5, atol=1e-4) + assert np.isclose(net.res_cost, abs(net.res_sgen.q_mvar.values) * 1.5, atol=1e-4) + if __name__ == "__main__": pytest.main([__file__, "-xs"]) diff --git a/pandapower/test/opf/test_curtailment.py b/pandapower/test/opf/test_curtailment.py index 2f05c1d22..f9a4d67db 100644 --- a/pandapower/test/opf/test_curtailment.py +++ b/pandapower/test/opf/test_curtailment.py @@ -5,8 +5,11 @@ import pytest -from numpy import array, allclose, all -import pandapower as pp +from numpy import allclose, all + +from pandapower.create import create_empty_network, create_bus, create_transformer, create_line, create_load, \ + create_ext_grid, create_gen, create_poly_cost +from pandapower.run import runopp try: import pandaplan.core.pplog as logging @@ -17,31 +20,31 @@ def test_minimize_active_power_curtailment(): - net = pp.create_empty_network() + net = create_empty_network() # create buses - bus1 = pp.create_bus(net, vn_kv=220.) - bus2 = pp.create_bus(net, vn_kv=110.) - bus3 = pp.create_bus(net, vn_kv=110.) - bus4 = pp.create_bus(net, vn_kv=110.) + bus1 = create_bus(net, vn_kv=220.) + bus2 = create_bus(net, vn_kv=110.) + bus3 = create_bus(net, vn_kv=110.) + bus4 = create_bus(net, vn_kv=110.) # create 220/110 kV transformer - pp.create_transformer(net, bus1, bus2, std_type="100 MVA 220/110 kV") + create_transformer(net, bus1, bus2, std_type="100 MVA 220/110 kV") # create 110 kV lines - pp.create_line(net, bus2, bus3, length_km=70., std_type='149-AL1/24-ST1A 110.0') - pp.create_line(net, bus3, bus4, length_km=50., std_type='149-AL1/24-ST1A 110.0') - pp.create_line(net, bus4, bus2, length_km=40., std_type='149-AL1/24-ST1A 110.0') + create_line(net, bus2, bus3, length_km=70., std_type='149-AL1/24-ST1A 110.0') + create_line(net, bus3, bus4, length_km=50., std_type='149-AL1/24-ST1A 110.0') + create_line(net, bus4, bus2, length_km=40., std_type='149-AL1/24-ST1A 110.0') # create loads - pp.create_load(net, bus2, p_mw=60, controllable=False) - pp.create_load(net, bus3, p_mw=70, controllable=False) - pp.create_load(net, bus4, p_mw=10, controllable=False) + create_load(net, bus2, p_mw=60, controllable=False) + create_load(net, bus3, p_mw=70, controllable=False) + create_load(net, bus4, p_mw=10, controllable=False) # create generators - pp.create_ext_grid(net, bus1) - pp.create_gen(net, bus3, p_mw=80., max_p_mw=80., min_p_mw=0., vm_pu=1.01, controllable=True) - pp.create_gen(net, bus4, p_mw=0.1, max_p_mw=100., min_p_mw=0., vm_pu=1.01, controllable=True) + create_ext_grid(net, bus1) + create_gen(net, bus3, p_mw=80., max_p_mw=80., min_p_mw=0., vm_pu=1.01, controllable=True) + create_gen(net, bus4, p_mw=0.1, max_p_mw=100., min_p_mw=0., vm_pu=1.01, controllable=True) net.trafo["max_loading_percent"] = 50. net.line["max_loading_percent"] = 50. @@ -50,10 +53,10 @@ def test_minimize_active_power_curtailment(): net.bus["max_vm_pu"] = 1.02 # use cheapest gen first, avoid ext_grid as much as possible (until vm_pu max is reached for gens) - pp.create_poly_cost(net, 0, "gen", cp1_eur_per_mw=0.02) - pp.create_poly_cost(net, 1, "gen", cp1_eur_per_mw=0.0) - pp.create_poly_cost(net, 0, "ext_grid", cp1_eur_per_mw=0.3) - pp.runopp(net, calculate_voltage_angles=True) + create_poly_cost(net, 0, "gen", cp1_eur_per_mw=0.02) + create_poly_cost(net, 1, "gen", cp1_eur_per_mw=0.0) + create_poly_cost(net, 0, "ext_grid", cp1_eur_per_mw=0.3) + runopp(net, calculate_voltage_angles=True) assert net["OPF_converged"] # checks limits in general assert all(net.res_line.loading_percent < 50.01) diff --git a/pandapower/test/opf/test_dcline.py b/pandapower/test/opf/test_dcline.py index 953de7a54..f9fd7dc0f 100644 --- a/pandapower/test/opf/test_dcline.py +++ b/pandapower/test/opf/test_dcline.py @@ -3,11 +3,13 @@ # Copyright (c) 2016-2024 by University of Kassel and Fraunhofer Institute for Energy Economics # and Energy System Technology (IEE), Kassel. All rights reserved. - import pytest from numpy import array, allclose, isclose -import pandapower as pp +from pandapower.auxiliary import OPFNotConverged +from pandapower.create import create_empty_network, create_bus, create_ext_grid, create_line, create_dcline, \ + create_load, create_pwl_cost, create_poly_cost +from pandapower.run import runopp from pandapower.test.consistency_checks import consistency_checks try: @@ -20,24 +22,24 @@ @pytest.fixture def dcline_net(): - net = pp.create_empty_network() + net = create_empty_network() - b5 = pp.create_bus(net, 380) - b3 = pp.create_bus(net, 380) - b2 = pp.create_bus(net, 380) - b4 = pp.create_bus(net, 380) - b1 = pp.create_bus(net, 380) + b5 = create_bus(net, 380) + b3 = create_bus(net, 380) + b2 = create_bus(net, 380) + b4 = create_bus(net, 380) + b1 = create_bus(net, 380) - pp.create_ext_grid(net, b1, 1.02, min_p_mw=0., max_p_mw=1e9) - pp.create_line(net, b1, b2, 30, "490-AL1/64-ST1A 380.0") - pp.create_dcline(net, name="dc line", from_bus=b2, to_bus=b3, p_mw=200, loss_percent=1.0, - loss_mw=0.5, vm_from_pu=1.01, vm_to_pu=1.012, max_p_mw=1000, - in_service=True, index=4) - pp.create_line(net, b3, b4, 20, "490-AL1/64-ST1A 380.0") + create_ext_grid(net, b1, 1.02, min_p_mw=0., max_p_mw=1e9) + create_line(net, b1, b2, 30, "490-AL1/64-ST1A 380.0") + create_dcline(net, name="dc line", from_bus=b2, to_bus=b3, p_mw=200, loss_percent=1.0, + loss_mw=0.5, vm_from_pu=1.01, vm_to_pu=1.012, max_p_mw=1000, + in_service=True, index=4) + create_line(net, b3, b4, 20, "490-AL1/64-ST1A 380.0") - pp.create_load(net, bus=b4, p_mw=800, controllable=False) - pp.create_line(net, b4, b5, 20, "490-AL1/64-ST1A 380.0") - pp.create_ext_grid(net, b5, 1.02, min_p_mw=0., max_p_mw=1e9) + create_load(net, bus=b4, p_mw=800, controllable=False) + create_line(net, b4, b5, 20, "490-AL1/64-ST1A 380.0") + create_ext_grid(net, b5, 1.02, min_p_mw=0., max_p_mw=1e9) return net @@ -45,9 +47,9 @@ def dcline_net(): def get_delta_try_except(net): for delta in [1e-5, 1e-6, 1e-7, 1e-8, 1e-9, 1e-10, 1e-11, 1e-12]: try: - pp.runopp(net, delta=delta) + runopp(net, delta=delta) return delta - except pp.OPFNotConverged: + except OPFNotConverged: continue return 1e-10 @@ -56,12 +58,12 @@ def get_delta_try_except(net): " python version. Should be reworked.") def test_dispatch1(dcline_net): net = dcline_net - pp.create_pwl_cost(net, 0, "ext_grid", [[-1e12, 1e9, 100]]) - pp.create_pwl_cost(net, 1, "ext_grid", [[-1e12, 1e9, 80]]) + create_pwl_cost(net, 0, "ext_grid", [[-1e12, 1e9, 100]]) + create_pwl_cost(net, 1, "ext_grid", [[-1e12, 1e9, 80]]) net.bus["max_vm_pu"] = 2 net.bus["min_vm_pu"] = 0 # needs to be constrained more than default net.line["max_loading_percent"] = 1000 # does not converge if unconstrained - pp.runopp(net, delta=1e-8) + runopp(net, delta=1e-8) consistency_checks(net) rel_loss_expect = (net.res_dcline.pl_mw - net.dcline.loss_mw) / \ (net.res_dcline.p_from_mw - net.res_dcline.pl_mw) * 100 @@ -81,17 +83,17 @@ def test_dispatch1(dcline_net): "ext_grid -> fail. See build_gen() in line 111 + 112") def test_dcline_dispatch2(dcline_net): net = dcline_net - pp.create_poly_cost(net, 0, "ext_grid", cp1_eur_per_mw=80) - pp.create_poly_cost(net, 1, "ext_grid", cp1_eur_per_mw=100) - # pp.create_poly_cost(net, 0, "ext_grid", array([.08, 0])) - # pp.create_poly_cost(net, 1, "ext_grid", array([.1, 0])) + create_poly_cost(net, 0, "ext_grid", cp1_eur_per_mw=80) + create_poly_cost(net, 1, "ext_grid", cp1_eur_per_mw=100) + # create_poly_cost(net, 0, "ext_grid", array([.08, 0])) + # create_poly_cost(net, 1, "ext_grid", array([.1, 0])) net.bus["max_vm_pu"] = 2 net.bus["min_vm_pu"] = 0 # needs to be constrained more than default net.line["max_loading_percent"] = 1000 # does not converge if unconstrained - # pp.runopp(net, delta=get_delta_try_except(net)) - pp.runopp(net) + # runopp(net, delta=get_delta_try_except(net)) + runopp(net) consistency_checks(net, rtol=1e-3) rel_loss_expect = (net.res_dcline.pl_mw - net.dcline.loss_mw) / \ (net.res_dcline.p_from_mw - net.res_dcline.pl_mw) * 100 @@ -119,11 +121,11 @@ def test_dcline_dispatch2(dcline_net): "ext_grid -> fail. See build_gen() in line 111 + 112") def test_dcline_dispatch3(dcline_net): net = dcline_net - pp.create_poly_cost(net, 4, "dcline", cp1_eur_per_mw=1.5) + create_poly_cost(net, 4, "dcline", cp1_eur_per_mw=1.5) net.bus["max_vm_pu"] = 1.03 # needs to be constrained more than default net.line["max_loading_percent"] = 1000 # does not converge if unconstrained - # pp.runopp(net, delta=get_delta_try_except(net)) - pp.runopp(net) + # runopp(net, delta=get_delta_try_except(net)) + runopp(net) consistency_checks(net, rtol=1e-1) # dc line is not dispatched because of the assigned costs @@ -131,9 +133,9 @@ def test_dcline_dispatch3(dcline_net): assert all(net.res_ext_grid.p_mw.values > 0) # costs for ext_grid at the end of the DC line get double the costs of DC line transfer - pp.create_poly_cost(net, 1, "ext_grid", cp1_eur_per_mw=2000) - pp.runopp(net) - # pp.runopp(net, delta=get_delta_try_except(net)) + create_poly_cost(net, 1, "ext_grid", cp1_eur_per_mw=2000) + runopp(net) + # runopp(net, delta=get_delta_try_except(net)) # now the total power is supplied through the DC line assert (net.res_dcline.at[4, "p_to_mw"]) < 1e3 diff --git a/pandapower/test/opf/test_oberrhein.py b/pandapower/test/opf/test_oberrhein.py index 15b56aeb3..d9c250638 100644 --- a/pandapower/test/opf/test_oberrhein.py +++ b/pandapower/test/opf/test_oberrhein.py @@ -3,10 +3,11 @@ # Copyright (c) 2016-2024 by University of Kassel and Fraunhofer Institute for Energy Economics # and Energy System Technology (IEE), Kassel. All rights reserved. - -import pandapower as pp -import pandapower.networks as nw import pytest + +from pandapower.networks import mv_oberrhein +from pandapower.run import runopp + try: import pandaplan.core.pplog as logging except ImportError: @@ -19,7 +20,7 @@ def test_opf_oberrhein(): """ Testing a simple network with transformer for loading constraints with OPF using a generator """ # create net - net = nw.mv_oberrhein() + net = mv_oberrhein() net.bus["max_vm_pu"] = 1.1 net.bus["min_vm_pu"] = 0.9 @@ -32,7 +33,7 @@ def test_opf_oberrhein(): net.sgen["controllable"] = True net.load["controllable"] = False # run OPF - pp.runopp(net, calculate_voltage_angles=False) + runopp(net, calculate_voltage_angles=False) assert net["OPF_converged"] diff --git a/pandapower/test/opf/test_opf_cigre.py b/pandapower/test/opf/test_opf_cigre.py index a782ae021..5976a1d0f 100644 --- a/pandapower/test/opf/test_opf_cigre.py +++ b/pandapower/test/opf/test_opf_cigre.py @@ -3,13 +3,12 @@ # Copyright (c) 2016-2024 by University of Kassel and Fraunhofer Institute for Energy Economics # and Energy System Technology (IEE), Kassel. All rights reserved. - - import numpy as np import pytest -import pandapower as pp -import pandapower.networks as nw +from pandapower.create import create_poly_cost +from pandapower.networks.cigre_networks import create_cigre_network_mv +from pandapower.run import runopp try: import pandaplan.core.pplog as logging @@ -23,7 +22,7 @@ def test_opf_cigre(): """ Testing a simple network with transformer for loading constraints with OPF using a generator """ # create net - net = nw.create_cigre_network_mv(with_der="pv_wind") + net = create_cigre_network_mv(with_der="pv_wind") net.bus["max_vm_pu"] = 1.1 net.bus["min_vm_pu"] = 0.9 @@ -41,7 +40,7 @@ def test_opf_cigre(): net.sgen.loc[net.sgen.bus == 9, 'in_service'] = False # run OPF - pp.runopp(net) + runopp(net) assert net["OPF_converged"] @@ -49,7 +48,7 @@ def test_some_sgens_not_controllable(): """ Testing a simple network with transformer for loading constraints with OPF using a generator """ # create net - net = nw.create_cigre_network_mv(with_der="pv_wind") + net = create_cigre_network_mv(with_der="pv_wind") net.bus["max_vm_pu"] = 1.1 net.bus["min_vm_pu"] = 0.9 @@ -67,11 +66,11 @@ def test_some_sgens_not_controllable(): net.sgen.loc[net.sgen.bus == 9, "controllable"] = False for sgen_idx, row in net["sgen"].iterrows(): - cost_sgen = pp.create_poly_cost(net, sgen_idx, 'sgen', cp1_eur_per_mw=1.) + cost_sgen = create_poly_cost(net, sgen_idx, 'sgen', cp1_eur_per_mw=1.) net.poly_cost.cp1_eur_per_mw.at[cost_sgen] = 100 # run OPF - pp.runopp(net, calculate_voltage_angles=False) + runopp(net, calculate_voltage_angles=False) assert net["OPF_converged"] # check if p_mw of non conrollable sgens are unchanged assert np.allclose(net.res_sgen.p_mw[~net.sgen.controllable], net.sgen.p_mw[~net.sgen.controllable]) diff --git a/pandapower/test/opf/test_pandamodels_converter.py b/pandapower/test/opf/test_pandamodels_converter.py index e37ebba0c..9a7efd803 100644 --- a/pandapower/test/opf/test_pandamodels_converter.py +++ b/pandapower/test/opf/test_pandamodels_converter.py @@ -6,17 +6,16 @@ import copy import json import os + import numpy as np import pytest -import pandapower.control -import pandapower.timeseries -import pandapower as pp + +import pandapower.test as test +from pandapower.converter import convert_pp_to_pm from pandapower.converter.pandamodels.from_pm import read_pm_results_to_net -from pandapower.converter.pandamodels.to_pm import init_ne_line +from pandapower.create import create_poly_cost from pandapower.pd2ppc import _pd2ppc -from pandapower.test.consistency_checks import consistency_checks -from pandapower.test.helper_functions import add_grid_connection, create_test_line -from pandapower.converter import convert_pp_to_pm +from pandapower.run import runopp from pandapower.test.opf.test_basic import simple_opf_test_net, net_3w_trafo_opf try: @@ -25,6 +24,7 @@ UnsupportedPythonError = Exception try: from julia.api import Julia + Julia(compiled_modules=False) from julia import Main @@ -45,15 +45,15 @@ def test_pm_to_pp_conversion(simple_opf_test_net): # Results are read from a result file containing the simple_opf_test_net net = simple_opf_test_net - pp.create_poly_cost(net, 0, "gen", cp1_eur_per_mw=100) + create_poly_cost(net, 0, "gen", cp1_eur_per_mw=100) # get pandapower opf results - pp.runopp(net, delta=1e-13) + runopp(net, delta=1e-13) va_degree = copy.deepcopy(net.res_bus.va_degree) vm_pu = copy.deepcopy(net.res_bus.vm_pu) # get previously calculated power models results - pm_res_file = os.path.join(os.path.abspath(os.path.dirname(pp.test.__file__)), + pm_res_file = os.path.join(os.path.abspath(os.path.dirname(test.__file__)), "test_files", "pm_example_res.json") with open(pm_res_file, "r") as fp: @@ -76,4 +76,4 @@ def test_obj_factors(net_3w_trafo_opf): if __name__ == '__main__': - pytest.main([__file__, "-xs"]) \ No newline at end of file + pytest.main([__file__, "-xs"]) diff --git a/pandapower/test/opf/test_pandamodels_runpm.py b/pandapower/test/opf/test_pandamodels_runpm.py index ff874a2ac..b32237098 100644 --- a/pandapower/test/opf/test_pandamodels_runpm.py +++ b/pandapower/test/opf/test_pandamodels_runpm.py @@ -3,26 +3,33 @@ # Copyright (c) 2016-2024 by University of Kassel and Fraunhofer Institute for Energy Economics # and Energy System Technology (IEE), Kassel. All rights reserved. -import os import copy -from pandapower.control import ConstControl -from pandapower.timeseries import DFData +import os +from copy import deepcopy + import numpy as np import pandas as pd import pytest -import pandapower as pp -import pandapower.networks as nw -import pandapower.control -import pandapower.timeseries -from copy import deepcopy + +from pandapower import pp_dir +from pandapower.control import ConstControl +from pandapower.converter import convert_pp_to_pm from pandapower.converter.pandamodels.to_pm import init_ne_line +from pandapower.create import create_storage, create_shunt, create_pwl_cost, create_poly_cost, create_empty_network, \ + create_bus, create_line, create_gen, create_load, create_transformer3w_from_parameters, create_sgen, \ + create_transformer3w +from pandapower.networks.cigre_networks import create_cigre_network_mv +from pandapower.networks.power_system_test_cases import case5, case9, case14, case30, case39, case57, case118, \ + case145, case300 +from pandapower.networks.simple_pandapower_test_networks import simple_four_bus_system +from pandapower.opf.pm_storage import read_pm_storage_results +from pandapower.run import rundcpp, runpp +from pandapower.runpm import runpm_pf, runpm_ac_opf, runpm_dc_opf, runpm_vstab, runpm_tnep, runpm_ots, runpm_qflex, \ + runpm_storage_opf, runpm_multi_qflex, runpm_ploss, runpm_loading, runpm_multi_vstab from pandapower.test.consistency_checks import consistency_checks from pandapower.test.helper_functions import add_grid_connection, create_test_line from pandapower.test.opf.test_basic import net_3w_trafo_opf -from pandapower.converter import convert_pp_to_pm -from pandapower import pp_dir -from pandapower.opf.pm_storage import read_pm_storage_results - +from pandapower.timeseries import DFData, run_timeseries try: from julia.core import UnsupportedPythonError @@ -30,8 +37,10 @@ UnsupportedPythonError = Exception try: from julia.api import Julia + Julia(compiled_modules=False) from julia import Main + julia_installed = True except (ImportError, RuntimeError, UnsupportedPythonError) as e: julia_installed = False @@ -39,7 +48,7 @@ def create_cigre_grid_with_time_series(json_path, net=None, add_ts_constaints=False): if net is None: - net = nw.create_cigre_network_mv("pv_wind") + net = create_cigre_network_mv("pv_wind") min_vm_pu = 0.95 max_vm_pu = 1.05 @@ -50,7 +59,7 @@ def create_cigre_grid_with_time_series(json_path, net=None, add_ts_constaints=Fa # close all switches net.switch.loc[:, "closed"] = True # add storage to bus 10 - pp.create_storage(net, 10, p_mw=0.5, max_e_mwh=.2, soc_percent=0., q_mvar=0., controllable=True) + create_storage(net, 10, p_mw=0.5, max_e_mwh=.2, soc_percent=0., q_mvar=0., controllable=True) # set the load type in the cigre grid, since it is not specified net["load"].loc[:, "type"] = "residential" @@ -92,17 +101,17 @@ def create_cigre_grid_with_time_series(json_path, net=None, add_ts_constaints=Fa df_qmin[df_qmin.columns] = net.sgen.min_q_mvar ConstControl(net, element="sgen", variable="max_p_mw", - element_index=net.sgen.index.tolist(), profile_name=net.sgen.index.tolist(), - data_source=DFData(sgen_ts)) + element_index=net.sgen.index.tolist(), profile_name=net.sgen.index.tolist(), + data_source=DFData(sgen_ts)) ConstControl(net, element="sgen", variable="min_p_mw", - element_index=net.sgen.index.tolist(), profile_name=net.sgen.index.tolist(), - data_source=DFData(sgen_ts)) + element_index=net.sgen.index.tolist(), profile_name=net.sgen.index.tolist(), + data_source=DFData(sgen_ts)) ConstControl(net, element="sgen", variable="max_q_mvar", - element_index=net.sgen.index.tolist(), profile_name=net.sgen.index.tolist(), - data_source=DFData(df_qmax)) + element_index=net.sgen.index.tolist(), profile_name=net.sgen.index.tolist(), + data_source=DFData(df_qmax)) ConstControl(net, element="sgen", variable="min_q_mvar", - element_index=net.sgen.index.tolist(), profile_name=net.sgen.index.tolist(), - data_source=DFData(df_qmin)) + element_index=net.sgen.index.tolist(), profile_name=net.sgen.index.tolist(), + data_source=DFData(df_qmin)) return net @@ -113,14 +122,14 @@ def assert_pf(net, dc=False): else: model = "ACPPowerModel" - pp.runpm_pf(net, pm_model=model) + runpm_pf(net, pm_model=model) va_pm = copy.deepcopy(net.res_bus.va_degree) vm_pm = copy.deepcopy(net.res_bus.vm_pu) if dc: - pp.rundcpp(net, calculate_voltage_angles=True) + rundcpp(net, calculate_voltage_angles=True) else: - pp.runpp(net, calculate_voltage_angles=True) + runpp(net, calculate_voltage_angles=True) va_pp = copy.deepcopy(net.res_bus.va_degree) vm_pp = copy.deepcopy(net.res_bus.vm_pu) @@ -133,37 +142,37 @@ def assert_pf(net, dc=False): @pytest.mark.skipif(not julia_installed, reason="requires julia installation") def test_pm_ac_powerflow_simple(): - net = nw.simple_four_bus_system() + net = simple_four_bus_system() net.trafo.loc[0, "shift_degree"] = 0. assert_pf(net, dc=False) @pytest.mark.skipif(not julia_installed, reason="requires julia installation") def test_pm_dc_powerflow_simple(): - net = nw.simple_four_bus_system() + net = simple_four_bus_system() net.trafo.loc[0, "shift_degree"] = 0. assert_pf(net, dc=True) @pytest.mark.skipif(not julia_installed, reason="requires julia installation") def test_pm_ac_powerflow_shunt(): - net = nw.simple_four_bus_system() - pp.create_shunt(net, 2, q_mvar=-0.5) + net = simple_four_bus_system() + create_shunt(net, 2, q_mvar=-0.5) net.trafo.loc[0, "shift_degree"] = 0. assert_pf(net, dc=False) @pytest.mark.skipif(not julia_installed, reason="requires julia installation") def test_pm_dc_powerflow_shunt(): - net = nw.simple_four_bus_system() - pp.create_shunt(net, 2, q_mvar=-0.5) + net = simple_four_bus_system() + create_shunt(net, 2, q_mvar=-0.5) net.trafo.loc[0, "shift_degree"] = 0. assert_pf(net, dc=True) @pytest.mark.skipif(not julia_installed, reason="requires julia installation") def test_pm_ac_powerflow_tap(): - net = nw.simple_four_bus_system() + net = simple_four_bus_system() net.trafo.loc[0, "shift_degree"] = 30. net.trafo.loc[0, "tap_pos"] = -2. assert_pf(net, dc=False) @@ -171,7 +180,7 @@ def test_pm_ac_powerflow_tap(): @pytest.mark.skipif(not julia_installed, reason="requires julia installation") def test_pm_dc_powerflow_tap(): - net = nw.simple_four_bus_system() + net = simple_four_bus_system() net.trafo.loc[0, "shift_degree"] = 0. assert_pf(net, dc=True) @@ -188,12 +197,12 @@ def test_compare_pwl_and_poly(net_3w_trafo_opf): net.ext_grid.loc[:, "max_p_mw"] = 999. net.ext_grid.loc[:, "max_q_mvar"] = 999. net.ext_grid.loc[:, "min_q_mvar"] = -999. - pp.create_pwl_cost(net, 0, 'ext_grid', [[0, 1, 1]]) - pp.create_pwl_cost(net, 0, 'gen', [[0, 30, 3], [30, 80, 3]]) - pp.create_pwl_cost(net, 1, 'gen', [[0, 80, 2]]) + create_pwl_cost(net, 0, 'ext_grid', [[0, 1, 1]]) + create_pwl_cost(net, 0, 'gen', [[0, 30, 3], [30, 80, 3]]) + create_pwl_cost(net, 1, 'gen', [[0, 80, 2]]) net.bus.loc[:, "max_vm_pu"] = 1.1 net.bus.loc[:, "min_vm_pu"] = .9 - pp.runpm_ac_opf(net) + runpm_ac_opf(net) consistency_checks(net) p_gen = net.res_gen.p_mw.values @@ -203,12 +212,12 @@ def test_compare_pwl_and_poly(net_3w_trafo_opf): net.pwl_cost = net.pwl_cost.drop(net.pwl_cost.index) - pp.create_poly_cost(net, 0, 'ext_grid', cp1_eur_per_mw=1) - pp.create_poly_cost(net, 0, 'gen', cp1_eur_per_mw=3) - pp.create_poly_cost(net, 1, 'gen', cp1_eur_per_mw=2) + create_poly_cost(net, 0, 'ext_grid', cp1_eur_per_mw=1) + create_poly_cost(net, 0, 'gen', cp1_eur_per_mw=3) + create_poly_cost(net, 1, 'gen', cp1_eur_per_mw=2) - # pp.runopp(net) - pp.runpm_ac_opf(net) + # runopp(net) + runpm_ac_opf(net) consistency_checks(net) np.allclose(p_gen, net.res_gen.p_mw.values) @@ -216,8 +225,8 @@ def test_compare_pwl_and_poly(net_3w_trafo_opf): np.allclose(vm_bus, net.res_bus.vm_pu.values) np.allclose(va_bus, net.res_bus.va_degree.values) - # pp.rundcopp(net) - pp.runpm_dc_opf(net) + # rundcopp(net) + runpm_dc_opf(net) consistency_checks(net, test_q=False) np.allclose(p_gen, net.res_gen.p_mw.values) @@ -227,56 +236,56 @@ def test_compare_pwl_and_poly(net_3w_trafo_opf): @pytest.mark.slow @pytest.mark.skipif(not julia_installed, reason="requires julia installation") def test_pwl(): - net = pp.create_empty_network() + net = create_empty_network() # create buses - bus1 = pp.create_bus(net, vn_kv=110., min_vm_pu=0.9, max_vm_pu=1.1) - bus2 = pp.create_bus(net, vn_kv=110., min_vm_pu=0.9, max_vm_pu=1.1) - bus3 = pp.create_bus(net, vn_kv=110., min_vm_pu=0.9, max_vm_pu=1.1) + bus1 = create_bus(net, vn_kv=110., min_vm_pu=0.9, max_vm_pu=1.1) + bus2 = create_bus(net, vn_kv=110., min_vm_pu=0.9, max_vm_pu=1.1) + bus3 = create_bus(net, vn_kv=110., min_vm_pu=0.9, max_vm_pu=1.1) # create 110 kV lines - pp.create_line(net, bus1, bus2, length_km=50., std_type='149-AL1/24-ST1A 110.0') - pp.create_line(net, bus2, bus3, length_km=50., std_type='149-AL1/24-ST1A 110.0') + create_line(net, bus1, bus2, length_km=50., std_type='149-AL1/24-ST1A 110.0') + create_line(net, bus2, bus3, length_km=50., std_type='149-AL1/24-ST1A 110.0') # create loads - pp.create_load(net, bus2, p_mw=80, controllable=False) + create_load(net, bus2, p_mw=80, controllable=False) # create generators - g1 = pp.create_gen(net, bus1, p_mw=80, min_p_mw=0, max_p_mw=80, vm_pu=1.01, slack=True) - g2 = pp.create_gen(net, bus3, p_mw=80, min_p_mw=0, max_p_mw=80, vm_pu=1.01) + g1 = create_gen(net, bus1, p_mw=80, min_p_mw=0, max_p_mw=80, vm_pu=1.01, slack=True) + g2 = create_gen(net, bus3, p_mw=80, min_p_mw=0, max_p_mw=80, vm_pu=1.01) # net.gen["controllable"] = False - pp.create_pwl_cost(net, g1, 'gen', [[0, 2, 2], [2, 80, 5]]) - pp.create_pwl_cost(net, g2, 'gen', [[0, 2, 2], [2, 80, 5]]) + create_pwl_cost(net, g1, 'gen', [[0, 2, 2], [2, 80, 5]]) + create_pwl_cost(net, g2, 'gen', [[0, 2, 2], [2, 80, 5]]) - pp.runpm_ac_opf(net) + runpm_ac_opf(net) consistency_checks(net, rtol=1e-3) assert np.isclose(net.res_gen.p_mw.iloc[0], net.res_gen.p_mw.iloc[1]) assert np.isclose(net.res_gen.q_mvar.iloc[0], net.res_gen.q_mvar.iloc[1]) net.pwl_cost = net.pwl_cost.drop(net.pwl_cost.index) - g3 = pp.create_gen(net, bus1, p_mw=80, min_p_mw=0, max_p_mw=80, vm_pu=1.01) + g3 = create_gen(net, bus1, p_mw=80, min_p_mw=0, max_p_mw=80, vm_pu=1.01) - pp.create_pwl_cost(net, g1, 'gen', [[0, 2, 1.], [2, 80, 8.]]) - pp.create_pwl_cost(net, g2, 'gen', [[0, 3, 2.], [3, 80, 14]]) - pp.create_pwl_cost(net, g3, 'gen', [[0, 1, 3.], [1, 80, 10.]]) + create_pwl_cost(net, g1, 'gen', [[0, 2, 1.], [2, 80, 8.]]) + create_pwl_cost(net, g2, 'gen', [[0, 3, 2.], [3, 80, 14]]) + create_pwl_cost(net, g3, 'gen', [[0, 1, 3.], [1, 80, 10.]]) net.load.p_mw = 1 - pp.runpm_ac_opf(net) + runpm_ac_opf(net) consistency_checks(net, rtol=1e-3) assert np.isclose(net.res_gen.p_mw.at[g2], 0) assert np.isclose(net.res_gen.p_mw.at[g3], 0) assert np.isclose(net.res_cost, net.res_gen.p_mw.at[g1], atol=1e-4) net.load.p_mw = 3 - pp.runpm_ac_opf(net) + runpm_ac_opf(net) consistency_checks(net, rtol=1e-3) assert np.isclose(net.res_gen.p_mw.at[g3], 0) assert np.isclose(net.res_gen.p_mw.at[g1], 2) assert np.isclose(net.res_cost, net.res_gen.p_mw.at[g1] + net.res_gen.p_mw.at[g2] * 2, atol=1e-4) net.load.p_mw = 5 - pp.runpm_ac_opf(net) + runpm_ac_opf(net) consistency_checks(net, rtol=1e-3) assert np.isclose(net.res_gen.p_mw.at[g1], 2) assert np.isclose(net.res_gen.p_mw.at[g2], 3) @@ -287,64 +296,64 @@ def test_pwl(): @pytest.mark.slow @pytest.mark.skipif(not julia_installed, reason="requires julia installation") def test_without_ext_grid(): - net = pp.create_empty_network() + net = create_empty_network() min_vm_pu = 0.95 max_vm_pu = 1.05 # create buses - bus1 = pp.create_bus(net, vn_kv=220., geodata=(5, 9)) - bus2 = pp.create_bus(net, vn_kv=110., geodata=(6, 10), min_vm_pu=min_vm_pu, max_vm_pu=max_vm_pu) - bus3 = pp.create_bus(net, vn_kv=110., geodata=(10, 9), min_vm_pu=min_vm_pu, max_vm_pu=max_vm_pu) - bus4 = pp.create_bus(net, vn_kv=110., geodata=(8, 8), min_vm_pu=min_vm_pu, max_vm_pu=max_vm_pu) - bus5 = pp.create_bus(net, vn_kv=110., geodata=(6, 8), min_vm_pu=min_vm_pu, max_vm_pu=max_vm_pu) + bus1 = create_bus(net, vn_kv=220., geodata=(5, 9)) + bus2 = create_bus(net, vn_kv=110., geodata=(6, 10), min_vm_pu=min_vm_pu, max_vm_pu=max_vm_pu) + bus3 = create_bus(net, vn_kv=110., geodata=(10, 9), min_vm_pu=min_vm_pu, max_vm_pu=max_vm_pu) + bus4 = create_bus(net, vn_kv=110., geodata=(8, 8), min_vm_pu=min_vm_pu, max_vm_pu=max_vm_pu) + bus5 = create_bus(net, vn_kv=110., geodata=(6, 8), min_vm_pu=min_vm_pu, max_vm_pu=max_vm_pu) # create 220/110/110 kV 3W-transformer - pp.create_transformer3w_from_parameters(net, bus1, bus2, bus5, vn_hv_kv=220, vn_mv_kv=110, - vn_lv_kv=110, vk_hv_percent=10., vk_mv_percent=10., - vk_lv_percent=10., vkr_hv_percent=0.5, - vkr_mv_percent=0.5, vkr_lv_percent=0.5, pfe_kw=100, - i0_percent=0.1, shift_mv_degree=0, shift_lv_degree=0, - sn_hv_mva=100, sn_mv_mva=50, sn_lv_mva=50) + create_transformer3w_from_parameters(net, bus1, bus2, bus5, vn_hv_kv=220, vn_mv_kv=110, + vn_lv_kv=110, vk_hv_percent=10., vk_mv_percent=10., + vk_lv_percent=10., vkr_hv_percent=0.5, + vkr_mv_percent=0.5, vkr_lv_percent=0.5, pfe_kw=100, + i0_percent=0.1, shift_mv_degree=0, shift_lv_degree=0, + sn_hv_mva=100, sn_mv_mva=50, sn_lv_mva=50) # create 110 kV lines - pp.create_line(net, bus2, bus3, length_km=70., std_type='149-AL1/24-ST1A 110.0') - pp.create_line(net, bus3, bus4, length_km=50., std_type='149-AL1/24-ST1A 110.0') - pp.create_line(net, bus4, bus2, length_km=40., std_type='149-AL1/24-ST1A 110.0') - pp.create_line(net, bus4, bus5, length_km=30., std_type='149-AL1/24-ST1A 110.0') + create_line(net, bus2, bus3, length_km=70., std_type='149-AL1/24-ST1A 110.0') + create_line(net, bus3, bus4, length_km=50., std_type='149-AL1/24-ST1A 110.0') + create_line(net, bus4, bus2, length_km=40., std_type='149-AL1/24-ST1A 110.0') + create_line(net, bus4, bus5, length_km=30., std_type='149-AL1/24-ST1A 110.0') # create loads - pp.create_load(net, bus2, p_mw=60, controllable=False) - pp.create_load(net, bus3, p_mw=70, controllable=False) - pp.create_load(net, bus4, p_mw=10, controllable=False) + create_load(net, bus2, p_mw=60, controllable=False) + create_load(net, bus3, p_mw=70, controllable=False) + create_load(net, bus4, p_mw=10, controllable=False) # create generators - g1 = pp.create_gen(net, bus1, p_mw=40, min_p_mw=0, min_q_mvar=-20, max_q_mvar=20, slack=True, min_vm_pu=min_vm_pu, - max_vm_pu=max_vm_pu) - pp.create_poly_cost(net, g1, 'gen', cp1_eur_per_mw=1000) + g1 = create_gen(net, bus1, p_mw=40, min_p_mw=0, min_q_mvar=-20, max_q_mvar=20, slack=True, min_vm_pu=min_vm_pu, + max_vm_pu=max_vm_pu) + create_poly_cost(net, g1, 'gen', cp1_eur_per_mw=1000) - g2 = pp.create_gen(net, bus3, p_mw=40, min_p_mw=0, min_q_mvar=-20, max_q_mvar=20, vm_pu=1.01, - min_vm_pu=min_vm_pu, max_vm_pu=max_vm_pu, max_p_mw=40.) - pp.create_poly_cost(net, g2, 'gen', cp1_eur_per_mw=2000) + g2 = create_gen(net, bus3, p_mw=40, min_p_mw=0, min_q_mvar=-20, max_q_mvar=20, vm_pu=1.01, + min_vm_pu=min_vm_pu, max_vm_pu=max_vm_pu, max_p_mw=40.) + create_poly_cost(net, g2, 'gen', cp1_eur_per_mw=2000) - g3 = pp.create_gen(net, bus4, p_mw=0.050, min_p_mw=0, min_q_mvar=-20, max_q_mvar=20, vm_pu=1.01, - min_vm_pu=min_vm_pu, - max_vm_pu=max_vm_pu, max_p_mw=0.05) - pp.create_poly_cost(net, g3, 'gen', cp1_eur_per_mw=3000) + g3 = create_gen(net, bus4, p_mw=0.050, min_p_mw=0, min_q_mvar=-20, max_q_mvar=20, vm_pu=1.01, + min_vm_pu=min_vm_pu, + max_vm_pu=max_vm_pu, max_p_mw=0.05) + create_poly_cost(net, g3, 'gen', cp1_eur_per_mw=3000) - pp.runpm_ac_opf(net) + runpm_ac_opf(net) consistency_checks(net, rtol=1e-3) assert np.isclose(net.res_gen.p_mw.at[g2], 0, atol=1e-5, rtol=1e-5) assert np.isclose(net.res_gen.p_mw.at[g3], 0, atol=1e-5, rtol=1e-5) assert np.isclose(net.res_cost, net.res_gen.p_mw.at[g1] * 1e3) net.trafo3w["max_loading_percent"] = 150. - pp.runpm_ac_opf(net) + runpm_ac_opf(net) consistency_checks(net, rtol=1e-3) assert 149. < net.res_trafo3w.loading_percent.values[0] < 150.01 assert np.isclose(net.res_cost, net.res_gen.p_mw.at[g1] * 1e3 + net.res_gen.p_mw.at[g2] * 2e3) - pp.runpm_dc_opf(net) + runpm_dc_opf(net) consistency_checks(net, rtol=1e-3, test_q=False) assert 149. < net.res_trafo3w.loading_percent.values[0] < 150.01 assert np.isclose(net.res_cost, net.res_gen.p_mw.at[g1] * 1e3 + net.res_gen.p_mw.at[g2] * 2e3) @@ -353,7 +362,7 @@ def test_without_ext_grid(): @pytest.mark.slow @pytest.mark.skipif(not julia_installed, reason="requires julia installation") def test_multiple_ext_grids(): - net = pp.create_empty_network() + net = create_empty_network() # generate three ext grids b11, b12, l11 = add_grid_connection(net, vn_kv=110.) b21, b22, l21 = add_grid_connection(net, vn_kv=110.) @@ -363,10 +372,10 @@ def test_multiple_ext_grids(): create_test_line(net, b22, b32) # create load and sgen to optimize - pp.create_load(net, b12, p_mw=60) + create_load(net, b12, p_mw=60) - g3 = pp.create_sgen(net, b12, p_mw=50, min_p_mw=20, max_p_mw=200, controllable=True) - pp.create_poly_cost(net, g3, 'sgen', cp1_eur_per_mw=10.) + g3 = create_sgen(net, b12, p_mw=50, min_p_mw=20, max_p_mw=200, controllable=True) + create_poly_cost(net, g3, 'sgen', cp1_eur_per_mw=10.) # set positive costs for ext_grid -> minimize ext_grid usage ext_grids = net.ext_grid.index net["ext_grid"].loc[0, "vm_pu"] = .99 @@ -374,27 +383,27 @@ def test_multiple_ext_grids(): net["ext_grid"].loc[2, "vm_pu"] = 1.01 for idx in ext_grids: # eg = net["ext_grid"].loc[idx] - pp.create_poly_cost(net, idx, 'ext_grid', cp1_eur_per_mw=10.) + create_poly_cost(net, idx, 'ext_grid', cp1_eur_per_mw=10.) - pp.runpm_ac_opf(net) + runpm_ac_opf(net) assert np.allclose(net.res_sgen.loc[0, "p_mw"], 60.) @pytest.mark.slow @pytest.mark.skipif(not julia_installed, reason="requires julia installation") def test_voltage_angles(): - net = pp.create_empty_network() + net = create_empty_network() b1, b2, l1 = add_grid_connection(net, vn_kv=110.) - b3 = pp.create_bus(net, vn_kv=20.) - b4 = pp.create_bus(net, vn_kv=10.) - b5 = pp.create_bus(net, vn_kv=10., in_service=False) - tidx = pp.create_transformer3w( + b3 = create_bus(net, vn_kv=20.) + b4 = create_bus(net, vn_kv=10.) + b5 = create_bus(net, vn_kv=10., in_service=False) + tidx = create_transformer3w( net, b2, b3, b4, std_type='63/25/38 MVA 110/20/10 kV', max_loading_percent=120) - pp.create_load(net, b3, p_mw=5, controllable=False) - load_id = pp.create_load(net, b4, p_mw=5, controllable=True, max_p_mw=25, min_p_mw=0, min_q_mvar=-1e-6, - max_q_mvar=1e-6) - pp.create_poly_cost(net, 0, "ext_grid", cp1_eur_per_mw=1) - pp.create_poly_cost(net, load_id, "load", cp1_eur_per_mw=1000) + create_load(net, b3, p_mw=5, controllable=False) + load_id = create_load(net, b4, p_mw=5, controllable=True, max_p_mw=25, min_p_mw=0, min_q_mvar=-1e-6, + max_q_mvar=1e-6) + create_poly_cost(net, 0, "ext_grid", cp1_eur_per_mw=1) + create_poly_cost(net, load_id, "load", cp1_eur_per_mw=1000) net.trafo3w.at[tidx, "shift_lv_degree"] = 10 net.trafo3w.at[tidx, "shift_mv_degree"] = 30 net.bus.loc[:, "max_vm_pu"] = 1.1 @@ -403,13 +412,13 @@ def test_voltage_angles(): # load is zero since costs are high. PF results should be the same as OPF net.load.loc[1, "p_mw"] = 0. - pp.runpp(net, calculate_voltage_angles=True) + runpp(net, calculate_voltage_angles=True) va_degree = net.res_bus.loc[:, "va_degree"].values vm_pu = net.res_bus.loc[:, "vm_pu"].values loading3w = net.res_trafo3w.loc[:, "loading_percent"].values net_opf = copy.deepcopy(net) - pp.runpm_ac_opf(net_opf) + runpm_ac_opf(net_opf) assert 30. < (net_opf.res_bus.va_degree.at[b1] - net_opf.res_bus.va_degree.at[b3]) % 360 < 32. assert 10. < (net_opf.res_bus.va_degree.at[b1] - net_opf.res_bus.va_degree.at[b4]) % 360 < 11. @@ -421,48 +430,48 @@ def test_voltage_angles(): def tnep_grid(): - net = pp.create_empty_network() + net = create_empty_network() min_vm_pu = 0.95 max_vm_pu = 1.05 # create buses - bus1 = pp.create_bus(net, vn_kv=110., geodata=(5, 9), min_vm_pu=min_vm_pu, max_vm_pu=max_vm_pu) - bus2 = pp.create_bus(net, vn_kv=110., geodata=(6, 10), min_vm_pu=min_vm_pu, max_vm_pu=max_vm_pu) - bus3 = pp.create_bus(net, vn_kv=110., geodata=(10, 9), min_vm_pu=min_vm_pu, max_vm_pu=max_vm_pu) - bus4 = pp.create_bus(net, vn_kv=110., geodata=(8, 8), min_vm_pu=min_vm_pu, max_vm_pu=max_vm_pu) + bus1 = create_bus(net, vn_kv=110., geodata=(5, 9), min_vm_pu=min_vm_pu, max_vm_pu=max_vm_pu) + bus2 = create_bus(net, vn_kv=110., geodata=(6, 10), min_vm_pu=min_vm_pu, max_vm_pu=max_vm_pu) + bus3 = create_bus(net, vn_kv=110., geodata=(10, 9), min_vm_pu=min_vm_pu, max_vm_pu=max_vm_pu) + bus4 = create_bus(net, vn_kv=110., geodata=(8, 8), min_vm_pu=min_vm_pu, max_vm_pu=max_vm_pu) # create 110 kV lines - pp.create_line(net, bus1, bus2, length_km=70., std_type='149-AL1/24-ST1A 110.0') - pp.create_line(net, bus1, bus3, length_km=50., std_type='149-AL1/24-ST1A 110.0') - pp.create_line(net, bus1, bus4, length_km=100., std_type='149-AL1/24-ST1A 110.0') + create_line(net, bus1, bus2, length_km=70., std_type='149-AL1/24-ST1A 110.0') + create_line(net, bus1, bus3, length_km=50., std_type='149-AL1/24-ST1A 110.0') + create_line(net, bus1, bus4, length_km=100., std_type='149-AL1/24-ST1A 110.0') # create loads - pp.create_load(net, bus2, p_mw=60) - pp.create_load(net, bus3, p_mw=70) - pp.create_load(net, bus4, p_mw=50) + create_load(net, bus2, p_mw=60) + create_load(net, bus3, p_mw=70) + create_load(net, bus4, p_mw=50) # create generators - g1 = pp.create_gen(net, bus1, p_mw=9.513270, min_p_mw=0, max_p_mw=200, vm_pu=1.01, slack=True) - pp.create_poly_cost(net, g1, 'gen', cp1_eur_per_mw=1) + g1 = create_gen(net, bus1, p_mw=9.513270, min_p_mw=0, max_p_mw=200, vm_pu=1.01, slack=True) + create_poly_cost(net, g1, 'gen', cp1_eur_per_mw=1) - g2 = pp.create_gen(net, bus2, p_mw=78.403291, min_p_mw=0, max_p_mw=200, vm_pu=1.01) - pp.create_poly_cost(net, g2, 'gen', cp1_eur_per_mw=3) + g2 = create_gen(net, bus2, p_mw=78.403291, min_p_mw=0, max_p_mw=200, vm_pu=1.01) + create_poly_cost(net, g2, 'gen', cp1_eur_per_mw=3) - g3 = pp.create_gen(net, bus3, p_mw=92.375601, min_p_mw=0, max_p_mw=200, vm_pu=1.01) - pp.create_poly_cost(net, g3, 'gen', cp1_eur_per_mw=3) + g3 = create_gen(net, bus3, p_mw=92.375601, min_p_mw=0, max_p_mw=200, vm_pu=1.01) + create_poly_cost(net, g3, 'gen', cp1_eur_per_mw=3) net.line["max_loading_percent"] = 20 # possible new lines (set out of service in line DataFrame) - l1 = pp.create_line(net, bus1, bus4, 10., std_type="305-AL1/39-ST1A 110.0", name="new_line1", - max_loading_percent=20., in_service=False) - l2 = pp.create_line(net, bus2, bus4, 20., std_type="149-AL1/24-ST1A 110.0", name="new_line2", - max_loading_percent=20., in_service=False) - l3 = pp.create_line(net, bus3, bus4, 30., std_type='149-AL1/24-ST1A 110.0', name="new_line3", - max_loading_percent=20., in_service=False) - l4 = pp.create_line(net, bus3, bus4, 40., std_type='149-AL1/24-ST1A 110.0', name="new_line4", - max_loading_percent=20., in_service=False) + l1 = create_line(net, bus1, bus4, 10., std_type="305-AL1/39-ST1A 110.0", name="new_line1", + max_loading_percent=20., in_service=False) + l2 = create_line(net, bus2, bus4, 20., std_type="149-AL1/24-ST1A 110.0", name="new_line2", + max_loading_percent=20., in_service=False) + l3 = create_line(net, bus3, bus4, 30., std_type='149-AL1/24-ST1A 110.0', name="new_line3", + max_loading_percent=20., in_service=False) + l4 = create_line(net, bus3, bus4, 40., std_type='149-AL1/24-ST1A 110.0', name="new_line4", + max_loading_percent=20., in_service=False) new_line_index = [l1, l2, l3, l4] construction_costs = [10., 20., 30., 45.] @@ -477,17 +486,17 @@ def tnep_grid(): def test_pm_tnep(): net = tnep_grid() # check if max line loading percent is violated (should be) - pp.runpp(net) + runpp(net) assert np.any(net["res_line"].loc[:, "loading_percent"] > net["line"].loc[:, "max_loading_percent"]) # run power models tnep optimization - pp.runpm_tnep(net, pm_model="ACPPowerModel") + runpm_tnep(net, pm_model="ACPPowerModel") # set lines to be built in service lines_to_built = net["res_ne_line"].loc[net["res_ne_line"].loc[:, "built"], "built"].index net["line"].loc[lines_to_built, "in_service"] = True # run a power flow calculation again and check if max_loading percent is still violated - pp.runpp(net) + runpp(net) # check max line loading results assert not np.any(net["res_line"].loc[:, "loading_percent"] > net["line"].loc[:, "max_loading_percent"]) @@ -498,15 +507,15 @@ def test_pm_tnep(): # @pytest.mark.xfail(reason="OTS does not correctly consider net.sn_mva. Probably the impedances [pu]" # " are not correctly calculated.") def test_ots_opt(): - net = nw.case5() + net = case5() net.sn_mva = 1. branch_status = net["line"].loc[:, "in_service"].values assert np.array_equal(np.array([1, 1, 1, 1, 1, 1]).astype(bool), branch_status.astype(bool)) - pp.runpm_ots(net) + runpm_ots(net) branch_status = net["res_line"].loc[:, "in_service"].values - pp.runpp(net) + runpp(net) net.line.loc[:, "in_service"] = branch_status.astype(bool) - pp.runpp(net) + runpp(net) try: assert np.array_equal(np.array([1, 1, 1, 0, 1, 0]).astype(bool), branch_status.astype(bool)) except AssertionError: @@ -519,23 +528,23 @@ def test_timeseries_pandamodels(): profiles = pd.DataFrame() n_timesteps = 3 profiles['load1'] = np.random.random(n_timesteps) * 2e1 - ds = pp.timeseries.DFData(profiles) + ds = DFData(profiles) - net = nw.simple_four_bus_system() + net = simple_four_bus_system() time_steps = range(3) - pp.control.ConstControl(net, 'load', 'p_mw', element_index=0, data_source=ds, profile_name='load1', - scale_factor=0.85) + ConstControl(net, 'load', 'p_mw', element_index=0, data_source=ds, profile_name='load1', + scale_factor=0.85) net.load['controllable'] = False - pp.timeseries.run_timeseries(net, time_steps, continue_on_divergence=True, verbose=False, recycle=False, - run=pp.runpm_dc_opf) + run_timeseries(net, time_steps, continue_on_divergence=True, verbose=False, recycle=False, + run=runpm_dc_opf) @pytest.mark.skipif(not julia_installed, reason="requires julia installation") def test_runpm_vstab(): - net = nw.create_cigre_network_mv(with_der="pv_wind") + net = create_cigre_network_mv(with_der="pv_wind") net.sgen.p_mw = net.sgen.p_mw * 8 net.sgen.sn_mva = net.sgen.sn_mva * 8 - pp.runpp(net) + runpp(net) net_org = deepcopy(net) net.load['controllable'] = False @@ -558,16 +567,16 @@ def test_runpm_vstab(): net.line["max_loading_percent"] = 500.0 for idx in net.sgen.index: - pp.create_poly_cost(net, idx, "sgen", 1.0) + create_poly_cost(net, idx, "sgen", 1.0) for idx in net.gen.index: - pp.create_poly_cost(net, idx, "gen", 1.0) + create_poly_cost(net, idx, "gen", 1.0) for idx in net.ext_grid.index: - pp.create_poly_cost(net, idx, "ext_grid", 1.0) + create_poly_cost(net, idx, "ext_grid", 1.0) net.bus["pm_param/setpoint_v"] = None net.bus["pm_param/setpoint_v"].loc[net.sgen.bus] = 0.99 - pp.runpm_vstab(net) + runpm_vstab(net) assert np.allclose(net.res_bus.vm_pu[net.sgen.bus], 0.99, atol=1e-2, rtol=1e-2) assert np.not_equal(net_org.res_sgen.q_mvar.values.all(), net.res_sgen.q_mvar.values.all()) @@ -587,26 +596,25 @@ def test_storage_opt(): assert set(pm["time_series"]["load"]["1"]["p_mw"].keys()) == set([str(i) for i in range(5, 26)]) net = create_cigre_grid_with_time_series(json_path) - pp.runpm_storage_opf(net, from_time_step=0, to_time_step=5) + runpm_storage_opf(net, from_time_step=0, to_time_step=5) storage_results_1 = read_pm_storage_results(net) assert net._pm_org_result["multinetwork"] assert net._pm["pm_solver"] == "juniper" assert net._pm["pm_mip_solver"] == "cbc" assert len(net.res_ts_opt) == 5 - net2 = create_cigre_grid_with_time_series(json_path) net2.sn_mva = 100.0 - pp.runpm_storage_opf(net2, from_time_step=0, to_time_step=5) + runpm_storage_opf(net2, from_time_step=0, to_time_step=5) storage_results_100 = read_pm_storage_results(net2) assert abs(storage_results_100[0].values - storage_results_1[0].values).max() < 1e-6 @pytest.mark.slow -@pytest.mark.skipif(julia_installed == False, reason="requires julia installation") +@pytest.mark.skipif(not julia_installed, reason="requires julia installation") def test_runpm_multi_vstab(): - net = nw.create_cigre_network_mv(with_der="pv_wind") + net = create_cigre_network_mv(with_der="pv_wind") net.load['controllable'] = False net.sgen['controllable'] = True # lower and upper bounds for buses @@ -628,7 +636,7 @@ def test_runpm_multi_vstab(): net.trafo["max_loading_percent"] = 100.0 net.line["max_loading_percent"] = 100.0 - net.bus["pm_param/setpoint_v"] = None # add extra column + net.bus["pm_param/setpoint_v"] = None # add extra column net.bus["pm_param/setpoint_v"].loc[net.sgen.bus] = 0.96 # load time series data for 96 time steps @@ -636,7 +644,7 @@ def test_runpm_multi_vstab(): create_cigre_grid_with_time_series(json_path, net, True) # run time series opf - pp.runpm_multi_vstab(net, from_time_step=0, to_time_step=96) + runpm_multi_vstab(net, from_time_step=0, to_time_step=96) assert len(net.res_ts_opt) == 96 # get opf-results @@ -649,11 +657,10 @@ def test_runpm_multi_vstab(): @pytest.mark.slow -@pytest.mark.skipif(julia_installed == False, reason="requires julia installation") +@pytest.mark.skipif(not julia_installed, reason="requires julia installation") def test_runpm_qflex_and_multi_qflex(): - - net = nw.create_cigre_network_mv(with_der="pv_wind") - pp.runpp(net) + net = create_cigre_network_mv(with_der="pv_wind") + runpp(net) net.load['controllable'] = False net.sgen['controllable'] = True @@ -676,31 +683,31 @@ def test_runpm_qflex_and_multi_qflex(): net.trafo["max_loading_percent"] = 100.0 net.line["max_loading_percent"] = 100.0 - net.trafo["pm_param/setpoint_q"] = None # add extra column + net.trafo["pm_param/setpoint_q"] = None # add extra column net.trafo["pm_param/setpoint_q"].loc[0] = -5 net.trafo["pm_param/side"] = None net.trafo["pm_param/side"][0] = "lv" # run opf - pp.runpm_qflex(net) + runpm_qflex(net) opt_q = net.res_trafo.q_lv_mvar[0] - assert abs(opt_q + 5) < 1e-6 + assert abs(opt_q + 5) < 1e-6 # test for multi_qflex # load time series data for 96 time steps json_path = os.path.join(pp_dir, "test", "opf", "cigre_timeseries_15min.json") create_cigre_grid_with_time_series(json_path, net, True) - pp.runpm_multi_qflex(net, from_time_step=0, to_time_step=96) + runpm_multi_qflex(net, from_time_step=0, to_time_step=96) # get opf-results y_multi = [] for t in range(96): - y_multi.append(abs(abs(net.res_ts_opt[str(t)].res_trafo.q_lv_mvar[0])-5)) + y_multi.append(abs(abs(net.res_ts_opt[str(t)].res_trafo.q_lv_mvar[0]) - 5)) assert np.array(y_multi).max() < 1e-6 @pytest.mark.skipif(not julia_installed, reason="requires julia installation") def test_runpm_ploss_loading(): - net = nw.create_cigre_network_mv(with_der="pv_wind") + net = create_cigre_network_mv(with_der="pv_wind") net.load['controllable'] = False net.sgen['controllable'] = True net.sgen["max_p_mw"] = net.sgen.p_mw.values @@ -717,56 +724,55 @@ def test_runpm_ploss_loading(): net.line["max_loading_percent"] = 100.0 net.line["pm_param/target_branch"] = True net.switch.loc[:, "closed"] = True - pp.runpp(net) + runpp(net) net_org = deepcopy(net) - pp.runpm_ploss(net) + runpm_ploss(net) - ### test loss reduction with Q-optimierung + # test loss reduction with Q-optimierung assert net.res_line.pl_mw.values.sum() < net_org.res_line.pl_mw.values.sum() net.line = net.line.drop(columns=["pm_param/target_branch"]) net.trafo["pm_param/target_branch"] = True - pp.runpm_ploss(net) + runpm_ploss(net) assert net.res_trafo.pl_mw.values.sum() < net_org.res_trafo.pl_mw.values.sum() - ### test loading reduction with Q-optimierung + # test loading reduction with Q-optimierung net = deepcopy(net_org) - pp.runpm_loading(net) - assert (net.res_line.loading_percent.values - \ - net_org.res_line.loading_percent.values).sum() < 0 + runpm_loading(net) + assert (net.res_line.loading_percent.values - net_org.res_line.loading_percent.values).sum() < 0 -@pytest.mark.skipif(julia_installed == False, reason="requires julia installation") +@pytest.mark.skipif(not julia_installed, reason="requires julia installation") def test_convergence_dc_opf(): for cpnd in [True, False]: - net = nw.case5() - pp.runpm_dc_opf(net, correct_pm_network_data=cpnd) - net = nw.case9() - pp.runpm_dc_opf(net, correct_pm_network_data=cpnd) - net = nw.case14() - pp.runpm_dc_opf(net, correct_pm_network_data=cpnd) - net = nw.case30() - pp.runpm_dc_opf(net, correct_pm_network_data=cpnd) - net = nw.case39() - pp.runpm_dc_opf(net, correct_pm_network_data=cpnd) - net = nw.case57() - pp.runpm_dc_opf(net, correct_pm_network_data=cpnd) - net = nw.case118() - pp.runpm_dc_opf(net, correct_pm_network_data=cpnd) - net = nw.case145() - pp.runpm_dc_opf(net, correct_pm_network_data=cpnd) - net = nw.case300() - pp.runpm_dc_opf(net, correct_pm_network_data=cpnd) - - -@pytest.mark.skipif(julia_installed == False, reason="requires julia installation") + net = case5() + runpm_dc_opf(net, correct_pm_network_data=cpnd) + net = case9() + runpm_dc_opf(net, correct_pm_network_data=cpnd) + net = case14() + runpm_dc_opf(net, correct_pm_network_data=cpnd) + net = case30() + runpm_dc_opf(net, correct_pm_network_data=cpnd) + net = case39() + runpm_dc_opf(net, correct_pm_network_data=cpnd) + net = case57() + runpm_dc_opf(net, correct_pm_network_data=cpnd) + net = case118() + runpm_dc_opf(net, correct_pm_network_data=cpnd) + net = case145() + runpm_dc_opf(net, correct_pm_network_data=cpnd) + net = case300() + runpm_dc_opf(net, correct_pm_network_data=cpnd) + + +@pytest.mark.skipif(not julia_installed, reason="requires julia installation") def test_ac_opf_differnt_snmva(): - net = nw.case9() + net = case9() res = pd.DataFrame(columns=net.bus.index.tolist()) for i, snmva in enumerate([1, 13, 45, 78, 98, 100]): net.sn_mva = snmva - pp.runpm_ac_opf(net) + runpm_ac_opf(net) res.loc[i] = net.res_bus.vm_pu.values for i in res.columns: assert res[i].values.min() - res[i].values.max() < 1e-10 diff --git a/pandapower/test/opf/test_pp_vs_pm.py b/pandapower/test/opf/test_pp_vs_pm.py index d58e24932..358f3236d 100644 --- a/pandapower/test/opf/test_pp_vs_pm.py +++ b/pandapower/test/opf/test_pp_vs_pm.py @@ -3,14 +3,18 @@ # Copyright (c) 2016-2024 by University of Kassel and Fraunhofer Institute for Energy Economics # and Energy System Technology (IEE), Kassel. All rights reserved. -from pandapower.pypower.idx_bus import BUS_I, VMAX, VMIN, BUS_TYPE, REF +import copy + import numpy as np import pytest -import copy from numpy import array + from pandapower.converter.pypower import from_ppc -import pandapower as pp +from pandapower.create import create_ext_grid from pandapower.pd2ppc import _pd2ppc +from pandapower.pypower.idx_bus import BUS_I, VMAX, VMIN, BUS_TYPE, REF +from pandapower.run import runpp, runopp +from pandapower.runpm import runpm_ac_opf try: from julia.core import UnsupportedPythonError @@ -18,6 +22,7 @@ UnsupportedPythonError = Exception try: from julia.api import Julia + Julia(compiled_modules=False) from julia import Main @@ -34,7 +39,7 @@ # test data from :https://github.com/lanl-ansi/PowerModels.jl/blob/master/test/data/matpower/case5_clm.m -def case5_pm_matfile_I(): +def case5_pm_matfile_i(): mpc = {"branch": array([ [1, 2, 0.00281, 0.0281, 0.00712, 400.0, 0.0, 0.0, 0.0, 0.0, 1, -30.0, 30.0], [1, 4, 0.00304, 0.0304, 0.00658, 426, 0.0, 0.0, 0.0, 0.0, 1, -30.0, 30.0], @@ -70,9 +75,9 @@ def case5_pm_matfile_I(): def test_case5_pm_pd2ppc(): # load net - net = case5_pm_matfile_I() + net = case5_pm_matfile_i() # run pd2ppc with ext_grid controllable = False - pp.runpp(net) + runpp(net) assert "controllable" not in net.ext_grid net["_options"]["mode"] = "opf" ppc = _pd2ppc(net) @@ -96,7 +101,7 @@ def test_case5_pm_pd2ppc(): assert net.ext_grid["in_service"].values.dtype == bool assert net.ext_grid["bus"].values.dtype == "uint32" - pp.create_ext_grid(net, bus=4, vm_pu=net.res_bus.vm_pu.loc[4], controllable=False) + create_ext_grid(net, bus=4, vm_pu=net.res_bus.vm_pu.loc[4], controllable=False) assert net.ext_grid["bus"].values.dtype == "uint32" assert net.ext_grid["in_service"].values.dtype == bool @@ -113,13 +118,13 @@ def test_case5_pm_pd2ppc(): def test_opf_ext_grid_controllable(): # load net - net = case5_pm_matfile_I() + net = case5_pm_matfile_i() net_old = copy.deepcopy(net) net_new = copy.deepcopy(net) # run pd2ppc with ext_grid controllable = False - pp.runopp(net_old, delta=1e-12) + runopp(net_old, delta=1e-12) net_new.ext_grid["controllable"] = True - pp.runopp(net_new, delta=1e-12) + runopp(net_new, delta=1e-12) eg_bus = net.ext_grid.bus.at[0] assert np.isclose(net_old.res_bus.vm_pu[eg_bus], 1.06414000007302) assert np.isclose(net_new.res_bus.vm_pu[eg_bus], net_new.res_bus.vm_pu[eg_bus]) @@ -130,11 +135,11 @@ def test_opf_ext_grid_controllable(): @pytest.mark.xfail def test_opf_create_ext_grid_controllable(): # load net - net = case5_pm_matfile_I() + net = case5_pm_matfile_i() # run pd2ppc with ext_grid controllable = False - pp.create_ext_grid(net, bus=1, controllable=True) - # pp.create_ext_grid(net, bus=4, controllable=True, min_p_mw=0, max_p_mw=200, min_q_mvar=-150, max_q_mvar=150) - pp.runopp(net) + create_ext_grid(net, bus=1, controllable=True) + # create_ext_grid(net, bus=4, controllable=True, min_p_mw=0, max_p_mw=200, min_q_mvar=-150, max_q_mvar=150) + runopp(net) assert np.isclose(net.res_bus.vm_pu[net.ext_grid.bus[0]], 1.0641399999827315) @@ -142,17 +147,17 @@ def test_opf_create_ext_grid_controllable(): @pytest.mark.skipif(not julia_installed, reason="requires julia installation") def test_opf_ext_grid_controllable_pm(): # load net - net = case5_pm_matfile_I() + net = case5_pm_matfile_i() net_old = copy.deepcopy(net) - pp.runpp(net_old) - pp.runpm_ac_opf(net_old, calculate_voltage_angles=True, correct_pm_network_data=False, opf_flow_lim="I") + runpp(net_old) + runpm_ac_opf(net_old, calculate_voltage_angles=True, correct_pm_network_data=False, opf_flow_lim="I") net_new = copy.deepcopy(net) net_new.ext_grid["controllable"] = True - pp.runpp(net_new) - pp.runpm_ac_opf(net_new, calculate_voltage_angles=True, correct_pm_network_data=False, - opf_flow_lim="I") + runpp(net_new) + runpm_ac_opf(net_new, calculate_voltage_angles=True, correct_pm_network_data=False, + opf_flow_lim="I") eg_bus = net.ext_grid.bus.at[0] assert np.isclose(net_old.res_bus.vm_pu[eg_bus], 1.06414000007302) @@ -162,4 +167,3 @@ def test_opf_ext_grid_controllable_pm(): if __name__ == "__main__": pytest.main([__file__, "-xs"]) - diff --git a/pandapower/test/plotting/test_create_colormaps.py b/pandapower/test/plotting/test_create_colormaps.py index e9cc979b9..8667fde53 100644 --- a/pandapower/test/plotting/test_create_colormaps.py +++ b/pandapower/test/plotting/test_create_colormaps.py @@ -5,13 +5,14 @@ import numpy as np -import pandapower.plotting as plot import pytest +from pandapower.plotting.colormaps import cmap_discrete, cmap_continuous, cmap_logarithmic + def test_cmap_discrete(): cmap_list = [((0, 10), "green"), ((10, 30), "yellow"), ((30, 100), "red")] - cmap, norm = plot.cmap_discrete(cmap_list) + cmap, norm = cmap_discrete(cmap_list) assert cmap.N == 3 assert norm.N == 4 assert norm(0) == 0 @@ -24,7 +25,7 @@ def test_cmap_discrete(): def test_cmap_continuous(): cmap_list = [(0.97, "blue"), (1.0, "green"), (1.03, "red")] - cmap, norm = plot.cmap_continuous(cmap_list) + cmap, norm = cmap_continuous(cmap_list) assert np.allclose(cmap(0.99), (0.984313725490196, 0.007873894655901603, 0.0, 1.0)) assert np.allclose(cmap(1.02), (1.0, 0.0, 0.0, 1.0)) @@ -35,7 +36,7 @@ def test_cmap_continuous(): def test_cmap_logarithmic(): min_value, max_value = 1.0, 1.03 colors = ["blue", "green", "red"] - cmap, norm = plot.cmap_logarithmic(min_value, max_value, colors) + cmap, norm = cmap_logarithmic(min_value, max_value, colors) assert np.allclose(cmap(0.1), (0.0, 0.09770172300400634, 0.8053598487029561, 1.0)) assert np.allclose(cmap(0.5), (0.0, 0.5002328217805124, 0.003442425359135415, 1.0)) assert np.allclose(cmap(0.8), (0.5970222233016451, 0.20227904085250753, 0.0, 1.0)) diff --git a/pandapower/test/plotting/test_generic_coordinates.py b/pandapower/test/plotting/test_generic_coordinates.py index 2aa2ae707..55d6c7262 100644 --- a/pandapower/test/plotting/test_generic_coordinates.py +++ b/pandapower/test/plotting/test_generic_coordinates.py @@ -3,14 +3,16 @@ # Copyright (c) 2016-2024 by University of Kassel and Fraunhofer Institute for Energy Economics # and Energy System Technology (IEE), Kassel. All rights reserved. +import numpy as np import pytest + +from pandapower.networks.simple_pandapower_test_networks import simple_four_bus_system +from pandapower.plotting.generic_geodata import create_generic_coordinates from pandapower.test.helper_functions import create_test_network -from pandapower.plotting.generic_geodata import create_generic_coordinates, build_igraph_from_pp -import pandapower as pp -import pandapower.networks as nw -import numpy as np + try: import igraph + IGRAPH_INSTALLED = True except ImportError: IGRAPH_INSTALLED = False @@ -32,9 +34,10 @@ def test_create_generic_coordinates_nx(): create_generic_coordinates(net, library="networkx") assert len(net.bus_geodata) == len(net.bus) + @pytest.mark.skipif(IGRAPH_INSTALLED is False, reason="Requires igraph.") def test_create_generic_coordinates_igraph_custom_table_index(): - net = nw.simple_four_bus_system() + net = simple_four_bus_system() for buses in [[0, 1], [0, 2], [0, 1, 2]]: create_generic_coordinates(net, buses=buses, geodata_table="test", overwrite=True) assert np.all(net.test.index == buses) diff --git a/pandapower/test/plotting/test_geo.py b/pandapower/test/plotting/test_geo.py index a3aac1c1e..3417b1575 100644 --- a/pandapower/test/plotting/test_geo.py +++ b/pandapower/test/plotting/test_geo.py @@ -3,18 +3,20 @@ # Copyright (c) 2016-2024 by University of Kassel and Fraunhofer Institute for Energy Economics # and Energy System Technology (IEE), Kassel. All rights reserved. -import os -import math import copy +import math +import os import geojson import pandas as pd import pytest from pandas.testing import assert_frame_equal, assert_index_equal -import pandapower.plotting.geo as geo +from pandapower.networks.mv_oberrhein import mv_oberrhein +from pandapower.plotting.geo import _node_geometries_from_geodata, _branch_geometries_from_geodata, \ + _transform_node_geometry_to_geodata, _transform_branch_geometry_to_coords, _convert_xy_epsg, \ + convert_gis_to_geodata, convert_geodata_to_gis, convert_geodata_to_geojson, dump_to_geojson from pandapower.test.helper_functions import create_test_network -import pandapower.networks as pn def _bus_geojson_to_geodata_(_net): @@ -29,11 +31,12 @@ def _bus_geojson_to_geodata_(_net): def _line_geojson_to_geodata_(_net): - _net["line_geodata"] = _net.line.geo.dropna().apply(geojson.loads).apply(geojson.utils.coords).apply(list).to_frame().rename(columns={"geo": "coords"}) + _net["line_geodata"] = _net.line.geo.dropna().apply(geojson.loads).apply(geojson.utils.coords).apply( + list).to_frame().rename(columns={"geo": "coords"}) _net.line.drop("geo", axis=1, inplace=True) -@pytest.fixture(name='net', params=(create_test_network(), pn.mv_oberrhein())) +@pytest.fixture(name='net', params=(create_test_network(), mv_oberrhein())) def test_network(request): """ Fixture which yields different networks for testing. @@ -59,7 +62,7 @@ def test__node_geometries_from_geodata(get_network_and_result): _net, expected = get_network_and_result _bus_geojson_to_geodata_(_net) - result = geo._node_geometries_from_geodata(_net.bus_geodata) + result = _node_geometries_from_geodata(_net.bus_geodata) # is mostly the same as assert_geodataframe_equal with check_less_precise=True, but the tolerance in the function # can't be adapted assert result.shape == expected.shape @@ -70,7 +73,8 @@ def test__node_geometries_from_geodata(get_network_and_result): left2 = result.select_dtypes(exclude="geometry") right2 = expected.select_dtypes(exclude="geometry") assert_index_equal(result.columns, expected.columns, exact="equiv", obj="GeoDataFrame.columns") - assert_frame_equal(left2, right2, check_dtype=True, check_index_type="equiv", check_column_type="equiv", obj="GeoDataFrame") + assert_frame_equal(left2, right2, check_dtype=True, check_index_type="equiv", check_column_type="equiv", + obj="GeoDataFrame") def test__branch_geometries_from_geodata(get_network_and_result): @@ -80,7 +84,7 @@ def test__branch_geometries_from_geodata(get_network_and_result): _line_geojson_to_geodata_(_net) - result = geo._branch_geometries_from_geodata(_net.line_geodata) + result = _branch_geometries_from_geodata(_net.line_geodata) # is mostly the same as assert_geodataframe_equal with check_less_precise=True, but the tolerance in the function # can't be adapted assert result.shape == expected.shape @@ -102,8 +106,8 @@ def test__transform_node_geometry_to_geodata(get_network_and_result): _bus_geojson_to_geodata_(_net) # Transforming to geodata to test the inverse... - _net.bus_geodata = geo._node_geometries_from_geodata(_net.bus_geodata) - result = geo._transform_node_geometry_to_geodata(_net.bus_geodata) + _net.bus_geodata = _node_geometries_from_geodata(_net.bus_geodata) + result = _transform_node_geometry_to_geodata(_net.bus_geodata) # is mostly the same as assert_geodataframe_equal with check_less_precise=True, but the tolerance in the function # can't be adapted assert result.shape == expected.shape @@ -124,8 +128,8 @@ def test__transform_branch_geometry_to_coords(get_network_and_result): _net, expected = get_network_and_result _line_geojson_to_geodata_(_net) - _net.line_geodata = geo._branch_geometries_from_geodata(_net.line_geodata) - result = geo._transform_branch_geometry_to_coords(_net.line_geodata) + _net.line_geodata = _branch_geometries_from_geodata(_net.line_geodata) + result = _transform_branch_geometry_to_coords(_net.line_geodata) # is mostly the same as assert_geodataframe_equal with check_less_precise=True, but the tolerance in the function # can't be adapted assert result.shape == expected.shape @@ -143,20 +147,20 @@ def test__transform_branch_geometry_to_coords(get_network_and_result): def test__convert_xy_epsg(): x = 9.487 y = 51.320 - result = geo._convert_xy_epsg(x, y, 4326, 31467) + result = _convert_xy_epsg(x, y, 4326, 31467) expected = (3534023, 5687359) assert result == pytest.approx(expected) - result = geo._convert_xy_epsg(x, y, 4326, 3857) + result = _convert_xy_epsg(x, y, 4326, 3857) expected = (1056088, 6678094) assert result == pytest.approx(expected) x = 3534023 y = 5687359 - result = geo._convert_xy_epsg(x, y, 31467, 4326) + result = _convert_xy_epsg(x, y, 31467, 4326) expected = (9.487, 51.320) assert result == pytest.approx(expected, abs=1e-3) x = [9.487, 9] y = [51.320, 51] - result_x, result_y = geo._convert_xy_epsg(x, y, 4326, 31467) + result_x, result_y = _convert_xy_epsg(x, y, 4326, 31467) expected_x, expected_y = ([3534023, 3500073], [5687359, 5651645]) assert result_x == pytest.approx(expected_x) assert result_y == pytest.approx(expected_y) @@ -169,7 +173,7 @@ def test_convert_gis_to_geodata(): from geopandas import testing converted_node = pd.DataFrame({'x': [1., 1.], 'y': [2., 3.], 'coords': [float('nan'), float('nan')], - 'geometry': [Point(1., 2.), Point(1., 3.)]}) + 'geometry': [Point(1., 2.), Point(1., 3.)]}) converted_node.set_index(pd.Index([1, 7]), inplace=True) converted_branch = pd.DataFrame({'coords': [[(1., 2.), (3., 4.)]], 'geometry': LineString([[1, 2], [3, 4]])}) @@ -177,27 +181,27 @@ def test_convert_gis_to_geodata(): _bus_geojson_to_geodata_(_net) _line_geojson_to_geodata_(_net) - geo.convert_geodata_to_gis(_net) + convert_geodata_to_gis(_net) node_geodata = _net.bus_geodata branch_geodata = _net.line_geodata - geo.convert_gis_to_geodata(_net) + convert_gis_to_geodata(_net) _net.bus_geodata.equals(converted_node) _net.line_geodata.equals(converted_branch) _net = create_test_network() _bus_geojson_to_geodata_(_net) _line_geojson_to_geodata_(_net) - geo.convert_geodata_to_gis(_net) - geo.convert_gis_to_geodata(_net, node_geodata=False) + convert_geodata_to_gis(_net) + convert_gis_to_geodata(_net, node_geodata=False) testing.assert_geodataframe_equal(_net.bus_geodata, node_geodata) _net.line_geodata.equals(converted_branch) _net = create_test_network() _bus_geojson_to_geodata_(_net) _line_geojson_to_geodata_(_net) - geo.convert_geodata_to_gis(_net) - geo.convert_gis_to_geodata(_net, branch_geodata=False) + convert_geodata_to_gis(_net) + convert_gis_to_geodata(_net, branch_geodata=False) _net.bus_geodata.equals(converted_node) testing.assert_geodataframe_equal(_net.line_geodata, branch_geodata) @@ -222,21 +226,21 @@ def test_convert_geodata_to_gis(): node_geodata = _net.bus_geodata branch_geodata = _net.line_geodata - geo.convert_geodata_to_gis(_net) + convert_geodata_to_gis(_net) testing.assert_geodataframe_equal(_net.bus_geodata, converted_node) testing.assert_geodataframe_equal(_net.line_geodata, converted_branch) _net = create_test_network() _bus_geojson_to_geodata_(_net) _line_geojson_to_geodata_(_net) - geo.convert_geodata_to_gis(_net, node_geodata=False) + convert_geodata_to_gis(_net, node_geodata=False) _net.bus_geodata.equals(node_geodata) testing.assert_geodataframe_equal(_net.line_geodata, converted_branch) _net = create_test_network() _bus_geojson_to_geodata_(_net) _line_geojson_to_geodata_(_net) - geo.convert_geodata_to_gis(_net, branch_geodata=False) + convert_geodata_to_gis(_net, branch_geodata=False) testing.assert_geodataframe_equal(_net.bus_geodata, converted_node) _net.line_geodata.equals(branch_geodata) @@ -257,70 +261,121 @@ def test_dump_to_geojson(): _net = create_test_network() _bus_geojson_to_geodata_(_net) _line_geojson_to_geodata_(_net) - geo.convert_geodata_to_geojson(_net) + convert_geodata_to_geojson(_net) - result = geo.dump_to_geojson(_net) + result = dump_to_geojson(_net) assert isinstance(result, FeatureCollection) assert dumps(result, sort_keys=True) == '{"features": [], "type": "FeatureCollection"}' # test exporting nodes - result = geo.dump_to_geojson(_net, nodes=True) + result = dump_to_geojson(_net, nodes=True) assert isinstance(result, FeatureCollection) - assert dumps(result, sort_keys=True) == '{"features": [{"geometry": {"coordinates": [1.0, 2.0], "type": "Point"}, "id": "bus-1", "properties": {"in_service": true, "name": "bus2", "pp_index": 1, "pp_type": "bus", "type": "b", "vn_kv": 0.4, "zone": null}, "type": "Feature"}, {"geometry": {"coordinates": [1.0, 3.0], "type": "Point"}, "id": "bus-7", "properties": {"in_service": true, "name": "bus3", "pp_index": 7, "pp_type": "bus", "type": "b", "vn_kv": 0.4, "zone": null}, "type": "Feature"}], "type": "FeatureCollection"}' + assert dumps(result, sort_keys=True) == ('{"features": [{"geometry": {"coordinates": [1.0, 2.0], "type": "Point"}, ' + '"id": "bus-1", "properties": {"in_service": true, "name": "bus2", ' + '"pp_index": 1, "pp_type": "bus", "type": "b", "vn_kv": 0.4, ' + '"zone": null}, "type": "Feature"}, {"geometry": {"coordinates": [1.0, ' + '3.0], "type": "Point"}, "id": "bus-7", "properties": {"in_service": ' + 'true, "name": "bus3", "pp_index": 7, "pp_type": "bus", "type": "b", ' + '"vn_kv": 0.4, "zone": null}, "type": "Feature"}], ' + '"type": "FeatureCollection"}') # test exporting branches - result = geo.dump_to_geojson(_net, branches=True) + result = dump_to_geojson(_net, branches=True) assert isinstance(result, FeatureCollection) - assert dumps(result, sort_keys=True) == '{"features": [{"geometry": {"coordinates": [[1.0, 2.0], [3.0, 4.0]], "type": "LineString"}, "id": "line-0", "properties": {"c_nf_per_km": 720.0, "df": 1.0, "from_bus": 1, "g_us_per_km": 0.0, "ices": 0.389985, "in_service": true, "length_km": 1.0, "max_i_ka": 0.328, "name": "line1", "parallel": 1, "pp_index": 0, "pp_type": "line", "r_ohm_per_km": 0.2067, "std_type": null, "to_bus": 7, "type": null, "x_ohm_per_km": 0.1897522}, "type": "Feature"}], "type": "FeatureCollection"}' + assert dumps(result, sort_keys=True) == ('{"features": [{"geometry": {"coordinates": [[1.0, 2.0], [3.0, 4.0]], ' + '"type": "LineString"}, "id": "line-0", "properties": {"c_nf_per_km": ' + '720.0, "df": 1.0, "from_bus": 1, "g_us_per_km": 0.0, "ices": 0.389985, ' + '"in_service": true, "length_km": 1.0, "max_i_ka": 0.328, ' + '"name": "line1", "parallel": 1, "pp_index": 0, "pp_type": "line", ' + '"r_ohm_per_km": 0.2067, "std_type": null, "to_bus": 7, "type": null, ' + '"x_ohm_per_km": 0.1897522}, "type": "Feature"}], ' + '"type": "FeatureCollection"}') # test exporting both - result = geo.dump_to_geojson(_net, nodes=True, branches=True) + result = dump_to_geojson(_net, nodes=True, branches=True) assert isinstance(result, FeatureCollection) - assert dumps(result, sort_keys=True) == '{"features": [{"geometry": {"coordinates": [1.0, 2.0], "type": "Point"}, "id": "bus-1", "properties": {"in_service": true, "name": "bus2", "pp_index": 1, "pp_type": "bus", "type": "b", "vn_kv": 0.4, "zone": null}, "type": "Feature"}, {"geometry": {"coordinates": [1.0, 3.0], "type": "Point"}, "id": "bus-7", "properties": {"in_service": true, "name": "bus3", "pp_index": 7, "pp_type": "bus", "type": "b", "vn_kv": 0.4, "zone": null}, "type": "Feature"}, {"geometry": {"coordinates": [[1.0, 2.0], [3.0, 4.0]], "type": "LineString"}, "id": "line-0", "properties": {"c_nf_per_km": 720.0, "df": 1.0, "from_bus": 1, "g_us_per_km": 0.0, "ices": 0.389985, "in_service": true, "length_km": 1.0, "max_i_ka": 0.328, "name": "line1", "parallel": 1, "pp_index": 0, "pp_type": "line", "r_ohm_per_km": 0.2067, "std_type": null, "to_bus": 7, "type": null, "x_ohm_per_km": 0.1897522}, "type": "Feature"}], "type": "FeatureCollection"}' + assert dumps(result, sort_keys=True) == ('{"features": [{"geometry": {"coordinates": [1.0, 2.0], "type": "Point"}, ' + '"id": "bus-1", "properties": {"in_service": true, "name": "bus2", ' + '"pp_index": 1, "pp_type": "bus", "type": "b", "vn_kv": 0.4, ' + '"zone": null}, "type": "Feature"}, {"geometry": {"coordinates": [1.0, ' + '3.0], "type": "Point"}, "id": "bus-7", "properties": {"in_service": ' + 'true, "name": "bus3", "pp_index": 7, "pp_type": "bus", "type": "b", ' + '"vn_kv": 0.4, "zone": null}, "type": "Feature"}, {"geometry": {' + '"coordinates": [[1.0, 2.0], [3.0, 4.0]], "type": "LineString"}, ' + '"id": "line-0", "properties": {"c_nf_per_km": 720.0, "df": 1.0, ' + '"from_bus": 1, "g_us_per_km": 0.0, "ices": 0.389985, "in_service": ' + 'true, "length_km": 1.0, "max_i_ka": 0.328, "name": "line1", "parallel": ' + '1, "pp_index": 0, "pp_type": "line", "r_ohm_per_km": 0.2067, ' + '"std_type": null, "to_bus": 7, "type": null, "x_ohm_per_km": ' + '0.1897522}, "type": "Feature"}], "type": "FeatureCollection"}') # test exporting specific nodes - result = geo.dump_to_geojson(_net, nodes=[1]) + result = dump_to_geojson(_net, nodes=[1]) assert isinstance(result, FeatureCollection) - assert dumps(result, sort_keys=True) == '{"features": [{"geometry": {"coordinates": [1.0, 2.0], "type": "Point"}, "id": "bus-1", "properties": {"in_service": true, "name": "bus2", "pp_index": 1, "pp_type": "bus", "type": "b", "vn_kv": 0.4, "zone": null}, "type": "Feature"}], "type": "FeatureCollection"}' + assert dumps(result, sort_keys=True) == ('{"features": [{"geometry": {"coordinates": [1.0, 2.0], "type": "Point"}, ' + '"id": "bus-1", "properties": {"in_service": true, "name": "bus2", ' + '"pp_index": 1, "pp_type": "bus", "type": "b", "vn_kv": 0.4, ' + '"zone": null}, "type": "Feature"}], "type": "FeatureCollection"}') # test exporting specific branches - result = geo.dump_to_geojson(_net, branches=[0]) + result = dump_to_geojson(_net, branches=[0]) assert isinstance(result, FeatureCollection) - assert dumps(result, sort_keys=True) == '{"features": [{"geometry": {"coordinates": [[1.0, 2.0], [3.0, 4.0]], "type": "LineString"}, "id": "line-0", "properties": {"c_nf_per_km": 720.0, "df": 1.0, "from_bus": 1, "g_us_per_km": 0.0, "ices": 0.389985, "in_service": true, "length_km": 1.0, "max_i_ka": 0.328, "name": "line1", "parallel": 1, "pp_index": 0, "pp_type": "line", "r_ohm_per_km": 0.2067, "std_type": null, "to_bus": 7, "type": null, "x_ohm_per_km": 0.1897522}, "type": "Feature"}], "type": "FeatureCollection"}' + assert dumps(result, sort_keys=True) == ('{"features": [{"geometry": {"coordinates": [[1.0, 2.0], [3.0, 4.0]], ' + '"type": "LineString"}, "id": "line-0", "properties": {"c_nf_per_km": ' + '720.0, "df": 1.0, "from_bus": 1, "g_us_per_km": 0.0, "ices": 0.389985, ' + '"in_service": true, "length_km": 1.0, "max_i_ka": 0.328, ' + '"name": "line1", "parallel": 1, "pp_index": 0, "pp_type": "line", ' + '"r_ohm_per_km": 0.2067, "std_type": null, "to_bus": 7, "type": null, ' + '"x_ohm_per_km": 0.1897522}, "type": "Feature"}], ' + '"type": "FeatureCollection"}') # test exporting props from bus and res_bus _net.res_bus.loc[1, ["vm_pu", "va_degree", "p_mw", "q_mvar"]] = [1.0, 1.0, 1.0, 1.0] - result = geo.dump_to_geojson(_net, nodes=[1]) + result = dump_to_geojson(_net, nodes=[1]) assert isinstance(result, FeatureCollection) - assert dumps(result, sort_keys=True) == '{"features": [{"geometry": {"coordinates": [1.0, 2.0], "type": "Point"}, "id": "bus-1", "properties": {"in_service": true, "name": "bus2", "p_mw": 1.0, "pp_index": 1, "pp_type": "bus", "q_mvar": 1.0, "type": "b", "va_degree": 1.0, "vm_pu": 1.0, "vn_kv": 0.4, "zone": null}, "type": "Feature"}], "type": "FeatureCollection"}' + assert dumps(result, sort_keys=True) == ('{"features": [{"geometry": {"coordinates": [1.0, 2.0], "type": "Point"}, ' + '"id": "bus-1", "properties": {"in_service": true, "name": "bus2", ' + '"p_mw": 1.0, "pp_index": 1, "pp_type": "bus", "q_mvar": 1.0, ' + '"type": "b", "va_degree": 1.0, "vm_pu": 1.0, "vn_kv": 0.4, ' + '"zone": null}, "type": "Feature"}], "type": "FeatureCollection"}') # test exporting props from bus and res_bus - _net.res_line.loc[0, _net.res_line.columns] = [7.0]*len(_net.res_line.columns) - result = geo.dump_to_geojson(_net, branches=[0]) + _net.res_line.loc[0, _net.res_line.columns] = [7.0] * len(_net.res_line.columns) + result = dump_to_geojson(_net, branches=[0]) assert isinstance(result, FeatureCollection) - assert dumps(result, sort_keys=True) == '{"features": [{"geometry": {"coordinates": [[1.0, 2.0], [3.0, 4.0]], "type": "LineString"}, "id": "line-0", "properties": {"c_nf_per_km": 720.0, "df": 1.0, "from_bus": 1, "g_us_per_km": 0.0, "i_from_ka": 7.0, "i_ka": 7.0, "i_to_ka": 7.0, "ices": 0.389985, "in_service": true, "length_km": 1.0, "loading_percent": 7.0, "max_i_ka": 0.328, "name": "line1", "p_from_mw": 7.0, "p_to_mw": 7.0, "parallel": 1, "pl_mw": 7.0, "pp_index": 0, "pp_type": "line", "q_from_mvar": 7.0, "q_to_mvar": 7.0, "ql_mvar": 7.0, "r_ohm_per_km": 0.2067, "std_type": null, "to_bus": 7, "type": null, "va_from_degree": 7.0, "va_to_degree": 7.0, "vm_from_pu": 7.0, "vm_to_pu": 7.0, "x_ohm_per_km": 0.1897522}, "type": "Feature"}], "type": "FeatureCollection"}' + assert dumps(result, sort_keys=True) == ('{"features": [{"geometry": {"coordinates": [[1.0, 2.0], [3.0, 4.0]], ' + '"type": "LineString"}, "id": "line-0", "properties": {"c_nf_per_km": ' + '720.0, "df": 1.0, "from_bus": 1, "g_us_per_km": 0.0, "i_from_ka": 7.0, ' + '"i_ka": 7.0, "i_to_ka": 7.0, "ices": 0.389985, "in_service": true, ' + '"length_km": 1.0, "loading_percent": 7.0, "max_i_ka": 0.328, ' + '"name": "line1", "p_from_mw": 7.0, "p_to_mw": 7.0, "parallel": 1, ' + '"pl_mw": 7.0, "pp_index": 0, "pp_type": "line", "q_from_mvar": 7.0, ' + '"q_to_mvar": 7.0, "ql_mvar": 7.0, "r_ohm_per_km": 0.2067, "std_type": ' + 'null, "to_bus": 7, "type": null, "va_from_degree": 7.0, "va_to_degree": ' + '7.0, "vm_from_pu": 7.0, "vm_to_pu": 7.0, "x_ohm_per_km": 0.1897522}, ' + '"type": "Feature"}], "type": "FeatureCollection"}') def test_convert_geodata_to_geojson(): pytest.importorskip("geojson") pytest.importorskip("pandapower") - import pandapower as pp import geojson + from pandapower.create import create_empty_network, create_bus, create_line # Erstelle ein Beispielnetzwerk - _net = pp.create_empty_network() + _net = create_empty_network() # FĂĽge Busse hinzu - pp.create_bus(_net, 0, geodata=(10, 20)) - pp.create_bus(_net, 1, geodata=(30, 40)) + create_bus(_net, 0, geodata=(10, 20)) + create_bus(_net, 1, geodata=(30, 40)) # FĂĽge Leitungen hinzu - pp.create_line(_net, 0, 1, 1, std_type="NAYY 4x50 SE", geodata=[[10, 20], [30, 40]]) + create_line(_net, 0, 1, 1, std_type="NAYY 4x50 SE", geodata=[[10, 20], [30, 40]]) _bus_geojson_to_geodata_(_net) _line_geojson_to_geodata_(_net) # Rufe die Funktion zum Konvertieren auf - geo.convert_geodata_to_geojson(_net) + convert_geodata_to_geojson(_net) # ĂśberprĂĽfe die Ergebnisse assert _net.bus.at[0, "geo"] == geojson.dumps(geojson.Point((10, 20)), sort_keys=True) diff --git a/pandapower/test/plotting/test_plotting_toolbox.py b/pandapower/test/plotting/test_plotting_toolbox.py index 332897996..bd263698f 100644 --- a/pandapower/test/plotting/test_plotting_toolbox.py +++ b/pandapower/test/plotting/test_plotting_toolbox.py @@ -4,40 +4,43 @@ # and Energy System Technology (IEE), Kassel. All rights reserved. from copy import deepcopy -import pytest + import pandas as pd +import pytest -import pandapower as pp +from pandapower.networks.power_system_test_cases import case9 +from pandapower.plotting.plotting_toolbox import set_line_geodata_from_bus_geodata +from pandapower.plotting.simple_plot import simple_plot def test_set_line_geodata_from_bus_geodata(): - net = pp.networks.case9() + net = case9() bus_geo_data = deepcopy(net.bus.geo) - empty_line_geo = pd.Series(None, index=net.line.index, dtype=object) # ensure that line geo data - assert not net.bus.geo.isnull().any() # ensure that bus geo data is available + empty_line_geo = pd.Series(None, index=net.line.index, dtype=object) # ensure that line geo data + assert not net.bus.geo.isnull().any() # ensure that bus geo data is available - pp.plotting.simple_plot(net, show_plot=False) # test that plotting works with case9 file + simple_plot(net, show_plot=False) # test that plotting works with case9 file # --- create line geo data from complete net.bus.geo to empty net.line.geo - net.line.geo = deepcopy(empty_line_geo) # ensure that line geo data is missing - pp.plotting.set_line_geodata_from_bus_geodata(net) + net.line.geo = deepcopy(empty_line_geo) # ensure that line geo data is missing + set_line_geodata_from_bus_geodata(net) assert not net.line.geo.isnull().any() - pp.plotting.simple_plot(net, show_plot=False) # test that plotting works with case9 file + simple_plot(net, show_plot=False) # test that plotting works with case9 file # --- create line geo data from complete net.bus.geo to incomplete net.line.geo net.line.at[2, "geo"] = None net.line.at[4, "geo"] = None - pp.plotting.set_line_geodata_from_bus_geodata(net) + set_line_geodata_from_bus_geodata(net) assert not net.line.geo.isnull().any() - pp.plotting.simple_plot(net, show_plot=False) # test that plotting works with case9 file + simple_plot(net, show_plot=False) # test that plotting works with case9 file # --- create line geo data from complete net.bus.geo to incomplete net.line.geo using overwrite net.line.at[2, "geo"] = None net.line.at[4, "geo"] = None - pp.plotting.set_line_geodata_from_bus_geodata(net, overwrite=True) + set_line_geodata_from_bus_geodata(net, overwrite=True) assert not net.line.geo.isnull().any() - pp.plotting.simple_plot(net, show_plot=False) # test that plotting works with case9 file + simple_plot(net, show_plot=False) # test that plotting works with case9 file # --- create line geo data from incomplete net.bus.geo to incomplete net.line.geo # (-> no warning expected since all missing data can be filled by available bus data) @@ -45,11 +48,11 @@ def test_set_line_geodata_from_bus_geodata(): net.bus.at[4, "geo"] = None net.line.at[0, "geo"] = None net.line.at[5, "geo"] = None - pp.plotting.set_line_geodata_from_bus_geodata(net) + set_line_geodata_from_bus_geodata(net) assert not net.line.geo.isnull().any() net.bus.at[2, "geo"] = bus_geo_data.at[2] net.bus.at[4, "geo"] = bus_geo_data.at[4] - pp.plotting.simple_plot(net, show_plot=False) # test that plotting works with case9 file + simple_plot(net, show_plot=False) # test that plotting works with case9 file # --- create line geo data from incomplete net.bus.geo to incomplete net.line.geo # using line_index (-> no warning expected since all missing data can be filled by available bus @@ -58,18 +61,18 @@ def test_set_line_geodata_from_bus_geodata(): net.bus.at[4, "geo"] = None net.line.at[6, "geo"] = None net.line.at[7, "geo"] = None - pp.plotting.set_line_geodata_from_bus_geodata(net, line_index=[6, 7]) + set_line_geodata_from_bus_geodata(net, line_index=[6, 7]) assert not net.line.geo.isnull().any() net.bus.at[2, "geo"] = bus_geo_data.at[2] net.bus.at[4, "geo"] = bus_geo_data.at[4] - pp.plotting.simple_plot(net, show_plot=False) # test that plotting works with case9 file + simple_plot(net, show_plot=False) # test that plotting works with case9 file # --- create line geo data from incomplete net.bus.geo to empty net.line.geo # (-> warning expected) net.bus.at[2, "geo"] = None net.bus.at[4, "geo"] = None - net.line.geo = deepcopy(empty_line_geo) # ensure that line geo data is missing - pp.plotting.set_line_geodata_from_bus_geodata(net) + net.line.geo = deepcopy(empty_line_geo) # ensure that line geo data is missing + set_line_geodata_from_bus_geodata(net) if __name__ == "__main__": diff --git a/pandapower/test/plotting/test_simple_plotly.py b/pandapower/test/plotting/test_simple_plotly.py index 6017f5a81..8af172d13 100644 --- a/pandapower/test/plotting/test_simple_plotly.py +++ b/pandapower/test/plotting/test_simple_plotly.py @@ -3,14 +3,19 @@ # Copyright (c) 2016-2024 by University of Kassel and Fraunhofer Institute for Energy Economics # and Energy System Technology (IEE), Kassel. All rights reserved. -from tempfile import gettempdir from os.path import join +from tempfile import gettempdir + import pytest + +from pandapower.networks.create_examples import example_multivoltage +from pandapower.networks.mv_oberrhein import mv_oberrhein from pandapower.plotting import create_weighted_marker_trace from pandapower.plotting.plotly import simple_plotly -import pandapower.networks as nw + try: import plotly + PLOTLY_INSTALLED = True except ImportError: PLOTLY_INSTALLED = False @@ -19,7 +24,7 @@ @pytest.mark.slow @pytest.mark.skipif(not PLOTLY_INSTALLED, reason="plotly functions require the plotly package") def test_simple_plotly_coordinates(): - net = nw.mv_oberrhein(include_substations=True) + net = mv_oberrhein(include_substations=True) net.load.scaling, net.sgen.scaling = 1, 1 # different markers and sizemodes as examples markers_load = create_weighted_marker_trace(net, elm_type="load", color="red", @@ -31,17 +36,17 @@ def test_simple_plotly_coordinates(): fig = simple_plotly(net, filename=join(gettempdir(), "temp-plot.html"), auto_open=False, additional_traces=[markers_sgen, markers_load]) assert len(fig.data) == (len(net.line) + 1) + (len(net.trafo) + 1) + 6 - # +1 for the infofunc traces, - # +6 = 1 bus trace + 1 ext_grid trace + 2 weighted marker traces + 2 scale traces + # +1 for the infofunc traces, + # +6 = 1 bus trace + 1 ext_grid trace + 2 weighted marker traces + 2 scale traces @pytest.mark.slow @pytest.mark.skipif(not PLOTLY_INSTALLED, reason="plotly functions require the plotly package") def test_simple_plotly_3w(): # net with 3W-transformer - net = nw.example_multivoltage() + net = example_multivoltage() fig = simple_plotly(net, filename=join(gettempdir(), "temp-plot.html"), auto_open=False) - assert len(fig.data) == (len(net.line) + 1) + (len(net.trafo) + 1) + (len(net.trafo3w)*3 + 1) + 2 + assert len(fig.data) == (len(net.line) + 1) + (len(net.trafo) + 1) + (len(net.trafo3w) * 3 + 1) + 2 # +1 is for infofunc traces, +2 = 1 bus trace + 1 ext_grid trace diff --git a/pandapower/test/plotting/test_to_html.py b/pandapower/test/plotting/test_to_html.py index 6da8ccdb5..22dedc4ee 100644 --- a/pandapower/test/plotting/test_to_html.py +++ b/pandapower/test/plotting/test_to_html.py @@ -3,18 +3,18 @@ # Copyright (c) 2016-2024 by University of Kassel and Fraunhofer Institute for Energy Economics # and Energy System Technology (IEE), Kassel. All rights reserved. - import os + import pytest -import pandapower.plotting +from pandapower.plotting.to_html import to_html from pandapower.test.helper_functions import create_test_network def test_html(tmp_path): net = create_test_network() filename = os.path.abspath(str(tmp_path)) + "testfile.html" - pandapower.plotting.to_html(net, filename) + to_html(net, filename) if __name__ == "__main__": diff --git a/pandapower/test/protection/__init__.py b/pandapower/test/protection/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/pandapower/test/protection/test_fuse.py b/pandapower/test/protection/test_fuse.py index d7f972f42..be2263aa9 100644 --- a/pandapower/test/protection/test_fuse.py +++ b/pandapower/test/protection/test_fuse.py @@ -1,15 +1,20 @@ -import pytest import copy + import numpy as np -import pandapower as pp -from pandapower import load_std_type, create_std_type -from pandapower.control import plot_characteristic +import pytest + +from pandapower.create import create_empty_network, create_buses, create_ext_grid, create_lines_from_parameters, \ + create_transformer, create_switch, create_switches, create_load, create_bus, create_sgen, create_gen, create_line, \ + create_shunt, create_lines, create_loads +from pandapower.file_io import from_json_string, to_json +from pandapower.networks.create_examples import example_simple from pandapower.protection.protection_devices.fuse import Fuse from pandapower.protection.run_protection import calculate_protection_times -import pandapower.shortcircuit as sc -from pandapower.test.helper_functions import assert_net_equal from pandapower.protection.utility_functions import plot_tripped_grid_protection_device - +from pandapower.run import runpp +from pandapower.shortcircuit.calc_sc import calc_sc +from pandapower.std_types import create_std_type +from pandapower.test.helper_functions import assert_net_equal try: import matplotlib.pyplot as plt @@ -26,11 +31,11 @@ def test_protection_function(): f3 = Fuse(net=net, rated_i_a=315, fuse_type="Siemens NH-2-315", switch_index=3) # create fault at bus 3, check that fuse melts in 0.1451 seconds - sc.calc_sc(net, bus=3, branch_results=True) + calc_sc(net, bus=3, branch_results=True) protection_result = f3.protection_function(net, scenario="sc") - assert protection_result['trip_melt'] == True, 'trip_melt should be True' - assert net.protection.at[0, "object"].tripped == True, 'Fuse.tripped should be True' + assert protection_result['trip_melt'], 'trip_melt should be True' + assert net.protection.at[0, "object"].tripped, 'Fuse.tripped should be True' assert np.isclose(protection_result['trip_melt_time_s'], 0.145108), 'melt_time_s3 should be close to 0.145108 seconds for fault at bus 3' @@ -57,7 +62,7 @@ def test_calculate_protection_times(): # create fault at bus 3 net_sc3 = copy.deepcopy(net) - sc.calc_sc(net_sc3, bus=3, branch_results=True) + calc_sc(net_sc3, bus=3, branch_results=True) print("\nnet_sc3 has fault at bus 3\n") print(net_sc3) @@ -66,7 +71,7 @@ def test_calculate_protection_times(): # create fault at bus 2 net_sc2 = copy.deepcopy(net) - sc.calc_sc(net_sc2, bus=2, branch_results=True) + calc_sc(net_sc2, bus=2, branch_results=True) print("\nnet_sc2 has fault at bus 2\n") print(net_sc2) @@ -88,7 +93,7 @@ def test_plot_tripped_grid_protection_device1(): for k in range(5): Fuse(net=net, switch_index=k, fuse_type=fuse_list[k]) - sc.calc_sc(net, bus=k, branch_results=True) + calc_sc(net, bus=k, branch_results=True) protection_results = calculate_protection_times(net, scenario='sc') plot_tripped_grid_protection_device(net, protection_results, sc_bus=k, sc_location=0) @@ -102,7 +107,7 @@ def test_plot_tripped_grid_protection_device2(): Fuse(net=net, switch_index=k, fuse_type=fuse_list[k]) # perform short circuit calculation at bus 2 - sc.calc_sc(net, bus=3, branch_results=True) + calc_sc(net, bus=3, branch_results=True) # calculate protection times protection_results = calculate_protection_times(net, scenario='sc') @@ -134,7 +139,7 @@ def test_calc_prot_times_with_std_lib(): print(net.bus) for row_index, row in net.bus.iterrows(): net_sc = copy.deepcopy(net) - sc.calc_sc(net_sc, bus=row_index, branch_results=True) + calc_sc(net_sc, bus=row_index, branch_results=True) print("\nnet_sc has fault at bus " + str(row_index) + '\n') df_protection_results = calculate_protection_times(net_sc) @@ -143,9 +148,9 @@ def test_calc_prot_times_pp_scenario(): # test calculate_protection_times() function with power flow scenario net = fuse_test_net3() Fuse(net=net, switch_index=4, fuse_type="Siemens NH-1-16") # fuse is underrated - pp.runpp(net) + runpp(net) protection_times = calculate_protection_times(net, scenario="pp") - assert protection_times.trip_melt.at[0] == True, 'trip_melt for switch 4 should be True in pp scenario' + assert protection_times.trip_melt.at[0], 'trip_melt for switch 4 should be True in pp scenario' def test_reset_device(): @@ -153,10 +158,10 @@ def test_reset_device(): net = fuse_test_net3() Fuse(net=net, switch_index=0, fuse_type="HV 63A") net.protection.at[0, "object"].tripped = True - assert net.protection.at[0, "object"].tripped == True, 'Fuse should manually trip' + assert net.protection.at[0, "object"].tripped, 'Fuse should manually trip' net.protection.at[0, "object"].reset_device() - assert net.protection.at[0, "object"].tripped == False, 'Fuse should reset' + assert not net.protection.at[0, "object"].tripped, 'Fuse should reset' def test_has_tripped(): @@ -164,7 +169,7 @@ def test_has_tripped(): net = fuse_test_net3() Fuse(net=net, switch_index=0, fuse_type="HV 63A") net.protection.at[0, "object"].tripped = True - assert net.protection.at[0, "object"].has_tripped() == True, '.has_tripped() should equal True' + assert net.protection.at[0, "object"].has_tripped(), '.has_tripped() should equal True' def test_status_to_net(): @@ -172,7 +177,7 @@ def test_status_to_net(): Fuse(net=net, switch_index=0, fuse_type="HV 63A") net.protection.at[0, "object"].tripped = True net.protection.object.at[0].status_to_net(net) - assert net.switch.closed.at[0] == False, 'switch 0 should be open (Closed = False)' + assert not net.switch.closed.at[0], 'switch 0 should be open (Closed = False)' def test_create_new_std_type(): @@ -188,9 +193,9 @@ def test_create_new_std_type(): 'x_total': [50, 5000]} create_std_type(net, data=new_fuse_data, name='New Fuse', element="fuse") Fuse(net=net, switch_index=4, fuse_type='New Fuse', curve_select=1) - sc.calc_sc(net, bus=4, branch_results=True) + calc_sc(net, bus=4, branch_results=True) protection_results = calculate_protection_times(net, scenario='sc') - assert protection_results.trip_melt.at[0] == True, 'New Fuse should melt' + assert protection_results.trip_melt.at[0], 'New Fuse should melt' assert protection_results.trip_melt_time_s.at[0] > 0, 'Melt time should be from x_total curve (greater than 0)' @@ -198,10 +203,10 @@ def test_net3(): # investigate why bus-bus switch isn't working net = fuse_test_net3() print(net.switch) - pp.runpp(net) + runpp(net) print("\n\n\n") print(net.res_switch) - sc.calc_sc(net, bus=4, branch_results=True) + calc_sc(net, bus=4, branch_results=True) print("\n\n\n") print(net.res_switch_sc) assert not np.isnan(net.res_switch.i_ka.at[4]), 'i_ka for switch 4 should not be NaN ' @@ -220,16 +225,16 @@ def test_prot_func_tripping(): Fuse(net=net, switch_index=k, fuse_type=fuse_list[k]) # run short-circuit calculation - sc.calc_sc(net=net, bus=4, branch_results=True) + calc_sc(net=net, bus=4, branch_results=True) df_protection_results = calculate_protection_times(net) print(net.switch) def test_powerflow_simple(): - # test the res_switch output from the pandapower.networks.example_simple() - net = pp.networks.example_simple() - pp.runpp(net) + # test the res_switch output from the example_simple() + net = example_simple() + runpp(net) print(net) print(net.switch) print(net.res_switch) @@ -245,49 +250,49 @@ def test_json_fuse(): for k in range(5): Fuse(net=net, switch_index=k, fuse_type=fuse_list[k]) # net2 is copy of net before calc_sc is done - net2 = pp.from_json_string(pp.to_json(net)) + net2 = from_json_string(to_json(net)) assert_net_equal(net, net2) - #pp.runpp(net2) - sc.calc_sc(net2, bus=3, branch_results=True) + # runpp(net2) + calc_sc(net2, bus=3, branch_results=True) # net3 is copy of net after calc_sc is run on net - sc.calc_sc(net, bus=3, branch_results=True) - net3 = pp.from_json_string(pp.to_json(net)) + calc_sc(net, bus=3, branch_results=True) + net3 = from_json_string(to_json(net)) protection_results2 = calculate_protection_times(net2, scenario="sc") protection_results3 = calculate_protection_times(net3, scenario="sc") - assert protection_results2.trip_melt.at[3] == True, 'trip_melt Fuse 3 should be True' + assert protection_results2.trip_melt.at[3], 'trip_melt Fuse 3 should be True' assert np.isclose(protection_results2.trip_melt_time_s.at[3], 0.145108), \ 'melt_time_s3 should be close to 0.145108 seconds for fault at bus 3' - assert protection_results3.trip_melt.at[3] == True, 'trip_melt Fuse 3 should be True' + assert protection_results3.trip_melt.at[3], 'trip_melt Fuse 3 should be True' assert np.isclose(protection_results3.trip_melt_time_s.at[3], 0.145108), \ 'melt_time_s3 should be close to 0.145108 seconds for fault at bus 3' def fuse_test_net3(): # network with transformer to test HV fuse curve_select - net = pp.create_empty_network() + net = create_empty_network() # create buses - pp.create_buses(net, nr_buses=5, vn_kv=[20, 0.4, 0.4, 0.4, 0.4], index=[0, 1, 2, 3, 4], name=None, type="n", - geodata=[(0, 0), (0, -2), (0, -4), (0, -6), (0, -8)]) + create_buses(net, nr_buses=5, vn_kv=[20, 0.4, 0.4, 0.4, 0.4], index=[0, 1, 2, 3, 4], name=None, type="n", + geodata=[(0, 0), (0, -2), (0, -4), (0, -6), (0, -8)]) # create external grid - pp.create_ext_grid(net, 0, vm_pu=1.0, va_degree=0, s_sc_max_mva=100, s_sc_min_mva=50, rx_max=0.1, rx_min=0.1) - pp.create_lines_from_parameters(net, from_buses=[1, 2], to_buses=[2, 3], length_km=[0.1, 0.1], r_ohm_per_km=0.2067, - x_ohm_per_km=0.080424, c_nf_per_km=261, name=None, index=[0, 1], max_i_ka=0.27) + create_ext_grid(net, 0, vm_pu=1.0, va_degree=0, s_sc_max_mva=100, s_sc_min_mva=50, rx_max=0.1, rx_min=0.1) + create_lines_from_parameters(net, from_buses=[1, 2], to_buses=[2, 3], length_km=[0.1, 0.1], r_ohm_per_km=0.2067, + x_ohm_per_km=0.080424, c_nf_per_km=261, name=None, index=[0, 1], max_i_ka=0.27) net.line["endtemp_degree"] = 250 # create transformer - pp.create_transformer(net, hv_bus=0, lv_bus=1, std_type="0.63 MVA 20/0.4 kV") + create_transformer(net, hv_bus=0, lv_bus=1, std_type="0.63 MVA 20/0.4 kV") # Define trafo fuses - pp.create_switches(net, buses=[0, 1], elements=[0, 0], et='t', type="fuse") + create_switches(net, buses=[0, 1], elements=[0, 0], et='t', type="fuse") # Define line fuses - pp.create_switches(net, buses=[1, 2], elements=[0, 1], et='l', type="fuse") + create_switches(net, buses=[1, 2], elements=[0, 1], et='l', type="fuse") # Define load fuse (bus-bus switch) - pp.create_switch(net, bus=3, element=4, et='b', type="fuse", z_ohm=0.0001) + create_switch(net, bus=3, element=4, et='b', type="fuse", z_ohm=0.0001) # define load - pp.create_load(net, bus=4, p_mw=0.1, q_mvar=0, const_z_percent=0, const_i_percent=0, sn_mva=.1, - name=None, scaling=1., index=0) + create_load(net, bus=4, p_mw=0.1, q_mvar=0, const_z_percent=0, const_i_percent=0, sn_mva=.1, + name=None, scaling=1., index=0) return net @@ -303,60 +308,59 @@ def test_fuse_fault_oc_scenario(): Fuse(net=net, switch_index=k, fuse_type=fuse_list[k]) # perform short circuit calculation at bus 2 - sc.calc_sc(net, bus=3, branch_results=True) + calc_sc(net, bus=3, branch_results=True) # calculate protection times protection_results = calculate_protection_times(net, scenario='sc') # for fuse with the fastest melting time, melt the corresponding switch net.protection.object.at[protection_results.trip_melt_time_s.idxmin()].status_to_net(net) - assert net.switch.closed.at[3] == False, 'Fuse 3 should melt, switch 3 should be open' + assert not net.switch.closed.at[3], 'Fuse 3 should melt, switch 3 should be open' # after fault is cleared, close the CB at bus 6 so that Load 0 continues to get power net.switch.at[9, "closed"] = True # perform power flow calculation - pp.runpp(net) + runpp(net) # check if any fuses melt after fault has been cleared overload_results = calculate_protection_times(net, scenario="pp") net.protection.object.at[overload_results.trip_melt_time_s.idxmin()].status_to_net(net) - pp.runpp(net) - assert net.switch.closed.at[6] == False, 'Fuse 6 should melt, switch 6 should open' - + runpp(net) + assert not net.switch.closed.at[6], 'Fuse 6 should melt, switch 6 should open' def fuse_test_net2(): # network with transformer to test HV fuse curve_select # load switch (index 4) is configured as bus-bus - net = pp.create_empty_network() + net = create_empty_network() # create buses - pp.create_buses(net, nr_buses=4, vn_kv=[20, 0.4, 0.4, 0.4], index=[0, 1, 2, 3], name=None, type="n", - geodata=[(0, 0), (0, -2), (0, -4), (0, -6)]) + create_buses(net, nr_buses=4, vn_kv=[20, 0.4, 0.4, 0.4], index=[0, 1, 2, 3], name=None, type="n", + geodata=[(0, 0), (0, -2), (0, -4), (0, -6)]) # create external grid - pp.create_ext_grid(net, 0, vm_pu=1.0, va_degree=0, s_sc_max_mva=100, s_sc_min_mva=50, rx_max=0.1, rx_min=0.1) + create_ext_grid(net, 0, vm_pu=1.0, va_degree=0, s_sc_max_mva=100, s_sc_min_mva=50, rx_max=0.1, rx_min=0.1) - pp.create_lines_from_parameters(net, from_buses=[1, 2], to_buses=[2, 3], length_km=[0.1, 0.1], r_ohm_per_km=0.2067, - x_ohm_per_km=0.080424, c_nf_per_km=261, name=None, index=[0, 1], max_i_ka=0.27) + create_lines_from_parameters(net, from_buses=[1, 2], to_buses=[2, 3], length_km=[0.1, 0.1], r_ohm_per_km=0.2067, + x_ohm_per_km=0.080424, c_nf_per_km=261, name=None, index=[0, 1], max_i_ka=0.27) net.line["endtemp_degree"] = 250 # create transformer - pp.create_transformer(net, hv_bus=0, lv_bus=1, std_type="0.63 MVA 20/0.4 kV") + create_transformer(net, hv_bus=0, lv_bus=1, std_type="0.63 MVA 20/0.4 kV") # Define trafo fuses - pp.create_switches(net, buses=[0, 1], elements=[0, 0], et='t', type="fuse") + create_switches(net, buses=[0, 1], elements=[0, 0], et='t', type="fuse") # Define line fuses - pp.create_switches(net, buses=[1, 2, 3], elements=[0, 1, 1], et='l', type="fuse") + create_switches(net, buses=[1, 2, 3], elements=[0, 1, 1], et='l', type="fuse") # define load - pp.create_load(net, bus=3, p_mw=0.1, q_mvar=0, const_z_percent=0, const_i_percent=0, sn_mva=.1, - name=None, scaling=1., index=0) + create_load(net, bus=3, p_mw=0.1, q_mvar=0, const_z_percent=0, const_i_percent=0, sn_mva=.1, + name=None, scaling=1., index=0) return net @@ -365,57 +369,57 @@ def modified_simple_net(): # modify simple network from create_examples.py to include resistance values for switches # this should hopefully the NaN issue during power flow and short circuit calculations - net = pp.create_empty_network() + net = create_empty_network() # create buses - bus1 = pp.create_bus(net, name="HV Busbar", vn_kv=110., type="b") - bus2 = pp.create_bus(net, name="HV Busbar 2", vn_kv=110., type="b") - bus3 = pp.create_bus(net, name="HV Transformer Bus", vn_kv=110., type="n") - bus4 = pp.create_bus(net, name="MV Transformer Bus", vn_kv=20., type="n") - bus5 = pp.create_bus(net, name="MV Main Bus", vn_kv=20., type="b") - bus6 = pp.create_bus(net, name="MV Bus 1", vn_kv=20., type="b") - bus7 = pp.create_bus(net, name="MV Bus 2", vn_kv=20., type="b") + bus1 = create_bus(net, name="HV Busbar", vn_kv=110., type="b") + bus2 = create_bus(net, name="HV Busbar 2", vn_kv=110., type="b") + bus3 = create_bus(net, name="HV Transformer Bus", vn_kv=110., type="n") + bus4 = create_bus(net, name="MV Transformer Bus", vn_kv=20., type="n") + bus5 = create_bus(net, name="MV Main Bus", vn_kv=20., type="b") + bus6 = create_bus(net, name="MV Bus 1", vn_kv=20., type="b") + bus7 = create_bus(net, name="MV Bus 2", vn_kv=20., type="b") # create external grid - pp.create_ext_grid(net, bus1, vm_pu=1.02, va_degree=50) + create_ext_grid(net, bus1, vm_pu=1.02, va_degree=50) # create transformer - pp.create_transformer(net, bus3, bus4, name="110kV/20kV transformer", - std_type="25 MVA 110/20 kV") + create_transformer(net, bus3, bus4, name="110kV/20kV transformer", + std_type="25 MVA 110/20 kV") # create lines - pp.create_line(net, bus1, bus2, length_km=10, - std_type="N2XS(FL)2Y 1x300 RM/35 64/110 kV", name="Line 1") - line2 = pp.create_line(net, bus5, bus6, length_km=2.0, - std_type="NA2XS2Y 1x240 RM/25 12/20 kV", name="Line 2") - line3 = pp.create_line(net, bus6, bus7, length_km=3.5, - std_type="48-AL1/8-ST1A 20.0", name="Line 3") - line4 = pp.create_line(net, bus7, bus5, length_km=2.5, - std_type="NA2XS2Y 1x240 RM/25 12/20 kV", name="Line 4") + create_line(net, bus1, bus2, length_km=10, + std_type="N2XS(FL)2Y 1x300 RM/35 64/110 kV", name="Line 1") + line2 = create_line(net, bus5, bus6, length_km=2.0, + std_type="NA2XS2Y 1x240 RM/25 12/20 kV", name="Line 2") + line3 = create_line(net, bus6, bus7, length_km=3.5, + std_type="48-AL1/8-ST1A 20.0", name="Line 3") + line4 = create_line(net, bus7, bus5, length_km=2.5, + std_type="NA2XS2Y 1x240 RM/25 12/20 kV", name="Line 4") # create bus-bus switches - pp.create_switch(net, bus2, bus3, et="b", type="CB", z_ohm=0.1) - pp.create_switch(net, bus4, bus5, et="b", type="CB", z_ohm=0.1) + create_switch(net, bus2, bus3, et="b", type="CB", z_ohm=0.1) + create_switch(net, bus4, bus5, et="b", type="CB", z_ohm=0.1) # create bus-line switches - pp.create_switch(net, bus5, line2, et="l", type="LBS", closed=True, z_ohm=0.1) - pp.create_switch(net, bus6, line2, et="l", type="LBS", closed=True, z_ohm=0.1) - pp.create_switch(net, bus6, line3, et="l", type="LBS", closed=True, z_ohm=0.1) - pp.create_switch(net, bus7, line3, et="l", type="LBS", closed=False, z_ohm=0.1) - pp.create_switch(net, bus7, line4, et="l", type="LBS", closed=True, z_ohm=0.1) - pp.create_switch(net, bus5, line4, et="l", type="LBS", closed=True, z_ohm=0.1) + create_switch(net, bus5, line2, et="l", type="LBS", closed=True, z_ohm=0.1) + create_switch(net, bus6, line2, et="l", type="LBS", closed=True, z_ohm=0.1) + create_switch(net, bus6, line3, et="l", type="LBS", closed=True, z_ohm=0.1) + create_switch(net, bus7, line3, et="l", type="LBS", closed=False, z_ohm=0.1) + create_switch(net, bus7, line4, et="l", type="LBS", closed=True, z_ohm=0.1) + create_switch(net, bus5, line4, et="l", type="LBS", closed=True, z_ohm=0.1) # create load - pp.create_load(net, bus7, p_mw=2, q_mvar=4, scaling=0.6, name="load") + create_load(net, bus7, p_mw=2, q_mvar=4, scaling=0.6, name="load") # create generator - pp.create_gen(net, bus6, p_mw=6, max_q_mvar=3, min_q_mvar=-3, vm_pu=1.03, - name="generator") + create_gen(net, bus6, p_mw=6, max_q_mvar=3, min_q_mvar=-3, vm_pu=1.03, + name="generator") # create static generator - pp.create_sgen(net, bus7, p_mw=2, q_mvar=-0.5, name="static generator") + create_sgen(net, bus7, p_mw=2, q_mvar=-0.5, name="static generator") # create shunt - pp.create_shunt(net, bus3, q_mvar=-0.96, p_mw=0, name='Shunt') + create_shunt(net, bus3, q_mvar=-0.96, p_mw=0, name='Shunt') return net @@ -423,38 +427,39 @@ def modified_simple_net(): def fuse_test_net4(): # test network to demonstrate overcurrent protection in tutorial - net = pp.create_empty_network() + net = create_empty_network() # create buses - pp.create_buses(net, nr_buses=9, vn_kv=[20, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4], - index=[0, 1, 2, 3, 4, 5, 6, 7, 8], name=None, type="n", - geodata=[(0, 0), (0, -2), (-2, -4), (-2, -6), (-2, -8), (2, -4), (2, -6), (2, -8), (2, -10)]) + create_buses(net, nr_buses=9, vn_kv=[20, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4], + index=[0, 1, 2, 3, 4, 5, 6, 7, 8], name=None, type="n", + geodata=[(0, 0), (0, -2), (-2, -4), (-2, -6), (-2, -8), (2, -4), (2, -6), (2, -8), (2, -10)]) # create external grid - pp.create_ext_grid(net, 0, vm_pu=1.0, va_degree=0, s_sc_max_mva=500, s_sc_min_mva=80, rx_max=0.1, rx_min=0.1) + create_ext_grid(net, 0, vm_pu=1.0, va_degree=0, s_sc_max_mva=500, s_sc_min_mva=80, rx_max=0.1, rx_min=0.1) - pp.create_lines(net, from_buses=[1, 2, 3, 1, 5, 6, 7, 6], to_buses=[2, 3, 4, 5, 6, 7, 8, 4], - length_km=[0.2, 0.2, 0.2, 0.1, 0.1, 0.1, 0.1, 0.1], std_type="94-AL1/15-ST1A 0.4") + create_lines(net, from_buses=[1, 2, 3, 1, 5, 6, 7, 6], to_buses=[2, 3, 4, 5, 6, 7, 8, 4], + length_km=[0.2, 0.2, 0.2, 0.1, 0.1, 0.1, 0.1, 0.1], std_type="94-AL1/15-ST1A 0.4") net.line["endtemp_degree"] = 250 # create transformer - pp.create_transformer(net, hv_bus=0, lv_bus=1, std_type="0.25 MVA 20/0.4 kV") + create_transformer(net, hv_bus=0, lv_bus=1, std_type="0.25 MVA 20/0.4 kV") # Define trafo fuses - pp.create_switches(net, buses=[0, 1], elements=[0, 0], et='t', type="fuse") + create_switches(net, buses=[0, 1], elements=[0, 0], et='t', type="fuse") # Define line fuses - pp.create_switches(net, buses=[1, 2, 3, 1, 5, 6, 7], elements=[0, 1, 2, 3, 4, 5, 6], et='l', type="fuse") + create_switches(net, buses=[1, 2, 3, 1, 5, 6, 7], elements=[0, 1, 2, 3, 4, 5, 6], et='l', type="fuse") # Define circuit breaker switch - pp.create_switch(net, bus=6, element=7, et='l', type="CB", closed=False) + create_switch(net, bus=6, element=7, et='l', type="CB", closed=False) # define load - pp.create_loads(net, buses=[4, 8], p_mw=[0.1, 0.05], q_mvar=0, const_z_percent=0, const_i_percent=0, name=None, - index=[0, 1]) + create_loads(net, buses=[4, 8], p_mw=[0.1, 0.05], q_mvar=0, const_z_percent=0, const_i_percent=0, name=None, + index=[0, 1]) return net + if __name__ == "__main__": pytest.main([__file__, "-s"]) diff --git a/pandapower/test/protection/test_oc_relay.py b/pandapower/test/protection/test_oc_relay.py index 224d48e6d..5301e27d5 100644 --- a/pandapower/test/protection/test_oc_relay.py +++ b/pandapower/test/protection/test_oc_relay.py @@ -1,10 +1,12 @@ import numpy as np -import pandapower as pp -from pandapower.protection.run_protection import calculate_protection_times -import pandapower.shortcircuit as sc + +from pandapower.create import create_empty_network, create_buses, create_ext_grid, create_lines, create_switches, \ + create_loads from pandapower.protection.protection_devices.ocrelay import OCRelay +from pandapower.protection.run_protection import calculate_protection_times from pandapower.protection.utility_functions import create_sc_bus from pandapower.protection.utility_functions import plot_tripped_grid_protection_device +from pandapower.shortcircuit.calc_sc import calc_sc try: import matplotlib.pyplot as plt @@ -21,14 +23,13 @@ def test_oc_relay_dtoc(): OCRelay(net, switch_index=k, oc_relay_type='DTOC', time_settings=[0.07, 0.5, 0.3]) net_sc = create_sc_bus(net, sc_line_id=4, sc_fraction=0.5) - sc.calc_sc(net_sc, bus=max(net_sc.bus.index), branch_results=True) + calc_sc(net_sc, bus=max(net_sc.bus.index), branch_results=True) protection_results = calculate_protection_times(net_sc, scenario='sc') assert protection_results.trip_melt_time_s.at[0] == 1.4 assert protection_results.trip_melt_time_s.at[2] == 1.1 assert protection_results.trip_melt_time_s.at[4] == 0.07 - def test_oc_relay_idmt(): net = oc_relay_net() net.switch.type = 'CB_IDMT' @@ -37,7 +38,7 @@ def test_oc_relay_idmt(): OCRelay(net, switch_index=k, oc_relay_type='IDMT', time_settings=[1, 0.5]) net_sc = create_sc_bus(net, sc_line_id=4, sc_fraction=0.5) - sc.calc_sc(net_sc, bus=max(net_sc.bus.index), branch_results=True) + calc_sc(net_sc, bus=max(net_sc.bus.index), branch_results=True) protection_results = calculate_protection_times(net_sc, scenario='sc') assert np.isclose(protection_results.trip_melt_time_s.at[0], 4.8211) assert np.isclose(protection_results.trip_melt_time_s.at[2], 4.3211) @@ -50,7 +51,7 @@ def test_oc_relay_idtoc(): for k in range(6): OCRelay(net, switch_index=k, oc_relay_type='IDTOC', time_settings=[0.07, 0.5, 0.3, 1, 0.5]) net_sc = create_sc_bus(net, sc_line_id=4, sc_fraction=0.5) - sc.calc_sc(net_sc, bus=max(net_sc.bus.index), branch_results=True) + calc_sc(net_sc, bus=max(net_sc.bus.index), branch_results=True) protection_results = calculate_protection_times(net_sc, scenario='sc') assert protection_results.trip_melt_time_s.at[0] == 1.4 assert protection_results.trip_melt_time_s.at[2] == 1.1 @@ -76,7 +77,7 @@ def test_oc_relay_plots(): OCRelay(net, switch_index=k, oc_relay_type=oc_relay_type_list[k], time_settings=time_settings_list[k]) net_sc = create_sc_bus(net, sc_line_id=4, sc_fraction=0.5) - sc.calc_sc(net_sc, bus=max(net_sc.bus.index), branch_results=True) + calc_sc(net_sc, bus=max(net_sc.bus.index), branch_results=True) protection_results = calculate_protection_times(net_sc, scenario='sc') print('\n#################################################\n\n') print(protection_results) @@ -109,37 +110,32 @@ def test_plot_tripped_grid_protection_device(): OCRelay(net, switch_index=k, oc_relay_type='DTOC', time_settings=[0.07, 0.5, 0.3]) net_sc = create_sc_bus(net, sc_line_id=2, sc_fraction=0.5) - sc.calc_sc(net_sc, bus=max(net_sc.bus.index), branch_results=True) + calc_sc(net_sc, bus=max(net_sc.bus.index), branch_results=True) protection_results = calculate_protection_times(net_sc, scenario='sc') plot_tripped_grid_protection_device(net_sc, protection_results, sc_bus=max(net_sc.bus.index), sc_location=0.5) def oc_relay_net(): # create an empty network - net = pp.create_empty_network() + net = create_empty_network() # create buses - pp.create_buses(net, nr_buses=7, vn_kv=20, index=[0, 1, 2, 3, 4, 5, 6], name=None, type="n", - geodata=[(0, 0), (0, -1), (-2, -2), (-2, -4), (2, -2), (2, -3), (2, -4)]) + create_buses(net, nr_buses=7, vn_kv=20, index=[0, 1, 2, 3, 4, 5, 6], name=None, type="n", + geodata=[(0, 0), (0, -1), (-2, -2), (-2, -4), (2, -2), (2, -3), (2, -4)]) # create external grids - pp.create_ext_grid(net, 0, vm_pu=1.0, va_degree=0, s_sc_max_mva=100, s_sc_min_mva=50, rx_max=0.1, rx_min=0.1) + create_ext_grid(net, 0, vm_pu=1.0, va_degree=0, s_sc_max_mva=100, s_sc_min_mva=50, rx_max=0.1, rx_min=0.1) - pp.create_lines(net, from_buses=[0, 1, 2, 1, 4, 5], to_buses=[1, 2, 3, 4, 5, 6], length_km=[2, 5, 4, 4, 0.5, 0.5], - std_type="NAYY 4x50 SE", - name=None, index=[0, 1, 2, 3, 4, 5], df=1., parallel=1) + create_lines(net, from_buses=[0, 1, 2, 1, 4, 5], to_buses=[1, 2, 3, 4, 5, 6], length_km=[2, 5, 4, 4, 0.5, 0.5], + std_type="NAYY 4x50 SE", + name=None, index=[0, 1, 2, 3, 4, 5], df=1., parallel=1) net.line["endtemp_degree"] = 250 # Define switches - pp.create_switches(net, buses=[0, 1, 1, 2, 4, 5], elements= - [0, 1, 3, 2, 4, 5], et='l', type="CB_DTOC") + create_switches(net, buses=[0, 1, 1, 2, 4, 5], elements=[0, 1, 3, 2, 4, 5], et='l', type="CB_DTOC") # define load - pp.create_loads(net, buses=[3, 6], p_mw=[5, 2], q_mvar=[1, 1], const_z_percent=0, const_i_percent=0, sn_mva=None, - name=None, scaling=1., index=[0, 1]) + create_loads(net, buses=[3, 6], p_mw=[5, 2], q_mvar=[1, 1], const_z_percent=0, const_i_percent=0, sn_mva=None, + name=None, scaling=1., index=[0, 1]) return net - - - - diff --git a/pandapower/test/run_tests.py b/pandapower/test/run_tests.py index 050e8e2b7..82c4e8743 100644 --- a/pandapower/test/run_tests.py +++ b/pandapower/test/run_tests.py @@ -12,15 +12,14 @@ import pytest -from pandapower.test import test_path, tutorials_path - -import pandapower as pp +from pandapower import pp_dir +from pandapower.test import tutorials_path try: import pandaplan.core.pplog as logging except ImportError: import logging -test_dir = os.path.abspath(os.path.join(pp.pp_dir, "test")) +test_dir = os.path.abspath(os.path.join(pp_dir, "test")) logger = logging.getLogger() diff --git a/pandapower/test/shortcircuit/test_1ph.py b/pandapower/test/shortcircuit/test_1ph.py index fce8387dd..f8a3d5956 100644 --- a/pandapower/test/shortcircuit/test_1ph.py +++ b/pandapower/test/shortcircuit/test_1ph.py @@ -3,55 +3,58 @@ # Copyright (c) 2016-2024 by University of Kassel and Fraunhofer Institute for Energy Economics # and Energy System Technology (IEE), Kassel. All rights reserved. -import pandapower as pp -import pandapower.shortcircuit as sc -import pandapower.test -import numpy as np import os + +import numpy as np import pytest +from pandapower import pp_dir +from pandapower.auxiliary import get_free_id +from pandapower.create import create_bus, create_ext_grid, create_line, create_transformer, create_empty_network, \ + create_switch, create_transformer3w_from_parameters, create_line_from_parameters, create_gen, \ + create_transformer_from_parameters, create_buses, create_impedance +from pandapower.file_io import from_json +from pandapower.shortcircuit.calc_sc import calc_sc +from pandapower.std_types import create_std_type, add_zero_impedance_parameters + def check_results(net, vc, result): - res_ika = net.res_bus_sc[(net.bus.zone==vc) & (net.bus.in_service)].ikss_ka.values + res_ika = net.res_bus_sc[(net.bus.zone == vc) & net.bus.in_service].ikss_ka.values if not np.allclose(result, res_ika, rtol=0, atol=1e-6): - raise ValueError("Incorrect results for vector group %s"%vc, res_ika, result) + raise ValueError("Incorrect results for vector group %s" % vc, res_ika, result) def add_network(net, vector_group): - b1 = pp.create_bus(net, 110, zone=vector_group, index=pp.get_free_id(net.bus)) - b2 = pp.create_bus(net, 20, zone=vector_group) - pp.create_bus(net, 20, in_service=False) - b3 = pp.create_bus(net, 20, zone=vector_group) - b4 = pp.create_bus(net, 20, zone=vector_group) - pp.create_bus(net, 20) - - pp.create_ext_grid(net, b1, s_sc_max_mva=100, s_sc_min_mva=100, rx_min=0.35, rx_max=0.35) + b1 = create_bus(net, 110, zone=vector_group, index=get_free_id(net.bus)) + b2 = create_bus(net, 20, zone=vector_group) + create_bus(net, 20, in_service=False) + b3 = create_bus(net, 20, zone=vector_group) + b4 = create_bus(net, 20, zone=vector_group) + create_bus(net, 20) + + create_ext_grid(net, b1, s_sc_max_mva=100, s_sc_min_mva=100, rx_min=0.35, rx_max=0.35) net.ext_grid["r0x0_max"] = 0.4 net.ext_grid["x0x_max"] = 1.0 net.ext_grid["r0x0_min"] = 0.4 net.ext_grid["x0x_min"] = 1.0 - pp.create_std_type(net, {"r_ohm_per_km": 0.122, "x_ohm_per_km": 0.112, "c_nf_per_km": 304, - "max_i_ka": 0.421, "endtemp_degree": 70.0, "r0_ohm_per_km": 0.244, - "x0_ohm_per_km": 0.336, "c0_nf_per_km": 2000, "g0_us_per_km": 0}, "unsymmetric_line_type") - l1 = pp.create_line(net, b2, b3, length_km=10, std_type="unsymmetric_line_type", - index=pp.get_free_id(net.line)+1) - l2 = pp.create_line(net, b3, b4, length_km=15, std_type="unsymmetric_line_type") - pp.create_line(net, b3, b4, length_km=15, std_type="unsymmetric_line_type", in_service=False) - - transformer_type = {"i0_percent": 0.071, "pfe_kw": 29, "vkr_percent": 0.282, - "sn_mva": 25, "vn_lv_kv": 20.0, "vn_hv_kv": 110.0, "vk_percent": 11.2, - "shift_degree": 150, "vector_group": vector_group, "tap_side": "hv", - "tap_neutral": 0, "tap_min": -9, "tap_max": 9, "tap_step_degree": 0, - "tap_step_percent": 1.5, "tap_phase_shifter": False, "vk0_percent": 5, - "vkr0_percent": 0.4, "mag0_percent": 10, "mag0_rx": 0.4, - "si0_hv_partial": 0.9} - pp.create_std_type(net, transformer_type, vector_group, "trafo") - t1 = pp.create_transformer(net, b1, b2, std_type=vector_group, parallel=2, - index=pp.get_free_id(net.trafo)+1) - pp.create_transformer(net, b1, b2, std_type=vector_group, in_service=False) - pp.add_zero_impedance_parameters(net) + create_std_type(net, {"r_ohm_per_km": 0.122, "x_ohm_per_km": 0.112, "c_nf_per_km": 304, "max_i_ka": 0.421, + "endtemp_degree": 70.0, "r0_ohm_per_km": 0.244, "x0_ohm_per_km": 0.336, "c0_nf_per_km": 2000, + "g0_us_per_km": 0}, "unsymmetric_line_type") + l1 = create_line(net, b2, b3, length_km=10, std_type="unsymmetric_line_type", index=get_free_id(net.line) + 1) + l2 = create_line(net, b3, b4, length_km=15, std_type="unsymmetric_line_type") + create_line(net, b3, b4, length_km=15, std_type="unsymmetric_line_type", in_service=False) + + transformer_type = {"i0_percent": 0.071, "pfe_kw": 29, "vkr_percent": 0.282, "sn_mva": 25, "vn_lv_kv": 20.0, + "vn_hv_kv": 110.0, "vk_percent": 11.2, "shift_degree": 150, "vector_group": vector_group, + "tap_side": "hv", "tap_neutral": 0, "tap_min": -9, "tap_max": 9, "tap_step_degree": 0, + "tap_step_percent": 1.5, "tap_phase_shifter": False, "vk0_percent": 5, "vkr0_percent": 0.4, + "mag0_percent": 10, "mag0_rx": 0.4, "si0_hv_partial": 0.9} + create_std_type(net, transformer_type, vector_group, "trafo") + t1 = create_transformer(net, b1, b2, std_type=vector_group, parallel=2, index=get_free_id(net.trafo) + 1) + create_transformer(net, b1, b2, std_type=vector_group, in_service=False) + add_zero_impedance_parameters(net) return l1, l2, t1 @@ -70,10 +73,10 @@ def test_1ph_shortcircuit(): } for vc, result in results.items(): - net = pp.create_empty_network(sn_mva=17) + net = create_empty_network(sn_mva=17) add_network(net, vc) try: - sc.calc_sc(net, fault="1ph", case="max") + calc_sc(net, fault="1ph", case="max") except Exception as e: raise UserWarning(f"{str(e)}: Did not converge after adding transformer with vector group {vc}") check_results(net, vc, result) @@ -81,265 +84,226 @@ def test_1ph_shortcircuit(): def test_1ph_shortcircuit_3w(): # vector groups without "N" have no impact on the 1ph - # here we check both functions, with Y invertion and with LU factorization for individual buses - # The cuirrents are taken from the calculation with commercial software for reference + # here we check both functions, with Y inversion and with LU factorization for individual buses + # The currents are taken from the calculation with commercial software for reference results = { - "ddd": [1.5193429, 0, 0], - "ddy": [1.5193429, 0, 0], - "dyd": [1.5193429, 0, 0], - "dyy": [1.5193429, 0, 0], - "ydd": [1.5193429, 0, 0], - "ydy": [1.5193429, 0, 0], - "yyd": [1.5193429, 0, 0], - "yyy": [1.5193429, 0, 0], - "ynyd": [1.783257, 0, 0], - "yndy": [1.79376470, 0, 0], # ok - "yynd": [1.5193429, 3.339398, 0], - "ydyn": [1.5193429, 0, 8.836452], # ok - "ynynd": [1.783257, 3.499335, 0], - "yndyn": [1.79376470, 0, 9.04238714], # ok - "yndd": [1.843545, 0, 0], - "ynyy": [1.5193429, 0, 0] # ok but why? - } + "ddd": [1.5193429, 0, 0], + "ddy": [1.5193429, 0, 0], + "dyd": [1.5193429, 0, 0], + "dyy": [1.5193429, 0, 0], + "ydd": [1.5193429, 0, 0], + "ydy": [1.5193429, 0, 0], + "yyd": [1.5193429, 0, 0], + "yyy": [1.5193429, 0, 0], + "ynyd": [1.783257, 0, 0], + "yndy": [1.79376470, 0, 0], # ok + "yynd": [1.5193429, 3.339398, 0], + "ydyn": [1.5193429, 0, 8.836452], # ok + "ynynd": [1.783257, 3.499335, 0], + "yndyn": [1.79376470, 0, 9.04238714], # ok + "yndd": [1.843545, 0, 0], + "ynyy": [1.5193429, 0, 0] # ok but why? + } for vg, result in results.items(): net = single_3w_trafo_grid(vg) - sc.calc_sc(net, fault="1ph", case="max") + calc_sc(net, fault="1ph", case="max") assert np.allclose(net.res_bus_sc.ikss_ka.values, result, rtol=0, atol=1e-6) net2 = single_3w_trafo_grid(vg) for bus in net2.bus.index.values: - sc.calc_sc(net2, fault="1ph", case="max", inverse_y=False, bus=bus) + calc_sc(net2, fault="1ph", case="max", inverse_y=False, bus=bus) assert np.allclose(net.res_bus_sc.ikss_ka.at[bus], net2.res_bus_sc.ikss_ka.at[bus], rtol=0, atol=1e-9) def test_1ph_shortcircuit_min(): results = { - "Yy": [0.52209346201, 0.66632662571, 0.66756160176, 0.72517293174] - ,"Yyn": [0.52209346201, 2.4135757259, 1.545054139, 0.99373917957] - ,"Yd": [0.52209346201, 0.66632662571, 0.66756160176, 0.72517293174] - ,"YNy": [0.62316686505, 0.66632662571, 0.66756160176, 0.72517293174] - ,"YNyn":[0.620287259, 2.9155736491, 1.7561556936, 1.0807305212] - ,"YNd": [0.75434229157, 0.66632662571, 0.66756160176, 0.72517293174] - ,"Dy": [0.52209346201, 0.66632662571, 0.66756160176, 0.72517293174] - ,"Dyn": [0.52209346201, 3.4393798093, 1.9535982949, 1.1558364456] - ,"Dd": [0.52209346201, 0.66632662571, 0.66756160176, 0.72517293174] - } + "Yy": [0.52209346201, 0.66632662571, 0.66756160176, 0.72517293174], + "Yyn": [0.52209346201, 2.4135757259, 1.545054139, 0.99373917957], + "Yd": [0.52209346201, 0.66632662571, 0.66756160176, 0.72517293174], + "YNy": [0.62316686505, 0.66632662571, 0.66756160176, 0.72517293174], + "YNyn": [0.620287259, 2.9155736491, 1.7561556936, 1.0807305212], + "YNd": [0.75434229157, 0.66632662571, 0.66756160176, 0.72517293174], + "Dy": [0.52209346201, 0.66632662571, 0.66756160176, 0.72517293174], + "Dyn": [0.52209346201, 3.4393798093, 1.9535982949, 1.1558364456], + "Dd": [0.52209346201, 0.66632662571, 0.66756160176, 0.72517293174] + } for inv_y in (False, True): for vc, result in results.items(): - net = pp.create_empty_network(sn_mva=16) + net = create_empty_network(sn_mva=16) add_network(net, vc) try: - sc.calc_sc(net, fault="1ph", case="min", inverse_y=inv_y) + calc_sc(net, fault="1ph", case="min", inverse_y=inv_y) except Exception as e: raise UserWarning(f"{str(e)}: Did not converge after adding transformer with vector group {vc}") check_results(net, vc, result) def test_iec60909_example_4(): - file = os.path.join(pp.pp_dir, "test", "test_files", "IEC60909-4_example.json") - net = pp.from_json(file) + file = os.path.join(pp_dir, "test", "test_files", "IEC60909-4_example.json") + net = from_json(file) for inv_y in (False, True): - sc.calc_sc(net, fault="1ph", inverse_y=inv_y) - assert np.isclose(net.res_bus_sc[net.bus.name=="Q"].ikss_ka.values[0], 10.05957231) - assert np.isclose(net.res_bus_sc[net.bus.name=="T2LV"].ikss_ka.values[0], 34.467353142) - assert np.isclose(net.res_bus_sc[net.bus.name=="F1"].ikss_ka.values[0], 35.53066312) - assert np.isclose(net.res_bus_sc[net.bus.name=="F2"].ikss_ka.values[0], 34.89135137) - assert np.isclose(net.res_bus_sc[net.bus.name=="F3"].ikss_ka.values[0], 5.0321033105) - assert np.isclose(net.res_bus_sc[net.bus.name=="Cable/Line IC"].ikss_ka.values[0], 16.362586813) + calc_sc(net, fault="1ph", inverse_y=inv_y) + assert np.isclose(net.res_bus_sc[net.bus.name == "Q"].ikss_ka.values[0], 10.05957231) + assert np.isclose(net.res_bus_sc[net.bus.name == "T2LV"].ikss_ka.values[0], 34.467353142) + assert np.isclose(net.res_bus_sc[net.bus.name == "F1"].ikss_ka.values[0], 35.53066312) + assert np.isclose(net.res_bus_sc[net.bus.name == "F2"].ikss_ka.values[0], 34.89135137) + assert np.isclose(net.res_bus_sc[net.bus.name == "F3"].ikss_ka.values[0], 5.0321033105) + assert np.isclose(net.res_bus_sc[net.bus.name == "Cable/Line IC"].ikss_ka.values[0], 16.362586813) def test_iec60909_example_4_bus_selection(): - file = os.path.join(pp.pp_dir, "test", "test_files", "IEC60909-4_example.json") - net = pp.from_json(file) + file = os.path.join(pp_dir, "test", "test_files", "IEC60909-4_example.json") + net = from_json(file) for inv_y in (False, True): - sc.calc_sc(net, fault="1ph", inverse_y=inv_y, - bus=net.bus[net.bus.name.isin(("F1", "F2"))].index) - assert np.isclose(net.res_bus_sc.at[net.bus[net.bus.name=="F1"].index[0], - "ikss_ka"], 35.53066312) - assert np.isclose(net.res_bus_sc.at[net.bus[net.bus.name=="F2"].index[0], - "ikss_ka"], 34.89135137) + calc_sc(net, fault="1ph", inverse_y=inv_y, bus=net.bus[net.bus.name.isin(("F1", "F2"))].index) + assert np.isclose(net.res_bus_sc.at[net.bus[net.bus.name == "F1"].index[0], "ikss_ka"], 35.53066312) + assert np.isclose(net.res_bus_sc.at[net.bus[net.bus.name == "F2"].index[0], "ikss_ka"], 34.89135137) @pytest.mark.parametrize("inverse_y", (True, False), ids=("Inverse Y", "LU factorization")) def test_iec60909_example_4_bus_selection_br_res(inverse_y): - file = os.path.join(pp.pp_dir, "test", "test_files", "IEC60909-4_example.json") - net = pp.from_json(file) - sc.calc_sc(net, fault="1ph", inverse_y=inverse_y, - bus=net.bus[net.bus.name.isin(("F1", "F2"))].index, - branch_results=True) - sc.calc_sc(net, fault="1ph", inverse_y=inverse_y, - bus=net.bus[net.bus.name.isin(("F1", "F2"))].index, - branch_results=True, return_all_currents=True) - assert np.isclose(net.res_bus_sc.at[net.bus[net.bus.name=="F1"].index[0], - "ikss_ka"], 35.53066312) - assert np.isclose(net.res_bus_sc.at[net.bus[net.bus.name=="F2"].index[0], - "ikss_ka"], 34.89135137) + file = os.path.join(pp_dir, "test", "test_files", "IEC60909-4_example.json") + net = from_json(file) + calc_sc(net, fault="1ph", inverse_y=inverse_y, bus=net.bus[net.bus.name.isin(("F1", "F2"))].index, + branch_results=True) + calc_sc(net, fault="1ph", inverse_y=inverse_y, bus=net.bus[net.bus.name.isin(("F1", "F2"))].index, + branch_results=True, return_all_currents=True) + assert np.isclose(net.res_bus_sc.at[net.bus[net.bus.name == "F1"].index[0], "ikss_ka"], 35.53066312) + assert np.isclose(net.res_bus_sc.at[net.bus[net.bus.name == "F2"].index[0], "ikss_ka"], 34.89135137) @pytest.mark.parametrize("inverse_y", (True, False), ids=("Inverse Y", "LU factorization")) def test_1ph_with_switches(inverse_y): - net = pp.create_empty_network(sn_mva=67) + net = create_empty_network(sn_mva=67) vc = "Yy" l1, l2, _ = add_network(net, vc) - sc.calc_sc(net, fault="1ph", case="max", inverse_y=inverse_y) - pp.create_line(net, net.line.to_bus.at[l2], net.line.from_bus.at[l1], length_km=15, - std_type="unsymmetric_line_type", parallel=2.) - pp.add_zero_impedance_parameters(net) - pp.create_switch(net, bus=net.line.to_bus.at[l2], element=l2, et="l", closed=False) - sc.calc_sc(net, fault="1ph", case="max") + calc_sc(net, fault="1ph", case="max", inverse_y=inverse_y) + create_line(net, net.line.to_bus.at[l2], net.line.from_bus.at[l1], length_km=15, std_type="unsymmetric_line_type", + parallel=2.) + add_zero_impedance_parameters(net) + create_switch(net, bus=net.line.to_bus.at[l2], element=l2, et="l", closed=False) + calc_sc(net, fault="1ph", case="max") check_results(net, vc, [0.52209347338, 2.0620266652, 2.3255761263, 2.3066467489]) def single_3w_trafo_grid(vector_group, sn_mva=123): - net = pp.create_empty_network(sn_mva=sn_mva) - b1 = pp.create_bus(net, vn_kv=380., geodata=(1,1)) - b2 = pp.create_bus(net, vn_kv=110., geodata=(0,1)) - b3 = pp.create_bus(net, vn_kv=30., geodata=(1,0)) - pp.create_ext_grid(net, b1, s_sc_max_mva=1000, s_sc_min_mva=800, - rx_max=0.1, x0x_max=1, r0x0_max=0.1, - rx_min=0.1, x0x_min=1, r0x0_min=0.1) - - pp.create_transformer3w_from_parameters(net, - hv_bus=b1, mv_bus=b2, lv_bus=b3, - vn_hv_kv=400, vn_mv_kv=120, vn_lv_kv=30, - sn_hv_mva=350, sn_mv_mva=350, sn_lv_mva=50, - pfe_kw=0, i0_percent=0, - vk_hv_percent=21, vkr_hv_percent=.26, - vk_mv_percent=7, vkr_mv_percent=.16, - vk_lv_percent=10., vkr_lv_percent=.16, - vk0_hv_percent=44.1, vkr0_hv_percent=0.26, - vk0_mv_percent=6.2996, vkr0_mv_percent=0.03714, - vk0_lv_percent=6.2996, vkr0_lv_percent=0.03714, - vector_group=vector_group) + net = create_empty_network(sn_mva=sn_mva) + b1 = create_bus(net, vn_kv=380., geodata=(1, 1)) + b2 = create_bus(net, vn_kv=110., geodata=(0, 1)) + b3 = create_bus(net, vn_kv=30., geodata=(1, 0)) + create_ext_grid(net, b1, s_sc_max_mva=1000, s_sc_min_mva=800, rx_max=0.1, x0x_max=1, r0x0_max=0.1, rx_min=0.1, + x0x_min=1, r0x0_min=0.1) + + create_transformer3w_from_parameters(net, hv_bus=b1, mv_bus=b2, lv_bus=b3, vn_hv_kv=400, vn_mv_kv=120, vn_lv_kv=30, + sn_hv_mva=350, sn_mv_mva=350, sn_lv_mva=50, pfe_kw=0, i0_percent=0, + vk_hv_percent=21, vkr_hv_percent=.26, vk_mv_percent=7, vkr_mv_percent=.16, + vk_lv_percent=10., vkr_lv_percent=.16, vk0_hv_percent=44.1, + vkr0_hv_percent=0.26, vk0_mv_percent=6.2996, vkr0_mv_percent=0.03714, + vk0_lv_percent=6.2996, vkr0_lv_percent=0.03714, vector_group=vector_group) return net def iec_60909_4_small(n_t3=1, num_earth=1, with_gen=False): - net = pp.create_empty_network(sn_mva=3) + net = create_empty_network(sn_mva=3) - b1 = pp.create_bus(net, vn_kv=380.) - b2 = pp.create_bus(net, vn_kv=110.) - b3 = pp.create_bus(net, vn_kv=110.) - b5 = pp.create_bus(net, vn_kv=110.) - b8 = pp.create_bus(net, vn_kv=30.) - HG2 = pp.create_bus(net, vn_kv=10) + b1 = create_bus(net, vn_kv=380.) + b2 = create_bus(net, vn_kv=110.) + b3 = create_bus(net, vn_kv=110.) + b5 = create_bus(net, vn_kv=110.) + b8 = create_bus(net, vn_kv=30.) + hg2 = create_bus(net, vn_kv=10) - pp.create_ext_grid(net, b1, s_sc_max_mva=38 * 380 * np.sqrt(3), rx_max=0.1, x0x_max=3, r0x0_max=0.15, - s_sc_min_mva=38 * 380 * np.sqrt(3) / 10, rx_min=0.1, x0x_min=3, r0x0_min=0.15,) - pp.create_ext_grid(net, b5, s_sc_max_mva=16 * 110 * np.sqrt(3), rx_max=0.1, x0x_max=3.3, r0x0_max=0.2, - s_sc_min_mva=16 * 110 * np.sqrt(3) / 10, rx_min=0.1, x0x_min=3.3, r0x0_min=0.2) + create_ext_grid(net, b1, s_sc_max_mva=38 * 380 * np.sqrt(3), rx_max=0.1, x0x_max=3, r0x0_max=0.15, + s_sc_min_mva=38 * 380 * np.sqrt(3) / 10, rx_min=0.1, x0x_min=3, r0x0_min=0.15, ) + create_ext_grid(net, b5, s_sc_max_mva=16 * 110 * np.sqrt(3), rx_max=0.1, x0x_max=3.3, r0x0_max=0.2, + s_sc_min_mva=16 * 110 * np.sqrt(3) / 10, rx_min=0.1, x0x_min=3.3, r0x0_min=0.2) if num_earth == 1: vector_group = ("YYNd", "YNYd") else: vector_group = ("YNYNd", "YNYNd") - if n_t3==2: - pp.create_transformer3w_from_parameters(net, - hv_bus=b1, mv_bus=b2, lv_bus=b8, - vn_hv_kv=400, vn_mv_kv=120, vn_lv_kv=30, - sn_hv_mva=350, sn_mv_mva=350, sn_lv_mva=50, - pfe_kw=0, i0_percent=0, - vk_hv_percent=21, vkr_hv_percent=.26, - vk_mv_percent=7, vkr_mv_percent=.16, - vk_lv_percent=10., vkr_lv_percent=.16, - vk0_hv_percent=44.1, vkr0_hv_percent=0.26, - vk0_mv_percent=6.2996, vkr0_mv_percent=0.03714, - vk0_lv_percent=6.2996, vkr0_lv_percent=0.03714, - vector_group=vector_group[0]) - pp.create_transformer3w_from_parameters(net, - hv_bus=b1, mv_bus=b2, lv_bus=b8, - vn_hv_kv=400, vn_mv_kv=120, vn_lv_kv=30, - sn_hv_mva=350, sn_mv_mva=350, sn_lv_mva=50, - pfe_kw=0, i0_percent=0, - vk_hv_percent=21, vkr_hv_percent=.26, - vk_mv_percent=7, vkr_mv_percent=.16, - vk_lv_percent=10., vkr_lv_percent=.16, - vk0_hv_percent=44.1, vkr0_hv_percent=0.26, - vk0_mv_percent=6.2996, vkr0_mv_percent=0.03714, - vk0_lv_percent=6.2996, vkr0_lv_percent=0.03714, - vector_group=vector_group[1]) - - pp.create_line_from_parameters(net, b2, b3, name="L1", - c_nf_per_km=0, max_i_ka=0, # FIXME: Optional for SC - length_km=20, r_ohm_per_km=0.12, x_ohm_per_km=0.39, - r0_ohm_per_km=0.32, x0_ohm_per_km=1.26, c0_nf_per_km=0, g0_us_per_km=0, endtemp_degree=80) - pp.create_line_from_parameters(net, b2, b5, name="L3a", - c_nf_per_km=0, max_i_ka=0, - length_km=5, r_ohm_per_km=0.12, x_ohm_per_km=0.39, - r0_ohm_per_km=0.52, x0_ohm_per_km=1.86, c0_nf_per_km=0, g0_us_per_km=0, endtemp_degree=80) - pp.create_line_from_parameters(net, b2, b5, name="L3b", - c_nf_per_km=0, max_i_ka=0, - length_km=5, r_ohm_per_km=0.12, x_ohm_per_km=0.39, - r0_ohm_per_km=0.52, x0_ohm_per_km=1.86, c0_nf_per_km=0, g0_us_per_km=0, endtemp_degree=80) - pp.create_line_from_parameters(net, b5, b3, name="L4", - c_nf_per_km=0, max_i_ka=0, - length_km=10, r_ohm_per_km=0.096, x_ohm_per_km=0.388, - r0_ohm_per_km=0.22, x0_ohm_per_km=1.1, c0_nf_per_km=0, g0_us_per_km=0, endtemp_degree=80) + if n_t3 == 2: + create_transformer3w_from_parameters(net, hv_bus=b1, mv_bus=b2, lv_bus=b8, vn_hv_kv=400, vn_mv_kv=120, + vn_lv_kv=30, sn_hv_mva=350, sn_mv_mva=350, sn_lv_mva=50, pfe_kw=0, + i0_percent=0, vk_hv_percent=21, vkr_hv_percent=.26, vk_mv_percent=7, + vkr_mv_percent=.16, vk_lv_percent=10., vkr_lv_percent=.16, + vk0_hv_percent=44.1, vkr0_hv_percent=0.26, vk0_mv_percent=6.2996, + vkr0_mv_percent=0.03714, vk0_lv_percent=6.2996, vkr0_lv_percent=0.03714, + vector_group=vector_group[0]) + create_transformer3w_from_parameters(net, hv_bus=b1, mv_bus=b2, lv_bus=b8, vn_hv_kv=400, vn_mv_kv=120, vn_lv_kv=30, + sn_hv_mva=350, sn_mv_mva=350, sn_lv_mva=50, pfe_kw=0, i0_percent=0, + vk_hv_percent=21, vkr_hv_percent=.26, vk_mv_percent=7, vkr_mv_percent=.16, + vk_lv_percent=10., vkr_lv_percent=.16, vk0_hv_percent=44.1, + vkr0_hv_percent=0.26, vk0_mv_percent=6.2996, vkr0_mv_percent=0.03714, + vk0_lv_percent=6.2996, vkr0_lv_percent=0.03714, vector_group=vector_group[1]) + + create_line_from_parameters(net, b2, b3, name="L1", c_nf_per_km=0, max_i_ka=0, # FIXME: Optional for SC + length_km=20, r_ohm_per_km=0.12, x_ohm_per_km=0.39, r0_ohm_per_km=0.32, + x0_ohm_per_km=1.26, c0_nf_per_km=0, g0_us_per_km=0, endtemp_degree=80) + create_line_from_parameters(net, b2, b5, name="L3a", c_nf_per_km=0, max_i_ka=0, length_km=5, r_ohm_per_km=0.12, + x_ohm_per_km=0.39, r0_ohm_per_km=0.52, x0_ohm_per_km=1.86, c0_nf_per_km=0, + g0_us_per_km=0, endtemp_degree=80) + create_line_from_parameters(net, b2, b5, name="L3b", c_nf_per_km=0, max_i_ka=0, length_km=5, r_ohm_per_km=0.12, + x_ohm_per_km=0.39, r0_ohm_per_km=0.52, x0_ohm_per_km=1.86, c0_nf_per_km=0, + g0_us_per_km=0, endtemp_degree=80) + create_line_from_parameters(net, b5, b3, name="L4", c_nf_per_km=0, max_i_ka=0, length_km=10, r_ohm_per_km=0.096, + x_ohm_per_km=0.388, r0_ohm_per_km=0.22, x0_ohm_per_km=1.1, c0_nf_per_km=0, + g0_us_per_km=0, endtemp_degree=80) if with_gen: - t1 = pp.create_transformer_from_parameters(net, b3, HG2, sn_mva=100, - pfe_kw=0, i0_percent=0, vn_hv_kv=120., vn_lv_kv=10.5, vk_percent=12, vkr_percent=0.5, - vk0_percent=12, vkr0_percent=0.5, mag0_percent=100, mag0_rx=0, si0_hv_partial=0.5, - shift_degree=5, vector_group="Yd", power_station_unit=True) - pp.create_gen(net, HG2, p_mw=0.9 * 100, vn_kv=10.5, - xdss_pu=0.16, rdss_ohm=0.005, cos_phi=0.9, sn_mva=100, pg_percent=7.5, - slack=True, power_station_trafo=t1) + t1 = create_transformer_from_parameters(net, b3, hg2, sn_mva=100, pfe_kw=0, i0_percent=0, vn_hv_kv=120., + vn_lv_kv=10.5, vk_percent=12, vkr_percent=0.5, vk0_percent=12, + vkr0_percent=0.5, mag0_percent=100, mag0_rx=0, si0_hv_partial=0.5, + shift_degree=5, vector_group="Yd", power_station_unit=True) + create_gen(net, hg2, p_mw=0.9 * 100, vn_kv=10.5, xdss_pu=0.16, rdss_ohm=0.005, cos_phi=0.9, sn_mva=100, + pg_percent=7.5, slack=True, power_station_trafo=t1) return net def iec_60909_4_t1(): - net = pp.create_empty_network(sn_mva=26) - pp.create_bus(net, vn_kv=110.) - pp.create_bus(net, vn_kv=20.) - - t1 = pp.create_transformer_from_parameters(net, 0, 1, sn_mva=150, - pfe_kw=0, i0_percent=0, - vn_hv_kv=115., vn_lv_kv=21, vk_percent=16, vkr_percent=0.5, - pt_percent=12, oltc=True, vk0_percent=15.2, - vkr0_percent=0.5, xn_ohm=22, vector_group="YNd", - mag0_percent=100, mag0_rx=0, si0_hv_partial=0.5, - power_station_unit=True) - pp.create_gen(net, 1, p_mw=0.85 * 150, vn_kv=21, - xdss_pu=0.14, rdss_ohm=0.002, cos_phi=0.85, sn_mva=150, pg_percent=0, - power_station_trafo=t1) + net = create_empty_network(sn_mva=26) + create_bus(net, vn_kv=110.) + create_bus(net, vn_kv=20.) + + t1 = create_transformer_from_parameters(net, 0, 1, sn_mva=150, pfe_kw=0, i0_percent=0, vn_hv_kv=115., vn_lv_kv=21, + vk_percent=16, vkr_percent=0.5, pt_percent=12, oltc=True, vk0_percent=15.2, + vkr0_percent=0.5, xn_ohm=22, vector_group="YNd", mag0_percent=100, + mag0_rx=0, si0_hv_partial=0.5, power_station_unit=True) + create_gen(net, 1, p_mw=0.85 * 150, vn_kv=21, xdss_pu=0.14, rdss_ohm=0.002, cos_phi=0.85, sn_mva=150, pg_percent=0, + power_station_trafo=t1) return net def vde_232(): - net = pp.create_empty_network(sn_mva=12) + net = create_empty_network(sn_mva=12) # hv buses - pp.create_bus(net, 110, geodata=(0,0)) - pp.create_bus(net, 21, geodata=(1,0)) - - pp.create_ext_grid(net, 0, s_sc_max_mva=13.61213 * 110 * np.sqrt(3), rx_max=0.20328, - x0x_max=3.47927, r0x0_max=3.03361*0.20328/3.47927) - pp.create_transformer_from_parameters(net, 0, 1, 150, 115, 21, 0.5, 16, - pfe_kw=0, i0_percent=0, tap_step_percent=1, - tap_max=12, tap_min=-12, tap_neutral=0, tap_side='hv', - vector_group="YNd", - vk0_percent=np.sqrt(np.square(0.95*15.99219) + np.square(0.5)), - vkr0_percent=0.5, - mag0_percent=100, mag0_rx=0, - si0_hv_partial=0.9, - pt_percent=12, oltc=True, - power_station_unit=True, - xn_ohm=22) - - pp.create_gen(net, 1, 150, 1, 150, vn_kv=21, xdss_pu=0.14, rdss_ohm=0.002, cos_phi=0.85, power_station_trafo=0, pg_percent=5) + create_bus(net, 110, geodata=(0, 0)) + create_bus(net, 21, geodata=(1, 0)) + + create_ext_grid(net, 0, s_sc_max_mva=13.61213 * 110 * np.sqrt(3), rx_max=0.20328, x0x_max=3.47927, + r0x0_max=3.03361 * 0.20328 / 3.47927) + create_transformer_from_parameters(net, 0, 1, 150, 115, 21, 0.5, 16, pfe_kw=0, i0_percent=0, tap_step_percent=1, + tap_max=12, tap_min=-12, tap_neutral=0, tap_side='hv', vector_group="YNd", + vk0_percent=np.sqrt(np.square(0.95 * 15.99219) + np.square(0.5)), + vkr0_percent=0.5, mag0_percent=100, mag0_rx=0, si0_hv_partial=0.9, pt_percent=12, + oltc=True, power_station_unit=True, xn_ohm=22) + + create_gen(net, 1, 150, 1, 150, vn_kv=21, xdss_pu=0.14, rdss_ohm=0.002, cos_phi=0.85, power_station_trafo=0, + pg_percent=5) # z_q u_nq = 110 i_kqss = 13.61213 z_q = 1.1 * u_nq / (np.sqrt(3) * i_kqss) rx_max = 0.20328 - x_q = z_q / np.sqrt(1+rx_max**2) + x_q = z_q / np.sqrt(1 + rx_max ** 2) x_0q = x_q * 3.47927 - r_0q = x_0q * 3.03361*0.20328/3.47927 - z_0q = r_0q + 1j*x_0q + r_0q = x_0q * 3.03361 * 0.20328 / 3.47927 + z_0q = r_0q + 1j * x_0q return net @@ -352,7 +316,7 @@ def test_iec60909_example_4_one_trafo3w(): # x = 6.0598429694 ikss_pf = [24.4009, 8.2481, 6.1728, 10.1851] - sc.calc_sc(net, fault="1ph") + calc_sc(net, fault="1ph") assert np.allclose(net.res_bus_sc.ikss_ka.values[:4], np.array(ikss_pf), atol=1e-4) @@ -361,7 +325,7 @@ def test_iec60909_example_4_two_trafo3w(): ikss_pf_2t3 = [24.5772, 14.7247, 8.1060, 15.2749] - sc.calc_sc(net, fault="1ph") + calc_sc(net, fault="1ph") assert np.allclose(net.res_bus_sc.ikss_ka.values[:4], np.array(ikss_pf_2t3), atol=1e-4) @@ -375,10 +339,10 @@ def test_iec60909_example_4_two_trafo3w_two_earth(): ikss_pf_max = [26.0499, 20.9472, 9.1722, 18.7457] ikss_pf_min = [3.9622, 8.3914, 5.0248, 6.9413] - sc.calc_sc(net, fault="1ph", case="max") + calc_sc(net, fault="1ph", case="max") assert np.allclose(net.res_bus_sc.ikss_ka.values[:4], np.array(ikss_pf_max), atol=1e-4) - sc.calc_sc(net, fault="1ph", case="min") + calc_sc(net, fault="1ph", case="min") assert np.allclose(net.res_bus_sc.ikss_ka.values[:4], np.array(ikss_pf_min), atol=1e-4) @@ -386,37 +350,37 @@ def test_iec60909_example_4_two_trafo3w_two_earth(): def test_iec_60909_4_small_with_t2_1ph(): net = iec_60909_4_small(n_t3=2, num_earth=1, with_gen=True) net.gen = net.gen.iloc[0:0, :] - sc.calc_sc(net, fault="1ph", case="max", ip=True, tk_s=0.1, kappa_method="C") + calc_sc(net, fault="1ph", case="max", ip=True, tk_s=0.1, kappa_method="C") ikss_max = [24.57717, 16.96235, 11.6109, 18.07836] # ikss_min = [3.5001, 8.4362, 7.4743, 7.7707] - assert np.allclose(net.res_bus_sc.ikss_ka.values[:4], np.array(ikss_max), atol=1e-4) + assert np.allclose(net.res_bus_ikss_ka.values[:4], np.array(ikss_max), atol=1e-4) @pytest.mark.skip("1ph gen-close sc calculation still under develop") def test_iec_60909_4_small_with_gen_1ph_no_ps_detection(): net = iec_60909_4_small(n_t3=2, num_earth=1, with_gen=True) - net.gen.power_station_trafo=np.nan - net.trafo.power_station_unit=np.nan - sc.calc_sc(net, fault="1ph", case="max", ip=True, tk_s=0.1, kappa_method="C") + net.gen.power_station_trafo = np.nan + net.trafo.power_station_unit = np.nan + calc_sc(net, fault="1ph", case="max", ip=True, tk_s=0.1, kappa_method="C") ikss_max = [24.60896, 17.2703, 12.3771, 18.4723] # ikss_min = [3.5001, 8.4362, 7.4743, 7.7707] # ip_min = [8.6843, 21.6173, 18.0242, 19.4261] - assert np.allclose(net.res_bus_sc.ikss_ka.values[:4], np.array(ikss_max), atol=1e-4) + assert np.allclose(net.res_bus_ikss_ka.values[:4], np.array(ikss_max), atol=1e-4) def test_iec_60909_4_small_with_gen_ps_unit_1ph(): net = iec_60909_4_small(n_t3=2, num_earth=1, with_gen=True) - sc.calc_sc(net, fault="1ph", case="max", ip=True, tk_s=0.1, kappa_method="C") + calc_sc(net, fault="1ph", case="max", ip=True, tk_s=0.1, kappa_method="C") ikss_max = [24.6109, 17.4363, 12.7497, 18.6883] # ikss_min = [3.5001, 8.4362, 7.4743, 7.7707] # ip_min = [8.6843, 21.6173, 18.0242, 19.4261] # TODO: This needs to be fixed!! - # assert np.allclose(net.res_bus_sc.ikss_ka.values[:4], np.array(ikss_max), atol=1e-4) + # assert np.allclose(net.res_bus_sc.ikss_ka.values[:4], np.array(ikss_max), atol=1e-4) def test_vde_232_with_gen_ps_unit_1ph(): @@ -425,7 +389,7 @@ def test_vde_232_with_gen_ps_unit_1ph(): # from pandapower.pypower.idx_bus import * net = vde_232() - sc.calc_sc(net, fault="1ph", case="max", ip=True, tk_s=0.1, kappa_method="C") + calc_sc(net, fault="1ph", case="max", ip=True, tk_s=0.1, kappa_method="C") assert np.isclose(net.res_bus_sc.at[0, 'ikss_ka'], 9.04979, rtol=0, atol=1e-4) assert np.isclose(net.res_bus_sc.at[0, 'rk0_ohm'], 2.09392, rtol=0, atol=1e-4) assert np.isclose(net.res_bus_sc.at[0, 'xk0_ohm'], 14.3989, rtol=0, atol=1e-4) @@ -433,7 +397,7 @@ def test_vde_232_with_gen_ps_unit_1ph(): def test_t1_iec60909_4(): net = iec_60909_4_t1() - sc.calc_sc(net, fault="1ph", case="max", ip=True, tk_s=0.1, kappa_method="C") + calc_sc(net, fault="1ph", case="max", ip=True, tk_s=0.1, kappa_method="C") assert np.isclose(net.res_bus_sc.at[0, 'ikss_ka'], 1.587457, rtol=0, atol=1e-4) assert np.isclose(net.res_bus_sc.at[0, 'rk0_ohm'], 0.439059, rtol=0, atol=1e-4) assert np.isclose(net.res_bus_sc.at[0, 'xk0_ohm'], 79.340169, rtol=0, atol=1e-4) @@ -442,27 +406,21 @@ def test_t1_iec60909_4(): def test_1ph_sn_mva_ext_grid(): - net1 = pp.create_empty_network(sn_mva=1) - b1 = pp.create_bus(net1, 110) - pp.create_ext_grid(net1, b1, s_sc_max_mva=1000, s_sc_min_mva=800, - rx_max=0.1, x0x_max=1, r0x0_max=0.1, - rx_min=0.1, x0x_min=1, r0x0_min=0.1) + net1 = create_empty_network(sn_mva=1) + b1 = create_bus(net1, 110) + create_ext_grid(net1, b1, s_sc_max_mva=1000, s_sc_min_mva=800, rx_max=0.1, x0x_max=1, r0x0_max=0.1, rx_min=0.1, + x0x_min=1, r0x0_min=0.1) + net2 = create_empty_network(sn_mva=17) + b1 = create_bus(net2, 110) + create_ext_grid(net2, b1, s_sc_max_mva=1000, s_sc_min_mva=800, rx_max=0.1, x0x_max=1, r0x0_max=0.1, rx_min=0.1, + x0x_min=1, r0x0_min=0.1) - net2 = pp.create_empty_network(sn_mva=17) - b1 = pp.create_bus(net2, 110) - pp.create_ext_grid(net2, b1, s_sc_max_mva=1000, s_sc_min_mva=800, - rx_max=0.1, x0x_max=1, r0x0_max=0.1, - rx_min=0.1, x0x_min=1, r0x0_min=0.1) + calc_sc(net1, fault="1ph", case="max") + calc_sc(net2, fault="1ph", case="max") - sc.calc_sc(net1, fault="1ph", case="max") - sc.calc_sc(net2, fault="1ph", case="max") - - res = {'ikss_ka': 5.2486388108147795, - 'rk0_ohm': 1.3243945001694957, - 'xk0_ohm': 13.243945001694957, - 'rk_ohm': 1.3243945001694957, - 'xk_ohm': 13.243945001694957} + res = {'ikss_ka': 5.2486388108147795, 'rk0_ohm': 1.3243945001694957, 'xk0_ohm': 13.243945001694957, + 'rk_ohm': 1.3243945001694957, 'xk_ohm': 13.243945001694957} for var in res.keys(): assert np.allclose(net1.res_bus_sc[var], net2.res_bus_sc[var], atol=1e-6, rtol=0) @@ -470,70 +428,58 @@ def test_1ph_sn_mva_ext_grid(): def test_line(): - net = pp.create_empty_network(sn_mva=17) - b1 = pp.create_bus(net, 110) - pp.create_ext_grid(net, b1, s_sc_max_mva=1000, s_sc_min_mva=800, - rx_max=0.1, x0x_max=1, r0x0_max=0.1, - rx_min=0.1, x0x_min=1, r0x0_min=0.1) + net = create_empty_network(sn_mva=17) + b1 = create_bus(net, 110) + create_ext_grid(net, b1, s_sc_max_mva=1000, s_sc_min_mva=800, rx_max=0.1, x0x_max=1, r0x0_max=0.1, rx_min=0.1, + x0x_min=1, r0x0_min=0.1) - b2 = pp.create_bus(net, 110) + b2 = create_bus(net, 110) - pp.create_line_from_parameters(net, b1, b2, 1, 1, 0.5, 0., 10, r0_ohm_per_km=4, x0_ohm_per_km=0.25, c0_nf_per_km=0.) - sc.calc_sc(net, fault="1ph", case="max") + create_line_from_parameters(net, b1, b2, 1, 1, 0.5, 0., 10, r0_ohm_per_km=4, x0_ohm_per_km=0.25, c0_nf_per_km=0.) + calc_sc(net, fault="1ph", case="max") assert np.allclose(net.res_bus_sc.ikss_ka, [5.248639, 4.968909], rtol=0, atol=1e-6) res = net.res_bus_sc.copy() - sc.calc_sc(net, fault="1ph", case="max") + calc_sc(net, fault="1ph", case="max") assert np.allclose(net.res_bus_sc, res, rtol=0, atol=1e-6) def test_trafo(): - results = { - "Yy": [5.248639, 0], - "Yyn": [5.248639, 0.812581], - "Yd": [5.248639, 0], - "Dy": [5.248639, 0], - "Dd": [5.248639, 0], - "Dyn": [5.248639, 17.245191], - "YNd": [6.324033, 0], - "YNy": [5.265657, 0], - "YNyn": [5.265737, 14.413729]} + results = {"Yy": [5.248639, 0], "Yyn": [5.248639, 0.812581], "Yd": [5.248639, 0], "Dy": [5.248639, 0], + "Dd": [5.248639, 0], "Dyn": [5.248639, 17.245191], "YNd": [6.324033, 0], "YNy": [5.265657, 0], + "YNyn": [5.265737, 14.413729]} for vc in results.keys(): - net = pp.create_empty_network(sn_mva=1) - pp.create_bus(net, vn_kv=110.) - pp.create_bus(net, vn_kv=20.) - - pp.create_ext_grid(net, 0, s_sc_max_mva=1000, s_sc_min_mva=800, - rx_max=0.1, x0x_max=1, r0x0_max=0.1, - rx_min=0.1, x0x_min=1, r0x0_min=0.1) - - t1 = pp.create_transformer_from_parameters(net, 0, 1, sn_mva=150, - pfe_kw=10, i0_percent=0.1, - vn_hv_kv=115., vn_lv_kv=21, vk_percent=16, vkr_percent=0.5, - pt_percent=12, vk0_percent=15.2, - vkr0_percent=0.5, vector_group=vc, - mag0_percent=100, mag0_rx=0, si0_hv_partial=0.5) - sc.calc_sc(net, fault="1ph", case="max") + net = create_empty_network(sn_mva=1) + create_bus(net, vn_kv=110.) + create_bus(net, vn_kv=20.) + + create_ext_grid(net, 0, s_sc_max_mva=1000, s_sc_min_mva=800, rx_max=0.1, x0x_max=1, r0x0_max=0.1, rx_min=0.1, + x0x_min=1, r0x0_min=0.1) + + t1 = create_transformer_from_parameters(net, 0, 1, sn_mva=150, pfe_kw=10, i0_percent=0.1, vn_hv_kv=115., + vn_lv_kv=21, vk_percent=16, vkr_percent=0.5, pt_percent=12, + vk0_percent=15.2, vkr0_percent=0.5, vector_group=vc, mag0_percent=100, + mag0_rx=0, si0_hv_partial=0.5) + calc_sc(net, fault="1ph", case="max") res = net.res_bus_sc.copy() net.sn_mva = 123 - sc.calc_sc(net, fault="1ph", case="max") + calc_sc(net, fault="1ph", case="max") assert np.allclose(net.res_bus_sc, res, rtol=0, atol=1e-6), f"failed for vector group {vc}" assert np.allclose(net.res_bus_sc.ikss_ka, results[vc], rtol=0, atol=1e-6), f"{vc}: inconsistent results" def test_sc_1ph_impedance(): - net = pp.create_empty_network() - pp.create_buses(net, 2, 110) - pp.create_ext_grid(net, 0, s_sc_max_mva=1000, s_sc_min_mva=800, - rx_max=0.1, x0x_max=1, r0x0_max=0.1, - rx_min=0.1, x0x_min=1, r0x0_min=0.1) - pp.create_impedance(net, 0, 1, rft_pu=0.2, xft_pu=0.4, sn_mva=50, rtf_pu=0.25, xtf_pu=0.5, - rft0_pu=0.1, xft0_pu=0.2, rtf0_pu=0.05, xtf0_pu=0.1, gf0_pu=0, bf0_pu=0) - - sc.calc_sc(net, fault="1ph") + net = create_empty_network() + create_buses(net, 2, 110) + create_ext_grid(net, 0, s_sc_max_mva=1000, s_sc_min_mva=800, rx_max=0.1, x0x_max=1, r0x0_max=0.1, rx_min=0.1, + x0x_min=1, r0x0_min=0.1) + create_impedance(net, 0, 1, rft_pu=0.2, xft_pu=0.4, sn_mva=50, rtf_pu=0.25, xtf_pu=0.5, rft0_pu=0.1, xft0_pu=0.2, + rtf0_pu=0.05, xtf0_pu=0.1, gf0_pu=0, bf0_pu=0) + + calc_sc(net, fault="1ph") assert np.allclose(net.res_bus_sc.ikss_ka, [5.248639, 0.625166], rtol=0, atol=1e-6) assert np.allclose(net.res_bus_sc.rk0_ohm, [1.324394, 12.762198], rtol=0, atol=1e-6) diff --git a/pandapower/test/shortcircuit/test_all_currents.py b/pandapower/test/shortcircuit/test_all_currents.py index 2e996ce91..ce3e85f47 100644 --- a/pandapower/test/shortcircuit/test_all_currents.py +++ b/pandapower/test/shortcircuit/test_all_currents.py @@ -6,27 +6,28 @@ import numpy as np import pytest -from scipy.linalg import inv -import pandapower as pp -import pandapower.shortcircuit as sc +from pandapower.create import create_empty_network, create_bus, create_ext_grid, create_line, create_sgen, \ + create_transformer_from_parameters, create_transformers_from_parameters, create_line_from_parameters, create_buses, \ + create_lines_from_parameters, create_switch, create_load, create_shunt, create_ward, create_xward from pandapower.pypower.idx_brch import F_BUS, T_BUS, TAP, BR_R, BR_X - -from pandapower.pypower.idx_bus_sc import * +from pandapower.pypower.idx_bus_sc import IKSS1, PHI_IKSS1_DEGREE +from pandapower.run import runpp +from pandapower.shortcircuit.calc_sc import calc_sc def three_bus_example(): - net = pp.create_empty_network(sn_mva=56) - b1 = pp.create_bus(net, 110) - b2 = pp.create_bus(net, 110) - b3 = pp.create_bus(net, 110) - - pp.create_ext_grid(net, b1, s_sc_max_mva=100., s_sc_min_mva=80., rx_min=0.4, rx_max=0.4) - pp.create_line(net, b1, b2, std_type="305-AL1/39-ST1A 110.0" , length_km=20.) - pp.create_line(net, b2, b3, std_type="N2XS(FL)2Y 1x185 RM/35 64/110 kV" , length_km=15.) + net = create_empty_network(sn_mva=56) + b1 = create_bus(net, 110) + b2 = create_bus(net, 110) + b3 = create_bus(net, 110) + + create_ext_grid(net, b1, s_sc_max_mva=100., s_sc_min_mva=80., rx_min=0.4, rx_max=0.4) + create_line(net, b1, b2, std_type="305-AL1/39-ST1A 110.0", length_km=20.) + create_line(net, b2, b3, std_type="N2XS(FL)2Y 1x185 RM/35 64/110 kV", length_km=15.) net.line["endtemp_degree"] = 80 - pp.create_sgen(net, b2, sn_mva=2, p_mw=0, k=1.2) + create_sgen(net, b2, sn_mva=2, p_mw=0, k=1.2) net.ext_grid['x0x_min'] = 0.1 net.ext_grid['r0x0_min'] = 0.1 @@ -41,116 +42,114 @@ def three_bus_example(): def three_bus_permuted_index(): - net = pp.create_empty_network(sn_mva=67) - b1 = pp.create_bus(net, 110, index=4) - b2 = pp.create_bus(net, 110, index=3) - b3 = pp.create_bus(net, 110, index=0) - - pp.create_ext_grid(net, b1, s_sc_max_mva=100., s_sc_min_mva=80., rx_min=0.4, rx_max=0.4) - pp.create_line(net, b1, b2, std_type="305-AL1/39-ST1A 110.0" , length_km=20., index=1) - pp.create_line(net, b2, b3, std_type="N2XS(FL)2Y 1x185 RM/35 64/110 kV" , length_km=15., index=0) + net = create_empty_network(sn_mva=67) + b1 = create_bus(net, 110, index=4) + b2 = create_bus(net, 110, index=3) + b3 = create_bus(net, 110, index=0) + + create_ext_grid(net, b1, s_sc_max_mva=100., s_sc_min_mva=80., rx_min=0.4, rx_max=0.4) + create_line(net, b1, b2, std_type="305-AL1/39-ST1A 110.0", length_km=20., index=1) + create_line(net, b2, b3, std_type="N2XS(FL)2Y 1x185 RM/35 64/110 kV", length_km=15., index=0) net.line["endtemp_degree"] = 80 - pp.create_sgen(net, b2, sn_mva=2, p_mw=0, k=1.2) + create_sgen(net, b2, sn_mva=2, p_mw=0, k=1.2) return net # def gen_three_bus_example(): -# net = pp.create_empty_network(sn_mva=2) -# b1 = pp.create_bus(net, vn_kv=10.) -# b2 = pp.create_bus(net, vn_kv=10.) -# b3 = pp.create_bus(net, vn_kv=10.) -# #pp.create_bus(net, vn_kv=0.4, in_service=False) -# pp.create_gen(net, b2, vn_kv=10.5, xdss_pu=0.2, rdss_pu=0.001, cos_phi=0.8, p_mw=0.1, sn_mva=2.5) -# pp.create_line_from_parameters(net, b1, b2, length_km=1.0, max_i_ka=0.29, +# net = create_empty_network(sn_mva=2) +# b1 = create_bus(net, vn_kv=10.) +# b2 = create_bus(net, vn_kv=10.) +# b3 = create_bus(net, vn_kv=10.) +# #create_bus(net, vn_kv=0.4, in_service=False) +# create_gen(net, b2, vn_kv=10.5, xdss_pu=0.2, rdss_pu=0.001, cos_phi=0.8, p_mw=0.1, sn_mva=2.5) +# create_line_from_parameters(net, b1, b2, length_km=1.0, max_i_ka=0.29, # r_ohm_per_km=0.1548, x_ohm_per_km=0.0816814, c_nf_per_km=165) -# pp.create_line_from_parameters(net, b2, b3, length_km=1.0, max_i_ka=0.29, +# create_line_from_parameters(net, b2, b3, length_km=1.0, max_i_ka=0.29, # r_ohm_per_km=0.1548, x_ohm_per_km=0.0816814, c_nf_per_km=165) # net.line["endtemp_degree"] = 165 -# pp.create_ext_grid(net, b1, s_sc_max_mva=10., s_sc_min_mva=8., rx_min=0.4, rx_max=0.4) -# #pp.create_switch(net, b3, b1, et="b") +# create_ext_grid(net, b1, s_sc_max_mva=10., s_sc_min_mva=8., rx_min=0.4, rx_max=0.4) +# #create_switch(net, b3, b1, et="b") # return net def net_transformer_simple(): - net = pp.create_empty_network(sn_mva=2) - b1 = pp.create_bus(net, vn_kv=10.) - b2 = pp.create_bus(net, vn_kv=.4) - pp.create_ext_grid(net, b1, s_sc_max_mva=100., s_sc_min_mva=40., rx_min=0.1, rx_max=0.1) - pp.create_transformer_from_parameters(net, b1, b2, vn_hv_kv=10., vn_lv_kv=0.4, vk_percent=6., - vkr_percent=0.5, pfe_kw=14, shift_degree=0.0, - tap_side="hv", tap_neutral=0, tap_min=-2, tap_max=2, tap_pos=0, - tap_step_percent=2.5, parallel=1, sn_mva=0.4, i0_percent=0.5) + net = create_empty_network(sn_mva=2) + b1 = create_bus(net, vn_kv=10.) + b2 = create_bus(net, vn_kv=.4) + create_ext_grid(net, b1, s_sc_max_mva=100., s_sc_min_mva=40., rx_min=0.1, rx_max=0.1) + create_transformer_from_parameters(net, b1, b2, vn_hv_kv=10., vn_lv_kv=0.4, vk_percent=6., vkr_percent=0.5, + pfe_kw=14, shift_degree=0.0, tap_side="hv", tap_neutral=0, tap_min=-2, tap_max=2, + tap_pos=0, tap_step_percent=2.5, parallel=1, sn_mva=0.4, i0_percent=0.5) return net def net_transformer_simple_2(): - net = pp.create_empty_network(sn_mva=2) - b1 = pp.create_bus(net, vn_kv=10.) - b1a = pp.create_bus(net, vn_kv=10.) - b2 = pp.create_bus(net, vn_kv=.4) - b3 = pp.create_bus(net, vn_kv=.4) - b4 = pp.create_bus(net, vn_kv=.4) - pp.create_ext_grid(net, b1, s_sc_max_mva=100., s_sc_min_mva=40., rx_min=0.1, rx_max=0.1) - pp.create_transformers_from_parameters(net, [b1, b1a], [b2, b3], vn_hv_kv=10., vn_lv_kv=0.4, vk_percent=6., - vkr_percent=0.5, pfe_kw=14, shift_degree=0.0, - tap_side="hv", tap_neutral=0, tap_min=-2, tap_max=2, tap_pos=0, - tap_step_percent=2.5, parallel=1, sn_mva=0.4, i0_percent=0.5) - pp.create_line_from_parameters(net, b1, b1a, 1, 0.099, 0.156, 125, 0.457) - pp.create_line_from_parameters(net, b3, b4, 1, 0.099, 0.156, 125, 0.457) + net = create_empty_network(sn_mva=2) + b1 = create_bus(net, vn_kv=10.) + b1a = create_bus(net, vn_kv=10.) + b2 = create_bus(net, vn_kv=.4) + b3 = create_bus(net, vn_kv=.4) + b4 = create_bus(net, vn_kv=.4) + create_ext_grid(net, b1, s_sc_max_mva=100., s_sc_min_mva=40., rx_min=0.1, rx_max=0.1) + create_transformers_from_parameters(net, [b1, b1a], [b2, b3], vn_hv_kv=10., vn_lv_kv=0.4, vk_percent=6., + vkr_percent=0.5, pfe_kw=14, shift_degree=0.0, tap_side="hv", tap_neutral=0, + tap_min=-2, tap_max=2, tap_pos=0, tap_step_percent=2.5, parallel=1, sn_mva=0.4, + i0_percent=0.5) + create_line_from_parameters(net, b1, b1a, 1, 0.099, 0.156, 125, 0.457) + create_line_from_parameters(net, b3, b4, 1, 0.099, 0.156, 125, 0.457) return net def net_transformer_simple_3(): - net = pp.create_empty_network(sn_mva=100) - pp.create_buses(net, 2, 30) - pp.create_buses(net, 3, 10) - pp.create_buses(net, 2, 0.4) + net = create_empty_network(sn_mva=100) + create_buses(net, 2, 30) + create_buses(net, 3, 10) + create_buses(net, 2, 0.4) - pp.create_ext_grid(net, 0, s_sc_max_mva=100., s_sc_min_mva=40., rx_min=0.1, rx_max=0.1) + create_ext_grid(net, 0, s_sc_max_mva=100., s_sc_min_mva=40., rx_min=0.1, rx_max=0.1) # 30/10 - pp.create_transformers_from_parameters(net, [0, 1], [2, 3], sn_mva=10, vn_hv_kv=30., vn_lv_kv=10, - vk_percent=6., vkr_percent=0.5, i0_percent=0.1, pfe_kw=10, - shift_degree=0.0, tap_side="hv", tap_neutral=0, tap_min=-2, - tap_max=2, tap_pos=0, tap_step_percent=2.5, parallel=1) + create_transformers_from_parameters(net, [0, 1], [2, 3], sn_mva=10, vn_hv_kv=30., vn_lv_kv=10, vk_percent=6., + vkr_percent=0.5, i0_percent=0.1, pfe_kw=10, shift_degree=0.0, tap_side="hv", + tap_neutral=0, tap_min=-2, tap_max=2, tap_pos=0, tap_step_percent=2.5, + parallel=1) # 10/0.4 - pp.create_transformer_from_parameters(net, 4, 5, sn_mva=0.4, vn_hv_kv=10., vn_lv_kv=0.4, vk_percent=6., - vkr_percent=0.5, pfe_kw=14, i0_percent=0.5, shift_degree=0.0, - tap_side="hv", tap_neutral=0, tap_min=-2, tap_max=2, tap_pos=0, - tap_step_percent=2.5, parallel=1) - pp.create_lines_from_parameters(net, [0, 3, 5], [1, 4, 6], 1, 0.099, 0.156, 400, 0.457) + create_transformer_from_parameters(net, 4, 5, sn_mva=0.4, vn_hv_kv=10., vn_lv_kv=0.4, vk_percent=6., + vkr_percent=0.5, pfe_kw=14, i0_percent=0.5, shift_degree=0.0, tap_side="hv", + tap_neutral=0, tap_min=-2, tap_max=2, tap_pos=0, tap_step_percent=2.5, + parallel=1) + create_lines_from_parameters(net, [0, 3, 5], [1, 4, 6], 1, 0.099, 0.156, 400, 0.457) return net def net_transformer_simple_4(): net = net_transformer_simple_3() - pp.create_bus(net, 10) - pp.create_bus(net, 0.4) - pp.create_lines_from_parameters(net, [2, 8], [7, 6], 1, 0.099, 0.156, 400, 0.457) - pp.create_transformer_from_parameters(net, 7, 8, sn_mva=0.4, vn_hv_kv=10., vn_lv_kv=0.4, vk_percent=6., - vkr_percent=0.5, pfe_kw=14, i0_percent=0.5, shift_degree=0.0, - tap_side="hv", tap_neutral=0, tap_min=-2, tap_max=2, tap_pos=0, - tap_step_percent=2.5, parallel=1) - pp.create_switch(net, 6, 4, "l", closed=True) - pp.create_sgen(net, 3, 0, 0, 20, k=1.2, kappa=1) - pp.create_load(net, 6, 0.1) + create_bus(net, 10) + create_bus(net, 0.4) + create_lines_from_parameters(net, [2, 8], [7, 6], 1, 0.099, 0.156, 400, 0.457) + create_transformer_from_parameters(net, 7, 8, sn_mva=0.4, vn_hv_kv=10., vn_lv_kv=0.4, vk_percent=6., + vkr_percent=0.5, pfe_kw=14, i0_percent=0.5, shift_degree=0.0, tap_side="hv", + tap_neutral=0, tap_min=-2, tap_max=2, tap_pos=0, tap_step_percent=2.5, + parallel=1) + create_switch(net, 6, 4, "l", closed=True) + create_sgen(net, 3, 0, 0, 20, k=1.2, kappa=1) + create_load(net, 6, 0.1) return net def net_transformer(): - net = pp.create_empty_network(sn_mva=2) - b1a = pp.create_bus(net, vn_kv=10.) - b1b = pp.create_bus(net, vn_kv=10.) - b2 = pp.create_bus(net, vn_kv=.4) - pp.create_bus(net, vn_kv=0.4, in_service=False) #add out of service bus to test oos indexing - pp.create_ext_grid(net, b1a, s_sc_max_mva=100., s_sc_min_mva=40., rx_min=0.1, rx_max=0.1) - pp.create_switch(net, b1a, b1b, et="b") - pp.create_transformer_from_parameters(net, b1b, b2, vn_hv_kv=11., vn_lv_kv=0.42, vk_percent=6., - vkr_percent=0.5, pfe_kw=14, shift_degree=0.0, - tap_side="hv", tap_neutral=0, tap_min=-2, tap_max=2, tap_pos=2, - tap_step_percent=2.5, parallel=2, sn_mva=0.4, i0_percent=0.5) - pp.create_shunt(net, b2, q_mvar=0.050, p_mw=0.0500) #adding a shunt shouldn't change the result + net = create_empty_network(sn_mva=2) + b1a = create_bus(net, vn_kv=10.) + b1b = create_bus(net, vn_kv=10.) + b2 = create_bus(net, vn_kv=.4) + create_bus(net, vn_kv=0.4, in_service=False) # add out of service bus to test oos indexing + create_ext_grid(net, b1a, s_sc_max_mva=100., s_sc_min_mva=40., rx_min=0.1, rx_max=0.1) + create_switch(net, b1a, b1b, et="b") + create_transformer_from_parameters(net, b1b, b2, vn_hv_kv=11., vn_lv_kv=0.42, vk_percent=6., vkr_percent=0.5, + pfe_kw=14, shift_degree=0.0, tap_side="hv", tap_neutral=0, tap_min=-2, tap_max=2, + tap_pos=2, tap_step_percent=2.5, parallel=2, sn_mva=0.4, i0_percent=0.5) + create_shunt(net, b2, q_mvar=0.050, p_mw=0.0500) # adding a shunt shouldn't change the result return net @@ -161,21 +160,19 @@ def test_all_currents_sgen(): # g # net = three_bus_example() - sc.calc_sc(net, case="max", ip=True, ith=True, branch_results=True, return_all_currents=True) + calc_sc(net, case="max", ip=True, ith=True, branch_results=True, return_all_currents=True) assert np.allclose(net.res_line_sc.ikss_ka.values, np.array([0.01259673, 0.49593036, 0.48628848, 0., 0., 0.49888962]), atol=1e-5) - assert np.allclose(net.res_line_sc.ip_ka.values, - np.array([0.01781447, 0.92787447, 0.90729584, 0., 0., 0.92511655]), atol=1e-5) - assert np.allclose(net.res_line_sc.ith_ka.values, - np.array([0.01265116, 0.4981196, 0.48841266, 0., 0., 0.50106884]), atol=1e-5) + assert np.allclose(net.res_line_sc.ip_ka.values, np.array([0.01781447, 0.92787447, 0.90729584, 0., 0., 0.92511655]), + atol=1e-5) + assert np.allclose(net.res_line_sc.ith_ka.values, np.array([0.01265116, 0.4981196, 0.48841266, 0., 0., 0.50106884]), + atol=1e-5) - sc.calc_sc(net, case="min", ip=True, ith=True, branch_results=True, return_all_currents=True) - assert np.allclose(net.res_line_sc.ikss_ka.values, - np.array([0., 0.3989686, 0.3919381, 0., 0., 0.3919381]), atol=1e-5) - assert np.allclose(net.res_line_sc.ip_ka.values, - np.array([0., 0.74438751, 0.728265, 0., 0., 0.728265]), atol=1e-5) - assert np.allclose(net.res_line_sc.ith_ka.values, - np.array([0., 0.40071219, 0.393626, 0., 0., 0.393626]), atol=1e-5) + calc_sc(net, case="min", ip=True, ith=True, branch_results=True, return_all_currents=True) + assert np.allclose(net.res_line_sc.ikss_ka.values, np.array([0., 0.3989686, 0.3919381, 0., 0., 0.3919381]), + atol=1e-5) + assert np.allclose(net.res_line_sc.ip_ka.values, np.array([0., 0.74438751, 0.728265, 0., 0., 0.728265]), atol=1e-5) + assert np.allclose(net.res_line_sc.ith_ka.values, np.array([0., 0.40071219, 0.393626, 0., 0., 0.393626]), atol=1e-5) def test_all_currents_1ph_max(): @@ -187,14 +184,14 @@ def test_all_currents_1ph_max(): # # With generator net = three_bus_example() - sc.calc_sc(net, case="max", fault='1ph', branch_results=True, return_all_currents=True) + calc_sc(net, case="max", fault='1ph', branch_results=True, return_all_currents=True) i_bus_with_sgen = net.res_bus_sc.copy() i_line_with_gen = net.res_line_sc.copy() # Without generator net = three_bus_example() net.sgen.in_service = False - sc.calc_sc(net, case="max", fault='1ph') + calc_sc(net, case="max", fault='1ph') i_bus_without_sgen = net.res_bus_sc.copy() # Isolate sgen contrib @@ -202,8 +199,8 @@ def test_all_currents_1ph_max(): assert np.isclose(i_line_with_gen.ikss_ka.loc[(0, 0)], i_bus_only_sgen.ikss_ka.at[0], atol=1e-4) assert np.isclose(i_line_with_gen.ikss_ka.loc[(0, 1)], i_bus_without_sgen.ikss_ka.at[1], atol=1e-4) - assert np.isclose(i_line_with_gen.ikss_ka.loc[(0, 2)], i_bus_without_sgen.ikss_ka.at[2] - - (i_bus_only_sgen.ikss_ka.at[1] - i_bus_only_sgen.ikss_ka.at[2]) , atol=1e-4) + assert np.isclose(i_line_with_gen.ikss_ka.loc[(0, 2)], i_bus_without_sgen.ikss_ka.at[2] - ( + i_bus_only_sgen.ikss_ka.at[1] - i_bus_only_sgen.ikss_ka.at[2]), atol=1e-4) assert np.isclose(i_line_with_gen.ikss_ka.loc[(1, 0)], 0., atol=1e-4) assert np.isclose(i_line_with_gen.ikss_ka.loc[(1, 1)], 0., atol=1e-4) assert np.isclose(i_line_with_gen.ikss_ka.loc[(1, 2)], i_bus_with_sgen.ikss_ka.at[2], atol=1e-4) @@ -218,13 +215,13 @@ def test_all_currents_1ph_min(): # # With generator net = three_bus_example() - sc.calc_sc(net, case="min", fault='1ph', branch_results=True, return_all_currents=True) + calc_sc(net, case="min", fault='1ph', branch_results=True, return_all_currents=True) i_bus_with_sgen = net.res_bus_sc.copy() i_line_with_gen = net.res_line_sc.copy() # Without generator net.sgen.in_service = False - sc.calc_sc(net, case="min", fault='1ph', branch_results=True) + calc_sc(net, case="min", fault='1ph', branch_results=True) i_bus_without_sgen = net.res_bus_sc.copy() # Isolate sgen contrib @@ -232,8 +229,8 @@ def test_all_currents_1ph_min(): assert np.isclose(i_line_with_gen.ikss_ka.loc[(0, 0)], i_bus_only_sgen.ikss_ka.at[0], atol=1e-4) assert np.isclose(i_line_with_gen.ikss_ka.loc[(0, 1)], i_bus_without_sgen.ikss_ka.at[1], atol=1e-4) - assert np.isclose(i_line_with_gen.ikss_ka.loc[(0, 2)], i_bus_without_sgen.ikss_ka.at[2] - - (i_bus_only_sgen.ikss_ka.at[1] - i_bus_only_sgen.ikss_ka.at[2]) , atol=1e-4) + assert np.isclose(i_line_with_gen.ikss_ka.loc[(0, 2)], i_bus_without_sgen.ikss_ka.at[2] - ( + i_bus_only_sgen.ikss_ka.at[1] - i_bus_only_sgen.ikss_ka.at[2]), atol=1e-4) assert np.isclose(i_line_with_gen.ikss_ka.loc[(1, 0)], 0., atol=1e-4) assert np.isclose(i_line_with_gen.ikss_ka.loc[(1, 1)], 0., atol=1e-4) assert np.isclose(i_line_with_gen.ikss_ka.loc[(1, 2)], i_bus_with_sgen.ikss_ka.at[2], atol=1e-4) @@ -247,49 +244,46 @@ def test_with_permuted_index(): # g # net = three_bus_permuted_index() - sc.calc_sc(net, case="max", ip=True, ith=True, branch_results=True, return_all_currents=True) + calc_sc(net, case="max", ip=True, ith=True, branch_results=True, return_all_currents=True) assert np.allclose(net.res_line_sc.ikss_ka.loc[[(1, 4), (1, 3), (1, 0), (0, 4), (0, 3), (0, 0)]].values, np.array([0.01259673, 0.49593036, 0.48628848, 0., 0., 0.49888962]), atol=1e-5) - sc.calc_sc(net, case="min", ip=True, ith=True, branch_results=True, return_all_currents=True) + calc_sc(net, case="min", ip=True, ith=True, branch_results=True, return_all_currents=True) assert np.allclose(net.res_line_sc.ikss_ka.loc[[(1, 4), (1, 3), (1, 0), (0, 4), (0, 3), (0, 0)]].values, np.array([0., 0.3989686, 0.3919381, 0., 0., 0.3919381]), atol=1e-5) def test_all_currents_with_oos_elements(): - net = three_bus_example() net.bus.loc[2, "in_service"] = False net.line.loc[1, "in_service"] = False - sc.calc_sc(net, case="max", branch_results=True, return_all_currents=True) + calc_sc(net, case="max", branch_results=True, return_all_currents=True) - assert np.allclose(net.res_line_sc.ikss_ka.loc[[(0, 0), (0, 1)]].values, - np.array([0.01259673, 0.49593036]), atol=1e-5) - assert np.allclose(net.res_line_sc.ikss_ka.loc[[(0, 2), (1, 0), (1, 1), (1, 2)]].values, - 0, atol=1e-10) + assert np.allclose(net.res_line_sc.ikss_ka.loc[[(0, 0), (0, 1)]].values, np.array([0.01259673, 0.49593036]), + atol=1e-5) + assert np.allclose(net.res_line_sc.ikss_ka.loc[[(0, 2), (1, 0), (1, 1), (1, 2)]].values, 0, atol=1e-10) - sc.calc_sc(net, case="min", branch_results=True, return_all_currents=True) - assert np.allclose(net.res_line_sc.ikss_ka.loc[[(0, 0), (0, 1)]].values, - np.array([0, 0.3989686]), atol=1e-5) # sgen does not contribute in case == "min" - # np.array([0.01259673, 0.3989686]), atol=1e-5) # <- old - assert np.allclose(net.res_line_sc.ikss_ka.loc[[(0, 2), (1, 0), (1, 1), (1, 2)]].values, - 0, atol=1e-10) + calc_sc(net, case="min", branch_results=True, return_all_currents=True) + assert np.allclose(net.res_line_sc.ikss_ka.loc[[(0, 0), (0, 1)]].values, np.array([0, 0.3989686]), + atol=1e-5) # sgen does not contribute in case == "min" + # np.array([0.01259673, 0.3989686]), atol=1e-5) # <- old + assert np.allclose(net.res_line_sc.ikss_ka.loc[[(0, 2), (1, 0), (1, 1), (1, 2)]].values, 0, atol=1e-10) # TODO: This example should not work anymore # def test_branch_all_currents_gen(): # net = gen_three_bus_example() -# sc.calc_sc(net, case="max", branch_results=True, return_all_currents=True) +# calc_sc(net, case="max", branch_results=True, return_all_currents=True) # assert np.allclose(net.res_line_sc.ikss_ka.values, # np.array([0.76204252, 0.57040645, 0.55786693, 0., 0., 1.28698045])) -# sc.calc_sc(net, case="min", branch_results=True, return_all_currents=True) +# calc_sc(net, case="min", branch_results=True, return_all_currents=True) # assert np.allclose(net.res_line_sc.ikss_ka.values, # np.array([0.69255026, 0.45574755, 0.44487882, 0., 0., 1.10747517])) def test_branch_all_currents_trafo_simple(): net = net_transformer_simple() - sc.calc_sc(net, case='max', ip=True, ith=True, lv_tol_percent=6., branch_results=True, bus=1) + calc_sc(net, case='max', ip=True, ith=True, lv_tol_percent=6., branch_results=True, bus=1) assert np.isclose(net.res_bus_sc.ikss_ka, 9.749917, atol=1e-6, rtol=0) assert np.isclose(net.res_bus_sc.skss_mw, 6.75494, atol=1e-6, rtol=0) @@ -307,7 +301,7 @@ def test_branch_all_currents_trafo_simple(): assert np.isclose(net.res_trafo_sc.vm_lv_pu, 0, atol=1e-6, rtol=0) assert np.isclose(net.res_trafo_sc.va_lv_degree, 0, atol=1e-6, rtol=0) - sc.calc_sc(net, case='max', ip=True, ith=True, lv_tol_percent=6., branch_results=False, bus=0) + calc_sc(net, case='max', ip=True, ith=True, lv_tol_percent=6., branch_results=False, bus=0) assert np.isclose(net.res_bus_sc.ikss_ka, 5.773503, atol=1e-6, rtol=0) assert np.isclose(net.res_bus_sc.skss_mw, 100, atol=1e-6, rtol=0) @@ -315,11 +309,10 @@ def test_branch_all_currents_trafo_simple(): def add_aux_trafo(net, trafo_idx): hv_bus = net.trafo.at[trafo_idx, 'hv_bus'] - aux_bus = pp.create_bus(net, net.trafo.at[trafo_idx, 'vn_hv_kv']) + aux_bus = create_bus(net, net.trafo.at[trafo_idx, 'vn_hv_kv']) net.trafo.at[trafo_idx, 'hv_bus'] = aux_bus - pp.create_transformer_from_parameters(net, hv_bus, aux_bus, net.trafo.at[trafo_idx, 'sn_mva'], - net.bus.at[hv_bus, 'vn_kv'], net.bus.at[aux_bus, 'vn_kv'], - 1e-6, 1e-5, 0, 0) + create_transformer_from_parameters(net, hv_bus, aux_bus, net.trafo.at[trafo_idx, 'sn_mva'], + net.bus.at[hv_bus, 'vn_kv'], net.bus.at[aux_bus, 'vn_kv'], 1e-6, 1e-5, 0, 0) @pytest.mark.parametrize("inverse_y", (True, False), ids=("Inverse Y", "LU factorization")) @@ -328,10 +321,10 @@ def test_branch_all_currents_trafo_simple_other_voltage3(inverse_y): net.trafo.at[1, "vn_hv_kv"] = 31 net.trafo.at[2, "vn_hv_kv"] = 11 - sc.calc_sc(net, case='max', lv_tol_percent=6., branch_results=True, bus=6, inverse_y=inverse_y) + calc_sc(net, case='max', lv_tol_percent=6., branch_results=True, bus=6, inverse_y=inverse_y) - assert np.allclose(net.res_bus_sc.loc[6].values, - [1.16712302, 0.80860656, 0.10127268, 0.18141131], rtol=0, atol=1e-6) + assert np.allclose(net.res_bus_sc.loc[6].values, [1.16712302, 0.80860656, 0.10127268, 0.18141131], rtol=0, + atol=1e-6) res_line_sc = np.array([[0.013691, 0.013691, -60.827605, 0.013691, 119.172395, 0.4132998, 0.7358034, -0.413244, -0.735716, 1.186326, -0.150470, 1.186180, -0.150091], @@ -353,10 +346,10 @@ def test_branch_all_currents_trafo_simple_other_voltage3(inverse_y): net.trafo.at[1, "vn_hv_kv"] = 29 net.trafo.at[2, "vn_hv_kv"] = 9 - sc.calc_sc(net, case='max', lv_tol_percent=6., branch_results=True, bus=6, inverse_y=inverse_y) + calc_sc(net, case='max', lv_tol_percent=6., branch_results=True, bus=6, inverse_y=inverse_y) - assert np.allclose(net.res_bus_sc.loc[6].values, - [1.15940813, 0.80326152, 0.10147573, 0.18288051], rtol=0, atol=1e-6) + assert np.allclose(net.res_bus_sc.loc[6].values, [1.15940813, 0.80326152, 0.10147573, 0.18288051], rtol=0, + atol=1e-6) res_line_sc = np.array([[0.017769, 0.017769, -60.975224, 0.017769, 119.024776, 0.408286, 0.728168, -0.4081925, -0.7280205, 0.904182, - 0.254709, 0.903993, - 0.254055], @@ -378,20 +371,18 @@ def test_branch_all_currents_trafo_simple_other_voltage3(inverse_y): net.trafo.at[1, "vn_hv_kv"] = 31 net.trafo.at[2, "vn_hv_kv"] = 11 - sc.calc_sc(net, case='max', lv_tol_percent=6., branch_results=True, bus=4, inverse_y=inverse_y) - assert np.allclose(net.res_bus_sc.loc[4].values, - [3.490484425, 60.45696064, 0.26224866, 1.80047754], rtol=0, atol=3e-6) + calc_sc(net, case='max', lv_tol_percent=6., branch_results=True, bus=4, inverse_y=inverse_y) + assert np.allclose(net.res_bus_sc.loc[4].values, [3.490484425, 60.45696064, 0.26224866, 1.80047754], rtol=0, + atol=3e-6) res_line_sc = np.array([[1.125963, 1.125963, -81.712857, 1.125963, 98.287143, 5.838649, 28.341696, -5.462115, -27.748369, 0.494590, - 3.353461, 0.483378, - 2.848843], [3.490484, 3.490484, -81.712857, 3.490484, 98.287143, 3.618494, 5.701869, 0, 0, 0.111701, - - 24.112697, 0, 0], - [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]) + - 24.112697, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]) relevant = [i for i, c in enumerate(net.res_line_sc.columns) if not np.all(np.isnan(net.res_line_sc[c]))] assert np.allclose(net.res_line_sc.iloc[:, relevant].values, res_line_sc[:, relevant], rtol=0, atol=1e-6) res_trafo_sc = np.array([[0, 0, 0, 0, 0, 0, 0, 0, 0.494590, -3.353461, 0.494590, -3.353461], [1.125963, - 81.712857, 3.490484, 98.287143, 5.462115, 27.748369, -3.618494, -5.701869, - 0.483378, -2.848843, 0.111701, -24.112697], - [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]) + 0.483378, -2.848843, 0.111701, -24.112697], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]) relevant = [i for i, c in enumerate(net.res_trafo_sc.columns) if not np.all(np.isnan(net.res_trafo_sc[c]))] assert np.allclose(net.res_trafo_sc.iloc[:, relevant].values, res_trafo_sc[:, relevant], rtol=0, atol=1e-6) @@ -400,10 +391,9 @@ def test_branch_all_currents_trafo_simple_other_voltage3(inverse_y): net.trafo.at[1, "vn_lv_kv"] = 9 net.trafo.at[2, "vn_lv_kv"] = 0.42 - sc.calc_sc(net, case='max', lv_tol_percent=6., branch_results=True, bus=6, inverse_y=inverse_y) + calc_sc(net, case='max', lv_tol_percent=6., branch_results=True, bus=6, inverse_y=inverse_y) - assert np.allclose(net.res_bus_sc.loc[6].values, - [1.153265, 0.799006, 0.101542, 0.184117], rtol=0, atol=1e-6) + assert np.allclose(net.res_bus_sc.loc[6].values, [1.153265, 0.799006, 0.101542, 0.184117], rtol=0, atol=1e-6) res_line_sc = np.array([[0.014531, 0.014531, - 61.122864, 0.014531, 118.877136, 0.404535, 0.728398, - 0.404473, - 0.728299, 1.103480, - 0.169658, 1.103325, - 0.169187], [0.048437, 0.048437, - 61.122864, 0.048437, 118.877136, 0.404185, 0.724860, - 0.403488, @@ -430,16 +420,16 @@ def test_type_c_trafo_simple_other_voltage4(inverse_y): # net.trafo.at[1, "vn_hv_kv"] = 31 net.trafo.at[2, "vn_hv_kv"] = 11 - pp.runpp(net) - sc.calc_sc(net, case='max', lv_tol_percent=6., branch_results=True, bus=6, use_pre_fault_voltage=True, inverse_y=inverse_y) + runpp(net) + calc_sc(net, case='max', lv_tol_percent=6., branch_results=True, bus=6, use_pre_fault_voltage=True, + inverse_y=inverse_y) baseMVA = net.sn_mva # MVA baseV = net.bus.vn_kv.values # kV # baseI = baseMVA / (baseV * np.sqrt(3)) # baseZ = baseV ** 2 / baseMVA - assert np.allclose(net.res_bus_sc.loc[6].values, - [2.096122, 1.452236, 0.054549, 0.085178], rtol=0, atol=1e-6) + assert np.allclose(net.res_bus_sc.loc[6].values, [2.096122, 1.452236, 0.054549, 0.085178], rtol=0, atol=1e-6) res_line_sc = np.array([[0.012104, 0.010331, -52.747518, 0.012104, 121.050735, 0.322524, 0.419803, -0.322487, -0.529717, 0.986152, -0.281725, 0.986032, -0.281941], @@ -480,61 +470,47 @@ def test_type_c_trafo_simple_other_voltage4_sgen(inverse_y): net.sgen.q_mvar = 0 net.sgen.kappa = 1 net.sgen.k = 1.2 - pp.create_load(net, 7, 10, 3) - pp.create_switch(net, 6, 4, 'l', False) + create_load(net, 7, 10, 3) + create_switch(net, 6, 4, 'l', False) net.trafo.at[1, "vn_hv_kv"] = 31 net.trafo.at[2, "vn_lv_kv"] = 0.42 - pp.runpp(net) - sc.calc_sc(net, case='max', lv_tol_percent=6., branch_results=True, bus=6, use_pre_fault_voltage=True, - inverse_y=inverse_y) + runpp(net) + calc_sc(net, case='max', lv_tol_percent=6., branch_results=True, bus=6, use_pre_fault_voltage=True, + inverse_y=inverse_y) baseMVA = net.sn_mva # MVA baseV = net.bus.vn_kv.values # kV baseI = baseMVA / (baseV * np.sqrt(3)) baseZ = baseV ** 2 / baseMVA - assert np.allclose(net.res_bus_sc.loc[6].values, - [1.12072796, 0.77646312, 0.11355049, 0.15946966], rtol=0, atol=1e-6) - - res_line_sc = np.array([[0.37233817, 0.37202159, -171.92326236, 0.37233817, - 8.4072921, -19.05762949, 2.78907414, 19.09876936, - -2.83670764, 0.99637, -0.24936231, 0.99798561, - -0.04098874], - [0.04744828, 0.04684176, -52.75384134, 0.04744828, - 126.82145161, 0.39363348, 0.67731344, -0.39297336, - -0.68797096, 0.9655717, 7.08233793, 0.96406436, - 7.08617078], - [1.12072796, 1.12071697, -53.94177232, 1.12072796, - 126.05787127, 0.37304125, 0.58781451, 0., - 0., 0.89663052, 3.65803177, 0., - 0.], - [0.6275538, 0.62734921, -21.12040944, 0.6275538, - 158.81863754, 10.05721887, 3.15086826, -9.94029022, - -2.97825453, 0.96992777, -3.72493869, 0.95467304, - -4.50238709], - [0., 0.0000277, 85.40612729, 0., - 0., 0., -0.00001832, 0., - 0., 0.95459186, -4.56234781, 0.95460121, - -4.56270483]]) + assert np.allclose(net.res_bus_sc.loc[6].values, [1.12072796, 0.77646312, 0.11355049, 0.15946966], rtol=0, + atol=1e-6) + + res_line_sc = np.array([[0.37233817, 0.37202159, -171.92326236, 0.37233817, 8.4072921, -19.05762949, 2.78907414, + 19.09876936, -2.83670764, 0.99637, -0.24936231, 0.99798561, -0.04098874], + [0.04744828, 0.04684176, -52.75384134, 0.04744828, 126.82145161, 0.39363348, 0.67731344, + -0.39297336, -0.68797096, 0.9655717, 7.08233793, 0.96406436, 7.08617078], + [1.12072796, 1.12071697, -53.94177232, 1.12072796, 126.05787127, 0.37304125, 0.58781451, 0., + 0., 0.89663052, 3.65803177, 0., 0.], + [0.6275538, 0.62734921, -21.12040944, 0.6275538, 158.81863754, 10.05721887, 3.15086826, + -9.94029022, -2.97825453, 0.96992777, -3.72493869, 0.95467304, -4.50238709], + [0., 0.0000277, 85.40612729, 0., 0., 0., -0.00001832, 0., 0., 0.95459186, -4.56234781, + 0.95460121, -4.56270483]]) non_degree = [i for i, c in enumerate(net.res_line_sc.columns) if not "degree" in c] degree = [i for i, c in enumerate(net.res_line_sc.columns) if "degree" in c] assert np.allclose(net.res_line_sc.values[:, non_degree], res_line_sc[:, non_degree], rtol=0, atol=6e-5) assert np.allclose(net.res_line_sc.values[:, degree], res_line_sc[:, degree], rtol=0, atol=0.05) - res_trafo_sc = np.array([[0.20929507, -21.10342929, 0.62734921, 158.87959058, - 10.1259613, 3.85742992, -10.05721888, -3.15086826, - 0.99637, -0.24936231, 0.96992777, -3.72493869], - [0.37233817, -171.5927079, 1.15480275, 8.40493491, - -19.09876937, 2.83670764, 19.30799817, -0.44577867, - 0.99798561, -0.04098874, 0.9655717, 7.08233793], - [0.04744828, -53.17854903, 1.12071698, 126.05822829, - 0.39297335, 0.68797096, -0.37304126, -0.58781451, - 0.96406436, 7.08617078, 0.89663052, 3.65803177], - [0.00077159, -4.48005446, 0.0000277, -94.62521878, - 0.01275854, -0.00000497, 0., 0.00001832, + res_trafo_sc = np.array([[0.20929507, -21.10342929, 0.62734921, 158.87959058, 10.1259613, 3.85742992, -10.05721888, + -3.15086826, 0.99637, -0.24936231, 0.96992777, -3.72493869], + [0.37233817, -171.5927079, 1.15480275, 8.40493491, -19.09876937, 2.83670764, 19.30799817, + -0.44577867, 0.99798561, -0.04098874, 0.9655717, 7.08233793], + [0.04744828, -53.17854903, 1.12071698, 126.05822829, 0.39297335, 0.68797096, -0.37304126, + -0.58781451, 0.96406436, 7.08617078, 0.89663052, 3.65803177], + [0.00077159, -4.48005446, 0.0000277, -94.62521878, 0.01275854, -0.00000497, 0., 0.00001832, 0.95467304, -4.50238709, 0.95459186, -4.56234781]]) non_degree = [i for i, c in enumerate(net.res_trafo_sc.columns) if "degree" not in c] degree = [i for i, c in enumerate(net.res_trafo_sc.columns) if "degree" in c] @@ -544,43 +520,43 @@ def test_type_c_trafo_simple_other_voltage4_sgen(inverse_y): @pytest.mark.parametrize("inverse_y", (True, False), ids=("Inverse Y", "LU factorization")) def test_type_c_sgen_trafo4(inverse_y): - net = pp.create_empty_network(sn_mva=100) - pp.create_buses(net, 2, 110) - pp.create_ext_grid(net, 0, s_sc_max_mva=100, s_sc_min_mva=80, rx_max=0.4, rx_min=0.4) - pp.create_line_from_parameters(net, 0, 1, 20, 0.0949, 0.38, 9.2, 0.74) - pp.create_sgen(net, 1, 30, 0, 50, k=1, kappa=1) - pp.runpp(net) - sc.calc_sc(net, use_pre_fault_voltage=True, branch_results=True, bus=1, inverse_y=inverse_y) - - assert np.allclose(net.res_bus_sc.values, [0.680859, 129.720994, 3.049814, 152.46668], rtol=0, atol=1e-5) - - res_line_sc = [0.4184267, 0.41833479, -87.77946741, 0.4184267, 92.21738882, 0.99691065, - 3.99091307, 0., 0., 0.05161055, -11.80466263, 0., 0.] + net = create_empty_network(sn_mva=100) + create_buses(net, 2, 110) + create_ext_grid(net, 0, s_sc_max_mva=100, s_sc_min_mva=80, rx_max=0.4, rx_min=0.4) + create_line_from_parameters(net, 0, 1, 20, 0.0949, 0.38, 9.2, 0.74) + create_sgen(net, 1, 30, 0, 50, k=1, kappa=1) + runpp(net) + calc_sc(net, use_pre_fault_voltage=True, branch_results=True, bus=1, inverse_y=inverse_y) + + assert np.allclose(net.res_bus_sc.values, [0.680859, 129.720994, 3.049814, 152.46668], rtol=0, atol=1e-5) + + res_line_sc = [0.4184267, 0.41833479, -87.77946741, 0.4184267, 92.21738882, 0.99691065, 3.99091307, 0., 0., + 0.05161055, -11.80466263, 0., 0.] assert np.allclose(net.res_line_sc.values, res_line_sc, rtol=0, atol=1e-6) net.sgen.at[0, 'kappa'] = 1.2 - sc.calc_sc(net, use_pre_fault_voltage=True, branch_results=True, bus=1, inverse_y=inverse_y) + calc_sc(net, use_pre_fault_voltage=True, branch_results=True, bus=1, inverse_y=inverse_y) assert np.allclose(net.res_bus_sc.values, [0.6821, 129.95747, 3.049814, 152.46668], rtol=0, atol=1e-5) - res_line_sc = [0.4184267, 0.41833479, -87.77946741, 0.4184267, 92.21738882, 0.99691065, - 3.99091307, 0., 0., 0.05161055, -11.80466263, 0., 0.] + res_line_sc = [0.4184267, 0.41833479, -87.77946741, 0.4184267, 92.21738882, 0.99691065, 3.99091307, 0., 0., + 0.05161055, -11.80466263, 0., 0.] assert np.allclose(net.res_line_sc.values, res_line_sc, rtol=0, atol=1e-6) @pytest.mark.parametrize("inverse_y", (True, False), ids=("Inverse Y", "LU factorization")) def test_load_type_c(inverse_y): - net = pp.create_empty_network(sn_mva=100) - pp.create_buses(net, 3, 110) - pp.create_ext_grid(net, 0, s_sc_max_mva=100, rx_max=0.1) - pp.create_line_from_parameters(net, 0, 1, 20, 0.0949, 0.38, 9.2, 0.74) - pp.create_line_from_parameters(net, 1, 2, 20, 0.099, 0.156, 400, 0.74) - pp.create_load(net, 1, 10, 3) + net = create_empty_network(sn_mva=100) + create_buses(net, 3, 110) + create_ext_grid(net, 0, s_sc_max_mva=100, rx_max=0.1) + create_line_from_parameters(net, 0, 1, 20, 0.0949, 0.38, 9.2, 0.74) + create_line_from_parameters(net, 1, 2, 20, 0.099, 0.156, 400, 0.74) + create_load(net, 1, 10, 3) - pp.runpp(net) - sc.calc_sc(net, use_pre_fault_voltage=True, branch_results=True, bus=2, inverse_y=inverse_y) + runpp(net) + calc_sc(net, use_pre_fault_voltage=True, branch_results=True, bus=2, inverse_y=inverse_y) - res_bus_sc = np.array([0.31443438, 59.9077952, 66.64954063, 194.98202182]) + res_bus_sc = np.array([0.31443438, 59.9077952, 66.64954063, 194.98202182]) assert np.allclose(net.res_bus_sc.loc[2].values, res_bus_sc, rtol=0, atol=1e-5) res_line_sc = np.array([[0.31393855, 0.31381306, -71.61339493, 0.31393855, 108.37684429, 1.15160782, 3.16677295, @@ -590,8 +566,8 @@ def test_load_type_c(inverse_y): assert np.allclose(net.res_line_sc.values, res_line_sc, rtol=0, atol=1e-6) # now test for fault at the load bus - sc.calc_sc(net, use_pre_fault_voltage=True, branch_results=True, bus=1, inverse_y=inverse_y) - res_bus_sc = np.array([ 0.32128852, 61.21368488, 63.19657030, 190.67254950]) + calc_sc(net, use_pre_fault_voltage=True, branch_results=True, bus=1, inverse_y=inverse_y) + res_bus_sc = np.array([0.32128852, 61.21368488, 63.19657030, 190.67254950]) assert np.allclose(net.res_bus_sc.loc[1].values, res_bus_sc, rtol=0, atol=1e-5) res_line_sc = np.array([[0.32128852, 0.32121795, -72.27006831, 0.32128852, 107.72678791, 0.58777062, 2.35301071, @@ -601,10 +577,10 @@ def test_load_type_c(inverse_y): # now try with positive p_mw, negative q_mvar net.load.q_mvar = -2 - pp.runpp(net) - sc.calc_sc(net, use_pre_fault_voltage=True, branch_results=True, bus=2, inverse_y=inverse_y) + runpp(net) + calc_sc(net, use_pre_fault_voltage=True, branch_results=True, bus=2, inverse_y=inverse_y) - res_bus_sc = np.array([ 0.29176418, 55.58854147, 77.40936019, 208.87369732]) + res_bus_sc = np.array([0.29176418, 55.58854147, 77.40936019, 208.87369732]) assert np.allclose(net.res_bus_sc.loc[2].values, res_bus_sc, rtol=0, atol=1e-5) res_line_sc = np.array([[0.29093901, 0.29082267, -70.14924675, 0.29093901, 109.84097608, 0.9903086, 2.72035994, @@ -615,10 +591,10 @@ def test_load_type_c(inverse_y): # now try with negative p_mw, negative q_mvar net.load.p_mw = -5 - pp.runpp(net) - sc.calc_sc(net, use_pre_fault_voltage=True, branch_results=True, bus=2, inverse_y=inverse_y) + runpp(net) + calc_sc(net, use_pre_fault_voltage=True, branch_results=True, bus=2, inverse_y=inverse_y) - res_bus_sc = np.array([ 0.27677319, 52.73237570, 22.92942615, 234.25805144]) + res_bus_sc = np.array([0.27677319, 52.73237570, 22.92942615, 234.25805144]) assert np.allclose(net.res_bus_sc.loc[2].values, res_bus_sc, rtol=0, atol=1.1e-5) res_line_sc = np.array([[0.27533477, 0.27522443, -84.57867986, 0.27533477, 95.41156578, 0.88536175, 2.43975772, @@ -631,10 +607,10 @@ def test_load_type_c(inverse_y): net.load.p_mw = 0 net.load.q_mvar = 0 - pp.runpp(net) - sc.calc_sc(net, use_pre_fault_voltage=True, branch_results=True, bus=2, inverse_y=inverse_y) + runpp(net) + calc_sc(net, use_pre_fault_voltage=True, branch_results=True, bus=2, inverse_y=inverse_y) - res_bus_sc = np.array([ 0.28905271 , 55.07193832, 40.36906664, 221.27455269]) + res_bus_sc = np.array([0.28905271, 55.07193832, 40.36906664, 221.27455269]) assert np.allclose(net.res_bus_sc.loc[2].values, res_bus_sc, rtol=0, atol=1e-5) res_line_sc = np.array([[0.28792032, 0.28780504, -79.93483554, 0.28792032, 100.05540903, 0.96823224, 2.66644109, @@ -646,16 +622,16 @@ def test_load_type_c(inverse_y): @pytest.mark.parametrize("inverse_y", (True, False), ids=("Inverse Y", "LU factorization")) def test_sgen_type_c(inverse_y): - net = pp.create_empty_network(sn_mva=100) - pp.create_buses(net, 3, 110) - pp.create_ext_grid(net, 0, s_sc_max_mva=100, rx_max=0.1, s_sc_min_mva=80, rx_min=0.4) - pp.create_line_from_parameters(net, 0, 1, 20, 0.0949, 0.38, 9.2, 0.74) - pp.create_line_from_parameters(net, 1, 2, 20, 0.099, 0.156, 400, 0.74) - pp.create_sgen(net, 1, 10, 3, 20, k=0, kappa=0) + net = create_empty_network(sn_mva=100) + create_buses(net, 3, 110) + create_ext_grid(net, 0, s_sc_max_mva=100, rx_max=0.1, s_sc_min_mva=80, rx_min=0.4) + create_line_from_parameters(net, 0, 1, 20, 0.0949, 0.38, 9.2, 0.74) + create_line_from_parameters(net, 1, 2, 20, 0.099, 0.156, 400, 0.74) + create_sgen(net, 1, 10, 3, 20, k=0, kappa=0) # first we test the contribution of the shunt impedance component only - pp.runpp(net) - sc.calc_sc(net, use_pre_fault_voltage=True, branch_results=True, bus=2, inverse_y=inverse_y) + runpp(net) + calc_sc(net, use_pre_fault_voltage=True, branch_results=True, bus=2, inverse_y=inverse_y) res_bus_sc = np.array([0.27140996, 51.71054206, 1.86837663, 240.35204316]) assert np.allclose(net.res_bus_sc.loc[2].values, res_bus_sc, rtol=0, atol=1.1e-5) @@ -669,8 +645,8 @@ def test_sgen_type_c(inverse_y): net.sgen.k = 1. net.sgen.kappa = 1. - pp.runpp(net) - sc.calc_sc(net, use_pre_fault_voltage=True, branch_results=True, bus=2, inverse_y=inverse_y) + runpp(net) + calc_sc(net, use_pre_fault_voltage=True, branch_results=True, bus=2, inverse_y=inverse_y) res_bus_sc = np.array([0.37460791, 71.37239201, 1.86837663, 240.35204316]) assert np.allclose(net.res_bus_sc.loc[2].values, res_bus_sc, rtol=0, atol=1.1e-5) @@ -684,10 +660,10 @@ def test_sgen_type_c(inverse_y): net.sgen.p_mw = 5 net.sgen.kappa = 1.2 - pp.runpp(net) - sc.calc_sc(net, use_pre_fault_voltage=True, branch_results=True, bus=2, inverse_y=inverse_y) + runpp(net) + calc_sc(net, use_pre_fault_voltage=True, branch_results=True, bus=2, inverse_y=inverse_y) - res_bus_sc = np.array([0.3757975, 71.59903955, 23.71256985, 238.47843258]) + res_bus_sc = np.array([0.3757975, 71.59903955, 23.71256985, 238.47843258]) assert np.allclose(net.res_bus_sc.loc[2].values, res_bus_sc, rtol=0, atol=1.1e-5) res_line_sc = np.array([[0.26809978, 0.26797339, -84.23219467, 0.26809978, 95.75537616, 1.01346202, 2.57650331, @@ -697,10 +673,10 @@ def test_sgen_type_c(inverse_y): assert np.allclose(net.res_line_sc.values, res_line_sc, rtol=0, atol=1.1e-6) - pp.runpp(net) - sc.calc_sc(net, case="min", use_pre_fault_voltage=True, branch_results=True, bus=2, inverse_y=inverse_y) + runpp(net) + calc_sc(net, case="min", use_pre_fault_voltage=True, branch_results=True, bus=2, inverse_y=inverse_y) - res_bus_sc = np.array([0.33334 , 63.509772, 152.076986, 240.321483]) + res_bus_sc = np.array([0.33334, 63.509772, 152.076986, 240.321483]) assert np.allclose(net.res_bus_sc.loc[2].values, res_bus_sc, rtol=0, atol=4e-5) res_line_sc = np.array([[0.22549428, 0.22549428, -57.7247817, 0.2256038, 122.26232395, 0.73906755, 1.86147343, @@ -711,17 +687,18 @@ def test_sgen_type_c(inverse_y): assert np.allclose(net.res_line_sc.values, res_line_sc, rtol=0, atol=4e-6) # test with fault impedance - pp.runpp(net) - sc.calc_sc(net, case="max", use_pre_fault_voltage=True, branch_results=True, bus=2, - inverse_y=inverse_y, r_fault_ohm=10, x_fault_ohm=5) + runpp(net) + calc_sc(net, case="max", use_pre_fault_voltage=True, branch_results=True, bus=2, inverse_y=inverse_y, + r_fault_ohm=10, x_fault_ohm=5) res_bus_sc = np.array([0.36193148, 68.95720876, 33.71256985, 243.47843258]) assert np.allclose(net.res_bus_sc.loc[2].values, res_bus_sc, rtol=0, atol=1.1e-5) - res_line_sc = np.array([[0.25310399, 0.25289333, -79.00626669, 0.25310399, 100.93191475, 3.76673885, 3.49235098, -3.4021955, - -2.03898166, 0.1066072, -36.17097137, 0.08225171, -48.13325967], - [0.36193148, 0.35610158, -80.79001608, 0.36193148, 97.60508469, 4.69831427, 3.01125907, -3.92983193, - -1.96491597, 0.08225171, -48.13325967, 0.06371612, -55.82986413]]) + res_line_sc = np.array([ + [0.25310399, 0.25289333, -79.00626669, 0.25310399, 100.93191475, 3.76673885, 3.49235098, -3.4021955, + -2.03898166, 0.1066072, -36.17097137, 0.08225171, -48.13325967], + [0.36193148, 0.35610158, -80.79001608, 0.36193148, 97.60508469, 4.69831427, 3.01125907, -3.92983193, + -1.96491597, 0.08225171, -48.13325967, 0.06371612, -55.82986413]]) assert np.allclose(net.res_line_sc.values, res_line_sc, rtol=0, atol=1e-6) @@ -731,27 +708,26 @@ def test_trafo_3w(): def test_trafo_impedance(): - net = pp.create_empty_network(sn_mva=0.16) - pp.create_bus(net, 20) - pp.create_buses(net, 2, 0.4) - pp.create_ext_grid(net, 0, s_sc_max_mva=346.4102, rx_max=0.1) + net = create_empty_network(sn_mva=0.16) + create_bus(net, 20) + create_buses(net, 2, 0.4) + create_ext_grid(net, 0, s_sc_max_mva=346.4102, rx_max=0.1) v_lv = 410 - pp.create_transformer_from_parameters(net, 0, 1, 0.4, 20, v_lv / 1e3, 1.15, 4, 0, 0) - pp.create_line_from_parameters(net, 1, 2, 0.004, 0.208, 0.068, 0, 1, parallel=2) - # pp.create_load(net, 2, 0.1) - - pp.runpp(net) + create_transformer_from_parameters(net, 0, 1, 0.4, 20, v_lv / 1e3, 1.15, 4, 0, 0) + create_line_from_parameters(net, 1, 2, 0.004, 0.208, 0.068, 0, 1, parallel=2) + # create_load(net, 2, 0.1) - sc.calc_sc(net, case='max', lv_tol_percent=6., bus=2, branch_results=True, use_pre_fault_voltage=False) + runpp(net) + calc_sc(net, case='max', lv_tol_percent=6., bus=2, branch_results=True, use_pre_fault_voltage=False) # trafo: z_tlv = 4 / 100 * v_lv ** 2 / (400 * 1e3) r_tlv = 4600 * v_lv ** 2 / ((400 * 1e3) ** 2) - x_tlv = np.sqrt(z_tlv**2 - r_tlv**2) - z_tlv = r_tlv + 1j*x_tlv - x_t = x_tlv * 400*1e3 / (v_lv ** 2) - k_t = 0.95 * 1.05 / (1+0.6 * x_t) + x_tlv = np.sqrt(z_tlv ** 2 - r_tlv ** 2) + z_tlv = r_tlv + 1j * x_tlv + x_t = x_tlv * 400 * 1e3 / (v_lv ** 2) + k_t = 0.95 * 1.05 / (1 + 0.6 * x_t) z_tk = k_t * z_tlv # line: @@ -759,8 +735,8 @@ def test_trafo_impedance(): # assert np.allclose(net.res_bus_sc.rk_ohm * 1e3, 5.18, rtol=0, atol=1e-6) # assert np.allclose(net.res_bus_sc.xk_ohm * 1e3, 16.37, rtol=0, atol=1e-6) - assert np.allclose(net._ppc['branch'][:, BR_R].real, [0.416*1e-3, z_tk.real], rtol=0, atol=1e-6) - assert np.allclose(net._ppc['branch'][:, BR_X].real, [0.136*1e-3, z_tk.imag], rtol=0, atol=1e-6) + assert np.allclose(net._ppc['branch'][:, BR_R].real, [0.416 * 1e-3, z_tk.real], rtol=0, atol=1e-6) + assert np.allclose(net._ppc['branch'][:, BR_X].real, [0.136 * 1e-3, z_tk.imag], rtol=0, atol=1e-6) ppci = net.ppci tap = ppci["branch"][:, TAP].real @@ -770,7 +746,7 @@ def test_trafo_impedance(): np.abs(v_1) np.angle(v_1, deg=True) - v_0 = v_1 + ikss1[2] * z_tk / 0.4 * np.sqrt(3) * 0.4/0.41 + v_0 = v_1 + ikss1[2] * z_tk / 0.4 * np.sqrt(3) * 0.4 / 0.41 np.abs(v_0) np.angle(v_0, deg=True) @@ -790,80 +766,80 @@ def test_trafo_impedance(): @pytest.mark.parametrize("inverse_y", (True, False), ids=("Inverse Y", "LU factorization")) def test_one_line(inverse_y): - net = pp.create_empty_network(sn_mva=1) - b1 = pp.create_bus(net, vn_kv=10.) - b2 = pp.create_bus(net, vn_kv=10.) - pp.create_ext_grid(net, b1, s_sc_max_mva=100., s_sc_min_mva=40., rx_min=0.1, rx_max=0.1) - pp.create_line_from_parameters(net, b1, b2, 1, 0.099, 0.156, 400, 0.457) - pp.create_load(net, b2, 20) - pp.runpp(net) + net = create_empty_network(sn_mva=1) + b1 = create_bus(net, vn_kv=10.) + b2 = create_bus(net, vn_kv=10.) + create_ext_grid(net, b1, s_sc_max_mva=100., s_sc_min_mva=40., rx_min=0.1, rx_max=0.1) + create_line_from_parameters(net, b1, b2, 1, 0.099, 0.156, 400, 0.457) + create_load(net, b2, 20) + runpp(net) bus_idx = 1 - sc.calc_sc(net, case='max', branch_results=True, bus=bus_idx, use_pre_fault_voltage=True, inverse_y=inverse_y) + calc_sc(net, case='max', branch_results=True, bus=bus_idx, use_pre_fault_voltage=True, inverse_y=inverse_y) - assert np.allclose(net.res_bus_sc.loc[1].values, - [4.79606369, 83.07025981, 0.47005260, 1.08109377], rtol=0, atol=1e-5) + assert np.allclose(net.res_bus_sc.loc[1].values, [4.79606369, 83.07025981, 0.47005260, 1.08109377], rtol=0, + atol=1e-5) - res_line_sc = np.array([[4.79606369, 4.79601668, -68.32665507, 4.79606369, 111.67298852, 6.83166135, - 10.76489439, 0., 0., 0.15348228, -10.72685098, 0., 0.]]) + res_line_sc = np.array([[4.79606369, 4.79601668, -68.32665507, 4.79606369, 111.67298852, 6.83166135, 10.76489439, + 0., 0., 0.15348228, -10.72685098, 0., 0.]]) assert np.allclose(net.res_line_sc, res_line_sc, rtol=0, atol=1e-6) @pytest.mark.parametrize("inverse_y", (True, False), ids=("Inverse Y", "LU factorization")) def test_return_all_currents(inverse_y): - net = pp.create_empty_network(sn_mva=1) - b1 = pp.create_bus(net, vn_kv=10.) - b2 = pp.create_bus(net, vn_kv=10.) - pp.create_ext_grid(net, b1, s_sc_max_mva=100., s_sc_min_mva=40., rx_min=0.1, rx_max=0.1) - pp.create_line_from_parameters(net, b1, b2, 1, 0.099, 0.156, 400, 0.457) - pp.create_load(net, b2, 20) - pp.runpp(net) + net = create_empty_network(sn_mva=1) + b1 = create_bus(net, vn_kv=10.) + b2 = create_bus(net, vn_kv=10.) + create_ext_grid(net, b1, s_sc_max_mva=100., s_sc_min_mva=40., rx_min=0.1, rx_max=0.1) + create_line_from_parameters(net, b1, b2, 1, 0.099, 0.156, 400, 0.457) + create_load(net, b2, 20) + runpp(net) bus_idx = [0, 1] # first test Type C: - sc.calc_sc(net, case='max', branch_results=True, bus=bus_idx, return_all_currents=True, use_pre_fault_voltage=True, - inverse_y=inverse_y) + calc_sc(net, case='max', branch_results=True, bus=bus_idx, return_all_currents=True, use_pre_fault_voltage=True, + inverse_y=inverse_y) res_line_sc = np.array([[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], - [4.79606369, 4.79601668, -68.32665507, 4.79606369, 111.67298852, 6.83166135, 10.76489439, - 0, 0, 0.15348228, -10.72685098, 0., 0.]]) + [4.79606369, 4.79601668, -68.32665507, 4.79606369, 111.67298852, 6.83166135, 10.76489439, 0, + 0, 0.15348228, -10.72685098, 0., 0.]]) assert np.allclose(net.res_line_sc, res_line_sc, rtol=0, atol=1e-6) # test Type A: - sc.calc_sc(net, case='max', branch_results=True, return_all_currents=True, bus=bus_idx, use_pre_fault_voltage=False, - inverse_y=inverse_y) + calc_sc(net, case='max', branch_results=True, return_all_currents=True, bus=bus_idx, use_pre_fault_voltage=False, + inverse_y=inverse_y) res_line_sc = np.array([[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], - [5.00936688, 5.00936688, -80.53631328, 5.00936688, 99.46368672, 7.45284566, 11.74387832, - 0, 0, 0.16030835, -22.93615278, 0., 0.]]) + [5.00936688, 5.00936688, -80.53631328, 5.00936688, 99.46368672, 7.45284566, 11.74387832, 0, + 0, 0.16030835, -22.93615278, 0., 0.]]) assert np.allclose(net.res_line_sc, res_line_sc, rtol=0, atol=1.5e-6) # several buses not implemented for Type C - pp.create_sgen(net, 1, 0) + create_sgen(net, 1, 0) with pytest.raises(NotImplementedError): - sc.calc_sc(net, case='max', branch_results=True, bus=bus_idx, use_pre_fault_voltage=True, inverse_y=inverse_y) + calc_sc(net, case='max', branch_results=True, bus=bus_idx, use_pre_fault_voltage=True, inverse_y=inverse_y) def test_branch_all_currents_trafo(): net = net_transformer() - sc.calc_sc(net, case='max', ip=True, ith=True, lv_tol_percent=10., branch_results=True, return_all_currents=True) + calc_sc(net, case='max', ip=True, ith=True, lv_tol_percent=10., branch_results=True, return_all_currents=True) - assert (abs(net.res_trafo_sc.ikss_lv_ka.loc[(0,0)] - 0.) <1e-5) - assert (abs(net.res_trafo_sc.ikss_lv_ka.loc[(0,1)] - 0.) <1e-5) - assert (abs(net.res_trafo_sc.ikss_lv_ka.loc[(0,2)] - 16.992258758) <1e-5) + assert (abs(net.res_trafo_sc.ikss_lv_ka.loc[(0, 0)] - 0.) < 1e-5) + assert (abs(net.res_trafo_sc.ikss_lv_ka.loc[(0, 1)] - 0.) < 1e-5) + assert (abs(net.res_trafo_sc.ikss_lv_ka.loc[(0, 2)] - 16.992258758) < 1e-5) - assert (abs(net.res_trafo_sc.ikss_hv_ka.loc[(0,0)] - 0.) <1e-5) - assert (abs(net.res_trafo_sc.ikss_hv_ka.loc[(0,1)] - 0.) <1e-5) - assert (abs(net.res_trafo_sc.ikss_hv_ka.loc[(0,2)] - 0.648795) <1e-5) + assert (abs(net.res_trafo_sc.ikss_hv_ka.loc[(0, 0)] - 0.) < 1e-5) + assert (abs(net.res_trafo_sc.ikss_hv_ka.loc[(0, 1)] - 0.) < 1e-5) + assert (abs(net.res_trafo_sc.ikss_hv_ka.loc[(0, 2)] - 0.648795) < 1e-5) def test_against_single_sc_results_line(): net = three_bus_permuted_index() - sc.calc_sc(net, case="max", branch_results=True, return_all_currents=True) + calc_sc(net, case="max", branch_results=True, return_all_currents=True) multi_results = net.res_line_sc.copy() for bus in net.bus.index: - sc.calc_sc(net, bus=bus, case="max", branch_results=True, return_all_currents=True) + calc_sc(net, bus=bus, case="max", branch_results=True, return_all_currents=True) line_bus_indices = [(line, bus) for line in net.line.index] single_result = net.res_line_sc.ikss_ka.values multi_result = multi_results.ikss_ka.loc[line_bus_indices].values @@ -872,11 +848,11 @@ def test_against_single_sc_results_line(): def test_against_single_sc_results_trafo(): net = net_transformer() - sc.calc_sc(net, case="max", branch_results=True, return_all_currents=True, inverse_y=False) + calc_sc(net, case="max", branch_results=True, return_all_currents=True, inverse_y=False) multi_results = net.res_trafo_sc.copy() for bus in net.bus.index[net.bus.in_service]: - sc.calc_sc(net, bus=bus, case="max", branch_results=True, return_all_currents=True, inverse_y=False) + calc_sc(net, bus=bus, case="max", branch_results=True, return_all_currents=True, inverse_y=False) trafo_bus_indices = [(trafo, bus) for trafo in net.trafo.index] single_result_lv = net.res_trafo_sc.ikss_lv_ka.values multi_result_lv = multi_results.ikss_lv_ka.loc[trafo_bus_indices].values @@ -888,12 +864,12 @@ def test_against_single_sc_results_trafo(): def test_ward(): - net = pp.create_empty_network(sn_mva=9) - pp.create_buses(net, 2, 110) - pp.create_ext_grid(net, 0, s_sc_max_mva=100, rx_max=0.1) - pp.create_line_from_parameters(net, 0, 1, 1, 0.5, 0.5, 0, 1000) - pp.create_ward(net, 1, 10, 5, 200, 100) - sc.calc_sc(net) + net = create_empty_network(sn_mva=9) + create_buses(net, 2, 110) + create_ext_grid(net, 0, s_sc_max_mva=100, rx_max=0.1) + create_line_from_parameters(net, 0, 1, 1, 0.5, 0.5, 0, 1000) + create_ward(net, 1, 10, 5, 200, 100) + calc_sc(net) ikss_ka = [1.209707, 1.209818] rk_ohm = [57.719840, 57.678686] xk_ohm = [-1.834709, -2.740132] @@ -903,12 +879,12 @@ def test_ward(): def test_xward(): - net = pp.create_empty_network(sn_mva=4) - pp.create_buses(net, 2, 110) - pp.create_ext_grid(net, 0, s_sc_max_mva=100, rx_max=0.1) - pp.create_line_from_parameters(net, 0, 1, 1, 0.5, 0.5, 0, 1000) - pp.create_xward(net, 1, 10, 5, 200, 100, 3, 1, vm_pu=1.02) - sc.calc_sc(net) + net = create_empty_network(sn_mva=4) + create_buses(net, 2, 110) + create_ext_grid(net, 0, s_sc_max_mva=100, rx_max=0.1) + create_line_from_parameters(net, 0, 1, 1, 0.5, 0.5, 0, 1000) + create_xward(net, 1, 10, 5, 200, 100, 3, 1, vm_pu=1.02) + calc_sc(net) ikss_ka = [1.209707, 1.209818] rk_ohm = [57.719840, 57.678686] xk_ohm = [-1.834709, -2.740132] diff --git a/pandapower/test/shortcircuit/test_gen.py b/pandapower/test/shortcircuit/test_gen.py index 01dae4855..662277007 100644 --- a/pandapower/test/shortcircuit/test_gen.py +++ b/pandapower/test/shortcircuit/test_gen.py @@ -4,76 +4,85 @@ # and Energy System Technology (IEE), Kassel. All rights reserved. import copy + +import numpy as np import pandas as pd import pytest -import pandapower as pp -import pandapower.shortcircuit as sc -import numpy as np +from pandapower.create import create_empty_network, create_bus, create_gen, create_line_from_parameters, create_switch, \ + create_ext_grid +from pandapower.shortcircuit.calc_sc import calc_sc + @pytest.fixture def one_line_one_generator(): - net = pp.create_empty_network(sn_mva=23) - b1 = pp.create_bus(net, vn_kv=10.) - b2 = pp.create_bus(net, vn_kv=10.) - b3 = pp.create_bus(net, vn_kv=10.) - pp.create_bus(net, vn_kv=0.4, in_service=False) - pp.create_gen(net, b1, vn_kv=10.5, xdss_pu=0.2, rdss_ohm=0.001, cos_phi=0.8, p_mw=0.1, sn_mva=2.5) - pp.create_gen(net, b1, vn_kv=10.5, xdss_pu=0.2, rdss_ohm=0.001, cos_phi=0.8, p_mw=0.1, sn_mva=2.5) - l = pp.create_line_from_parameters(net, b2, b1, length_km=1.0, max_i_ka=0.29, - r_ohm_per_km=0.1548, x_ohm_per_km=0.0816814, c_nf_per_km=165) - net.line.loc[l, "endtemp_degree"] = 165 - pp.create_switch(net, b3, b1, et="b") + net = create_empty_network(sn_mva=23) + b1 = create_bus(net, vn_kv=10.) + b2 = create_bus(net, vn_kv=10.) + b3 = create_bus(net, vn_kv=10.) + create_bus(net, vn_kv=0.4, in_service=False) + create_gen(net, b1, vn_kv=10.5, xdss_pu=0.2, rdss_ohm=0.001, cos_phi=0.8, p_mw=0.1, sn_mva=2.5) + create_gen(net, b1, vn_kv=10.5, xdss_pu=0.2, rdss_ohm=0.001, cos_phi=0.8, p_mw=0.1, sn_mva=2.5) + line = create_line_from_parameters(net, b2, b1, length_km=1.0, max_i_ka=0.29, r_ohm_per_km=0.1548, + x_ohm_per_km=0.0816814, c_nf_per_km=165) + net.line.loc[line, "endtemp_degree"] = 165 + create_switch(net, b3, b1, et="b") return net + @pytest.fixture def gen_three_bus_example(): - net = pp.create_empty_network(sn_mva=12) - b1 = pp.create_bus(net, vn_kv=10.) - b2 = pp.create_bus(net, vn_kv=10.) - b3 = pp.create_bus(net, vn_kv=10.) - #pp.create_bus(net, vn_kv=0.4, in_service=False) - pp.create_gen(net, b2, vn_kv=10.5, xdss_pu=0.2, rdss_ohm=0.001, cos_phi=0.8, p_mw=0.1, sn_mva=2.5) - pp.create_line_from_parameters(net, b1, b2, length_km=1.0, max_i_ka=0.29, - r_ohm_per_km=0.1548, x_ohm_per_km=0.0816814, c_nf_per_km=165) - pp.create_line_from_parameters(net, b2, b3, length_km=1.0, max_i_ka=0.29, - r_ohm_per_km=0.1548, x_ohm_per_km=0.0816814, c_nf_per_km=165) + net = create_empty_network(sn_mva=12) + b1 = create_bus(net, vn_kv=10.) + b2 = create_bus(net, vn_kv=10.) + b3 = create_bus(net, vn_kv=10.) + # create_bus(net, vn_kv=0.4, in_service=False) + create_gen(net, b2, vn_kv=10.5, xdss_pu=0.2, rdss_ohm=0.001, cos_phi=0.8, p_mw=0.1, sn_mva=2.5) + create_line_from_parameters(net, b1, b2, length_km=1.0, max_i_ka=0.29, r_ohm_per_km=0.1548, x_ohm_per_km=0.0816814, + c_nf_per_km=165) + create_line_from_parameters(net, b2, b3, length_km=1.0, max_i_ka=0.29, r_ohm_per_km=0.1548, x_ohm_per_km=0.0816814, + c_nf_per_km=165) net.line["endtemp_degree"] = 165 - pp.create_ext_grid(net, b1, s_sc_max_mva=10., s_sc_min_mva=8., rx_min=0.4, rx_max=0.4) - #pp.create_switch(net, b3, b1, et="b") + create_ext_grid(net, b1, s_sc_max_mva=10., s_sc_min_mva=8., rx_min=0.4, rx_max=0.4) + # create_switch(net, b3, b1, et="b") return net + def test_max_gen(one_line_one_generator): net = one_line_one_generator - sc.calc_sc(net, case="max", inverse_y=False) + calc_sc(net, case="max", inverse_y=False) assert np.allclose(net.res_bus_sc.ikss_ka.values[:3], [1.5395815, 1.5083952, 1.5395815], atol=1e-3) -# assert abs(net.res_bus_sc.ikss_ka.at[0] - 1.5395815) < 1e-7 -# assert abs(net.res_bus_sc.ikss_ka.at[2] - 1.5395815) < 1e-7 -# assert abs(net.res_bus_sc.ikss_ka.at[1] - 1.5083952) < 1e-7 + # assert abs(net.res_bus_sc.ikss_ka.at[0] - 1.5395815) < 1e-7 + # assert abs(net.res_bus_sc.ikss_ka.at[2] - 1.5395815) < 1e-7 + # assert abs(net.res_bus_sc.ikss_ka.at[1] - 1.5083952) < 1e-7 assert pd.isnull(net.res_bus_sc.ikss_ka.at[3]) + def test_branch_max_gen(gen_three_bus_example): net = gen_three_bus_example - sc.calc_sc(net, case="max", branch_results=True) + calc_sc(net, case="max", branch_results=True) assert np.allclose(net.res_line_sc.ikss_ka.values, np.array([0.76204252, 1.28698045]), atol=1e-3) + def test_min_gen(one_line_one_generator): net = one_line_one_generator - sc.calc_sc(net, case="min") + calc_sc(net, case="min") assert np.allclose(net.res_bus_sc.ikss_ka.values[:3], [1.3996195, 1.3697407, 1.3996195], atol=1e-3) # assert abs(net.res_bus_sc.ikss_ka.at[0] - 1.3996195) < 1e-7 # assert abs(net.res_bus_sc.ikss_ka.at[2] - 1.3996195) < 1e-7 # assert abs(net.res_bus_sc.ikss_ka.at[1] - 1.3697407) < 1e-7 assert pd.isnull(net.res_bus_sc.ikss_ka.at[3]) + def test_branch_min_gen(gen_three_bus_example): net = gen_three_bus_example - sc.calc_sc(net, case="min", branch_results=True) + calc_sc(net, case="min", branch_results=True) assert np.allclose(net.res_line_sc.ikss_ka.values, np.array([0.44487882, 1.10747517]), atol=1e-3) + def test_max_gen_fault_impedance(one_line_one_generator): net = one_line_one_generator - sc.calc_sc(net, case="max", r_fault_ohm=2, x_fault_ohm=10) + calc_sc(net, case="max", r_fault_ohm=2, x_fault_ohm=10) assert np.allclose(net.res_bus_sc.ikss_ka.values[:3], [0.4450868, 0.4418823, 0.4450868], atol=1e-3) # assert abs(net.res_bus_sc.ikss_ka.at[0] - 0.4450868) < 1e-7 # assert abs(net.res_bus_sc.ikss_ka.at[1] - 0.4418823) < 1e-7 @@ -82,20 +91,20 @@ def test_max_gen_fault_impedance(one_line_one_generator): def test_gen_ext_grid_same_bus(): - net = pp.create_empty_network() - b = pp.create_bus(net, 110) + net = create_empty_network() + b = create_bus(net, 110) net1 = copy.deepcopy(net) - pp.create_ext_grid(net1, b, s_sc_max_mva=1000, rx_max=0.4) - sc.calc_sc(net1) + create_ext_grid(net1, b, s_sc_max_mva=1000, rx_max=0.4) + calc_sc(net1) net2 = copy.deepcopy(net) - pp.create_gen(net2, b, 0, sn_mva=50, vn_kv=115, xdss_pu=0.2, rdss_ohm=20, cos_phi=0.8, pg_percent=0) - sc.calc_sc(net2) + create_gen(net2, b, 0, sn_mva=50, vn_kv=115, xdss_pu=0.2, rdss_ohm=20, cos_phi=0.8, pg_percent=0) + calc_sc(net2) net3 = copy.deepcopy(net1) - pp.create_gen(net3, b, 0, sn_mva=50, vn_kv=115, xdss_pu=0.2, rdss_ohm=20, cos_phi=0.8, pg_percent=0) - sc.calc_sc(net3) + create_gen(net3, b, 0, sn_mva=50, vn_kv=115, xdss_pu=0.2, rdss_ohm=20, cos_phi=0.8, pg_percent=0) + calc_sc(net3) # no idea why it is not close to 1e-6 assert np.isclose(net3.res_bus_sc.at[0, "ikss_ka"], @@ -103,30 +112,30 @@ def test_gen_ext_grid_same_bus(): # def test_rdss_estimations(): -# net = pp.create_empty_network(sn_mva=1) -# b1 = pp.create_bus(net, vn_kv=0.4) -# g1 = pp.create_gen(net, b1, vn_kv=0.4, xdss_pu=0.1, cos_phi=0.8, p_mw=0.1, sn_mva=0.1) -# b2 = pp.create_bus(net, vn_kv=20.) -# g2 = pp.create_gen(net, b2, vn_kv=21., xdss_pu=0.2, cos_phi=0.85, p_mw=0.1, sn_mva=2.5) -# b3 = pp.create_bus(net, vn_kv=20.) -# g3 = pp.create_gen(net, b3, vn_kv=30., xdss_pu=0.25, cos_phi=0.9, p_mw=0.1, sn_mva=150) - -# sc.calc_sc(net, case="max") +# net = create_empty_network(sn_mva=1) +# b1 = create_bus(net, vn_kv=0.4) +# g1 = create_gen(net, b1, vn_kv=0.4, xdss_pu=0.1, cos_phi=0.8, p_mw=0.1, sn_mva=0.1) +# b2 = create_bus(net, vn_kv=20.) +# g2 = create_gen(net, b2, vn_kv=21., xdss_pu=0.2, cos_phi=0.85, p_mw=0.1, sn_mva=2.5) +# b3 = create_bus(net, vn_kv=20.) +# g3 = create_gen(net, b3, vn_kv=30., xdss_pu=0.25, cos_phi=0.9, p_mw=0.1, sn_mva=150) + +# calc_sc(net, case="max") # assert np.isclose(net.res_bus_sc.ikss_ka.at[b1], 1.5130509845) # net.gen.at[g1, "rdss_pu"] = net.gen.xdss_pu.at[g1] * 0.15 -# sc.calc_sc(net, case="max") +# calc_sc(net, case="max") # assert np.isclose(net.res_bus_sc.ikss_ka.at[b1], 1.5130509845) -# sc.calc_sc(net, case="max") +# calc_sc(net, case="max") # assert np.isclose(net.res_bus_sc.ikss_ka.at[b2], 0.37894052506) # net.gen.at[g2, "rdss_pu"] = net.gen.xdss_pu.at[g2] * 0.07 -# sc.calc_sc(net, case="max") +# calc_sc(net, case="max") # assert np.isclose(net.res_bus_sc.ikss_ka.at[b2], 0.37894052506) -# sc.calc_sc(net, case="max") +# calc_sc(net, case="max") # assert np.isclose(net.res_bus_sc.ikss_ka.at[b3], 12.789334853) # net.gen.at[g3, "rdss_pu"] = net.gen.xdss_pu.at[g3] * 0.05 -# sc.calc_sc(net, case="max") +# calc_sc(net, case="max") # assert np.isclose(net.res_bus_sc.ikss_ka.at[b3], 12.789334853) @@ -137,73 +146,73 @@ def test_gen_ext_grid_same_bus(): # # globals().update(vars) # # del vars, calc_sc # # WIP -# net = pp.create_empty_network() -# b1, b2, b3, b4, b5 = pp.create_buses(net, 5, 20) +# net = create_empty_network() +# b1, b2, b3, b4, b5 = create_buses(net, 5, 20) # # skss = np.sqrt(3) * 400 * 40 # we assume 40 kA sc current in the 400-kV EHV grid -# # pp.create_ext_grid(net, b1, s_sc_max_mva=skss, s_sc_min_mva=0.8 * skss, rx_min=0.2, rx_max=0.4) -# pp.create_gen(net, b3, vn_kv=20, xdss_pu=0.2, rdss_pu=0.2*0.07, cos_phi=0.8, p_mw=5, sn_mva=5) -# pp.create_gen(net, b5, vn_kv=20, xdss_pu=0.2, rdss_pu=0.2*0.07, cos_phi=0.8, p_mw=10, sn_mva=10) +# # create_ext_grid(net, b1, s_sc_max_mva=skss, s_sc_min_mva=0.8 * skss, rx_min=0.2, rx_max=0.4) +# create_gen(net, b3, vn_kv=20, xdss_pu=0.2, rdss_pu=0.2*0.07, cos_phi=0.8, p_mw=5, sn_mva=5) +# create_gen(net, b5, vn_kv=20, xdss_pu=0.2, rdss_pu=0.2*0.07, cos_phi=0.8, p_mw=10, sn_mva=10) -# pp.create_line(net, b1, b2, std_type="305-AL1/39-ST1A 110.0", length_km=10) -# pp.create_line(net, b2, b3, std_type="305-AL1/39-ST1A 110.0", length_km=10) -# pp.create_line(net, b3, b4, std_type="305-AL1/39-ST1A 110.0", length_km=50) -# pp.create_line(net, b4, b5, std_type="305-AL1/39-ST1A 110.0", length_km=10) -# # sc.calc_single_sc(net, b5) -# sc.calc_sc(net, tk_s=5e-2) +# create_line(net, b1, b2, std_type="305-AL1/39-ST1A 110.0", length_km=10) +# create_line(net, b2, b3, std_type="305-AL1/39-ST1A 110.0", length_km=10) +# create_line(net, b3, b4, std_type="305-AL1/39-ST1A 110.0", length_km=50) +# create_line(net, b4, b5, std_type="305-AL1/39-ST1A 110.0", length_km=10) +# # calc_single_sc(net, b5) +# calc_sc(net, tk_s=5e-2) # def test_close_to_gen_simple2(): # # WIP -# net = pp.create_empty_network() -# # b1, b2 = pp.create_buses(net, 2, 110) -# b1 = pp.create_bus(net, 70) +# net = create_empty_network() +# # b1, b2 = create_buses(net, 2, 110) +# b1 = create_bus(net, 70) # # skss = np.sqrt(3) * 400 * 40 # we assume 40 kA sc current in the 400-kV EHV grid -# # pp.create_ext_grid(net, b1, s_sc_max_mva=skss, s_sc_min_mva=0.8 * skss, rx_min=0.2, rx_max=0.4) -# pp.create_gen(net, b1, vn_kv=70, xdss_pu=0.2, rdss_pu=0.2*0.07, cos_phi=0.8, p_mw=0, sn_mva=50) -# # pp.create_gen(net, b3, vn_kv=70, xdss_pu=0.2, rdss_pu=0.001, cos_phi=0.8, p_mw=50, sn_mva=60) +# # create_ext_grid(net, b1, s_sc_max_mva=skss, s_sc_min_mva=0.8 * skss, rx_min=0.2, rx_max=0.4) +# create_gen(net, b1, vn_kv=70, xdss_pu=0.2, rdss_pu=0.2*0.07, cos_phi=0.8, p_mw=0, sn_mva=50) +# # create_gen(net, b3, vn_kv=70, xdss_pu=0.2, rdss_pu=0.001, cos_phi=0.8, p_mw=50, sn_mva=60) -# # pp.create_line(net, b1, b2, std_type="305-AL1/39-ST1A 110.0", length_km=10) -# # pp.create_line(net, b2, b3, std_type="305-AL1/39-ST1A 110.0", length_km=10) -# # sc.calc_single_sc(net, b2) -# sc.calc_sc(net, tk_s=5e-2) +# # create_line(net, b1, b2, std_type="305-AL1/39-ST1A 110.0", length_km=10) +# # create_line(net, b2, b3, std_type="305-AL1/39-ST1A 110.0", length_km=10) +# # calc_single_sc(net, b2) +# calc_sc(net, tk_s=5e-2) # def test_generator_book(): -# net=pp.create_empty_network() -# b1= pp.create_bus(net, 110) -# b2= pp.create_bus(net, 6) +# net=create_empty_network() +# b1= create_bus(net, 110) +# b2= create_bus(net, 6) -# pp.create_ext_grid(net, b1, s_sc_max_mva=300, rx_max=0.1, s_sc_min_mva=250, rx_min=0.1) -# pp.create_transformer_from_parameters(net, b1, b2, 25, 110, 6, 0.5, 15, 15,0.1) -# pp.create_shunt(net, b2, 25, 0, 6) -# pp.create_gen(net, b2, 0, 1, sn_mva=25, vn_kv=6.3, xdss_pu=0.11, cos_phi=np.cos(np.arcsin(0.8))) -# sc.calc_sc(net, tk_s=2.5e-2) +# create_ext_grid(net, b1, s_sc_max_mva=300, rx_max=0.1, s_sc_min_mva=250, rx_min=0.1) +# create_transformer_from_parameters(net, b1, b2, 25, 110, 6, 0.5, 15, 15,0.1) +# create_shunt(net, b2, 25, 0, 6) +# create_gen(net, b2, 0, 1, sn_mva=25, vn_kv=6.3, xdss_pu=0.11, cos_phi=np.cos(np.arcsin(0.8))) +# calc_sc(net, tk_s=2.5e-2) # def test_shunt(): -# net=pp.create_empty_network() -# b1= pp.create_bus(net, 110) -# b2= pp.create_bus(net, 110) +# net=create_empty_network() +# b1= create_bus(net, 110) +# b2= create_bus(net, 110) -# pp.create_ext_grid(net, b1, s_sc_max_mva=300, rx_max=0.1) -# # pp.create_shunt(net, b2, 25, 0, 6) -# pp.create_line(net, b1, b2, std_type="305-AL1/39-ST1A 110.0", length_km=10) +# create_ext_grid(net, b1, s_sc_max_mva=300, rx_max=0.1) +# # create_shunt(net, b2, 25, 0, 6) +# create_line(net, b1, b2, std_type="305-AL1/39-ST1A 110.0", length_km=10) -# sc.calc_sc(net, tk_s=2.5e-2) +# calc_sc(net, tk_s=2.5e-2) # def test_power_station_unit(): -# net = pp.create_empty_network() -# b1, b2, b3, b4 = pp.create_buses(net, 4, 20) -# b5 = pp.create_bus(net, 10) +# net = create_empty_network() +# b1, b2, b3, b4 = create_buses(net, 4, 20) +# b5 = create_bus(net, 10) -# pp.create_ext_grid(net, b1, s_sc_max_mva=250, rx_max=0.1) +# create_ext_grid(net, b1, s_sc_max_mva=250, rx_max=0.1) -# pp.create_line(net, b1, b2, std_type="305-AL1/39-ST1A 110.0", length_km=10) -# pp.create_line(net, b2, b3, std_type="305-AL1/39-ST1A 110.0", length_km=10) -# pp.create_line(net, b3, b4, std_type="305-AL1/39-ST1A 110.0", length_km=50) +# create_line(net, b1, b2, std_type="305-AL1/39-ST1A 110.0", length_km=10) +# create_line(net, b2, b3, std_type="305-AL1/39-ST1A 110.0", length_km=10) +# create_line(net, b3, b4, std_type="305-AL1/39-ST1A 110.0", length_km=50) -# pp.create_transformer_from_parameters(net, b4, b5, 25, 20, 10, 0.41104, 10.3, 0.1, 0.1) -# pp.create_gen(net, b5, vn_kv=10, xdss_pu=0.12, cos_phi=0.8, p_mw=0, sn_mva=10) +# create_transformer_from_parameters(net, b4, b5, 25, 20, 10, 0.41104, 10.3, 0.1, 0.1) +# create_gen(net, b5, vn_kv=10, xdss_pu=0.12, cos_phi=0.8, p_mw=0, sn_mva=10) -# sc.calc_sc(net) +# calc_sc(net) if __name__ == '__main__': pytest.main([__file__, "-xs"]) diff --git a/pandapower/test/shortcircuit/test_iec60909_4.py b/pandapower/test/shortcircuit/test_iec60909_4.py index 2bd7b5a01..1e817c3c5 100644 --- a/pandapower/test/shortcircuit/test_iec60909_4.py +++ b/pandapower/test/shortcircuit/test_iec60909_4.py @@ -1,223 +1,169 @@ # -*- coding: utf-8 -*- -# Copyright (c) 2016-2017 by University of Kassel and Fraunhofer Institute for Wind Energy and -# Energy System Technology (IWES), Kassel. All rights reserved. Use of this source code is governed -# by a BSD-style license that can be found in the LICENSE file. +# Copyright (c) 2016-2024 by University of Kassel and Fraunhofer Institute for Energy Economics +# and Energy System Technology (IEE), Kassel. All rights reserved. import numpy as np import pytest -import pandapower as pp -import pandapower.shortcircuit as sc +from pandapower.create import create_empty_network, create_bus, create_ext_grid, create_transformer_from_parameters, \ + create_gen, create_transformer3w_from_parameters, create_line_from_parameters, create_xward, create_motor +from pandapower.shortcircuit.calc_sc import calc_sc from pandapower.shortcircuit.toolbox import detect_power_station_unit, calc_sc_on_line def iec_60909_4(): - net = pp.create_empty_network(sn_mva=34) - - b1 = pp.create_bus(net, vn_kv=380.) - b2 = pp.create_bus(net, vn_kv=110.) - b3 = pp.create_bus(net, vn_kv=110.) - b4 = pp.create_bus(net, vn_kv=110.) - b5 = pp.create_bus(net, vn_kv=110.) - b6 = pp.create_bus(net, vn_kv=10.) - b7 = pp.create_bus(net, vn_kv=10.) - b8 = pp.create_bus(net, vn_kv=30.) - - HG1 = pp.create_bus(net, vn_kv=20) - HG2 = pp.create_bus(net, vn_kv=10) # 10.5kV? - T_T5 = pp.create_bus(net, vn_kv=10) - T_T6 = pp.create_bus(net, vn_kv=10) - H = pp.create_bus(net, vn_kv=30.) - - pp.create_ext_grid(net, b1, s_sc_max_mva=38 * 380 * np.sqrt(3), rx_max=0.1, x0x_max=3, r0x0_max=0.15) - pp.create_ext_grid(net, b5, s_sc_max_mva=16 * 110 * np.sqrt(3), rx_max=0.1, x0x_max=3.3, r0x0_max=0.2) - - # t1 = pp.create_transformer_from_parameters(net, b4, HG1, sn_mva=150, + net = create_empty_network(sn_mva=34) + + b1 = create_bus(net, vn_kv=380.) + b2 = create_bus(net, vn_kv=110.) + b3 = create_bus(net, vn_kv=110.) + b4 = create_bus(net, vn_kv=110.) + b5 = create_bus(net, vn_kv=110.) + b6 = create_bus(net, vn_kv=10.) + b7 = create_bus(net, vn_kv=10.) + b8 = create_bus(net, vn_kv=30.) + + HG1 = create_bus(net, vn_kv=20) + HG2 = create_bus(net, vn_kv=10) # 10.5kV? + T_T5 = create_bus(net, vn_kv=10) + T_T6 = create_bus(net, vn_kv=10) + H = create_bus(net, vn_kv=30.) + + create_ext_grid(net, b1, s_sc_max_mva=38 * 380 * np.sqrt(3), rx_max=0.1, x0x_max=3, r0x0_max=0.15) + create_ext_grid(net, b5, s_sc_max_mva=16 * 110 * np.sqrt(3), rx_max=0.1, x0x_max=3.3, r0x0_max=0.2) + + # t1 = create_transformer_from_parameters(net, b4, HG1, sn_mva=150, # pfe_kw=0, i0_percent=0, # vn_hv_kv=115., vn_lv_kv=21, vk_percent=16, vkr_percent=0.5, # pt_percent=12, oltc=True) - t1 = pp.create_transformer_from_parameters(net, b4, HG1, sn_mva=150, - pfe_kw=0, i0_percent=0, - vn_hv_kv=115., vn_lv_kv=21, vk_percent=16, vkr_percent=0.5, - pt_percent=12, oltc=True, vk0_percent=15.2, - vkr0_percent=0.5, xn_ohm=22, vector_group="YNd", - mag0_percent=100, mag0_rx=0, si0_hv_partial=0.5, - power_station_unit=True) - pp.create_gen(net, HG1, p_mw=0.85 * 150, vn_kv=21, - xdss_pu=0.14, rdss_ohm=0.002, cos_phi=0.85, sn_mva=150, pg_percent=0, - power_station_trafo=t1) - - t2 = pp.create_transformer_from_parameters(net, b3, HG2, sn_mva=100, - pfe_kw=0, i0_percent=0, vn_hv_kv=120., vn_lv_kv=10.5, vk_percent=12, - vkr_percent=0.5, - oltc=False, vk0_percent=12, vkr0_percent=0.5, vector_group="Yd", - mag0_percent=100, mag0_rx=0, si0_hv_partial=0.5, - power_station_unit=True) - pp.create_gen(net, HG2, p_mw=0.9 * 100, vn_kv=10.5, - xdss_pu=0.16, rdss_ohm=0.005, cos_phi=0.9, sn_mva=100, pg_percent=7.5, - slack=True, power_station_trafo=t2) + t1 = create_transformer_from_parameters(net, b4, HG1, sn_mva=150, pfe_kw=0, i0_percent=0, vn_hv_kv=115., + vn_lv_kv=21, vk_percent=16, vkr_percent=0.5, pt_percent=12, oltc=True, + vk0_percent=15.2, vkr0_percent=0.5, xn_ohm=22, vector_group="YNd", + mag0_percent=100, mag0_rx=0, si0_hv_partial=0.5, power_station_unit=True) + create_gen(net, HG1, p_mw=0.85 * 150, vn_kv=21, xdss_pu=0.14, rdss_ohm=0.002, cos_phi=0.85, sn_mva=150, + pg_percent=0, power_station_trafo=t1) + + t2 = create_transformer_from_parameters(net, b3, HG2, sn_mva=100, pfe_kw=0, i0_percent=0, vn_hv_kv=120., + vn_lv_kv=10.5, vk_percent=12, vkr_percent=0.5, oltc=False, vk0_percent=12, + vkr0_percent=0.5, vector_group="Yd", mag0_percent=100, mag0_rx=0, + si0_hv_partial=0.5, power_station_unit=True) + create_gen(net, HG2, p_mw=0.9 * 100, vn_kv=10.5, xdss_pu=0.16, rdss_ohm=0.005, cos_phi=0.9, sn_mva=100, + pg_percent=7.5, slack=True, power_station_trafo=t2) # # Add gen 3 - # pp.create_gen(net, b6, p_mw=0.9 * 100, vn_kv=10.5, + # create_gen(net, b6, p_mw=0.9 * 100, vn_kv=10.5, # xdss_pu=0.1, rdss_ohm=0.018, cos_phi=0.8, sn_mva=10, pg_percent=5) # Add gen 3 - pp.create_gen(net, b6, p_mw=0, vn_kv=10.5, - xdss_pu=0.1, rdss_ohm=0.018, cos_phi=0.8, sn_mva=10, pg_percent=0) - - pp.create_transformer3w_from_parameters(net, - hv_bus=b1, mv_bus=b2, lv_bus=H, - vn_hv_kv=400, vn_mv_kv=120, vn_lv_kv=30, - sn_hv_mva=350, sn_mv_mva=350, sn_lv_mva=50, - pfe_kw=0, i0_percent=0, - vk_hv_percent=21, vkr_hv_percent=.26, - vk_mv_percent=7, vkr_mv_percent=.16, - vk_lv_percent=10., vkr_lv_percent=.16, - vk0_hv_percent=44.1, vkr0_hv_percent=0.26, - vk0_mv_percent=6.299627, vkr0_mv_percent=0.03714286, - vk0_lv_percent=6.299627, vkr0_lv_percent=0.03714286, - vector_group="YNyd", - tap_max=10, tap_min=-10, tap_pos=0, tap_neutral=0, - tap_side="hv", tap_step_percent=0.1) # vk0 = sqrt(vkr0^2 + vki0^2) = sqrt(vkr^2 + (2.1 * vki)^2) = sqrt(vkr^2 + (2.1)^2 * (vk^2 - vkr^2)) - pp.create_transformer3w_from_parameters(net, - hv_bus=b1, mv_bus=b2, lv_bus=b8, - vn_hv_kv=400, vn_mv_kv=120, vn_lv_kv=30, - sn_hv_mva=350, sn_mv_mva=350, sn_lv_mva=50, - pfe_kw=0, i0_percent=0, - vk_hv_percent=21, vkr_hv_percent=.26, - vk_mv_percent=7, vkr_mv_percent=.16, - vk_lv_percent=10., vkr_lv_percent=.16, - vk0_hv_percent=44.1, vkr0_hv_percent=0.26, - vk0_mv_percent=6.299627, vkr0_mv_percent=0.03714286, - vk0_lv_percent=6.299627, vkr0_lv_percent=0.03714286, - vector_group="Yynd", - tap_max=10, tap_min=-10, tap_pos=0, tap_neutral=0, - tap_side="hv", tap_step_percent=0.1) - - pp.create_transformer3w_from_parameters(net, - hv_bus=b5, mv_bus=b6, lv_bus=T_T5, - vn_hv_kv=115., vn_mv_kv=10.5, vn_lv_kv=10.5, - sn_hv_mva=31.5, sn_mv_mva=31.5, sn_lv_mva=31.5, - pfe_kw=0, i0_percent=0, - vk_hv_percent=12, vkr_hv_percent=.5, - vk_mv_percent=12, vkr_mv_percent=.5, - vk_lv_percent=12, vkr_lv_percent=.5, - vk0_hv_percent=12, vkr0_hv_percent=0.5, - vk0_mv_percent=12, vkr0_mv_percent=0.5, - vk0_lv_percent=12, vkr0_lv_percent=0.5, - vector_group="Yyd", - tap_max=10, tap_min=-10, tap_pos=0, tap_neutral=0, - tap_side="hv", tap_step_percent=0.1) - pp.create_transformer3w_from_parameters(net, - hv_bus=b5, mv_bus=b6, lv_bus=T_T6, - vn_hv_kv=115., vn_mv_kv=10.5, vn_lv_kv=10.5, - sn_hv_mva=31.5, sn_mv_mva=31.5, sn_lv_mva=31.5, - pfe_kw=0, i0_percent=0, - vk_hv_percent=12, vkr_hv_percent=.5, - vk_mv_percent=12, vkr_mv_percent=.5, - vk_lv_percent=12, vkr_lv_percent=.5, - vk0_hv_percent=12, vkr0_hv_percent=0.5, - vk0_mv_percent=12, vkr0_mv_percent=0.5, - vk0_lv_percent=12, vkr0_lv_percent=0.5, - vector_group="Yynd", - tap_max=10, tap_min=-10, tap_pos=0, tap_neutral=0, - tap_side="hv", tap_step_percent=0.1) # reactor is 100 Ohm - - pp.create_motor(net, b7, pn_mech_mw=5.0, cos_phi=0.88, cos_phi_n=0.88, - efficiency_n_percent=97.5, - vn_kv=10, rx=0.1, lrc_pu=5) + create_gen(net, b6, p_mw=0, vn_kv=10.5, xdss_pu=0.1, rdss_ohm=0.018, cos_phi=0.8, sn_mva=10, pg_percent=0) + + create_transformer3w_from_parameters(net, hv_bus=b1, mv_bus=b2, lv_bus=H, vn_hv_kv=400, vn_mv_kv=120, vn_lv_kv=30, + sn_hv_mva=350, sn_mv_mva=350, sn_lv_mva=50, pfe_kw=0, i0_percent=0, + vk_hv_percent=21, vkr_hv_percent=.26, vk_mv_percent=7, vkr_mv_percent=.16, + vk_lv_percent=10., vkr_lv_percent=.16, vk0_hv_percent=44.1, + vkr0_hv_percent=0.26, vk0_mv_percent=6.299627, vkr0_mv_percent=0.03714286, + vk0_lv_percent=6.299627, vkr0_lv_percent=0.03714286, vector_group="YNyd", + tap_max=10, tap_min=-10, tap_pos=0, tap_neutral=0, tap_side="hv", + tap_step_percent=0.1) + # vk0 = sqrt(vkr0^2 + vki0^2) = sqrt(vkr^2 + (2.1 * vki)^2) = sqrt(vkr^2 + (2.1)^2 * (vk^2 - vkr^2)) + create_transformer3w_from_parameters(net, hv_bus=b1, mv_bus=b2, lv_bus=b8, vn_hv_kv=400, vn_mv_kv=120, vn_lv_kv=30, + sn_hv_mva=350, sn_mv_mva=350, sn_lv_mva=50, pfe_kw=0, i0_percent=0, + vk_hv_percent=21, vkr_hv_percent=.26, vk_mv_percent=7, vkr_mv_percent=.16, + vk_lv_percent=10., vkr_lv_percent=.16, vk0_hv_percent=44.1, + vkr0_hv_percent=0.26, vk0_mv_percent=6.299627, vkr0_mv_percent=0.03714286, + vk0_lv_percent=6.299627, vkr0_lv_percent=0.03714286, vector_group="Yynd", + tap_max=10, tap_min=-10, tap_pos=0, tap_neutral=0, tap_side="hv", + tap_step_percent=0.1) + + create_transformer3w_from_parameters(net, hv_bus=b5, mv_bus=b6, lv_bus=T_T5, vn_hv_kv=115., vn_mv_kv=10.5, + vn_lv_kv=10.5, sn_hv_mva=31.5, sn_mv_mva=31.5, sn_lv_mva=31.5, pfe_kw=0, + i0_percent=0, vk_hv_percent=12, vkr_hv_percent=.5, vk_mv_percent=12, + vkr_mv_percent=.5, vk_lv_percent=12, vkr_lv_percent=.5, vk0_hv_percent=12, + vkr0_hv_percent=0.5, vk0_mv_percent=12, vkr0_mv_percent=0.5, vk0_lv_percent=12, + vkr0_lv_percent=0.5, vector_group="Yyd", tap_max=10, tap_min=-10, tap_pos=0, + tap_neutral=0, tap_side="hv", tap_step_percent=0.1) + create_transformer3w_from_parameters(net, hv_bus=b5, mv_bus=b6, lv_bus=T_T6, vn_hv_kv=115., vn_mv_kv=10.5, + vn_lv_kv=10.5, sn_hv_mva=31.5, sn_mv_mva=31.5, sn_lv_mva=31.5, pfe_kw=0, + i0_percent=0, vk_hv_percent=12, vkr_hv_percent=.5, vk_mv_percent=12, + vkr_mv_percent=.5, vk_lv_percent=12, vkr_lv_percent=.5, vk0_hv_percent=12, + vkr0_hv_percent=0.5, vk0_mv_percent=12, vkr0_mv_percent=0.5, vk0_lv_percent=12, + vkr0_lv_percent=0.5, vector_group="Yynd", tap_max=10, tap_min=-10, tap_pos=0, + tap_neutral=0, tap_side="hv", tap_step_percent=0.1) # reactor is 100 Ohm + + create_motor(net, b7, pn_mech_mw=5.0, cos_phi=0.88, cos_phi_n=0.88, efficiency_n_percent=97.5, vn_kv=10, rx=0.1, + lrc_pu=5) for _ in range(2): - pp.create_motor(net, b7, pn_mech_mw=2.0, cos_phi=0.89, cos_phi_n=0.89, - efficiency_n_percent=96.8, - vn_kv=10, rx=0.1, lrc_pu=5.2) - - pp.create_line_from_parameters(net, b2, b3, name="L1", - c_nf_per_km=0, max_i_ka=0, # FIXME: Optional for SC - length_km=20, r_ohm_per_km=0.12, x_ohm_per_km=0.39, - r0_ohm_per_km=0.32, x0_ohm_per_km=1.26, c0_nf_per_km=0, g0_us_per_km=0) - pp.create_line_from_parameters(net, b3, b4, name="L2", - c_nf_per_km=0, max_i_ka=0, - length_km=10, r_ohm_per_km=0.12, x_ohm_per_km=0.39, - r0_ohm_per_km=0.32, x0_ohm_per_km=1.26, c0_nf_per_km=0, g0_us_per_km=0) - pp.create_line_from_parameters(net, b2, b5, name="L3a", - c_nf_per_km=0, max_i_ka=0, - length_km=5, r_ohm_per_km=0.12, x_ohm_per_km=0.39, - r0_ohm_per_km=0.52, x0_ohm_per_km=1.86, c0_nf_per_km=0, g0_us_per_km=0) - pp.create_line_from_parameters(net, b2, b5, name="L3b", - c_nf_per_km=0, max_i_ka=0, - length_km=5, r_ohm_per_km=0.12, x_ohm_per_km=0.39, - r0_ohm_per_km=0.52, x0_ohm_per_km=1.86, c0_nf_per_km=0, g0_us_per_km=0) - pp.create_line_from_parameters(net, b5, b3, name="L4", - c_nf_per_km=0, max_i_ka=0, - length_km=10, r_ohm_per_km=0.096, x_ohm_per_km=0.388, - r0_ohm_per_km=0.22, x0_ohm_per_km=1.1, c0_nf_per_km=0, g0_us_per_km=0) - pp.create_line_from_parameters(net, b5, b4, name="L5", - c_nf_per_km=0, max_i_ka=0, - length_km=15, r_ohm_per_km=0.12, x_ohm_per_km=0.386, - r0_ohm_per_km=0.22, x0_ohm_per_km=1.1, c0_nf_per_km=0, g0_us_per_km=0) - pp.create_line_from_parameters(net, b6, b7, name="L6", - c_nf_per_km=0, max_i_ka=0, - length_km=1, r_ohm_per_km=0.082, x_ohm_per_km=0.086, - r0_ohm_per_km=0.082, x0_ohm_per_km=0.086, c0_nf_per_km=0, g0_us_per_km=0) + create_motor(net, b7, pn_mech_mw=2.0, cos_phi=0.89, cos_phi_n=0.89, efficiency_n_percent=96.8, vn_kv=10, rx=0.1, + lrc_pu=5.2) + + create_line_from_parameters(net, b2, b3, name="L1", c_nf_per_km=0, max_i_ka=0, # FIXME: Optional for SC + length_km=20, r_ohm_per_km=0.12, x_ohm_per_km=0.39, r0_ohm_per_km=0.32, + x0_ohm_per_km=1.26, c0_nf_per_km=0, g0_us_per_km=0) + create_line_from_parameters(net, b3, b4, name="L2", c_nf_per_km=0, max_i_ka=0, length_km=10, r_ohm_per_km=0.12, + x_ohm_per_km=0.39, r0_ohm_per_km=0.32, x0_ohm_per_km=1.26, c0_nf_per_km=0, + g0_us_per_km=0) + create_line_from_parameters(net, b2, b5, name="L3a", c_nf_per_km=0, max_i_ka=0, length_km=5, r_ohm_per_km=0.12, + x_ohm_per_km=0.39, r0_ohm_per_km=0.52, x0_ohm_per_km=1.86, c0_nf_per_km=0, + g0_us_per_km=0) + create_line_from_parameters(net, b2, b5, name="L3b", c_nf_per_km=0, max_i_ka=0, length_km=5, r_ohm_per_km=0.12, + x_ohm_per_km=0.39, r0_ohm_per_km=0.52, x0_ohm_per_km=1.86, c0_nf_per_km=0, + g0_us_per_km=0) + create_line_from_parameters(net, b5, b3, name="L4", c_nf_per_km=0, max_i_ka=0, length_km=10, r_ohm_per_km=0.096, + x_ohm_per_km=0.388, r0_ohm_per_km=0.22, x0_ohm_per_km=1.1, c0_nf_per_km=0, + g0_us_per_km=0) + create_line_from_parameters(net, b5, b4, name="L5", c_nf_per_km=0, max_i_ka=0, length_km=15, r_ohm_per_km=0.12, + x_ohm_per_km=0.386, r0_ohm_per_km=0.22, x0_ohm_per_km=1.1, c0_nf_per_km=0, + g0_us_per_km=0) + create_line_from_parameters(net, b6, b7, name="L6", c_nf_per_km=0, max_i_ka=0, length_km=1, r_ohm_per_km=0.082, + x_ohm_per_km=0.086, r0_ohm_per_km=0.082, x0_ohm_per_km=0.086, c0_nf_per_km=0, + g0_us_per_km=0) # bus F for 1ph fault: 1, 2, 3, 4 return net def iec_60909_4_small(with_xward=False): - net = pp.create_empty_network(sn_mva=6) - - b1 = pp.create_bus(net, vn_kv=380.) - b2 = pp.create_bus(net, vn_kv=110.) - b3 = pp.create_bus(net, vn_kv=110.) - b5 = pp.create_bus(net, vn_kv=110.) - b8 = pp.create_bus(net, vn_kv=30.) - H = pp.create_bus(net, vn_kv=30.) - HG2 = pp.create_bus(net, vn_kv=10) - - pp.create_ext_grid(net, b1, s_sc_max_mva=38 * 380 * np.sqrt(3), rx_max=0.1, x0x_max=3, r0x0_max=0.15) - pp.create_ext_grid(net, b5, s_sc_max_mva=16 * 110 * np.sqrt(3), rx_max=0.1, x0x_max=3.3, r0x0_max=0.2) - - t1 = pp.create_transformer_from_parameters(net, b3, HG2, sn_mva=100, - pfe_kw=0, i0_percent=0, vn_hv_kv=120., vn_lv_kv=10.5, vk_percent=12, vkr_percent=0.5, - vk0_percent=12, vkr0_percent=0.5, mag0_percent=100, mag0_rx=0, si0_hv_partial=0.5, - shift_degree=5, vector_group="Yd", power_station_unit=True) - pp.create_gen(net, HG2, p_mw=0.9 * 100, vn_kv=10.5, - xdss_pu=0.16, rdss_ohm=0.005, cos_phi=0.9, sn_mva=100, pg_percent=7.5, - slack=True, power_station_trafo=t1) - - pp.create_transformer3w_from_parameters(net, - hv_bus=b1, mv_bus=b2, lv_bus=H, - vn_hv_kv=400, vn_mv_kv=120, vn_lv_kv=30, - sn_hv_mva=350, sn_mv_mva=350, sn_lv_mva=50, - pfe_kw=0, i0_percent=0, # FIXME: Optional for SC - vk_hv_percent=21, vkr_hv_percent=.26, - vk_mv_percent=7, vkr_mv_percent=.16, - vk_lv_percent=10., vkr_lv_percent=.16) - pp.create_transformer3w_from_parameters(net, - hv_bus=b1, mv_bus=b2, lv_bus=b8, - vn_hv_kv=400, vn_mv_kv=120, vn_lv_kv=30, - sn_hv_mva=350, sn_mv_mva=350, sn_lv_mva=50, - pfe_kw=0, i0_percent=0, - vk_hv_percent=21, vkr_hv_percent=.26, - vk_mv_percent=7, vkr_mv_percent=.16, - vk_lv_percent=10., vkr_lv_percent=.16) - - pp.create_line_from_parameters(net, b2, b3, name="L1", - c_nf_per_km=0, max_i_ka=0, # FIXME: Optional for SC - length_km=20, r_ohm_per_km=0.12, x_ohm_per_km=0.39, - r0_ohm_per_km=0.32, x0_ohm_per_km=1.26, c0_nf_per_km=0, g0_us_per_km=0) - pp.create_line_from_parameters(net, b2, b5, name="L3a", - c_nf_per_km=0, max_i_ka=0, - length_km=5, r_ohm_per_km=0.12, x_ohm_per_km=0.39, - r0_ohm_per_km=0.52, x0_ohm_per_km=1.86, c0_nf_per_km=0, g0_us_per_km=0) - pp.create_line_from_parameters(net, b2, b5, name="L3b", - c_nf_per_km=0, max_i_ka=0, - length_km=5, r_ohm_per_km=0.12, x_ohm_per_km=0.39, - r0_ohm_per_km=0.52, x0_ohm_per_km=1.86, c0_nf_per_km=0, g0_us_per_km=0) - pp.create_line_from_parameters(net, b5, b3, name="L4", - c_nf_per_km=0, max_i_ka=0, - length_km=10, r_ohm_per_km=0.096, x_ohm_per_km=0.388, - r0_ohm_per_km=0.22, x0_ohm_per_km=1.1, c0_nf_per_km=0, g0_us_per_km=0) + net = create_empty_network(sn_mva=6) + + b1 = create_bus(net, vn_kv=380.) + b2 = create_bus(net, vn_kv=110.) + b3 = create_bus(net, vn_kv=110.) + b5 = create_bus(net, vn_kv=110.) + b8 = create_bus(net, vn_kv=30.) + H = create_bus(net, vn_kv=30.) + HG2 = create_bus(net, vn_kv=10) + + create_ext_grid(net, b1, s_sc_max_mva=38 * 380 * np.sqrt(3), rx_max=0.1, x0x_max=3, r0x0_max=0.15) + create_ext_grid(net, b5, s_sc_max_mva=16 * 110 * np.sqrt(3), rx_max=0.1, x0x_max=3.3, r0x0_max=0.2) + + t1 = create_transformer_from_parameters(net, b3, HG2, sn_mva=100, pfe_kw=0, i0_percent=0, vn_hv_kv=120., + vn_lv_kv=10.5, vk_percent=12, vkr_percent=0.5, vk0_percent=12, + vkr0_percent=0.5, mag0_percent=100, mag0_rx=0, si0_hv_partial=0.5, + shift_degree=5, vector_group="Yd", power_station_unit=True) + create_gen(net, HG2, p_mw=0.9 * 100, vn_kv=10.5, xdss_pu=0.16, rdss_ohm=0.005, cos_phi=0.9, sn_mva=100, + pg_percent=7.5, slack=True, power_station_trafo=t1) + + create_transformer3w_from_parameters(net, hv_bus=b1, mv_bus=b2, lv_bus=H, vn_hv_kv=400, vn_mv_kv=120, vn_lv_kv=30, + sn_hv_mva=350, sn_mv_mva=350, sn_lv_mva=50, pfe_kw=0, i0_percent=0, + # FIXME: Optional for SC + vk_hv_percent=21, vkr_hv_percent=.26, vk_mv_percent=7, vkr_mv_percent=.16, + vk_lv_percent=10., vkr_lv_percent=.16) + create_transformer3w_from_parameters(net, hv_bus=b1, mv_bus=b2, lv_bus=b8, vn_hv_kv=400, vn_mv_kv=120, vn_lv_kv=30, + sn_hv_mva=350, sn_mv_mva=350, sn_lv_mva=50, pfe_kw=0, i0_percent=0, + vk_hv_percent=21, vkr_hv_percent=.26, vk_mv_percent=7, vkr_mv_percent=.16, + vk_lv_percent=10., vkr_lv_percent=.16) + + create_line_from_parameters(net, b2, b3, name="L1", c_nf_per_km=0, max_i_ka=0, # FIXME: Optional for SC + length_km=20, r_ohm_per_km=0.12, x_ohm_per_km=0.39, r0_ohm_per_km=0.32, + x0_ohm_per_km=1.26, c0_nf_per_km=0, g0_us_per_km=0) + create_line_from_parameters(net, b2, b5, name="L3a", c_nf_per_km=0, max_i_ka=0, length_km=5, r_ohm_per_km=0.12, + x_ohm_per_km=0.39, r0_ohm_per_km=0.52, x0_ohm_per_km=1.86, c0_nf_per_km=0, + g0_us_per_km=0) + create_line_from_parameters(net, b2, b5, name="L3b", c_nf_per_km=0, max_i_ka=0, length_km=5, r_ohm_per_km=0.12, + x_ohm_per_km=0.39, r0_ohm_per_km=0.52, x0_ohm_per_km=1.86, c0_nf_per_km=0, + g0_us_per_km=0) + create_line_from_parameters(net, b5, b3, name="L4", c_nf_per_km=0, max_i_ka=0, length_km=10, r_ohm_per_km=0.096, + x_ohm_per_km=0.388, r0_ohm_per_km=0.22, x0_ohm_per_km=1.1, c0_nf_per_km=0, + g0_us_per_km=0) if with_xward: # impedance 10 Ohm and 20 Ohm is different than the 10 Ohm and 20 Ohm @@ -227,76 +173,69 @@ def iec_60909_4_small(with_xward=False): # how to calculate r and x in Ohm: # z_ward_pu = 1/y_ward_pu # vn_net = net.bus.loc[ward_buses, "vn_kv"].values - # z_base_ohm = (vn_net ** 2)# / base_sn_mva) + # z_base_ohm = (vn_net ** 2)# / base_sn_mva # z_ward_ohm = z_ward_pu * z_base_ohm - pp.create_xward(net, b5, 1, 0, 242, -484, 10, 20, 1) + create_xward(net, b5, 1, 0, 242, -484, 10, 20, 1) return net + def iec_60909_4_small_gen_only(): - net = pp.create_empty_network(sn_mva=56) + net = create_empty_network(sn_mva=56) - b3 = pp.create_bus(net, vn_kv=110.) - HG2 = pp.create_bus(net, vn_kv=10) + b3 = create_bus(net, vn_kv=110.) + HG2 = create_bus(net, vn_kv=10) - t1 = pp.create_transformer_from_parameters(net, b3, HG2, sn_mva=100, - pfe_kw=0, i0_percent=0, vn_hv_kv=120., vn_lv_kv=10.5, vk_percent=12, vkr_percent=0.5, - vk0_percent=12, vkr0_percent=0.5, mag0_percent=100, mag0_rx=0, si0_hv_partial=0.5, vector_group="Yd", - power_station_unit=True) - pp.create_gen(net, HG2, p_mw=0.9 * 100, vn_kv=10.5, - xdss_pu=0.16, rdss_ohm=0.005, cos_phi=0.9, sn_mva=100, pg_percent=7.5, - slack=True, power_station_trafo=t1) + t1 = create_transformer_from_parameters(net, b3, HG2, sn_mva=100, pfe_kw=0, i0_percent=0, vn_hv_kv=120., + vn_lv_kv=10.5, vk_percent=12, vkr_percent=0.5, vk0_percent=12, + vkr0_percent=0.5, mag0_percent=100, mag0_rx=0, si0_hv_partial=0.5, + vector_group="Yd", power_station_unit=True) + create_gen(net, HG2, p_mw=0.9 * 100, vn_kv=10.5, xdss_pu=0.16, rdss_ohm=0.005, cos_phi=0.9, sn_mva=100, + pg_percent=7.5, slack=True, power_station_trafo=t1) return net + def iec_60909_4_2gen(): - net = pp.create_empty_network(sn_mva=12) - - b3 = pp.create_bus(net, vn_kv=110.) - b4 = pp.create_bus(net, vn_kv=110.) - HG1 = pp.create_bus(net, vn_kv=20.) - HG2 = pp.create_bus(net, vn_kv=10.) - - t1 = pp.create_transformer_from_parameters(net, b4, HG1, sn_mva=150, - pfe_kw=0, i0_percent=0, - vn_hv_kv=115., vn_lv_kv=21, vk_percent=16, vkr_percent=0.5, - pt_percent=12, oltc=True, power_station_unit=True) - pp.create_gen(net, HG1, p_mw=0.85 * 150, vn_kv=21, - xdss_pu=0.14, rdss_ohm=0.002, cos_phi=0.85, sn_mva=150, pg_percent=0, - power_station_trafo=t1) - - t2 = pp.create_transformer_from_parameters(net, b3, HG2, sn_mva=100, - pfe_kw=0, i0_percent=0, vn_hv_kv=120., vn_lv_kv=10.5, vk_percent=12, vkr_percent=0.5, oltc=False, power_station_unit=True) - pp.create_gen(net, HG2, p_mw=0.9 * 100, vn_kv=10.5, - xdss_pu=0.16, rdss_ohm=0.005, cos_phi=0.9, sn_mva=100, pg_percent=7.5, - slack=True, power_station_trafo=t2) - - pp.create_line_from_parameters(net, b3, b4, name="L2", - c_nf_per_km=0, max_i_ka=0, - length_km=10, r_ohm_per_km=0.12, x_ohm_per_km=0.39) + net = create_empty_network(sn_mva=12) + + b3 = create_bus(net, vn_kv=110.) + b4 = create_bus(net, vn_kv=110.) + HG1 = create_bus(net, vn_kv=20.) + HG2 = create_bus(net, vn_kv=10.) + + t1 = create_transformer_from_parameters(net, b4, HG1, sn_mva=150, pfe_kw=0, i0_percent=0, vn_hv_kv=115., + vn_lv_kv=21, vk_percent=16, vkr_percent=0.5, pt_percent=12, oltc=True, + power_station_unit=True) + create_gen(net, HG1, p_mw=0.85 * 150, vn_kv=21, xdss_pu=0.14, rdss_ohm=0.002, cos_phi=0.85, sn_mva=150, + pg_percent=0, power_station_trafo=t1) + + t2 = create_transformer_from_parameters(net, b3, HG2, sn_mva=100, pfe_kw=0, i0_percent=0, vn_hv_kv=120., + vn_lv_kv=10.5, vk_percent=12, vkr_percent=0.5, oltc=False, + power_station_unit=True) + create_gen(net, HG2, p_mw=0.9 * 100, vn_kv=10.5, xdss_pu=0.16, rdss_ohm=0.005, cos_phi=0.9, sn_mva=100, + pg_percent=7.5, slack=True, power_station_trafo=t2) + + create_line_from_parameters(net, b3, b4, name="L2", c_nf_per_km=0, max_i_ka=0, length_km=10, r_ohm_per_km=0.12, + x_ohm_per_km=0.39) return net def vde_232(): - net = pp.create_empty_network(sn_mva=13) + net = create_empty_network(sn_mva=13) # hv buses - pp.create_bus(net, 110) - pp.create_bus(net, 21) - - pp.create_ext_grid(net, 0, s_sc_max_mva=13.61213 * 110 * np.sqrt(3), rx_max=0.20328, - x0x_max=3.47927, r0x0_max=3.03361) - pp.create_transformer_from_parameters(net, 0, 1, 150, 115, 21, 0.5, 16, - pfe_kw=0, i0_percent=0, tap_step_percent=1, - tap_max=12, tap_min=-12, tap_neutral=0, tap_side='hv', - vector_group="YNd", - vk0_percent=np.sqrt(np.square(0.95*15.99219) + np.square(0.5)), - vkr0_percent=0.5, - mag0_percent=100, mag0_rx=0, - si0_hv_partial=0.9, - pt_percent=12, oltc=True) + create_bus(net, 110) + create_bus(net, 21) + + create_ext_grid(net, 0, s_sc_max_mva=13.61213 * 110 * np.sqrt(3), rx_max=0.20328, x0x_max=3.47927, r0x0_max=3.03361) + create_transformer_from_parameters(net, 0, 1, 150, 115, 21, 0.5, 16, pfe_kw=0, i0_percent=0, tap_step_percent=1, + tap_max=12, tap_min=-12, tap_neutral=0, tap_side='hv', vector_group="YNd", + vk0_percent=np.sqrt(np.square(0.95 * 15.99219) + np.square(0.5)), + vkr0_percent=0.5, mag0_percent=100, mag0_rx=0, si0_hv_partial=0.9, pt_percent=12, + oltc=True) # todo: implement Zn (reactance grounding) -> Z_(0)S = Z_(0)THV*K_S + 3*Z_N - pp.create_gen(net, 1, 150, 1, 150, vn_kv=21, xdss_pu=0.14, rdss_ohm=0.002, cos_phi=0.85, power_station_trafo=0) + create_gen(net, 1, 150, 1, 150, vn_kv=21, xdss_pu=0.14, rdss_ohm=0.002, cos_phi=0.85, power_station_trafo=0) return net @@ -305,28 +244,30 @@ def test_iec_60909_4_3ph_small_without_gen(): # Deactivate all gens net.gen = net.gen.iloc[0:0, :] - sc.calc_sc(net, fault="3ph", case="max", ip=True, tk_s=0.1, kappa_method="C") - ikss_pf = [40.3390, 28.4130, 14.2095, 28.7195, 13.4191] + calc_sc(net, fault="3ph", case="max", ip=True, tk_s=0.1, kappa_method="C") + ikss_pf = [40.3390, 28.4130, 14.2095, 28.7195, 13.4191] ip_pf = [99.7374, 72.6580, 32.1954, 72.1443, 36.5036] assert np.allclose(net.res_bus_sc.ikss_ka.values[:5], np.array(ikss_pf), atol=1e-3) assert np.allclose(net.res_bus_sc.ip_ka.values[:5], np.array(ip_pf), atol=1e-3) + def test_iec_60909_4_3ph_small_with_gen(): net = iec_60909_4_small() - sc.calc_sc(net, fault="3ph", case="max", ip=True, tk_s=0.1, kappa_method="C") + calc_sc(net, fault="3ph", case="max", ip=True, tk_s=0.1, kappa_method="C") ikss_pf = [40.4754, 29.8334, 16.1684, 30.3573] ip_pf = [100.1164, 76.1134, 37.3576, 76.2689] ib_pf = [40.4754, 29.7337, 15.9593, 30.2245] - kappa_pf = [1.7490, 1.8040, 1.6338 , 1.7765] + kappa_pf = [1.7490, 1.8040, 1.6338, 1.7765] assert np.allclose(net.res_bus_sc.ikss_ka.values[:4], np.array(ikss_pf), atol=1e-3) assert np.allclose(net.res_bus_sc.ip_ka.values[:4], np.array(ip_pf), atol=1e-3) + def test_iec_60909_4_3ph_small_with_gen_xward(): net = iec_60909_4_small(with_xward=True) - sc.calc_sc(net, fault="3ph", case="max", ip=True, tk_s=0.1, kappa_method="C") + calc_sc(net, fault="3ph", case="max", ip=True, tk_s=0.1, kappa_method="C") ikss_pf = [40.6422, 31.6394, 16.7409, 33.2808] assert np.allclose(net.res_bus_sc.ikss_ka.values[:4], np.array(ikss_pf), atol=1e-3) @@ -335,7 +276,7 @@ def test_iec_60909_4_3ph_small_with_gen_xward(): def test_iec_60909_4_3ph_small_gen_only(): net = iec_60909_4_small_gen_only() - sc.calc_sc(net, fault="3ph", case="max", ip=True, ith=True, tk_s=0.1, kappa_method="C") + calc_sc(net, fault="3ph", case="max", ip=True, ith=True, tk_s=0.1, kappa_method="C") ikss_pf = [1.9755, 39.5042] ip_pf = [5.2316, 104.1085] ib_pf = [1.6071, 27.3470] @@ -344,10 +285,11 @@ def test_iec_60909_4_3ph_small_gen_only(): assert np.allclose(net.res_bus_sc.ikss_ka[:2].values, np.array(ikss_pf), atol=1e-3) assert np.allclose(net.res_bus_sc.ip_ka[:2].values, np.array(ip_pf), atol=1e-3) + def test_iec_60909_4_3ph_2gen(): net = iec_60909_4_2gen() - sc.calc_sc(net, fault="3ph", case="max", ip=True, tk_s=0.1, kappa_method="C") + calc_sc(net, fault="3ph", case="max", ip=True, tk_s=0.1, kappa_method="C") ikss_pf = [4.2821, 4.4280, 39.1090, 57.8129] ip_pf = [11.1157, 11.6306, 102.7821, 151.5569] ib_pf = [3.6605, 3.7571, 28.3801, 45.3742] @@ -363,7 +305,7 @@ def test_iec_60909_4_3ph_2gen_no_ps_detection(): net.trafo.power_station_unit = False net.gen.at[0, "in_service"] = False net.gen = net.gen.query("in_service") - sc.calc_sc(net, fault="3ph", case="max", ip=True, tk_s=0.1, kappa_method="C") + calc_sc(net, fault="3ph", case="max", ip=True, tk_s=0.1, kappa_method="C") ikss_pf = [1.8460, 1.6715, 6.8953, 39.5042] assert np.allclose(net.res_bus_sc.ikss_ka[:4].values, np.array(ikss_pf), atol=1e-3) @@ -373,7 +315,7 @@ def test_iec_60909_4_3ph_without_motor(): # Generator connected to normal bus does not need voltage correction net = iec_60909_4() net.motor = net.motor.iloc[0:0, :] - sc.calc_sc(net, fault="3ph", case="max", ip=True, tk_s=0.1, kappa_method="C") + calc_sc(net, fault="3ph", case="max", ip=True, tk_s=0.1, kappa_method="C") ikss_pf = [40.6347, 31.6635, 19.6231, 16.1956, 32.9971, 34.3559, 22.2762, 13.5726] ip_pf = [100.5427, 80.3509, 45.7157, 36.7855, 82.9406, 90.6143, 43.3826, 36.9103] @@ -381,35 +323,31 @@ def test_iec_60909_4_3ph_without_motor(): assert np.allclose(net.res_bus_sc.ikss_ka.values[:8], np.array(ikss_pf), atol=1e-3) assert np.allclose(net.res_bus_sc.ip_ka[:8].values, np.array(ip_pf), atol=1e-3) + def test_iec_60909_4_3ph(): net = iec_60909_4() - sc.calc_sc(net, fault="3ph", case="max", ip=True, tk_s=0.1, kappa_method="C") + calc_sc(net, fault="3ph", case="max", ip=True, tk_s=0.1, kappa_method="C") - ikss = [40.6447, 31.7831, 19.6730, 16.2277, 33.1894, - 37.5629, 25.5895, 13.5778, 52.4438, 80.5720] + ikss = [40.6447, 31.7831, 19.6730, 16.2277, 33.1894, 37.5629, 25.5895, 13.5778, 52.4438, 80.5720] # Ip for kappa B - ip_pf = [100.5766, 80.8249, 45.8249, 36.8041, 83.6266, - 99.1910, 51.3864, 36.9201, 136.2801, 210.3159] - ip_standard_kappa_c = [100.5677, 80.6079, 45.8111, 36.8427, - 83.4033, 98.1434, 51.6899, 36.9227] - ib = [40.645, 31.570, 19.388, 16.017, 32.795, 34.028, - 23.212, 13.578, 42.3867, 68.4172] - skss = [26751.51, 6055.49, 3748.20, 3091.78, 6323.43, - 650.61, 443.22, 705.52, 1816.71, 1395.55] + ip_pf = [100.5766, 80.8249, 45.8249, 36.8041, 83.6266, 99.1910, 51.3864, 36.9201, 136.2801, 210.3159] + ip_standard_kappa_c = [100.5677, 80.6079, 45.8111, 36.8427, 83.4033, 98.1434, 51.6899, 36.9227] + ib = [40.645, 31.570, 19.388, 16.017, 32.795, 34.028, 23.212, 13.578, 42.3867, 68.4172] + skss = [26751.51, 6055.49, 3748.20, 3091.78, 6323.43, 650.61, 443.22, 705.52, 1816.71, 1395.55] assert np.allclose(net.res_bus_sc.ikss_ka.values[:10], np.array(ikss), atol=1e-3) - assert np.allclose(net.res_bus_sc.ip_ka.values[:8], np.array(ip_standard_kappa_c ), atol=1e-3) + assert np.allclose(net.res_bus_sc.ip_ka.values[:8], np.array(ip_standard_kappa_c), atol=1e-3) assert np.allclose(net.res_bus_sc.skss_mw.values[:10], np.array(skss), atol=1e-2) + def test_iec_60909_4_3ph_min(): net = iec_60909_4() net.line["endtemp_degree"] = 80.0 - net.ext_grid["s_sc_min_mva"] = net.ext_grid["s_sc_max_mva"]/10 + net.ext_grid["s_sc_min_mva"] = net.ext_grid["s_sc_max_mva"] / 10 net.ext_grid["rx_min"] = net.ext_grid["rx_max"] - sc.calc_sc(net, fault="3ph", case="min", ip=True, tk_s=0.1, kappa_method="C") + calc_sc(net, fault="3ph", case="min", ip=True, tk_s=0.1, kappa_method="C") - ikss_min = [5.0501, 12.2915, 10.3292, 9.4708, 11.8604, - 28.3052, 18.6148, 10.9005, 44.5098, 67.9578] + ikss_min = [5.0501, 12.2915, 10.3292, 9.4708, 11.8604, 28.3052, 18.6148, 10.9005, 44.5098, 67.9578] assert np.allclose(net.res_bus_sc.ikss_ka.values[:10], np.array(ikss_min), atol=1e-3) @@ -423,23 +361,20 @@ def test_iec_60909_4_3ph_ps_trafo_flag(): net.gen.power_station_trafo.values[:] = np.nan detect_power_station_unit(net, mode="trafo") - sc.calc_sc(net, fault="3ph", case="max", ip=True, tk_s=0.1, kappa_method="C") + calc_sc(net, fault="3ph", case="max", ip=True, tk_s=0.1, kappa_method="C") - ikss = [40.6447, 31.7831, 19.6730, 16.2277, 33.1894, - 37.5629, 25.5895, 13.5778, 52.4438, 80.5720] + ikss = [40.6447, 31.7831, 19.6730, 16.2277, 33.1894, 37.5629, 25.5895, 13.5778, 52.4438, 80.5720] assert np.allclose(net.res_bus_sc.ikss_ka.values[:10], np.array(ikss), atol=1e-3) + def test_iec_60909_4_2ph(): net = iec_60909_4() - sc.calc_sc(net, fault="2ph", case="max", ip=True, tk_s=0.1, kappa_method="C") + calc_sc(net, fault="2ph", case="max", ip=True, tk_s=0.1, kappa_method="C") - ikss = [35.1994, 27.5249, 17.0373, 14.0536, 28.7429, - 32.5304, 22.1611, 11.7586, 45.4177, 69.7774] - ip = [87.0941, 69.8085, 39.6736, 31.9067, 72.2294, - 84.9946, 44.7648, 31.9760, 118.0221, 182.1389] + ikss = [35.1994, 27.5249, 17.0373, 14.0536, 28.7429, 32.5304, 22.1611, 11.7586, 45.4177, 69.7774] + ip = [87.0941, 69.8085, 39.6736, 31.9067, 72.2294, 84.9946, 44.7648, 31.9760, 118.0221, 182.1389] # No ib for 2ph sc calculation - skss = [7722.50, 1748.07, 1082.01, 892.52, 1825.42, - 187.81, 127.95, 203.67, 524.44, 402.86] + skss = [7722.50, 1748.07, 1082.01, 892.52, 1825.42, 187.81, 127.95, 203.67, 524.44, 402.86] assert np.allclose(net.res_bus_sc.ikss_ka.values[:10], np.array(ikss), atol=1e-3) assert np.allclose(net.res_bus_sc.ip_ka.values[:10], np.array(ip), atol=1e-3) @@ -449,16 +384,14 @@ def test_iec_60909_4_2ph(): @pytest.mark.skip("1ph gen-close sc calculation still under develop") def test_iec_60909_4_1ph(): net = iec_60909_4() - sc.calc_sc(net, fault="1ph", case="max", ip=True, tk_s=0.1, kappa_method="C") + calc_sc(net, fault="1ph", case="max", ip=True, tk_s=0.1, kappa_method="C") - ikss = [24.6526, 15.9722, 10.4106, 9.0498, 17.0452, - 0.06337, 0.0633, 0, 0.0001, 0.0001] - ip = [60.9982, 40.5086, 24.2424, 20.5464, 42.8337, - 0.1656, 0.1279, 0.0, 0.00025, 0.00033] + ikss = [24.6526, 15.9722, 10.4106, 9.0498, 17.0452, 0.06337, 0.0633, 0, 0.0001, 0.0001] + ip = [60.9982, 40.5086, 24.2424, 20.5464, 42.8337, 0.1656, 0.1279, 0.0, 0.00025, 0.00033] # No ib for 1ph sc calculation - assert np.allclose(net.res_bus_sc.ikss_ka.values[:10], np.array(ikss), atol=1e-4) - # assert np.allclose(net.res_bus_sc.ip.values[:8], np.array(ip), rtol=1e-4) + assert np.allclose(net.res_bus_sc.ikss_ka.values[:10], np.array(ikss), + atol=1e-4) # assert np.allclose(net.res_bus_sc.ip.values[:8], np.array(ip), rtol=1e-4) def test_detect_power_station_units(): @@ -476,14 +409,12 @@ def test_detect_power_station_units(): def test_sc_on_line(): net = iec_60909_4() - calc_sc_on_line(net, 2, 0.3) - # todo: actual test missing here!!! + calc_sc_on_line(net, 2, 0.3) # todo: actual test missing here!!! def test_vde_232(): net = vde_232() - sc.calc_sc(net, fault="3ph", case="max", ip=True, tk_s=0.1, kappa_method="C") - + calc_sc(net, fault="3ph", case="max", ip=True, tk_s=0.1, kappa_method="C") if __name__ == '__main__': diff --git a/pandapower/test/shortcircuit/test_impedance.py b/pandapower/test/shortcircuit/test_impedance.py index ad29a867b..d9d104f27 100644 --- a/pandapower/test/shortcircuit/test_impedance.py +++ b/pandapower/test/shortcircuit/test_impedance.py @@ -3,38 +3,39 @@ # Copyright (c) 2016-2024 by University of Kassel and Fraunhofer Institute for Energy Economics # and Energy System Technology (IEE), Kassel. All rights reserved. - - import numpy as np import pytest -import pandapower as pp -import pandapower.shortcircuit as sc +from pandapower.create import create_empty_network, create_bus, create_ext_grid, create_impedance +from pandapower.shortcircuit.calc_sc import calc_sc @pytest.fixture def impedance_net(): - net = pp.create_empty_network(sn_mva=78) - b1 = pp.create_bus(net, 220) - b2 = pp.create_bus(net, 30) - pp.create_ext_grid(net, b1, s_sc_max_mva=100., s_sc_min_mva=40., rx_min=0.1, rx_max=0.1) - pp.create_ext_grid(net, b2, s_sc_max_mva=100., s_sc_min_mva=40., rx_min=0.1, rx_max=0.1) - pp.create_impedance(net, b1, b2, rft_pu=0.01, xft_pu=0.02, rtf_pu=0.05, xtf_pu=0.01, sn_mva=1) + net = create_empty_network(sn_mva=78) + b1 = create_bus(net, 220) + b2 = create_bus(net, 30) + create_ext_grid(net, b1, s_sc_max_mva=100., s_sc_min_mva=40., rx_min=0.1, rx_max=0.1) + create_ext_grid(net, b2, s_sc_max_mva=100., s_sc_min_mva=40., rx_min=0.1, rx_max=0.1) + create_impedance(net, b1, b2, rft_pu=0.01, xft_pu=0.02, rtf_pu=0.05, xtf_pu=0.01, sn_mva=1) return net + def test_impedance_max(impedance_net): net = impedance_net - sc.calc_sc(net, case="max", ip=True, ith=True, kappa_method="B") + calc_sc(net, case="max", ip=True, ith=True, kappa_method="B") assert np.allclose(net.res_bus_sc.ikss_ka.values, [0.38042409891, 2.0550304761]) assert np.allclose(net.res_bus_sc.ip_ka.values, [0.88029252774, 4.3947194836]) assert np.allclose(net.res_bus_sc.ith_ka.values, [0.38460749284, 2.0703298078]) + def test_impedance_min(impedance_net): net = impedance_net - sc.calc_sc(net, case="min", ip=True, ith=True, kappa_method="B") + calc_sc(net, case="min", ip=True, ith=True, kappa_method="B") assert np.allclose(net.res_bus_sc.ikss_ka.values, [0.19991981619, 0.86978512768]) assert np.allclose(net.res_bus_sc.ip_ka.values, [0.50118698745, 1.755888097]) assert np.allclose(net.res_bus_sc.ith_ka.values, [0.20375890703, 0.87488745362]) + if __name__ == '__main__': pytest.main([__file__, "-xs"]) diff --git a/pandapower/test/shortcircuit/test_meshing_detection.py b/pandapower/test/shortcircuit/test_meshing_detection.py index 1b50cf856..7e2573774 100644 --- a/pandapower/test/shortcircuit/test_meshing_detection.py +++ b/pandapower/test/shortcircuit/test_meshing_detection.py @@ -3,27 +3,30 @@ # Copyright (c) 2016-2024 by University of Kassel and Fraunhofer Institute for Energy Economics # and Energy System Technology (IEE), Kassel. All rights reserved. - import os + import numpy as np import pytest -import pandapower as pp -import pandapower.shortcircuit as sc +from pandapower import pp_dir +from pandapower.create import create_bus, create_switch +from pandapower.file_io import from_json +from pandapower.shortcircuit.calc_sc import calc_sc @pytest.fixture def meshed_grid(): - net = pp.from_json(os.path.join(pp.pp_dir, "test", "shortcircuit", "sc_test_meshed_grid.json")) - bid = pp.create_bus(net, vn_kv=10.) - pp.create_switch(net, net.ext_grid.bus.iloc[0], bid, et="b") + net = from_json(os.path.join(pp_dir, "test", "shortcircuit", "sc_test_meshed_grid.json")) + bid = create_bus(net, vn_kv=10.) + create_switch(net, net.ext_grid.bus.iloc[0], bid, et="b") net.ext_grid.loc[net.ext_grid.index[0], "bus"] = bid - pp.create_bus(net, vn_kv=0.4, in_service=False) + create_bus(net, vn_kv=0.4, in_service=False) return net + def test_max_10_meshed_grid(meshed_grid): net = meshed_grid - sc.calc_sc(net, case='max', ip=True, ith=True, lv_tol_percent= 10., kappa_method="B") + calc_sc(net, case='max', ip=True, ith=True, lv_tol_percent=10., kappa_method="B") assert np.allclose(net.res_bus_sc.ikss_ka.values[:10], [5.773503, 14.82619, 4.606440, 4.068637, 13.61509, 2.812111, 1.212288, 1.525655, 1.781087, 1.568337], atol=1e-5) @@ -39,7 +42,7 @@ def test_max_10_meshed_grid(meshed_grid): def test_max_6_meshed_grid(meshed_grid): net = meshed_grid - sc.calc_sc(net, case='max', ip=True, ith=True, lv_tol_percent = 6., kappa_method="B") + calc_sc(net, case='max', ip=True, ith=True, lv_tol_percent=6., kappa_method="B") assert np.allclose(net.res_bus_sc.ikss_ka.values[:10], [5.773503, 14.75419, 4.437882, 4.068637, 13.53425, 2.701411, 1.159945, 1.460757, 1.705172, 1.501673], atol=1e-5) @@ -55,7 +58,7 @@ def test_max_6_meshed_grid(meshed_grid): def test_min_10_meshed_grid(meshed_grid): net = meshed_grid - sc.calc_sc(net, case='min', ip=True, ith=True, lv_tol_percent= 10., kappa_method="B") + calc_sc(net, case='min', ip=True, ith=True, lv_tol_percent=10., kappa_method="B") assert np.allclose(net.res_bus_sc.ikss_ka.values[:10], [2.309401, 11.3267, 2.879343, 1.884323, 10.40083, 1.693922, 0.7107017, 0.9000445, 1.055881, 0.928488], atol=1e-5) @@ -71,7 +74,7 @@ def test_min_10_meshed_grid(meshed_grid): def test_min_6_meshed_grid(meshed_grid): net = meshed_grid - sc.calc_sc(net, case='min', ip=True, ith=True, lv_tol_percent = 6., kappa_method="B") + calc_sc(net, case='min', ip=True, ith=True, lv_tol_percent=6., kappa_method="B") assert np.allclose(net.res_bus_sc.ikss_ka.values[:10], [2.309401, 11.75072, 2.895465, 1.884323, 10.77961, 1.700202, 0.7116519, 0.9016006, 1.0576, 0.9301236], atol=1e-5) @@ -84,5 +87,6 @@ def test_min_6_meshed_grid(meshed_grid): [2.348476, 11.87518, 2.899291, 1.889675, 10.8322, 1.705064, 0.7136779, 0.9041679, 1.058954, 0.9327717], atol=1e-5) + if __name__ == '__main__': pytest.main([__file__, "-xs"]) diff --git a/pandapower/test/shortcircuit/test_min_branch_results.py b/pandapower/test/shortcircuit/test_min_branch_results.py index 8d4885ecf..a795c03ad 100644 --- a/pandapower/test/shortcircuit/test_min_branch_results.py +++ b/pandapower/test/shortcircuit/test_min_branch_results.py @@ -3,31 +3,28 @@ # Copyright (c) 2016-2024 by University of Kassel and Fraunhofer Institute for Energy Economics # and Energy System Technology (IEE), Kassel. All rights reserved. - - import pytest -import pandapower as pp -import pandapower.shortcircuit as sc +from pandapower.create import create_empty_network, create_bus, create_line, create_ext_grid, create_sgen @pytest.fixture def feeder_network(): - net = pp.create_empty_network(sn_mva=11) - b1 = pp.create_bus(net, 110) - b2 = pp.create_bus(net, 110) - b3 = pp.create_bus(net, 110) - b4 = pp.create_bus(net, 110) - b5 = pp.create_bus(net, 110) - - pp.create_ext_grid(net, b1, s_sc_max_mva=100., s_sc_min_mva=80., rx_min=0.4, rx_max=0.4) - pp.create_line(net, b1, b2, std_type="305-AL1/39-ST1A 110.0" , length_km=20.) - pp.create_line(net, b2, b3, std_type="N2XS(FL)2Y 1x185 RM/35 64/110 kV" , length_km=15.) - pp.create_line(net, b1, b4, std_type="305-AL1/39-ST1A 110.0" , length_km=12.) - pp.create_line(net, b4, b5, std_type="N2XS(FL)2Y 1x185 RM/35 64/110 kV" , length_km=8.) + net = create_empty_network(sn_mva=11) + b1 = create_bus(net, 110) + b2 = create_bus(net, 110) + b3 = create_bus(net, 110) + b4 = create_bus(net, 110) + b5 = create_bus(net, 110) + + create_ext_grid(net, b1, s_sc_max_mva=100., s_sc_min_mva=80., rx_min=0.4, rx_max=0.4) + create_line(net, b1, b2, std_type="305-AL1/39-ST1A 110.0", length_km=20.) + create_line(net, b2, b3, std_type="N2XS(FL)2Y 1x185 RM/35 64/110 kV", length_km=15.) + create_line(net, b1, b4, std_type="305-AL1/39-ST1A 110.0", length_km=12.) + create_line(net, b4, b5, std_type="N2XS(FL)2Y 1x185 RM/35 64/110 kV", length_km=8.) net.line["endtemp_degree"] = 80 for b in [b2, b3, b4, b5]: - pp.create_sgen(net, b, sn_mva=2000, p_mw=0) + create_sgen(net, b, sn_mva=2000, p_mw=0) net.sgen["k"] = 1.2 return net diff --git a/pandapower/test/shortcircuit/test_motor.py b/pandapower/test/shortcircuit/test_motor.py index 28937c710..e44421ac7 100644 --- a/pandapower/test/shortcircuit/test_motor.py +++ b/pandapower/test/shortcircuit/test_motor.py @@ -7,49 +7,54 @@ import numpy as np import pytest -import pandapower as pp -import pandapower.shortcircuit as sc +from pandapower.create import create_empty_network, create_bus, create_ext_grid, create_line_from_parameters, \ + create_motor +from pandapower.shortcircuit.calc_sc import calc_sc + @pytest.fixture def motor_net(): - net = pp.create_empty_network(sn_mva=14) - b1 = pp.create_bus(net, vn_kv=0.4) - b2 = pp.create_bus(net, vn_kv=0.4) - b3 = pp.create_bus(net, vn_kv=0.4) - pp.create_ext_grid(net, b1, s_sc_max_mva=10., rx_max=0.1, s_sc_min_mva=8., - rx_min=0.1) - pp.create_line_from_parameters(net, from_bus=b1, to_bus=b2, length_km=1., - r_ohm_per_km=0.32, c_nf_per_km=0, - x_ohm_per_km=0.07, max_i_ka=1, - endtemp_degree=80) - pp.create_motor(net, b2, pn_mech_mw=0.5, lrc_pu=7., vn_kv=0.45, rx=0.4, - efficiency_n_percent=95, cos_phi_n=0.9, cos_phi=0.9) - pp.create_line_from_parameters(net, from_bus=b2, to_bus=b3, length_km=2., - r_ohm_per_km=0.32, c_nf_per_km=0, - x_ohm_per_km=0.07, max_i_ka=1, - endtemp_degree=80) + net = create_empty_network(sn_mva=14) + b1 = create_bus(net, vn_kv=0.4) + b2 = create_bus(net, vn_kv=0.4) + b3 = create_bus(net, vn_kv=0.4) + create_ext_grid(net, b1, s_sc_max_mva=10., rx_max=0.1, s_sc_min_mva=8., + rx_min=0.1) + create_line_from_parameters(net, from_bus=b1, to_bus=b2, length_km=1., + r_ohm_per_km=0.32, c_nf_per_km=0, + x_ohm_per_km=0.07, max_i_ka=1, + endtemp_degree=80) + create_motor(net, b2, pn_mech_mw=0.5, lrc_pu=7., vn_kv=0.45, rx=0.4, + efficiency_n_percent=95, cos_phi_n=0.9, cos_phi=0.9) + create_line_from_parameters(net, from_bus=b2, to_bus=b3, length_km=2., + r_ohm_per_km=0.32, c_nf_per_km=0, + x_ohm_per_km=0.07, max_i_ka=1, + endtemp_degree=80) return net + def test_motor_min(motor_net): net = motor_net - sc.calc_sc(net, case="min") + calc_sc(net, case="min") assert np.allclose(net.res_bus_sc.ikss_ka.values[:3], [11.547005315, 0.53709235574, 0.18070949061], rtol=1e-4) + def test_motor_max(motor_net): net = motor_net - sc.calc_sc(net, case="max") + calc_sc(net, case="max") assert np.allclose(net.res_bus_sc.ikss_ka.values[:3], [14.743809197, 5.626994278, 0.370730612], rtol=1e-4) + def test_motor_max_branch(motor_net): net = motor_net net.motor.in_service = False - sc.calc_sc(net, case="max") + calc_sc(net, case="max") ikss_without_motor = net.res_bus_sc.ikss_ka.copy() net.motor.in_service = True - sc.calc_sc(net, case="max", branch_results=True) + calc_sc(net, case="max", branch_results=True) assert np.allclose(net.res_bus_sc.ikss_ka.values[:3], [14.743809197, 5.626994278, 0.370730612], rtol=1e-4) # The maximum current through the first branch is the short-circuit current @@ -60,22 +65,25 @@ def test_motor_max_branch(motor_net): # at the third bus assert np.isclose(net.res_line_sc.ikss_ka.at[1], net.res_bus_sc.ikss_ka.at[2]) + def test_motor_min_branch(motor_net): net = motor_net net.motor.in_service = False - sc.calc_sc(net, case="min", branch_results=True) + calc_sc(net, case="min", branch_results=True) ikss_without_motor = net.res_line_sc.ikss_ka.values net.motor.in_service = True - sc.calc_sc(net, case="min", branch_results=True) + calc_sc(net, case="min", branch_results=True) assert np.allclose(ikss_without_motor, net.res_line_sc.ikss_ka.values) + def test_large_motor(motor_net): net = motor_net net.motor.pn_mech_mw = 10 - sc.calc_sc(net, case="max") + calc_sc(net, case="max") assert np.allclose(net.res_bus_sc.ikss_ka.values[:3], [14.695869025, 103.16722971, 0.38693418116], rtol=1e-4) + if __name__ == '__main__': pytest.main([__file__, "-xs"]) diff --git a/pandapower/test/shortcircuit/test_ring.py b/pandapower/test/shortcircuit/test_ring.py index 2544667b5..ab24f29e3 100644 --- a/pandapower/test/shortcircuit/test_ring.py +++ b/pandapower/test/shortcircuit/test_ring.py @@ -3,63 +3,66 @@ # Copyright (c) 2016-2024 by University of Kassel and Fraunhofer Institute for Energy Economics # and Energy System Technology (IEE), Kassel. All rights reserved. - - import numpy as np import pytest -import pandapower as pp -import pandapower.shortcircuit as sc +from pandapower.create import create_empty_network, create_bus, create_line, create_ext_grid, create_transformer, \ + create_switch +from pandapower.shortcircuit.calc_sc import calc_sc def ring_network(): - net = pp.create_empty_network(sn_mva=2.) - b0 = pp.create_bus(net, 220) - b1 = pp.create_bus(net, 110) - b2 = pp.create_bus(net, 110) - b3 = pp.create_bus(net, 110) - pp.create_ext_grid(net, b0, s_sc_max_mva=100., s_sc_min_mva=80., rx_min=0.4, rx_max=0.4) - pp.create_transformer(net, b0, b1, "100 MVA 220/110 kV") - pp.create_line(net, b1, b2, std_type="305-AL1/39-ST1A 110.0" , length_km=20.) - l2 = pp.create_line(net, b2, b3, std_type="N2XS(FL)2Y 1x185 RM/35 64/110 kV" , length_km=15.) - pp.create_line(net, b3, b1, std_type="N2XS(FL)2Y 1x185 RM/35 64/110 kV" , length_km=10.) - pp.create_switch(net, b3, l2, closed=False, et="l") + net = create_empty_network(sn_mva=2.) + b0 = create_bus(net, 220) + b1 = create_bus(net, 110) + b2 = create_bus(net, 110) + b3 = create_bus(net, 110) + create_ext_grid(net, b0, s_sc_max_mva=100., s_sc_min_mva=80., rx_min=0.4, rx_max=0.4) + create_transformer(net, b0, b1, "100 MVA 220/110 kV") + create_line(net, b1, b2, std_type="305-AL1/39-ST1A 110.0", length_km=20.) + l2 = create_line(net, b2, b3, std_type="N2XS(FL)2Y 1x185 RM/35 64/110 kV", length_km=15.) + create_line(net, b3, b1, std_type="N2XS(FL)2Y 1x185 RM/35 64/110 kV", length_km=10.) + create_switch(net, b3, l2, closed=False, et="l") return net def test_branch_results_open_ring(): net = ring_network() - sc.calc_sc(net, branch_results=True, inverse_y=False) + calc_sc(net, branch_results=True, inverse_y=False) assert np.allclose(net.res_trafo_sc.ikss_lv_ka.values, [0.47705988]) assert np.allclose(net.res_line_sc.ikss_ka.values, [0.45294928, 0.0, 0.47125418]) - + + def test_branch_results_open_ring_with_impedance(): net = ring_network() - sc.calc_sc(net, branch_results=True, inverse_y=False) + calc_sc(net, branch_results=True, inverse_y=False) res_line_no_imp = net.res_line_sc.ikss_ka.values.copy() # Make sure that with fault impedance, the total current should be smaller - sc.calc_sc(net, branch_results=True, inverse_y=False, r_fault_ohm=1, x_fault_ohm=5) + calc_sc(net, branch_results=True, inverse_y=False, r_fault_ohm=1, x_fault_ohm=5) non_null_flag = np.abs(res_line_no_imp) > 1e-10 assert np.all(net.res_line_sc.ikss_ka.values[non_null_flag] < res_line_no_imp[non_null_flag]) + def test_branch_results_closed_ring(): net = ring_network() net.switch.closed = True - sc.calc_sc(net, branch_results=True) + calc_sc(net, branch_results=True) assert np.allclose(net.res_trafo_sc.ikss_lv_ka.values, [0.47705988]) assert np.allclose(net.res_line_sc.ikss_ka.values, [0.17559325, 0.29778739, 0.40286545]) + def test_kappa_methods(): net = ring_network() net.switch.closed = True - sc.calc_sc(net, kappa_method="B", ip=True, inverse_y=False) + calc_sc(net, kappa_method="B", ip=True, inverse_y=False) assert np.allclose(net.res_bus_sc.ip_ka.values, [0.48810547956, 0.91192962511, 1.0264898716, 1.0360554521]) - sc.calc_sc(net, kappa_method="C", ip=True, topology="auto") + calc_sc(net, kappa_method="C", ip=True, topology="auto") assert np.allclose(net.res_bus_sc.ip_ka.values, [0.48810547956, 0.91192962511, 0.89331396461, 0.90103415924]) + if __name__ == '__main__': pytest.main([__file__, "-xs"]) diff --git a/pandapower/test/shortcircuit/test_sc_multi_bus.py b/pandapower/test/shortcircuit/test_sc_multi_bus.py index f6e178111..e70e23798 100644 --- a/pandapower/test/shortcircuit/test_sc_multi_bus.py +++ b/pandapower/test/shortcircuit/test_sc_multi_bus.py @@ -1,99 +1,103 @@ - # -*- coding: utf-8 -*- +# -*- coding: utf-8 -*- # Copyright (c) 2016-2020 by University of Kassel and Fraunhofer Institute for Energy Economics # and Energy System Technology (IEE), Kassel. All rights reserved. - -import os - +import numpy as np import pytest -import numpy as np -import pandapower as pp -import pandapower.shortcircuit as sc +from pandapower.create import create_empty_network, create_bus, create_line, create_ext_grid, create_transformer, \ + create_sgen +from pandapower.shortcircuit.calc_sc import calc_sc from pandapower.test.shortcircuit.test_meshing_detection import meshed_grid + @pytest.fixture def radial_grid(): - net = pp.create_empty_network(sn_mva=2.) - b0 = pp.create_bus(net, 220) - b1 = pp.create_bus(net, 110) - b2 = pp.create_bus(net, 110) - b3 = pp.create_bus(net, 110) - pp.create_ext_grid(net, b0, s_sc_max_mva=100., s_sc_min_mva=80., rx_min=0.4, rx_max=0.4) - pp.create_transformer(net, b0, b1, "100 MVA 220/110 kV") - pp.create_line(net, b1, b2, std_type="305-AL1/39-ST1A 110.0" , length_km=20.) - pp.create_line(net, b2, b3, std_type="N2XS(FL)2Y 1x185 RM/35 64/110 kV" , length_km=15.) + net = create_empty_network(sn_mva=2.) + b0 = create_bus(net, 220) + b1 = create_bus(net, 110) + b2 = create_bus(net, 110) + b3 = create_bus(net, 110) + create_ext_grid(net, b0, s_sc_max_mva=100., s_sc_min_mva=80., rx_min=0.4, rx_max=0.4) + create_transformer(net, b0, b1, "100 MVA 220/110 kV") + create_line(net, b1, b2, std_type="305-AL1/39-ST1A 110.0", length_km=20.) + create_line(net, b2, b3, std_type="N2XS(FL)2Y 1x185 RM/35 64/110 kV", length_km=15.) return net + @pytest.fixture def three_bus_big_sgen_example(): - net = pp.create_empty_network(sn_mva=3) - b1 = pp.create_bus(net, 110) - b2 = pp.create_bus(net, 110) - b3 = pp.create_bus(net, 110) + net = create_empty_network(sn_mva=3) + b1 = create_bus(net, 110) + b2 = create_bus(net, 110) + b3 = create_bus(net, 110) - pp.create_ext_grid(net, b1, s_sc_max_mva=100., s_sc_min_mva=80., rx_min=0.4, rx_max=0.4) - pp.create_line(net, b1, b2, std_type="305-AL1/39-ST1A 110.0" , length_km=20.) - pp.create_line(net, b2, b3, std_type="N2XS(FL)2Y 1x185 RM/35 64/110 kV" , length_km=15.) - net.line["endtemp_degree"] = 80 + create_ext_grid(net, b1, s_sc_max_mva=100., s_sc_min_mva=80., rx_min=0.4, rx_max=0.4) + create_line(net, b1, b2, std_type="305-AL1/39-ST1A 110.0", length_km=20.) + create_line(net, b2, b3, std_type="N2XS(FL)2Y 1x185 RM/35 64/110 kV", length_km=15.) + net.line["endtemp_degree"] = 80 + + create_sgen(net, b2, sn_mva=200., p_mw=0, k=1.2) + return net - pp.create_sgen(net, b2, sn_mva=200., p_mw=0, k=1.2) - return net -def test_radial_network(radial_grid): +def test_radial_network(radial_grid): net = radial_grid sc_bus = 3 - sc.calc_sc(net) + calc_sc(net) ik = net.res_bus_sc.ikss_ka.at[sc_bus] - sc.calc_sc(net, bus=sc_bus, inverse_y=False, branch_results=True, return_all_currents=True) + calc_sc(net, bus=sc_bus, inverse_y=False, branch_results=True, return_all_currents=True) assert np.isclose(net.res_bus_sc.ikss_ka.at[sc_bus], ik) assert np.isclose(net.res_line_sc.ikss_ka.loc[(1, sc_bus)], ik) assert np.isclose(net.res_line_sc.ikss_ka.loc[(0, sc_bus)], ik) assert np.isclose(net.res_trafo_sc.ikss_lv_ka.loc[(0, sc_bus)], ik) trafo_ratio = net.trafo.vn_lv_kv.values / net.trafo.vn_hv_kv.values - assert np.isclose(net.res_trafo_sc.ikss_hv_ka.loc[(0, sc_bus)], ik*trafo_ratio) + assert np.isclose(net.res_trafo_sc.ikss_hv_ka.loc[(0, sc_bus)], ik * trafo_ratio) sc_bus = 2 - sc.calc_sc(net) + calc_sc(net) ik = net.res_bus_sc.ikss_ka.at[sc_bus] - sc.calc_sc(net, bus=sc_bus, inverse_y=False, branch_results=True, return_all_currents=True) + calc_sc(net, bus=sc_bus, inverse_y=False, branch_results=True, return_all_currents=True) assert np.isclose(net.res_bus_sc.ikss_ka.at[sc_bus], ik) assert np.isclose(net.res_line_sc.ikss_ka.loc[(1, sc_bus)], 0) assert np.isclose(net.res_line_sc.ikss_ka.loc[(0, sc_bus)], ik) assert np.isclose(net.res_trafo_sc.ikss_lv_ka.loc[(0, sc_bus)], ik) trafo_ratio = net.trafo.vn_lv_kv.values / net.trafo.vn_hv_kv.values - assert np.isclose(net.res_trafo_sc.ikss_hv_ka.loc[(0, sc_bus)], ik*trafo_ratio) + assert np.isclose(net.res_trafo_sc.ikss_hv_ka.loc[(0, sc_bus)], ik * trafo_ratio) + def test_meshed_network(meshed_grid): net = meshed_grid - sc.calc_sc(net) + calc_sc(net) sc_bus = 5 ik = net.res_bus_sc.ikss_ka.at[sc_bus] - - sc.calc_sc(net, bus=sc_bus, inverse_y=False, branch_results=True, return_all_currents=True) + + calc_sc(net, bus=sc_bus, inverse_y=False, branch_results=True, return_all_currents=True) assert np.isclose(net.res_bus_sc.ikss_ka.at[sc_bus], ik) - line_ix = net.line[(net.line.to_bus==sc_bus) | (net.line.from_bus==sc_bus)].index + line_ix = net.line[(net.line.to_bus == sc_bus) | (net.line.from_bus == sc_bus)].index line_flow_into_sc = net.res_line_sc.loc[(line_ix, sc_bus), "ikss_ka"].sum() assert np.isclose(line_flow_into_sc, ik, atol=2e-3) -def test_big_gen_network(three_bus_big_sgen_example): + +def test_big_gen_network(three_bus_big_sgen_example): net = three_bus_big_sgen_example sc_bus = [0, 1, 2] - sc.calc_sc(net, bus=sc_bus, branch_results=True, return_all_currents=True, inverse_y=False) - assert np.isclose(net.res_line_sc.loc[(0, 0),"ikss_ka"], 1.25967331, atol=1e-3) - assert np.isclose(net.res_line_sc.loc[(1, 0),"ikss_ka"], 0., atol=2e-3) - assert np.isclose(net.res_line_sc.loc[(0, 2),"ikss_ka"], 0.46221808, atol=1e-3) - assert np.isclose(net.res_line_sc.loc[(1, 2),"ikss_ka"], 1.72233192, atol=1e-3) + calc_sc(net, bus=sc_bus, branch_results=True, return_all_currents=True, inverse_y=False) + assert np.isclose(net.res_line_sc.loc[(0, 0), "ikss_ka"], 1.25967331, atol=1e-3) + assert np.isclose(net.res_line_sc.loc[(1, 0), "ikss_ka"], 0., atol=2e-3) + assert np.isclose(net.res_line_sc.loc[(0, 2), "ikss_ka"], 0.46221808, atol=1e-3) + assert np.isclose(net.res_line_sc.loc[(1, 2), "ikss_ka"], 1.72233192, atol=1e-3) + -def test_big_gen_network_v2(three_bus_big_sgen_example): +def test_big_gen_network_v2(three_bus_big_sgen_example): net = three_bus_big_sgen_example sc_bus = [0, 2] - sc.calc_sc(net, bus=sc_bus, branch_results=True, return_all_currents=True, inverse_y=False) - assert np.isclose(net.res_line_sc.loc[(0, 0),"ikss_ka"], 1.25967331, atol=1e-3) - assert np.isclose(net.res_line_sc.loc[(1, 0),"ikss_ka"], 0., atol=2e-3) - assert np.isclose(net.res_line_sc.loc[(0, 2),"ikss_ka"], 0.46221808, atol=1e-3) - assert np.isclose(net.res_line_sc.loc[(1, 2),"ikss_ka"], 1.72233192, atol=1e-3) + calc_sc(net, bus=sc_bus, branch_results=True, return_all_currents=True, inverse_y=False) + assert np.isclose(net.res_line_sc.loc[(0, 0), "ikss_ka"], 1.25967331, atol=1e-3) + assert np.isclose(net.res_line_sc.loc[(1, 0), "ikss_ka"], 0., atol=2e-3) + assert np.isclose(net.res_line_sc.loc[(0, 2), "ikss_ka"], 0.46221808, atol=1e-3) + assert np.isclose(net.res_line_sc.loc[(1, 2), "ikss_ka"], 1.72233192, atol=1e-3) if __name__ == '__main__': diff --git a/pandapower/test/shortcircuit/test_sc_single_bus.py b/pandapower/test/shortcircuit/test_sc_single_bus.py index 88f6cf572..023c51985 100644 --- a/pandapower/test/shortcircuit/test_sc_single_bus.py +++ b/pandapower/test/shortcircuit/test_sc_single_bus.py @@ -1,100 +1,100 @@ - # -*- coding: utf-8 -*- +# -*- coding: utf-8 -*- # Copyright (c) 2016-2024 by University of Kassel and Fraunhofer Institute for Energy Economics # and Energy System Technology (IEE), Kassel. All rights reserved. - -import os - +import numpy as np import pytest -import numpy as np -import pandapower as pp -import pandapower.shortcircuit as sc +from pandapower.create import create_empty_network, create_bus, create_ext_grid, create_line, create_transformer, \ + create_sgen +from pandapower.shortcircuit.calc_sc import calc_sc from pandapower.test.shortcircuit.test_meshing_detection import meshed_grid + # @pytest.fixture def radial_grid(): - net = pp.create_empty_network(sn_mva=2.) - b0 = pp.create_bus(net, 220) - b1 = pp.create_bus(net, 110) - b2 = pp.create_bus(net, 110) - b3 = pp.create_bus(net, 110) - pp.create_ext_grid(net, b0, s_sc_max_mva=100., s_sc_min_mva=80., rx_min=0.4, rx_max=0.4) - pp.create_transformer(net, b0, b1, "100 MVA 220/110 kV") - pp.create_line(net, b1, b2, std_type="305-AL1/39-ST1A 110.0" , length_km=20.) - pp.create_line(net, b2, b3, std_type="N2XS(FL)2Y 1x185 RM/35 64/110 kV" , length_km=15.) + net = create_empty_network(sn_mva=2.) + b0 = create_bus(net, 220) + b1 = create_bus(net, 110) + b2 = create_bus(net, 110) + b3 = create_bus(net, 110) + create_ext_grid(net, b0, s_sc_max_mva=100., s_sc_min_mva=80., rx_min=0.4, rx_max=0.4) + create_transformer(net, b0, b1, "100 MVA 220/110 kV") + create_line(net, b1, b2, std_type="305-AL1/39-ST1A 110.0", length_km=20.) + create_line(net, b2, b3, std_type="N2XS(FL)2Y 1x185 RM/35 64/110 kV", length_km=15.) return net + # @pytest.fixture def three_bus_big_sgen_example(): - net = pp.create_empty_network(sn_mva=4) - b1 = pp.create_bus(net, 110) - b2 = pp.create_bus(net, 110) - b3 = pp.create_bus(net, 110) + net = create_empty_network(sn_mva=4) + b1 = create_bus(net, 110) + b2 = create_bus(net, 110) + b3 = create_bus(net, 110) + + create_ext_grid(net, b1, s_sc_max_mva=100., s_sc_min_mva=80., rx_min=0.4, rx_max=0.4) + create_line(net, b1, b2, std_type="305-AL1/39-ST1A 110.0", length_km=20.) + create_line(net, b2, b3, std_type="N2XS(FL)2Y 1x185 RM/35 64/110 kV", length_km=15.) + net.line["endtemp_degree"] = 80 - pp.create_ext_grid(net, b1, s_sc_max_mva=100., s_sc_min_mva=80., rx_min=0.4, rx_max=0.4) - pp.create_line(net, b1, b2, std_type="305-AL1/39-ST1A 110.0" , length_km=20.) - pp.create_line(net, b2, b3, std_type="N2XS(FL)2Y 1x185 RM/35 64/110 kV" , length_km=15.) - net.line["endtemp_degree"] = 80 + create_sgen(net, b2, sn_mva=200., p_mw=0, k=1.2) + return net - pp.create_sgen(net, b2, sn_mva=200., p_mw=0, k=1.2) - return net -def test_radial_network(): +def test_radial_network(): net = radial_grid() sc_bus = 3 - sc.calc_sc(net) + calc_sc(net) ik = net.res_bus_sc.ikss_ka.at[sc_bus] - sc.calc_sc(net, bus=sc_bus, branch_results=True) + calc_sc(net, bus=sc_bus, branch_results=True) assert np.isclose(net.res_line_sc.ikss_ka.at[1], ik) assert np.isclose(net.res_line_sc.ikss_ka.at[0], ik) assert np.isclose(net.res_trafo_sc.ikss_lv_ka.at[0], ik) trafo_ratio = net.trafo.vn_lv_kv.values / net.trafo.vn_hv_kv.values - assert np.isclose(net.res_trafo_sc.ikss_hv_ka.at[0], ik*trafo_ratio) - + assert np.isclose(net.res_trafo_sc.ikss_hv_ka.at[0], ik * trafo_ratio) + for inv_y in (False, True): sc_bus = 2 - sc.calc_sc(net, inverse_y=inv_y, branch_results=True) + calc_sc(net, inverse_y=inv_y, branch_results=True) ik = net.res_bus_sc.ikss_ka.at[sc_bus] - sc.calc_sc(net, bus=sc_bus, branch_results=True) + calc_sc(net, bus=sc_bus, branch_results=True) assert np.isclose(net.res_line_sc.ikss_ka.at[1], 0) assert np.isclose(net.res_line_sc.ikss_ka.at[0], ik) assert np.isclose(net.res_trafo_sc.ikss_lv_ka.at[0], ik) trafo_ratio = net.trafo.vn_lv_kv.values / net.trafo.vn_hv_kv.values - assert np.isclose(net.res_trafo_sc.ikss_hv_ka.at[0], ik*trafo_ratio) - + assert np.isclose(net.res_trafo_sc.ikss_hv_ka.at[0], ik * trafo_ratio) def test_meshed_network(meshed_grid): net = meshed_grid - sc.calc_sc(net) + calc_sc(net) sc_bus = 5 ik = net.res_bus_sc.ikss_ka.at[sc_bus] - + for inv_y in (False, True): - sc.calc_sc(net, bus=sc_bus, inverse_y=inv_y, branch_results=True) + calc_sc(net, bus=sc_bus, inverse_y=inv_y, branch_results=True) - line_flow_into_sc = net.res_line_sc.ikss_ka[(net.line.to_bus==sc_bus) | (net.line.from_bus==sc_bus)].sum() + line_flow_into_sc = net.res_line_sc.ikss_ka[(net.line.to_bus == sc_bus) | (net.line.from_bus == sc_bus)].sum() assert np.isclose(line_flow_into_sc, ik, atol=2e-3) def test_big_gen_network_calc_sc(): net = three_bus_big_sgen_example() - + for inv_y in (False, True): sc_bus = 0 - sc.calc_sc(net, bus=sc_bus, - branch_results=True, inverse_y=inv_y) - + calc_sc(net, bus=sc_bus, + branch_results=True, inverse_y=inv_y) + assert np.isclose(net.res_line_sc.ikss_ka.at[0], 1.25967331, atol=1e-3) assert np.isclose(net.res_line_sc.ikss_ka.at[1], 0., atol=1e-3) - + sc_bus = 2 - sc.calc_sc(net, bus=sc_bus, - branch_results=True, inverse_y=inv_y) + calc_sc(net, bus=sc_bus, + branch_results=True, inverse_y=inv_y) assert np.isclose(net.res_line_sc.ikss_ka.at[0], 0.46221808, atol=1e-3) assert np.isclose(net.res_line_sc.ikss_ka.at[1], 1.72233192, atol=1e-3) diff --git a/pandapower/test/shortcircuit/test_sc_voltage.py b/pandapower/test/shortcircuit/test_sc_voltage.py index 59418a07b..2dde64f95 100644 --- a/pandapower/test/shortcircuit/test_sc_voltage.py +++ b/pandapower/test/shortcircuit/test_sc_voltage.py @@ -3,31 +3,22 @@ # Copyright (c) 2016-2024 by University of Kassel and Fraunhofer Institute for Energy Economics # and Energy System Technology (IEE), Kassel. All rights reserved. - -import os - -import pytest - import numpy as np -import pandapower as pp -import pandapower.shortcircuit as sc -import pandas as pd +from pandapower.create import create_empty_network, create_bus, create_line, create_ext_grid, create_sgen, create_gen +from pandapower.shortcircuit.calc_sc import calc_sc from pandapower.test.shortcircuit.test_iec60909_4 import iec_60909_4 -#pd.set_option("display.width", 1000) -#pd.set_option("display.max_columns", 1000) - def simple_grid(): - net = pp.create_empty_network(sn_mva=4) - b1 = pp.create_bus(net, 110) - b2 = pp.create_bus(net, 110) - b3 = pp.create_bus(net, 110) - - pp.create_ext_grid(net, b1, s_sc_max_mva=100., s_sc_min_mva=80., rx_min=0.4, rx_max=0.4) - pp.create_line(net, b1, b2, std_type="305-AL1/39-ST1A 110.0", length_km=20.) - pp.create_line(net, b2, b3, std_type="N2XS(FL)2Y 1x185 RM/35 64/110 kV", length_km=15.) + net = create_empty_network(sn_mva=4) + b1 = create_bus(net, 110) + b2 = create_bus(net, 110) + b3 = create_bus(net, 110) + + create_ext_grid(net, b1, s_sc_max_mva=100., s_sc_min_mva=80., rx_min=0.4, rx_max=0.4) + create_line(net, b1, b2, std_type="305-AL1/39-ST1A 110.0", length_km=20.) + create_line(net, b2, b3, std_type="N2XS(FL)2Y 1x185 RM/35 64/110 kV", length_km=15.) net.line["endtemp_degree"] = 80 return net @@ -35,9 +26,9 @@ def simple_grid(): def test_voltage_sgen(): net = simple_grid() - pp.create_sgen(net, 1, sn_mva=200., p_mw=0, k=1.3) + create_sgen(net, 1, sn_mva=200., p_mw=0, k=1.3) # net.sn_mva = 110 * np.sqrt(3) - sc.calc_sc(net, case="max", ip=True, branch_results=True, bus=2) + calc_sc(net, case="max", ip=True, branch_results=True, bus=2) assert np.isclose(net.res_bus_sc.at[2, "ikss_ka"], 1.825315, atol=1e-6, rtol=0) assert np.isclose(net.res_bus_sc.at[2, "skss_mw"], 347.769263, atol=1e-5, rtol=0) @@ -51,7 +42,7 @@ def test_voltage_sgen(): assert np.allclose(net.res_line_sc.loc[:, "vm_to_pu"], [0.079654, 0], atol=1e-6, rtol=0) assert np.allclose(net.res_line_sc.loc[:, "va_to_degree"], [-10.818133, 0], atol=1e-6, rtol=0) - sc.calc_sc(net, case="max", ip=True, branch_results=True, bus=1) + calc_sc(net, case="max", ip=True, branch_results=True, bus=1) assert np.isclose(net.res_bus_sc.at[1, "ikss_ka"], 1.860576, atol=1e-6, rtol=0) assert np.isclose(net.res_bus_sc.at[1, "skss_mw"], 354.487419, atol=1e-5, rtol=0) @@ -69,9 +60,9 @@ def test_voltage_sgen(): def test_voltage_gen(): net = simple_grid() z_base_ohm = np.square(110) / 100 - pp.create_gen(net, 1, p_mw=0, sn_mva=100, vn_kv=110, - xdss_pu=0.14, rdss_ohm=0.00001653 * z_base_ohm, cos_phi=0.85, pg_percent=0) - sc.calc_sc(net, case="max", ip=True, branch_results=True, bus=2) + create_gen(net, 1, p_mw=0, sn_mva=100, vn_kv=110, + xdss_pu=0.14, rdss_ohm=0.00001653 * z_base_ohm, cos_phi=0.85, pg_percent=0) + calc_sc(net, case="max", ip=True, branch_results=True, bus=2) assert np.isclose(net.res_bus_sc.at[2, "ikss_ka"], 3.87955, atol=1e-6, rtol=0) assert np.isclose(net.res_bus_sc.at[2, "skss_mw"], 739.153586, atol=1e-5, rtol=0) @@ -85,7 +76,7 @@ def test_voltage_gen(): assert np.allclose(net.res_line_sc.loc[:, "vm_to_pu"], [0.169299, 0], atol=1e-6, rtol=0) assert np.allclose(net.res_line_sc.loc[:, "va_to_degree"], [-25.662429, 0], atol=1e-6, rtol=0) - sc.calc_sc(net, case="max", ip=True, branch_results=True, bus=1) + calc_sc(net, case="max", ip=True, branch_results=True, bus=1) assert np.isclose(net.res_bus_sc.at[1, "ikss_ka"], 4.491006, atol=1e-6, rtol=0) assert np.isclose(net.res_bus_sc.at[1, "skss_mw"], 855.651656, atol=1e-5, rtol=0) @@ -102,7 +93,7 @@ def test_voltage_gen(): def test_voltage_simple(): net = simple_grid() - sc.calc_sc(net, case="max", ip=True, ith=True, branch_results=True, bus=2) + calc_sc(net, case="max", ip=True, ith=True, branch_results=True, bus=2) assert np.isclose(net.res_bus_sc.at[2, "ikss_ka"], 0.486532, atol=1e-6, rtol=0) assert np.isclose(net.res_bus_sc.at[2, "skss_mw"], 92.696717, atol=1e-5, rtol=0) @@ -116,7 +107,7 @@ def test_voltage_simple(): assert np.allclose(net.res_line_sc.loc[:, "vm_to_pu"], [0.021232, 0], atol=1e-6, rtol=0) assert np.allclose(net.res_line_sc.loc[:, "va_to_degree"], [-10.818133, 0], atol=1e-6, rtol=0) - sc.calc_sc(net, case="max", ip=True, ith=True, branch_results=True, bus=1) + calc_sc(net, case="max", ip=True, ith=True, branch_results=True, bus=1) assert np.isclose(net.res_bus_sc.at[1, "ikss_ka"], 0.49593, atol=1e-6, rtol=0) assert np.isclose(net.res_bus_sc.at[1, "skss_mw"], 94.487419, atol=1e-5, rtol=0) @@ -132,12 +123,12 @@ def test_voltage_simple(): def test_voltage_very_simple(): - net = pp.create_empty_network(sn_mva=12) - b1 = pp.create_bus(net, 110) - b2 = pp.create_bus(net, 110) - pp.create_ext_grid(net, b1, s_sc_max_mva=100., s_sc_min_mva=80., rx_min=0.4, rx_max=0.4) - pp.create_line(net, b1, b2, std_type="305-AL1/39-ST1A 110.0", length_km=20.) - sc.calc_sc(net, case="max", ip=True, ith=True, branch_results=True, bus=1) + net = create_empty_network(sn_mva=12) + b1 = create_bus(net, 110) + b2 = create_bus(net, 110) + create_ext_grid(net, b1, s_sc_max_mva=100., s_sc_min_mva=80., rx_min=0.4, rx_max=0.4) + create_line(net, b1, b2, std_type="305-AL1/39-ST1A 110.0", length_km=20.) + calc_sc(net, case="max", ip=True, ith=True, branch_results=True, bus=1) assert np.isclose(net.res_bus_sc.at[1, "ikss_ka"], 0.49593, atol=1e-6, rtol=0) assert np.isclose(net.res_bus_sc.at[1, "skss_mw"], 94.487419, atol=1e-5, rtol=0) @@ -154,5 +145,4 @@ def test_voltage_very_simple(): def test_iec_60909_4(): net = iec_60909_4() - sc.calc_sc(net, case="max", ip=True, ith=True, branch_results=True, bus=2) - + calc_sc(net, case="max", ip=True, ith=True, branch_results=True, bus=2) diff --git a/pandapower/test/shortcircuit/test_sgen.py b/pandapower/test/shortcircuit/test_sgen.py index 4b4d35ef1..a4fe136aa 100644 --- a/pandapower/test/shortcircuit/test_sgen.py +++ b/pandapower/test/shortcircuit/test_sgen.py @@ -3,32 +3,33 @@ # Copyright (c) 2016-2024 by University of Kassel and Fraunhofer Institute for Energy Economics # and Energy System Technology (IEE), Kassel. All rights reserved. - import numpy as np import pytest -import pandapower as pp -import pandapower.shortcircuit as sc +from pandapower.create import create_empty_network, create_bus, create_ext_grid, create_transformer, create_sgen, \ + create_buses, create_transformer_from_parameters, create_line_from_parameters, create_lines_from_parameters, \ + create_sgens, create_line from pandapower.pypower.idx_brch import BR_R, BR_X +from pandapower.shortcircuit.calc_sc import calc_sc def simplest_test_grid(generator_type, step_up_trafo=False): - net = pp.create_empty_network(sn_mva=6) + net = create_empty_network(sn_mva=6) if step_up_trafo: - b0 = pp.create_bus(net, 20) - b1 = pp.create_bus(net, 0.4) - pp.create_transformer(net, b0, b1, "0.25 MVA 20/0.4 kV", parallel=10) + b0 = create_bus(net, 20) + b1 = create_bus(net, 0.4) + create_transformer(net, b0, b1, "0.25 MVA 20/0.4 kV", parallel=10) else: - b0 = b1 = pp.create_bus(net, 20) + b0 = b1 = create_bus(net, 20) - pp.create_ext_grid(net, b0, s_sc_max_mva=1e-12, rx_max=0) + create_ext_grid(net, b0, s_sc_max_mva=1e-12, rx_max=0) if generator_type == "async_doubly_fed": - pp.create_sgen(net, b1, 0, 0, 2.5, current_source=False, - generator_type=generator_type, max_ik_ka=0.388, kappa=1.7, rx=0.1) + create_sgen(net, b1, 0, 0, 2.5, current_source=False, + generator_type=generator_type, max_ik_ka=0.388, kappa=1.7, rx=0.1) elif generator_type == "current_source": - pp.create_sgen(net, b1, 0, 0, 2.5, generator_type=generator_type, current_source=True, k=1.3, rx=0.1) + create_sgen(net, b1, 0, 0, 2.5, generator_type=generator_type, current_source=True, k=1.3, rx=0.1) elif generator_type == "async": - pp.create_sgen(net, b1, 0, 0, 2.5, generator_type=generator_type, current_source=False, rx=0.1, lrc_pu=5) + create_sgen(net, b1, 0, 0, 2.5, generator_type=generator_type, current_source=False, rx=0.1, lrc_pu=5) else: raise NotImplementedError(f"unknown sgen generator type {generator_type}, can be one of " f"'full_size_converter', 'async', 'async_doubly_fed'") @@ -36,34 +37,34 @@ def simplest_test_grid(generator_type, step_up_trafo=False): def wind_park_grid(case): - net = pp.create_empty_network(sn_mva=7) - pp.create_bus(net, 110, index=1) - pp.create_buses(net, 13, 20) + net = create_empty_network(sn_mva=7) + create_bus(net, 110, index=1) + create_buses(net, 13, 20) - pp.create_ext_grid(net, 1, 1, s_sc_max_mva=10.5 * 110 * np.sqrt(3), rx_max=0.1) + create_ext_grid(net, 1, 1, s_sc_max_mva=10.5 * 110 * np.sqrt(3), rx_max=0.1) - pp.create_transformer_from_parameters(net, 1, 2, 31.5, 110, 20, 0.6, 12, 0, 0) + create_transformer_from_parameters(net, 1, 2, 31.5, 110, 20, 0.6, 12, 0, 0) - pp.create_line_from_parameters(net, 2, 3, 13.1, 0.0681, 0.102, 0, 1e3, 'L1', parallel=2) + create_line_from_parameters(net, 2, 3, 13.1, 0.0681, 0.102, 0, 1e3, 'L1', parallel=2) from_buses = np.array([3, 4, 3, 6, 7, 7, 3, 10, 11, 11, 12]) to_buses = np.array([4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 13]) length_km = [1.1, 0.55, 0.79, 0.17, 0.4, 0.55, 0.95, 0.24, 0.29, 0.15, 0.495] names = [f"L{i}" for i in range(2, 13)] - pp.create_lines_from_parameters(net, from_buses, to_buses, length_km, 0.211, 0.122, 0, 1e3, names) + create_lines_from_parameters(net, from_buses, to_buses, length_km, 0.211, 0.122, 0, 1e3, names) sgen_buses = np.array([4, 5, 6, 8, 9, 10, 12, 13, 3, 14]) - if case=="all_async_doubly_fed": - pp.create_sgens(net, sgen_buses, 0, 0, 2.5, rx=0.1, current_source=False, - generator_type="async_doubly_fed", max_ik_ka=0.388, kappa=1.7) + if case == "all_async_doubly_fed": + create_sgens(net, sgen_buses, 0, 0, 2.5, rx=0.1, current_source=False, + generator_type="async_doubly_fed", max_ik_ka=0.388, kappa=1.7) elif case == "all_full_size_converter": - pp.create_sgens(net, sgen_buses, 0, 0, 2.5, rx=0.1, k=1.3, current_source=True, - generator_type="current_source") + create_sgens(net, sgen_buses, 0, 0, 2.5, rx=0.1, k=1.3, current_source=True, + generator_type="current_source") elif case == "mixed": - pp.create_sgens(net, sgen_buses[:5], 0, 0, 2.5, rx=0.1, current_source=False, - generator_type="async_doubly_fed", max_ik_ka=0.388, kappa=1.7) - pp.create_sgens(net, sgen_buses[5:], 0, 0, 2.5, rx=0.1, k=1.3, current_source=True, - generator_type="current_source") + create_sgens(net, sgen_buses[:5], 0, 0, 2.5, rx=0.1, current_source=False, + generator_type="async_doubly_fed", max_ik_ka=0.388, kappa=1.7) + create_sgens(net, sgen_buses[5:], 0, 0, 2.5, rx=0.1, k=1.3, current_source=True, + generator_type="current_source") else: raise NotImplementedError(f"case {case} not implemented") @@ -73,43 +74,47 @@ def wind_park_grid(case): def wind_park_example(): - net = pp.create_empty_network(sn_mva=8) - b1 = pp.create_bus(net, vn_kv=110., index=1) - b2 = pp.create_bus(net, vn_kv=110., index=2) - b3 = pp.create_bus(net, vn_kv=110., index=3) - b4 = pp.create_bus(net, vn_kv=110., index=4) - pp.create_ext_grid(net, b1, s_sc_max_mva=20*110*np.sqrt(3), rx_max=0.1) - - pp.create_line_from_parameters(net, from_bus=b1, to_bus=b2, length_km=100, r_ohm_per_km=0.120, x_ohm_per_km=0.393, c_nf_per_km=0, max_i_ka=10) - pp.create_line_from_parameters(net, from_bus=b1, to_bus=b3, length_km=50, r_ohm_per_km=0.120, x_ohm_per_km=0.393, c_nf_per_km=0, max_i_ka=10) - pp.create_line_from_parameters(net, from_bus=b2, to_bus=b3, length_km=50, r_ohm_per_km=0.120, x_ohm_per_km=0.393, c_nf_per_km=0, max_i_ka=10) - pp.create_line_from_parameters(net, from_bus=b3, to_bus=b4, length_km=25, r_ohm_per_km=0.120, x_ohm_per_km=0.393, c_nf_per_km=0, max_i_ka=10) - - pp.create_sgen(net, b2, p_mw=0.1e3, sn_mva=100) - pp.create_sgen(net, b3, p_mw=0.050e3, sn_mva=50) - pp.create_sgen(net, b4, p_mw=0.050e3, sn_mva=50) + net = create_empty_network(sn_mva=8) + b1 = create_bus(net, vn_kv=110., index=1) + b2 = create_bus(net, vn_kv=110., index=2) + b3 = create_bus(net, vn_kv=110., index=3) + b4 = create_bus(net, vn_kv=110., index=4) + create_ext_grid(net, b1, s_sc_max_mva=20 * 110 * np.sqrt(3), rx_max=0.1) + + create_line_from_parameters(net, from_bus=b1, to_bus=b2, length_km=100, r_ohm_per_km=0.120, x_ohm_per_km=0.393, + c_nf_per_km=0, max_i_ka=10) + create_line_from_parameters(net, from_bus=b1, to_bus=b3, length_km=50, r_ohm_per_km=0.120, x_ohm_per_km=0.393, + c_nf_per_km=0, max_i_ka=10) + create_line_from_parameters(net, from_bus=b2, to_bus=b3, length_km=50, r_ohm_per_km=0.120, x_ohm_per_km=0.393, + c_nf_per_km=0, max_i_ka=10) + create_line_from_parameters(net, from_bus=b3, to_bus=b4, length_km=25, r_ohm_per_km=0.120, x_ohm_per_km=0.393, + c_nf_per_km=0, max_i_ka=10) + + create_sgen(net, b2, p_mw=0.1e3, sn_mva=100) + create_sgen(net, b3, p_mw=0.050e3, sn_mva=50) + create_sgen(net, b4, p_mw=0.050e3, sn_mva=50) net.sgen["k"] = 1.2 return net def three_bus_example(): - net = pp.create_empty_network(sn_mva=9) - b1 = pp.create_bus(net, 110) - b2 = pp.create_bus(net, 110) - b3 = pp.create_bus(net, 110) + net = create_empty_network(sn_mva=9) + b1 = create_bus(net, 110) + b2 = create_bus(net, 110) + b3 = create_bus(net, 110) - pp.create_ext_grid(net, b1, s_sc_max_mva=100., s_sc_min_mva=80., rx_min=0.4, rx_max=0.4, x0x_max=0.2, x0x_min=0.1, - r0x0_max=0.3, r0x0_min=0.2) + create_ext_grid(net, b1, s_sc_max_mva=100., s_sc_min_mva=80., rx_min=0.4, rx_max=0.4, x0x_max=0.2, x0x_min=0.1, + r0x0_max=0.3, r0x0_min=0.2) net.ext_grid['x0x_min'] = 0.1 net.ext_grid['r0x0_min'] = 0.1 - pp.create_line(net, b1, b2, std_type="305-AL1/39-ST1A 110.0" , length_km=20.) - pp.create_line(net, b2, b3, std_type="N2XS(FL)2Y 1x185 RM/35 64/110 kV" , length_km=15.) + create_line(net, b1, b2, std_type="305-AL1/39-ST1A 110.0", length_km=20.) + create_line(net, b2, b3, std_type="N2XS(FL)2Y 1x185 RM/35 64/110 kV", length_km=15.) net.line['r0_ohm_per_km'] = 0.1 net.line['x0_ohm_per_km'] = 0.1 net.line['c0_nf_per_km'] = 0.1 net.line["endtemp_degree"] = 80 - pp.create_sgen(net, b2, sn_mva=2, p_mw=0, k=1.2) + create_sgen(net, b2, sn_mva=2, p_mw=0, k=1.2) return net @@ -117,40 +122,40 @@ def big_sgen_three_bus_example(): # ext_grid-bus1--line0--bus2--line1--bus3 # | # sgen0 - net = pp.create_empty_network(sn_mva=2) - b1 = pp.create_bus(net, 110) - b2 = pp.create_bus(net, 110) - b3 = pp.create_bus(net, 110) + net = create_empty_network(sn_mva=2) + b1 = create_bus(net, 110) + b2 = create_bus(net, 110) + b3 = create_bus(net, 110) - pp.create_ext_grid(net, b1, s_sc_max_mva=100., s_sc_min_mva=80., rx_min=0.4, rx_max=0.4) + create_ext_grid(net, b1, s_sc_max_mva=100., s_sc_min_mva=80., rx_min=0.4, rx_max=0.4) net.ext_grid['x0x_min'] = 0.1 net.ext_grid['r0x0_min'] = 0.1 net.ext_grid['x0x_max'] = 0.1 net.ext_grid['r0x0_max'] = 0.1 - pp.create_line(net, b1, b2, std_type="305-AL1/39-ST1A 110.0" , length_km=20.) - pp.create_line(net, b2, b3, std_type="N2XS(FL)2Y 1x185 RM/35 64/110 kV" , length_km=15.) + create_line(net, b1, b2, std_type="305-AL1/39-ST1A 110.0", length_km=20.) + create_line(net, b2, b3, std_type="N2XS(FL)2Y 1x185 RM/35 64/110 kV", length_km=15.) net.line['r0_ohm_per_km'] = 0.1 net.line['x0_ohm_per_km'] = 0.1 net.line['c0_nf_per_km'] = 0.1 net.line["endtemp_degree"] = 80 - pp.create_sgen(net, b2, sn_mva=200., p_mw=0, k=1.2) + create_sgen(net, b2, sn_mva=200., p_mw=0, k=1.2) return net def test_max_3ph_branch_small_sgen(): net = three_bus_example() - sc.calc_sc(net, case="max", ip=True, ith=True, branch_results=True) + calc_sc(net, case="max", ip=True, ith=True, branch_results=True) assert np.allclose(net.res_bus_sc.ikss_ka.values, np.array([0.53746061, 0.50852707, 0.4988896])) - assert np.allclose(net.res_line_sc.ikss_ka.values, np.array([ 0.49593034, 0.4988896])) - assert np.allclose(net.res_line_sc.ip_ka.values, np.array([ 0.92787443, 0.9251165])) - assert np.allclose(net.res_line_sc.ith_ka.values, np.array([ 0.49811957, 0.50106881])) + assert np.allclose(net.res_line_sc.ikss_ka.values, np.array([0.49593034, 0.4988896])) + assert np.allclose(net.res_line_sc.ip_ka.values, np.array([0.92787443, 0.9251165])) + assert np.allclose(net.res_line_sc.ith_ka.values, np.array([0.49811957, 0.50106881])) def test_max_3ph_branch_big_sgen(): net = big_sgen_three_bus_example() - sc.calc_sc(net, case="max", ip=True, ith=True, branch_results=True) + calc_sc(net, case="max", ip=True, ith=True, branch_results=True) assert np.allclose(net.res_bus_sc.ikss_ka.values, np.array([1.78453722, 1.75560368, 1.72233192])) assert np.allclose(net.res_line_sc.ikss_ka.values, np.array([1.25967331, 1.72233192])) assert np.allclose(net.res_line_sc.ip_ka.values, np.array([1.78144709, 2.65532524])) @@ -159,9 +164,9 @@ def test_max_3ph_branch_big_sgen(): def test_min_3ph_branch_results_small_sgen(): net = three_bus_example() - sc.calc_sc(net, case="min", ip=True, ith=True, branch_results=True) - assert np.allclose(net.res_bus_sc.ikss_ka.values, np.array([0.419891, 0.398969, 0.391938]), atol=1e-6, rtol=0) - assert np.allclose(net.res_line_sc.ikss_ka.values, np.array([0.391938, 0.391938]), atol=1e-6, rtol=0) + calc_sc(net, case="min", ip=True, ith=True, branch_results=True) + assert np.allclose(net.res_bus_sc.ikss_ka.values, np.array([0.419891, 0.398969, 0.391938]), atol=1e-6, rtol=0) + assert np.allclose(net.res_line_sc.ikss_ka.values, np.array([0.391938, 0.391938]), atol=1e-6, rtol=0) assert np.allclose(net.res_line_sc.ip_ka.values, np.array([0.744387, 0.728265]), atol=1e-6, rtol=0) assert np.allclose(net.res_line_sc.ith_ka.values, np.array([0.400712, 0.393625]), atol=1e-6, rtol=0) @@ -169,11 +174,11 @@ def test_min_3ph_branch_results_small_sgen(): def test_min_3ph_branch_results_big_sgen(): net = big_sgen_three_bus_example() # net.sn_mva = 110 * np.sqrt(3) - # bacause in case "min" sgen is ignored, it does't matter if sgen is big or small - + # because in case "min" sgen is ignored, it doesn't matter if sgen is big or small - # the results here are the same as in the test test_min_3ph_branch_results_small_sgen - sc.calc_sc(net, case="min", ip=True, ith=True, branch_results=True) - assert np.allclose(net.res_bus_sc.ikss_ka.values, np.array([0.419891, 0.398969, 0.391938]), atol=1e-6, rtol=0) - assert np.allclose(net.res_line_sc.ikss_ka.values, np.array([0.391938, 0.391938]), atol=1e-6, rtol=0) + calc_sc(net, case="min", ip=True, ith=True, branch_results=True) + assert np.allclose(net.res_bus_sc.ikss_ka.values, np.array([0.419891, 0.398969, 0.391938]), atol=1e-6, rtol=0) + assert np.allclose(net.res_line_sc.ikss_ka.values, np.array([0.391938, 0.391938]), atol=1e-6, rtol=0) assert np.allclose(net.res_line_sc.ip_ka.values, np.array([0.744387, 0.728265]), atol=1e-6, rtol=0) assert np.allclose(net.res_line_sc.ith_ka.values, np.array([0.400712, 0.393625]), atol=1e-6, rtol=0) @@ -183,14 +188,14 @@ def test_max_1ph_branch_small_sgen(): # With generator net = three_bus_example() - sc.calc_sc(net, case="max", fault='1ph', branch_results=True) + calc_sc(net, case="max", fault='1ph', branch_results=True) i_bus_with_sgen = net.res_bus_sc.copy() i_line_with_gen = net.res_line_sc.copy() # Without generator net = three_bus_example() net.sgen.in_service = False - sc.calc_sc(net, case="max", fault='1ph', branch_results=True) + calc_sc(net, case="max", fault='1ph', branch_results=True) i_bus_without_sgen = net.res_bus_sc.copy() # Check coherence between bus result and branch results @@ -198,20 +203,19 @@ def test_max_1ph_branch_small_sgen(): assert np.isclose(i_line_with_gen.ikss_ka.at[1], i_bus_with_sgen.ikss_ka.at[2], atol=1e-4) - def test_max_1ph_branch_big_sgen(): # This test just check coherence between branch ikss_ka results and bus ikss_ka results # With generator net = big_sgen_three_bus_example() - sc.calc_sc(net, case="max", fault='1ph', branch_results=True) + calc_sc(net, case="max", fault='1ph', branch_results=True) i_bus_with_sgen = net.res_bus_sc.copy() i_line_with_gen = net.res_line_sc.copy() # Without generator net = big_sgen_three_bus_example() net.sgen.in_service = False - sc.calc_sc(net, case="max", fault='1ph', branch_results=True) + calc_sc(net, case="max", fault='1ph', branch_results=True) i_bus_without_sgen = net.res_bus_sc.copy() # Isolate sgen contribution @@ -228,14 +232,14 @@ def test_min_1ph_branch_small_sgen(): # With generator net = three_bus_example() - sc.calc_sc(net, case="min", fault='1ph', branch_results=True) + calc_sc(net, case="min", fault='1ph', branch_results=True) i_bus_with_sgen = net.res_bus_sc.copy() i_line_with_gen = net.res_line_sc.copy() # Without generator net = three_bus_example() net.sgen.in_service = False - sc.calc_sc(net, case="min", fault='1ph', branch_results=True) + calc_sc(net, case="min", fault='1ph', branch_results=True) i_bus_without_sgen = net.res_bus_sc.copy() # Isolate sgen contribution @@ -253,14 +257,14 @@ def test_min_1ph_branch_big_sgen(): # With generator net = big_sgen_three_bus_example() - sc.calc_sc(net, case="min", fault='1ph', branch_results=True) + calc_sc(net, case="min", fault='1ph', branch_results=True) i_bus_with_sgen = net.res_bus_sc.copy() i_line_with_sgen = net.res_line_sc.copy() # Without generator net = big_sgen_three_bus_example() net.sgen.in_service = False - sc.calc_sc(net, case="min", fault='1ph', branch_results=True) + calc_sc(net, case="min", fault='1ph', branch_results=True) i_bus_without_sgen = net.res_bus_sc.copy() # Isolate sgen contribution @@ -277,7 +281,7 @@ def test_min_1ph_branch_big_sgen(): def test_wind_park(): net = wind_park_example() - sc.calc_sc(net, ip=True) + calc_sc(net, ip=True) assert np.isclose(net.res_bus_sc.ikss_ka.at[2], 3.9034, rtol=1e-4) assert np.isclose(net.res_bus_sc.ip_ka.at[2], 7.3746, rtol=1e-4) @@ -285,7 +289,7 @@ def test_wind_park(): def test_wind_park_1(): # example from IEC 60909-4 section 8.5 net = wind_park_grid("all_async_doubly_fed") - sc.calc_sc(net) + calc_sc(net) ikss_ka = [10.745, 9.045, 6.978, 6.385, 6.095, 6.568, 6.478, 6.262, 6.184, 6.513, 6.394, 6.247, 5.993, 6.313] assert np.allclose(net.res_bus_sc.ikss_ka, ikss_ka, atol=1e-3, rtol=0) @@ -294,8 +298,8 @@ def test_wind_park_1(): def test_wind_park_2(): # example from IEC 60909-4 section 8.6 net = wind_park_grid("all_full_size_converter") - sc.calc_sc(net) - ikss_ka = [10.671, 8.387, 6.161, 5.728, 5.522, 5.852, 5.787, 5.633, + calc_sc(net) + ikss_ka = [10.671, 8.387, 6.161, 5.728, 5.522, 5.852, 5.787, 5.633, 5.577, 5.797, 5.708, 5.600, 5.419, 5.651] assert np.allclose(net.res_bus_sc.ikss_ka, ikss_ka, atol=1.5e-3, rtol=0) @@ -303,8 +307,8 @@ def test_wind_park_2(): def test_wind_park_3(): # example from IEC 60909-4 section 8.7 net = wind_park_grid("mixed") - sc.calc_sc(net) - ikss_ka = [10.713, 8.734, 6.570, 6.078, 5.834, 6.232, 6.157, 5.976, + calc_sc(net) + ikss_ka = [10.713, 8.734, 6.570, 6.078, 5.834, 6.232, 6.157, 5.976, 5.910, 6.124, 6.015, 5.884, 5.666, 5.946] assert np.allclose(net.res_bus_sc.ikss_ka, ikss_ka, atol=1e-3, rtol=0) @@ -312,7 +316,7 @@ def test_wind_park_3(): def test_wind_power_station_unit(): # full size converter (current source) net = simplest_test_grid('current_source') - sc.calc_sc(net, ip=True) + calc_sc(net, ip=True) vn_kv = net.bus.vn_kv.at[0] sn_mva = net.sgen.sn_mva.at[0] @@ -325,7 +329,7 @@ def test_wind_power_station_unit(): # doubly fed asynchronous generator (DFIG), kappa not calculated but provided by manufacturer net = simplest_test_grid("async_doubly_fed") - sc.calc_sc(net, ip=True) + calc_sc(net, ip=True) kappa = net.sgen.kappa.at[0] vn_kv = net.bus.vn_kv.at[0] @@ -338,15 +342,15 @@ def test_wind_power_station_unit(): assert np.isclose(net.res_bus_sc.at[0, 'ip_ka'], ikss_ka * kappa * np.sqrt(2), rtol=0, atol=1e-12) assert np.isclose(net.res_bus_sc.at[0, 'skss_mw'], skss_mw, rtol=0, atol=1e-9) - # asyncronous generator (also with a step-up trafo) + # asynchronous generator (also with a step-up trafo) net = simplest_test_grid("async") - sc.calc_sc(net, ip=True) + calc_sc(net, ip=True) vn_kv = net.bus.vn_kv.at[0] sn_mva = net.sgen.sn_mva.at[0] lrc_pu = net.sgen.lrc_pu.at[0] rx = net.sgen.rx.at[0] - z_g = 1 / lrc_pu * vn_kv**2 / sn_mva + z_g = 1 / lrc_pu * vn_kv ** 2 / sn_mva c = 1.1 ikss_ka = c * vn_kv / (np.sqrt(3) * z_g) kappa = 1.02 + 0.98 * np.exp(-3 * 0.1) @@ -357,7 +361,7 @@ def test_wind_power_station_unit(): # now async with a step-up trafo net = simplest_test_grid("async", True) - sc.calc_sc(net, ip=True) + calc_sc(net, ip=True) vn_kv = net.bus.vn_kv.at[1] sn_mva = net.sgen.sn_mva.at[0] @@ -375,8 +379,8 @@ def test_wind_power_station_unit(): assert np.isclose(net.res_bus_sc.at[1, 'rk_ohm'], z_g_complex.real, rtol=0, atol=1e-9) assert np.isclose(net.res_bus_sc.at[1, 'xk_ohm'], z_g_complex.imag, rtol=0, atol=1e-9) - base_z_ohm = 20**2 / net.sn_mva - z_thv = (net._ppc['branch'][0, BR_R] + 1j*net._ppc['branch'][0, BR_X]) * base_z_ohm + base_z_ohm = 20 ** 2 / net.sn_mva + z_thv = (net._ppc['branch'][0, BR_R] + 1j * net._ppc['branch'][0, BR_X]) * base_z_ohm t_r = 20 / 0.4 z_block = t_r ** 2 * z_g_complex + z_thv ikss_block_ka = c * 20 / (np.sqrt(3) * abs(z_block)) diff --git a/pandapower/test/shortcircuit/test_trafo3w.py b/pandapower/test/shortcircuit/test_trafo3w.py index cb586c0a8..7f11ea115 100644 --- a/pandapower/test/shortcircuit/test_trafo3w.py +++ b/pandapower/test/shortcircuit/test_trafo3w.py @@ -3,53 +3,53 @@ # Copyright (c) 2016-2024 by University of Kassel and Fraunhofer Institute for Energy Economics # and Energy System Technology (IEE), Kassel. All rights reserved. - import numpy as np import pytest -import pandapower as pp -import pandapower.shortcircuit as sc +from pandapower.create import create_empty_network, create_bus, create_ext_grid, create_load, \ + create_transformer3w_from_parameters +from pandapower.run import runpp +from pandapower.shortcircuit.calc_sc import calc_sc @pytest.fixture def trafo3w_net(): - net = pp.create_empty_network(sn_mva=5) - b1 = pp.create_bus(net, 220) - b2 = pp.create_bus(net, 30) - b3 = pp.create_bus(net, 10) - pp.create_ext_grid(net, b1, s_sc_max_mva=100., s_sc_min_mva=40., rx_min=0.1, rx_max=0.1) - pp.create_load(net, b2, 25, 5) - pp.create_load(net, b3, 25, 10) - pp.create_transformer3w_from_parameters(net, hv_bus=b1, mv_bus=b2, lv_bus=b3, vn_hv_kv=222, - vn_mv_kv=33, vn_lv_kv=11., sn_hv_mva=50, - sn_mv_mva=30, sn_lv_mva=20, vk_hv_percent=11, - vkr_hv_percent=1., vk_mv_percent=11, - vkr_mv_percent=1., vk_lv_percent=11., - vkr_lv_percent=1., pfe_kw=10, i0_percent=0.2) + net = create_empty_network(sn_mva=5) + b1 = create_bus(net, 220) + b2 = create_bus(net, 30) + b3 = create_bus(net, 10) + create_ext_grid(net, b1, s_sc_max_mva=100., s_sc_min_mva=40., rx_min=0.1, rx_max=0.1) + create_load(net, b2, 25, 5) + create_load(net, b3, 25, 10) + create_transformer3w_from_parameters( + net, hv_bus=b1, mv_bus=b2, lv_bus=b3, vn_hv_kv=222, vn_mv_kv=33, vn_lv_kv=11., sn_hv_mva=50, sn_mv_mva=30, + sn_lv_mva=20, vk_hv_percent=11, vkr_hv_percent=1., vk_mv_percent=11, vkr_mv_percent=1., vk_lv_percent=11., + vkr_lv_percent=1., pfe_kw=10, i0_percent=0.2 + ) return net def test_trafo3w_max(trafo3w_net): net = trafo3w_net - sc.calc_sc(net, case="max", lv_tol_percent=6., ip=True, ith=True) + calc_sc(net, case="max", lv_tol_percent=6., ip=True, ith=True) assert np.allclose(net.res_bus_sc.ikss_ka.values, [0.26243195543, 1.2151357496, 3.2407820253]) assert np.allclose(net.res_bus_sc.ip_ka.values, [0.64800210157, 3.0086118915, 8.0313060686]) assert np.allclose(net.res_bus_sc.ith_ka.values, [0.26687233494, 1.2361480166, 3.2972358704]) - pp.runpp(net) - sc.calc_sc(net, case="max", lv_tol_percent=6., ip=True, ith=True, use_pre_fault_voltage=True) + runpp(net) + calc_sc(net, case="max", lv_tol_percent=6., ip=True, ith=True, use_pre_fault_voltage=True) assert np.allclose(net.res_bus_sc.ikss_ka.values, [0.3437679, 1.67689443, 4.457388], rtol=0, atol=5e-4) def test_trafo3w_min(trafo3w_net): net = trafo3w_net - sc.calc_sc(net, case="min", lv_tol_percent=6., ip=True, ith=True) + calc_sc(net, case="min", lv_tol_percent=6., ip=True, ith=True) assert np.allclose(net.res_bus_sc.ikss_ka.values, [0.1049727799, 0.56507157823, 1.5934473235]) assert np.allclose(net.res_bus_sc.ip_ka.values, [0.25920083485, 1.3972274925, 3.9422963436]) assert np.allclose(net.res_bus_sc.ith_ka.values, [0.10674893166, 0.57473904595, 1.6208335668]) - pp.runpp(net) - sc.calc_sc(net, case="min", lv_tol_percent=6., ip=True, ith=True, use_pre_fault_voltage=True) + runpp(net) + calc_sc(net, case="min", lv_tol_percent=6., ip=True, ith=True, use_pre_fault_voltage=True) assert np.allclose(net.res_bus_sc.ikss_ka.values, [0.224954, 1.276104, 3.58033], rtol=0, atol=5e-4) diff --git a/pandapower/test/shortcircuit/test_transformer.py b/pandapower/test/shortcircuit/test_transformer.py index 6045e1c41..af50ca900 100644 --- a/pandapower/test/shortcircuit/test_transformer.py +++ b/pandapower/test/shortcircuit/test_transformer.py @@ -3,34 +3,34 @@ # Copyright (c) 2016-2024 by University of Kassel and Fraunhofer Institute for Energy Economics # and Energy System Technology (IEE), Kassel. All rights reserved. - import pytest -import pandapower as pp -import pandapower.shortcircuit as sc +from pandapower.create import create_empty_network, create_bus, create_ext_grid, create_switch, create_shunt, \ + create_transformer_from_parameters +from pandapower.shortcircuit.calc_sc import calc_sc @pytest.fixture def net_transformer(): - net = pp.create_empty_network(sn_mva=2) - b1a = pp.create_bus(net, vn_kv=10.) - b1b = pp.create_bus(net, vn_kv=10.) - b2 = pp.create_bus(net, vn_kv=.4) - pp.create_bus(net, vn_kv=0.4, in_service=False) # add out of service bus to test oos indexing - pp.create_ext_grid(net, b1a, s_sc_max_mva=100., s_sc_min_mva=40., rx_min=0.1, rx_max=0.1) - pp.create_switch(net, b1a, b1b, et="b") - pp.create_transformer_from_parameters(net, b1b, b2, vn_hv_kv=11., vn_lv_kv=0.42, vk_percent=6., - vkr_percent=0.5, pfe_kw=14, shift_degree=0.0, - tap_side="hv", tap_neutral=0, tap_min=-2, tap_max=2, tap_pos=2, - tap_step_percent=2.5, parallel=2, sn_mva=0.4, i0_percent=0.5) + net = create_empty_network(sn_mva=2) + b1a = create_bus(net, vn_kv=10.) + b1b = create_bus(net, vn_kv=10.) + b2 = create_bus(net, vn_kv=.4) + create_bus(net, vn_kv=0.4, in_service=False) # add out of service bus to test oos indexing + create_ext_grid(net, b1a, s_sc_max_mva=100., s_sc_min_mva=40., rx_min=0.1, rx_max=0.1) + create_switch(net, b1a, b1b, et="b") + create_transformer_from_parameters(net, b1b, b2, vn_hv_kv=11., vn_lv_kv=0.42, vk_percent=6., + vkr_percent=0.5, pfe_kw=14, shift_degree=0.0, + tap_side="hv", tap_neutral=0, tap_min=-2, tap_max=2, tap_pos=2, + tap_step_percent=2.5, parallel=2, sn_mva=0.4, i0_percent=0.5) # adding a shunt shouldn't change the result: - pp.create_shunt(net, b2, q_mvar=0.050, p_mw=0.0500) + create_shunt(net, b2, q_mvar=0.050, p_mw=0.0500) return net def test_max_10_trafo(net_transformer): net = net_transformer - sc.calc_sc(net, case='max', ip=True, ith=True, lv_tol_percent=10.) + calc_sc(net, case='max', ip=True, ith=True, lv_tol_percent=10.) assert (abs(net.res_bus_sc.ikss_ka.at[0] - 5.77350301940194) < 1e-5) assert (abs(net.res_bus_sc.ikss_ka.at[1] - 5.77350301940194) < 1e-5) assert (abs(net.res_bus_sc.ikss_ka.at[2] - 16.992258758) < 1e-5) @@ -46,7 +46,7 @@ def test_max_10_trafo(net_transformer): def test_max_6_trafo(net_transformer): net = net_transformer - sc.calc_sc(net, case='max', ip=True, ith=True, lv_tol_percent=6.) + calc_sc(net, case='max', ip=True, ith=True, lv_tol_percent=6.) assert (abs(net.res_bus_sc.ikss_ka.at[0] - 5.77350301940194) < 1e-5) assert (abs(net.res_bus_sc.ikss_ka.at[1] - 5.77350301940194) < 1e-5) assert (abs(net.res_bus_sc.ikss_ka.at[2] - 16.905912296) < 1e-5) @@ -62,7 +62,7 @@ def test_max_6_trafo(net_transformer): def test_min_10_trafo(net_transformer): net = net_transformer - sc.calc_sc(net, case='min', ip=True, ith=True, lv_tol_percent=10.) + calc_sc(net, case='min', ip=True, ith=True, lv_tol_percent=10.) assert (abs(net.res_bus_sc.ikss_ka.at[0] - 2.309401) < 1e-5) assert (abs(net.res_bus_sc.ikss_ka.at[1] - 2.309401) < 1e-5) assert (abs(net.res_bus_sc.ikss_ka.at[2] - 12.912468695) < 1e-5) @@ -78,7 +78,7 @@ def test_min_10_trafo(net_transformer): def test_min_6_trafo(net_transformer): net = net_transformer - sc.calc_sc(net, case='min', ip=True, ith=True, lv_tol_percent=6.) + calc_sc(net, case='min', ip=True, ith=True, lv_tol_percent=6.) assert (abs(net.res_bus_sc.ikss_ka.at[0] - 2.309401) < 1e-5) assert (abs(net.res_bus_sc.ikss_ka.at[1] - 2.309401) < 1e-5) assert (abs(net.res_bus_sc.ikss_ka.at[2] - 13.39058012) < 1e-5) @@ -94,7 +94,7 @@ def test_min_6_trafo(net_transformer): def test_min_10_trafo_2ph(net_transformer): net = net_transformer - sc.calc_sc(net, fault="2ph", case='min', ip=True, ith=True, lv_tol_percent=10.) + calc_sc(net, fault="2ph", case='min', ip=True, ith=True, lv_tol_percent=10.) assert (abs(net.res_bus_sc.ikss_ka.at[0] - 2.0000000702) < 1e-5) assert (abs(net.res_bus_sc.ikss_ka.at[2] - 11.182525915) < 1e-5) diff --git a/pandapower/test/test_files/save_version.py b/pandapower/test/test_files/save_version.py index 853095c5c..c48f84bed 100644 --- a/pandapower/test/test_files/save_version.py +++ b/pandapower/test/test_files/save_version.py @@ -2,13 +2,18 @@ # Copyright (c) 2016-2024 by University of Kassel and Fraunhofer Institute for Energy Economics # and Energy System Technology (IEE), Kassel. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. -import pandapower as pp import os -net = pp.networks.example_multivoltage() -pp.control.DiscreteTapControl(net, 1, 1.02, 1.03) -pp.control.create_trafo_characteristics(net, "trafo", 1, "vk_percent", [-2, 0, 2], [3.5, 4, 4.5]) -pp.runpp(net, run_control=True) -pp.to_json(net, os.path.join("old_versions", "example_%s.json" % pp.__version__)) +from pandapower import __version__ as pp_version +from pandapower.control.controller.trafo import DiscreteTapControl +from pandapower.control.util.auxiliary import create_trafo_characteristics +from pandapower.file_io import to_json +from pandapower.networks.create_examples import example_multivoltage +from pandapower.run import runpp + +net = example_multivoltage() +DiscreteTapControl(net, 1, 1.02, 1.03) +create_trafo_characteristics(net, "trafo", 1, "vk_percent", [-2, 0, 2], [3.5, 4, 4.5]) +runpp(net, run_control=True) +to_json(net, os.path.join("old_versions", "example_%s.json" % pp_version)) diff --git a/pandapower/test/timeseries/test_data_source.py b/pandapower/test/timeseries/test_data_source.py index 460627732..4eb7c1bba 100644 --- a/pandapower/test/timeseries/test_data_source.py +++ b/pandapower/test/timeseries/test_data_source.py @@ -3,25 +3,27 @@ # Copyright (c) 2016-2024 by University of Kassel and Fraunhofer Institute for Energy Economics # and Energy System Technology (IEE), Kassel. All rights reserved. +import copy import os + import pandas as pd import pytest -import copy -import pandapower.control -import pandapower.timeseries + from pandapower import pp_dir +from pandapower.timeseries.data_sources.frame_data import DFData + epsilon = 0.00000000000001 + def test_data_source(): """ Testing simply reading from file and checking the data. """ # load file - filename = os.path.join(pp_dir, "test", "timeseries", "test_files", "small_profile.csv") df = pd.read_csv(filename, sep=";") - my_data_source = pandapower.timeseries.DFData(df) + my_data_source = DFData(df) copy.deepcopy(my_data_source) assert my_data_source.get_time_step_value(time_step=0, profile_name="my_profilename") == 0.0 diff --git a/pandapower/test/timeseries/test_output_writer.py b/pandapower/test/timeseries/test_output_writer.py index 5bae0f702..cab3f1997 100644 --- a/pandapower/test/timeseries/test_output_writer.py +++ b/pandapower/test/timeseries/test_output_writer.py @@ -13,14 +13,15 @@ import pandas as pd import pytest -import pandapower as pp -import pandapower.control as ct -import pandapower.networks as nw -import pandapower.timeseries as ts from pandapower.control import ConstControl +from pandapower.create import create_pwl_cost +from pandapower.file_io import to_json, from_json from pandapower.networks import simple_four_bus_system +from pandapower.networks.power_system_test_cases import case5 +from pandapower.run import runpp from pandapower.test.timeseries.test_timeseries import create_data_source, simple_test_net -from pandapower.timeseries import DFData, OutputWriter +from pandapower.timeseries.data_sources.frame_data import DFData +from pandapower.timeseries.output_writer import OutputWriter from pandapower.timeseries.run_time_series import run_timeseries logger = logging.getLogger(__name__) @@ -37,8 +38,8 @@ def test_output_writer_log(simple_test_net): ds = DFData(df) # Create gen controller with datasource - ct.ConstControl(net, element="load", variable="p_mw", element_index=[0, 2], data_source=ds, - profile_name=[0, 2]) + ConstControl(net, element="load", variable="p_mw", element_index=[0, 2], data_source=ds, + profile_name=[0, 2]) # Create, add output and set outputwriter ow = OutputWriter(net, output_path=tempfile.gettempdir()) @@ -235,14 +236,14 @@ def test_store_and_load(simple_test_net): ow = OutputWriter(net, output_path=dirname, output_file_type=".json") ow.remove_log_variable("res_bus") tmp_file = os.path.join(dirname, "net.json") - pp.to_json(net, tmp_file) + to_json(net, tmp_file) del net del ow res_line_file = os.path.join(dirname, "res_line", "loading_percent.json") # del result file is one is present if os.path.isfile(res_line_file): os.remove(res_line_file) - net = pp.from_json(tmp_file) + net = from_json(tmp_file) ow = net.output_writer.iat[0, 0] assert len(ow.log_variables) == 1 assert ow.output_path == dirname @@ -266,7 +267,7 @@ def test_ppc_log(simple_test_net): log_variables=list()) ow.log_variable('ppc_bus', 'vm') ow.log_variable('ppc_bus', 'va') - pp.runpp(net, only_v_results=True, recycle={"bus_pq": True, "gen": False, "trafo": False}) + runpp(net, only_v_results=True, recycle={"bus_pq": True, "gen": False, "trafo": False}) run_timeseries(net, time_steps, recycle={"bus_pq": True, "gen": False, "trafo": False}, only_v_results=True, verbose=False) assert len(ow.output["ppc_bus.vm"]) == n_timesteps @@ -285,12 +286,12 @@ def test_ow_index(): ds_p = DFData(p_data) ds_v = DFData(v_data) - ct.ConstControl(net, element='load', variable='p_mw', - element_index=net.load.index.tolist(), data_source=ds_p, - profile_name=p_data.columns) - ct.ConstControl(net, element='ext_grid', variable='vm_pu', - element_index=0, data_source=ds_v, - profile_name='0') + ConstControl(net, element='load', variable='p_mw', + element_index=net.load.index.tolist(), data_source=ds_p, + profile_name=p_data.columns) + ConstControl(net, element='ext_grid', variable='vm_pu', + element_index=0, data_source=ds_v, + profile_name='0') ow = OutputWriter(net) ow.log_variable('res_bus', 'vm_pu') @@ -302,24 +303,24 @@ def test_ow_index(): def test_equal_eval_name_warning_and_costs(): - net = nw.case5() + net = case5() net.poly_cost = net.poly_cost.iloc[0:0] - pp.create_pwl_cost(net, 0, "sgen", [[0, 20, 1], [20, 30, 2]]) - pp.create_pwl_cost(net, 0, "gen", [[0, 20, 1], [20, 30, 2]]) - pp.create_pwl_cost(net, 1, "gen", [[0, 20, 1], [20, 30, 2]]) - pp.create_pwl_cost(net, 2, "gen", [[0, 20, 1], [20, 30, 2]]) + create_pwl_cost(net, 0, "sgen", [[0, 20, 1], [20, 30, 2]]) + create_pwl_cost(net, 0, "gen", [[0, 20, 1], [20, 30, 2]]) + create_pwl_cost(net, 1, "gen", [[0, 20, 1], [20, 30, 2]]) + create_pwl_cost(net, 2, "gen", [[0, 20, 1], [20, 30, 2]]) df = pd.DataFrame({0: [200, 300, 400, 500], 1: [400, 300, 100, 50], 2: [100, 300, 200, 100]}) - ds = ts.DFData(df.astype(np.float64)) - _ = ct.ConstControl(net, "load", "p_mw", net.load.index, profile_name=net.load.index, - data_source=ds) - ow = ts.OutputWriter(net, output_path=None) + ds = DFData(df.astype(np.float64)) + _ = ConstControl(net, "load", "p_mw", net.load.index, profile_name=net.load.index, + data_source=ds) + ow = OutputWriter(net, output_path=None) ow.log_variable("res_sgen", "p_mw", None, np.max, 'warnme') ow.log_variable("res_load", "p_mw", None, np.max, 'warnme') ow.log_variable("pwl_cost", "points", eval_function=cost_logging) ow.remove_log_variable("res_bus", "vm_pu") ow.remove_log_variable("res_line", "loading_percent") - ts.run_timeseries(net, verbose=False) + run_timeseries(net, verbose=False) p_sgen = ow.output["res_sgen.p_mw"] p_load = ow.output["res_load.p_mw"] diff --git a/pandapower/test/timeseries/test_timeseries.py b/pandapower/test/timeseries/test_timeseries.py index 0a75f3665..5af3fccce 100644 --- a/pandapower/test/timeseries/test_timeseries.py +++ b/pandapower/test/timeseries/test_timeseries.py @@ -3,46 +3,48 @@ # Copyright (c) 2016-2024 by University of Kassel and Fraunhofer Institute for Energy Economics # and Energy System Technology (IEE), Kassel. All rights reserved. +import logging import tempfile import numpy as np import pandas as pd import pytest -import pandapower.control.util.diagnostic -import pandapower as pp -import logging from pandapower.control import ContinuousTapControl, ConstControl - +from pandapower.control.util.diagnostic import logger as diagnostic_logger +from pandapower.create import create_empty_network, create_bus, create_ext_grid, create_line, create_transformer, \ + create_load, create_loads, create_buses, create_switch, create_lines, create_transformer3w_from_parameters +from pandapower.run import set_user_pf_options, runpp from pandapower.timeseries import DFData from pandapower.timeseries import OutputWriter from pandapower.timeseries.run_time_series import run_timeseries, control_diagnostic logger = logging.getLogger(__name__) + @pytest.fixture def simple_test_net(): - net = pp.create_empty_network() - pp.set_user_pf_options(net, init='dc', calculate_voltage_angles=True) - b0 = pp.create_bus(net, 110) - b1 = pp.create_bus(net, 110) - b2 = pp.create_bus(net, 20) - b3 = pp.create_bus(net, 20) - b4 = pp.create_bus(net, 6) + net = create_empty_network() + set_user_pf_options(net, init='dc', calculate_voltage_angles=True) + b0 = create_bus(net, 110) + b1 = create_bus(net, 110) + b2 = create_bus(net, 20) + b3 = create_bus(net, 20) + b4 = create_bus(net, 6) - pp.create_ext_grid(net, b0) - pp.create_line(net, b0, b1, 10, "149-AL1/24-ST1A 110.0") + create_ext_grid(net, b0) + create_line(net, b0, b1, 10, "149-AL1/24-ST1A 110.0") - pp.create_transformer(net, b1, b2, "25 MVA 110/20 kV", name='tr1') + create_transformer(net, b1, b2, "25 MVA 110/20 kV", name='tr1') - pp.create_transformer3w_from_parameters(net, b1, b3, b4, 110, 20, 6, 1e2, 1e2, 1e1, 3, 2, 2, 1, - 1, 1, 100, 1, 60, 30, 'hv', tap_step_percent=1.5, - tap_step_degree=0, tap_pos=0, tap_neutral=0, tap_max=10, - tap_min=-10, name='tr2') + create_transformer3w_from_parameters(net, b1, b3, b4, 110, 20, 6, 1e2, 1e2, 1e1, 3, 2, 2, 1, + 1, 1, 100, 1, 60, 30, 'hv', tap_step_percent=1.5, + tap_step_degree=0, tap_pos=0, tap_neutral=0, tap_max=10, + tap_min=-10, name='tr2') - pp.create_load(net, b2, 1.5e1, 1, name='trafo1') - pp.create_load(net, b3, 3e1, 1.5, name='trafo2_mv') - pp.create_load(net, b4, 2, -0.15, name='trafo2_lv') + create_load(net, b2, 1.5e1, 1, name='trafo1') + create_load(net, b3, 3e1, 1.5, name='trafo2_mv') + create_load(net, b4, 2, -0.15, name='trafo2_lv') return net @@ -112,12 +114,12 @@ def test_const_control(simple_test_net): def test_switch_states_in_time_series(): - net = pp.create_empty_network() - pp.create_buses(net, 3, 0.4) - pp.create_ext_grid(net, 0) - pp.create_loads(net, [1, 2], 0.1) - pp.create_lines(net, [0, 0], [1, 2], 0.1, "NAYY 4x50 SE") - pp.create_switch(net, 0, 0, "l") + net = create_empty_network() + create_buses(net, 3, 0.4) + create_ext_grid(net, 0) + create_loads(net, [1, 2], 0.1) + create_lines(net, [0, 0], [1, 2], 0.1, "NAYY 4x50 SE") + create_switch(net, 0, 0, "l") n_timesteps = 5 time_steps = range(n_timesteps) @@ -137,9 +139,9 @@ def test_switch_states_in_time_series(): assert np.allclose( profiles['load1'].values * profiles["switch_pos"].values + 0.1 + \ - ow.output['res_line.pl_mw'].sum(axis=1).values, + ow.output['res_line.pl_mw'].sum(axis=1).values, ow.output['res_ext_grid.p_mw'][0].values - ) + ) def test_const_control_write_to_object_attribute(simple_test_net): @@ -161,7 +163,8 @@ def test_const_control_write_to_object_attribute(simple_test_net): assert np.all(profiles['load1'].values * 0.85 == ow.output['load.p_mw'][0].values) assert np.all(profiles['slack_v'].values == ow.output['res_bus.vm_pu'][0].values) - assert np.allclose(profiles['trafo_v'].values, ow.output['res_bus.vm_pu'][net.trafo.at[0, 'lv_bus']].values, atol=1e-3, rtol=0) + assert np.allclose(profiles['trafo_v'].values, ow.output['res_bus.vm_pu'][net.trafo.at[0, 'lv_bus']].values, + atol=1e-3, rtol=0) def test_false_alarm_trafos(simple_test_net): @@ -170,7 +173,7 @@ def test_false_alarm_trafos(simple_test_net): import io s = io.StringIO() h = logging.StreamHandler(stream=s) - pandapower.control.util.diagnostic.logger.addHandler(h) + diagnostic_logger.addHandler(h) ContinuousTapControl(net, 0, 1) ContinuousTapControl(net, 0, 1, trafotype='3W') @@ -184,7 +187,7 @@ def test_false_alarm_trafos(simple_test_net): raise UserWarning('Control diagnostic raises false alarm! Controllers are fine, ' 'but warning is raised: %s' % s.getvalue()) - pandapower.control.util.diagnostic.logger.removeHandler(h) + diagnostic_logger.removeHandler(h) del h del s @@ -333,11 +336,11 @@ def test_user_pf_options(simple_test_net): ConstControl(net, 'ext_grid', 'vm_pu', element_index=0, data_source=ds, profile_name='slack_v') - pp.set_user_pf_options(net, distributed_slack=True) + set_user_pf_options(net, distributed_slack=True) run_timeseries(net, time_steps, verbose=False) assert net._options["distributed_slack"] - pp.runpp(net, distributed_slack=False) + runpp(net, distributed_slack=False) run_timeseries(net, time_steps, verbose=False) assert net._options["distributed_slack"] @@ -354,9 +357,9 @@ def test_user_pf_options_init_run(simple_test_net): ConstControl(net, 'ext_grid', 'vm_pu', element_index=0, data_source=ds, profile_name='slack_v') - pp.runpp(net) + runpp(net) - pp.set_user_pf_options(net, distributed_slack=True) + set_user_pf_options(net, distributed_slack=True) run_timeseries(net, time_steps, verbose=False) assert net._options["distributed_slack"] @@ -372,12 +375,12 @@ def test_user_pf_options_recycle_manual(simple_test_net): ConstControl(net, 'ext_grid', 'vm_pu', element_index=0, data_source=ds, profile_name='slack_v') - pp.runpp(net) + runpp(net) - pp.set_user_pf_options(net, distributed_slack=True, recycle=True) + set_user_pf_options(net, distributed_slack=True, recycle=True) run_timeseries(net, time_steps, verbose=False) assert net._options["distributed_slack"] if __name__ == '__main__': - pytest.main([__file__, "-xs"]) \ No newline at end of file + pytest.main([__file__, "-xs"]) diff --git a/pandapower/test/timeseries/test_timeseries_recycle.py b/pandapower/test/timeseries/test_timeseries_recycle.py index bc0b18845..60f2d1ff9 100644 --- a/pandapower/test/timeseries/test_timeseries_recycle.py +++ b/pandapower/test/timeseries/test_timeseries_recycle.py @@ -4,8 +4,9 @@ import numpy as np import pytest -import pandapower as pp from pandapower.control.controller.trafo.ContinuousTapControl import ContinuousTapControl +from pandapower.create import create_gen, create_bus, create_line, create_transformer, create_transformer3w +from pandapower.run import runpp, rundcpp from pandapower.test.timeseries.test_output_writer import create_data_source, OutputWriter, ConstControl, \ run_timeseries, simple_test_net from pandapower.timeseries.data_sources.frame_data import DFData @@ -16,7 +17,7 @@ time_steps = range(0, n_timesteps) -@pytest.fixture(params=[pp.runpp, pp.rundcpp]) +@pytest.fixture(params=[runpp, rundcpp]) def run_function(request): return request.param @@ -41,12 +42,13 @@ def test_batch_output_reader(simple_test_net): recycle = dict(trafo=False, gen=False, bus_pq=True) only_v = True - pp.runpp(net, only_v_results=only_v, recycle=recycle) + runpp(net, only_v_results=only_v, recycle=recycle) run_timeseries(net, time_steps, recycle=recycle, only_v_results=only_v, verbose=False) vm, va = ow.output["ppc_bus.vm"], ow.output["ppc_bus.va"] - # ppc was removed (set to None) in cleanup() after the timeseries was over. now we have to remake the net._ppc by running the power flow again - pp.runpp(net, only_v_results=only_v, recycle=recycle) + # ppc was removed (set to None) in cleanup() after the timeseries was over. now we have to remake the net._ppc by + # running the power flow again + runpp(net, only_v_results=only_v, recycle=recycle) s, s_abs, i_abs = v_to_i_s(net, vm, va) del net, ow, c @@ -69,14 +71,14 @@ def test_batch_output_reader(simple_test_net): ow.log_variable('res_bus', 'vm_pu') ow.log_variable('res_bus', 'va_degree') - pp.runpp(net) + runpp(net) run_timeseries(net, time_steps, trafo_loading="current", verbose=False) vm_pu, va_degree = ow.output["res_bus.vm_pu"], ow.output["res_bus.va_degree"] i_from_ka_normal, i_to_ka_normal = ow.output["res_line.i_from_ka"], ow.output["res_line.i_to_ka"] i_hv_ka_normal, i_lv_ka_normal = ow.output["res_trafo.i_hv_ka"], ow.output["res_trafo.i_lv_ka"] i3_hv_ka, i3_lm_ka, i3_lv_ka = ow.output["res_trafo3w.i_hv_ka"], ow.output["res_trafo3w.i_mv_ka"], \ - ow.output["res_trafo3w.i_lv_ka"] + ow.output["res_trafo3w.i_lv_ka"] t3_loading_percent_normal = ow.output["res_trafo3w.loading_percent"] loading_percent_normal = ow.output["res_line.loading_percent"] t_loading_percent_normal = ow.output["res_trafo.loading_percent"] @@ -87,7 +89,7 @@ def test_batch_output_reader(simple_test_net): i_ka, i_hv_ka, i_lv_ka, s_mva, ld_trafo = get_batch_trafo_results(net, i_abs, s_abs) i_h, i_m, i_l, ld3_trafo = get_batch_trafo3w_results(net, i_abs, s_abs) - # v batch contains aux buses of trafo3w. we can only compare non aux bus voltages + # v batch contains aux buses of trafo3w. we can only compare non-aux bus voltages assert np.allclose(v_normal, v_batch[:, :v_normal.shape[1]]) # line loading assert np.allclose(i_from_ka_normal, i_from_ka) @@ -156,7 +158,7 @@ def test_const_pq(simple_test_net, run_function): def test_const_gen(simple_test_net, run_function): # allows to use recycle = {"gen"} and fast output read net = simple_test_net - pp.create_gen(net, 1, p_mw=2.) + create_gen(net, 1, p_mw=2.) profiles, _ = create_data_source(n_timesteps) profiles['gen'] = np.random.random(n_timesteps) * 2e1 ds = DFData(profiles) @@ -201,7 +203,7 @@ def test_const_ext_grid(simple_test_net, run_function): assert np.allclose(vm_pu.values[:, 0], profiles["ext_grid"]) -def test_trafo_tap(simple_test_net, run_function=pp.runpp): +def test_trafo_tap(simple_test_net, run_function=runpp): # allows to use recycle = {"trafo"} but not fast output read net = simple_test_net _, ds = create_data_source(n_timesteps) @@ -221,7 +223,7 @@ def test_trafo_tap(simple_test_net, run_function=pp.runpp): assert np.allclose(ll, ow.output["res_line.loading_percent"]) -def test_trafo_tap_dc(simple_test_net, run_function=pp.rundcpp): +def test_trafo_tap_dc(simple_test_net, run_function=rundcpp): # allows to use recycle = {"trafo"} but not fast output read net = simple_test_net _, ds = create_data_source(n_timesteps) @@ -243,7 +245,7 @@ def test_trafo_tap_dc(simple_test_net, run_function=pp.rundcpp): assert np.allclose(ll, ow.output["res_line.loading_percent"]) -def test_const_pq_gen_trafo_tap(simple_test_net, run_function=pp.runpp): +def test_const_pq_gen_trafo_tap(simple_test_net, run_function=runpp): # allows to use recycle = {"bus_pq", "gen", "trafo"} net = simple_test_net profiles, _ = create_data_source(n_timesteps) @@ -268,7 +270,7 @@ def test_const_pq_gen_trafo_tap(simple_test_net, run_function=pp.runpp): assert np.allclose(ll, ow.output["res_line.loading_percent"]) -def test_const_pq_gen_trafo_tap_dc(simple_test_net, run_function=pp.rundcpp): +def test_const_pq_gen_trafo_tap_dc(simple_test_net, run_function=rundcpp): # allows to use recycle = {"bus_pq", "gen", "trafo"} net = simple_test_net profiles, _ = create_data_source(n_timesteps) @@ -332,7 +334,8 @@ def test_const_pq_gen_trafo_tap_shifter(simple_test_net, run_function): ds = DFData(profiles) # 1load c1 = add_const(net, ds, recycle=None) - c2 = add_const(net, ds, recycle=None, profile_name="ext_grid", variable=_v_var(run_function, False), element_index=0, + c2 = add_const(net, ds, recycle=None, profile_name="ext_grid", variable=_v_var(run_function, False), + element_index=0, element="ext_grid") c3 = add_const(net, ds, recycle=None, profile_name="trafo_tap", variable="tap_pos", element_index=0, element="trafo") @@ -342,7 +345,8 @@ def test_const_pq_gen_trafo_tap_shifter(simple_test_net, run_function): # calculate the same results without recycle c = add_const(net, ds, recycle=False) - c2 = add_const(net, ds, recycle=False, profile_name="ext_grid", variable=_v_var(run_function, False), element_index=0, + c2 = add_const(net, ds, recycle=False, profile_name="ext_grid", variable=_v_var(run_function, False), + element_index=0, element="ext_grid") c3 = add_const(net, ds, recycle=None, profile_name="trafo_tap", variable="tap_pos", element_index=0, element="trafo") @@ -355,10 +359,10 @@ def test_const_pq_out_of_service(simple_test_net, run_function): # allows to use recycle = {"bus_pq"} and fast output read net = simple_test_net for i in range(3): - b = pp.create_bus(net, 20., in_service=False) - pp.create_line(net, 2, b, std_type="149-AL1/24-ST1A 20.0", length_km=1., in_service=False) - pp.create_transformer(net, 2, b, std_type="25 MVA 110/20 kV", in_service=False) - pp.create_transformer3w(net, 1, 2, b, std_type="63/25/38 MVA 110/20/10 kV", in_service=False) + b = create_bus(net, 20., in_service=False) + create_line(net, 2, b, std_type="149-AL1/24-ST1A 20.0", length_km=1., in_service=False) + create_transformer(net, 2, b, std_type="25 MVA 110/20 kV", in_service=False) + create_transformer3w(net, 1, 2, b, std_type="63/25/38 MVA 110/20/10 kV", in_service=False) _, ds = create_data_source(n_timesteps) # 1load c = add_const(net, ds, recycle=None) diff --git a/pandapower/test/toolbox/test_comparison.py b/pandapower/test/toolbox/test_comparison.py index d5f605fec..811e2ed25 100644 --- a/pandapower/test/toolbox/test_comparison.py +++ b/pandapower/test/toolbox/test_comparison.py @@ -4,67 +4,68 @@ # and Energy System Technology (IEE), Kassel. All rights reserved. import copy + import pytest -import pandapower as pp -import pandapower.toolbox -import pandapower.toolbox.comparison as tbc -import pandapower.networks as nw +from pandapower.control.controller.trafo.ContinuousTapControl import ContinuousTapControl +from pandapower.create import create_bus +from pandapower.networks.cigre_networks import create_cigre_network_lv +from pandapower.toolbox.comparison import nets_equal, logger as tbc_logger def test_nets_equal(): - tbc.logger.setLevel(40) - original = nw.create_cigre_network_lv() + tbc_logger.setLevel(40) + original = create_cigre_network_lv() net = copy.deepcopy(original) # should be equal - assert pandapower.toolbox.nets_equal(original, net) - assert pandapower.toolbox.nets_equal(net, original) + assert nets_equal(original, net) + assert nets_equal(net, original) # detecting additional element - pp.create_bus(net, vn_kv=.4) - assert not pandapower.toolbox.nets_equal(original, net) - assert not pandapower.toolbox.nets_equal(net, original) + create_bus(net, vn_kv=.4) + assert not nets_equal(original, net) + assert not nets_equal(net, original) net = copy.deepcopy(original) # detecting removed element net["bus"] = net["bus"].drop(net.bus.index[0]) - assert not pandapower.toolbox.nets_equal(original, net) - assert not pandapower.toolbox.nets_equal(net, original) + assert not nets_equal(original, net) + assert not nets_equal(net, original) net = copy.deepcopy(original) # detecting alternated value net["load"].loc[net["load"].index[0], "p_mw"] += 0.1 - assert not pandapower.toolbox.nets_equal(original, net) - assert not pandapower.toolbox.nets_equal(net, original) + assert not nets_equal(original, net) + assert not nets_equal(net, original) net = copy.deepcopy(original) # detecting added column net["load"]["new_col"] = 0.1 - assert not pandapower.toolbox.nets_equal(original, net) - assert not pandapower.toolbox.nets_equal(net, original) + assert not nets_equal(original, net) + assert not nets_equal(net, original) net = copy.deepcopy(original) # not detecting alternated value if difference is beyond tolerance net["load"].loc[net["load"].index[0], "p_mw"] += 0.0001 - assert pandapower.toolbox.nets_equal(original, net, atol=0.1) - assert pandapower.toolbox.nets_equal(net, original, atol=0.1) + assert nets_equal(original, net, atol=0.1) + assert nets_equal(net, original, atol=0.1) # check controllers original.trafo.tap_side = original.trafo.tap_side.fillna("hv") net1 = copy.deepcopy(original) net2 = copy.deepcopy(original) - pp.control.ContinuousTapControl(net1, 0, 1.0) - pp.control.ContinuousTapControl(net2, 0, 1.0) + ContinuousTapControl(net1, 0, 1.0) + ContinuousTapControl(net2, 0, 1.0) c1 = net1.controller.at[0, "object"] c2 = net2.controller.at[0, "object"] assert c1 == c2 assert c1 is not c2 - assert pandapower.toolbox.nets_equal(net1, net2) + assert nets_equal(net1, net2) c1.vm_set_pu = 1.01 assert c1 != c2 - assert pandapower.toolbox.nets_equal(net1, net2, exclude_elms=["controller"]) - assert not pandapower.toolbox.nets_equal(net1, net2) + assert nets_equal(net1, net2, exclude_elms=["controller"]) + assert not nets_equal(net1, net2) if __name__ == '__main__': diff --git a/pandapower/test/toolbox/test_data_modification.py b/pandapower/test/toolbox/test_data_modification.py index e5fcc8965..cd1bf2037 100644 --- a/pandapower/test/toolbox/test_data_modification.py +++ b/pandapower/test/toolbox/test_data_modification.py @@ -4,48 +4,57 @@ # and Energy System Technology (IEE), Kassel. All rights reserved. import copy + import numpy as np import pandas as pd import pytest -import pandapower as pp -import pandapower.networks as nw -import pandapower.toolbox +from pandapower.create import create_measurement, create_empty_network, create_bus, create_load, create_sgen, \ + create_shunt, create_ward +from pandapower.networks.cigre_networks import create_cigre_network_mv +from pandapower.networks.create_examples import example_simple, example_multivoltage +from pandapower.run import runpp +from pandapower.test.helper_functions import assert_net_equal +from pandapower.toolbox.comparison import compare_arrays +from pandapower.toolbox.data_modification import reindex_elements, reindex_buses, add_column_from_node_to_elements, \ + add_column_from_element_to_elements, create_continuous_bus_index, create_continuous_elements_index, \ + set_scaling_by_type +from pandapower.toolbox.element_selection import pp_elements def test_add_column_from_node_to_elements(): - net = nw.create_cigre_network_mv("pv_wind") + net = create_cigre_network_mv("pv_wind") net.bus["subnet"] = ["subnet_%i" % i for i in range(net.bus.shape[0])] net.sgen["subnet"] = "already_given" net.switch["subnet"] = None net_orig = copy.deepcopy(net) branch_bus = ["from_bus", "lv_bus"] - pp.add_column_from_node_to_elements(net, "subnet", False, branch_bus=branch_bus) + add_column_from_node_to_elements(net, "subnet", False, branch_bus=branch_bus) def check_subnet_correctness(ntw, elements, branch_bus_el): for elm in elements: if "bus" in ntw[elm].columns: - assert all(pandapower.toolbox.compare_arrays(ntw[elm]["subnet"].values, - np.array(["subnet_%i" % bus for bus in ntw[elm].bus]))) + assert all(compare_arrays(ntw[elm]["subnet"].values, + np.array(["subnet_%i" % bus for bus in ntw[elm].bus]))) elif branch_bus_el[0] in ntw[elm].columns: - assert all(pandapower.toolbox.compare_arrays(ntw[elm]["subnet"].values, np.array([ + assert all(compare_arrays(ntw[elm]["subnet"].values, np.array([ "subnet_%i" % bus for bus in ntw[elm][branch_bus_el[0]]]))) elif branch_bus_el[1] in ntw[elm].columns: - assert all(pandapower.toolbox.compare_arrays(ntw[elm]["subnet"].values, np.array([ + assert all(compare_arrays(ntw[elm]["subnet"].values, np.array([ "subnet_%i" % bus for bus in ntw[elm][branch_bus_el[1]]]))) - check_subnet_correctness(net, pandapower.toolbox.pp_elements(bus=False) - {"sgen"}, branch_bus) + check_subnet_correctness(net, pp_elements(bus=False) - {"sgen"}, branch_bus) - pp.add_column_from_node_to_elements(net_orig, "subnet", True, branch_bus=branch_bus) - check_subnet_correctness(net_orig, pandapower.toolbox.pp_elements(bus=False), branch_bus) + add_column_from_node_to_elements(net_orig, "subnet", True, branch_bus=branch_bus) + check_subnet_correctness(net_orig, pp_elements(bus=False), branch_bus) def test_add_column_from_element_to_elements(): - net = nw.create_cigre_network_mv() - pp.create_measurement(net, "i", "trafo", 5, 3, 0, side="hv") - pp.create_measurement(net, "i", "line", 5, 3, 0, side="to") - pp.create_measurement(net, "p", "bus", 5, 3, 2) + net = create_cigre_network_mv() + create_measurement(net, "i", "trafo", 5, 3, 0, side="hv") + create_measurement(net, "i", "line", 5, 3, 0, side="to") + create_measurement(net, "p", "bus", 5, 3, 2) assert net.measurement.name.isnull().all() assert ~net.switch.name.isnull().all() orig_switch_names = copy.deepcopy(net.switch.name.values) @@ -55,25 +64,25 @@ def test_add_column_from_element_to_elements(): net.line.name.loc[net.switch.element.loc[net.switch.et == "l"]].values, net.trafo.name.loc[net.switch.element.loc[net.switch.et == "t"]].values) - pp.add_column_from_element_to_elements(net, "name", False) - assert all(pandapower.toolbox.compare_arrays(net.measurement.name.values, expected_measurement_names)) - assert all(pandapower.toolbox.compare_arrays(net.switch.name.values, orig_switch_names)) + add_column_from_element_to_elements(net, "name", False) + assert all(compare_arrays(net.measurement.name.values, expected_measurement_names)) + assert all(compare_arrays(net.switch.name.values, orig_switch_names)) del net.measurement["name"] - pp.add_column_from_element_to_elements(net, "name", True) - assert all(pandapower.toolbox.compare_arrays(net.measurement.name.values, expected_measurement_names)) - assert all(pandapower.toolbox.compare_arrays(net.switch.name.values, expected_switch_names)) + add_column_from_element_to_elements(net, "name", True) + assert all(compare_arrays(net.measurement.name.values, expected_measurement_names)) + assert all(compare_arrays(net.switch.name.values, expected_switch_names)) def test_reindex_buses(): - net_orig = nw.example_simple() - net = nw.example_simple() + net_orig = example_simple() + net = example_simple() to_add = 5 new_bus_idxs = np.array(list(net.bus.index)) + to_add bus_lookup = dict(zip(net["bus"].index.values, new_bus_idxs)) # a more complexe bus_lookup of course should also work, but this one is easy to check - pp.reindex_buses(net, bus_lookup) + reindex_buses(net, bus_lookup) for elm in net.keys(): if isinstance(net[elm], pd.DataFrame) and net[elm].shape[0]: @@ -88,30 +97,30 @@ def test_reindex_buses(): def test_continuos_bus_numbering(): - net = pp.create_empty_network() + net = create_empty_network() - bus0 = pp.create_bus(net, 0.4, index=12) - pp.create_load(net, bus0, p_mw=0.) - pp.create_load(net, bus0, p_mw=0.) - pp.create_load(net, bus0, p_mw=0.) - pp.create_load(net, bus0, p_mw=0.) + bus0 = create_bus(net, 0.4, index=12) + create_load(net, bus0, p_mw=0.) + create_load(net, bus0, p_mw=0.) + create_load(net, bus0, p_mw=0.) + create_load(net, bus0, p_mw=0.) - bus0 = pp.create_bus(net, 0.4, index=42) - pp.create_sgen(net, bus0, p_mw=0.) - pp.create_sgen(net, bus0, p_mw=0.) - pp.create_sgen(net, bus0, p_mw=0.) + bus0 = create_bus(net, 0.4, index=42) + create_sgen(net, bus0, p_mw=0.) + create_sgen(net, bus0, p_mw=0.) + create_sgen(net, bus0, p_mw=0.) - bus0 = pp.create_bus(net, 0.4, index=543) - pp.create_shunt(net, bus0, 2, 1) - pp.create_shunt(net, bus0, 2, 1) - pp.create_shunt(net, bus0, 2, 1) + bus0 = create_bus(net, 0.4, index=543) + create_shunt(net, bus0, 2, 1) + create_shunt(net, bus0, 2, 1) + create_shunt(net, bus0, 2, 1) - bus0 = pp.create_bus(net, 0.4, index=5675) - pp.create_ward(net, bus0, 2, 1, 1, 2) - pp.create_ward(net, bus0, 2, 1, 1, 2) - pp.create_ward(net, bus0, 2, 1, 1, 2) + bus0 = create_bus(net, 0.4, index=5675) + create_ward(net, bus0, 2, 1, 1, 2) + create_ward(net, bus0, 2, 1, 1, 2) + create_ward(net, bus0, 2, 1, 1, 2) - pp.create_continuous_bus_index(net) + create_continuous_bus_index(net) buses = net.bus.index assert all(buses[i] <= buses[i + 1] for i in range(len(buses) - 1)) # is ordered @@ -138,39 +147,39 @@ def test_continuos_bus_numbering(): def test_reindex_elements(): - net = nw.example_simple() + net = example_simple() new_sw_idx = [569, 763, 502, 258, 169, 259, 348, 522] - pp.reindex_elements(net, "switch", new_sw_idx) + reindex_elements(net, "switch", new_sw_idx) assert np.allclose(net.switch.index.values, new_sw_idx) net2 = copy.deepcopy(net) previous_idx = new_sw_idx[:3] new_sw_idx = [2, 3, 4] - pp.reindex_elements(net, "switch", new_sw_idx, previous_idx) + reindex_elements(net, "switch", new_sw_idx, previous_idx) assert np.allclose(net.switch.index.values[:3], new_sw_idx) # using lookup - pp.reindex_elements(net2, "switch", lookup=dict(zip(previous_idx, new_sw_idx))) - pp.test.assert_net_equal(net, net2) + reindex_elements(net2, "switch", lookup=dict(zip(previous_idx, new_sw_idx))) + assert_net_equal(net, net2) - pp.reindex_elements(net, "line", [77, 22], [2, 0]) + reindex_elements(net, "line", [77, 22], [2, 0]) assert np.allclose(net.line.index.values, [22, 1, 77, 3]) assert np.allclose(net.switch.element.iloc[[4, 5]], [77, 77]) old_idx = copy.deepcopy(net.bus.index.values) - pp.reindex_elements(net, "bus", old_idx + 2) + reindex_elements(net, "bus", old_idx + 2) assert np.allclose(net.bus.index.values, old_idx + 2) - pp.reindex_elements(net, "bus", [400, 600], [4, 6]) + reindex_elements(net, "bus", [400, 600], [4, 6]) assert 400 in net.bus.index assert 600 in net.bus.index def test_continuous_element_numbering(): from pandapower.estimation.util import add_virtual_meas_from_loadflow - net = nw.example_multivoltage() + net = example_multivoltage() # Add noises to index with some large number net.line = net.line.rename(index={4: 280}) @@ -181,11 +190,11 @@ def test_continuous_element_numbering(): net.switch.loc[(net.switch.et == "l") & (net.switch.element == 4), "element"] = 280 net.switch.loc[(net.switch.et == "t") & (net.switch.element == 0), "element"] = 300 net.switch.loc[(net.switch.et == "t") & (net.switch.element == 1), "element"] = 400 - pp.runpp(net) + runpp(net) add_virtual_meas_from_loadflow(net) assert net.measurement["element"].max() == 540 - pp.create_continuous_elements_index(net) + create_continuous_elements_index(net) assert net.line.index.max() == net.line.shape[0] - 1 assert net.trafo.index.max() == net.trafo.shape[0] - 1 assert net.trafo3w.index.max() == net.trafo3w.shape[0] - 1 @@ -193,18 +202,18 @@ def test_continuous_element_numbering(): def test_scaling_by_type(): - net = pp.create_empty_network() + net = create_empty_network() - bus0 = pp.create_bus(net, 0.4) - pp.create_load(net, bus0, p_mw=0., type="Household") - pp.create_sgen(net, bus0, p_mw=0., type="PV") + bus0 = create_bus(net, 0.4) + create_load(net, bus0, p_mw=0., type="Household") + create_sgen(net, bus0, p_mw=0., type="PV") - pp.set_scaling_by_type(net, {"Household": 42., "PV": 12}) + set_scaling_by_type(net, {"Household": 42., "PV": 12}) assert net.load.at[0, "scaling"] == 42 assert net.sgen.at[0, "scaling"] == 12 - pp.set_scaling_by_type(net, {"Household": 0, "PV": 0}) + set_scaling_by_type(net, {"Household": 0, "PV": 0}) assert net.load.at[0, "scaling"] == 0 assert net.sgen.at[0, "scaling"] == 0 diff --git a/pandapower/test/toolbox/test_element_selection.py b/pandapower/test/toolbox/test_element_selection.py index 238d88b74..08357cffa 100644 --- a/pandapower/test/toolbox/test_element_selection.py +++ b/pandapower/test/toolbox/test_element_selection.py @@ -2,19 +2,24 @@ # Copyright (c) 2016-2024 by University of Kassel and Fraunhofer Institute for Energy Economics # and Energy System Technology (IEE), Kassel. All rights reserved. + import pandas as pd import pytest -import pandapower as pp -import pandapower.toolbox -from pandapower import networks as nw +from pandapower.create import create_empty_network, create_bus, create_transformer3w, create_transformer, create_line, \ + create_switch, create_buses, create_gens, create_sgens, create_measurement, create_poly_cost +from pandapower.networks.create_examples import example_multivoltage +from pandapower.networks.power_system_test_cases import case9 +from pandapower.toolbox.element_selection import get_element_indices, next_bus, get_connected_elements, \ + get_connected_buses, false_elm_links_loop, get_connected_buses_at_switches, pp_elements, element_bus_tuples, \ + count_elements, branch_element_bus_dict def test_get_element_indices(): - net = nw.example_multivoltage() - idx1 = pp.get_element_indices(net, "bus", ["Bus HV%i" % i for i in range(1, 4)]) - idx2 = pp.get_element_indices(net, ["bus", "line"], "HV", exact_match=False) - idx3 = pp.get_element_indices(net, ["bus", "line"], ["Bus HV3", "MV Line6"]) + net = example_multivoltage() + idx1 = get_element_indices(net, "bus", ["Bus HV%i" % i for i in range(1, 4)]) + idx2 = get_element_indices(net, ["bus", "line"], "HV", exact_match=False) + idx3 = get_element_indices(net, ["bus", "line"], ["Bus HV3", "MV Line6"]) assert [32, 33, 34] == idx1 assert ([32, 33, 34, 35] == idx2[0]).all() assert ([0, 1, 2, 3, 4, 5] == idx2[1]).all() @@ -22,151 +27,153 @@ def test_get_element_indices(): def test_next_bus(): - net = pp.create_empty_network() - - bus0 = pp.create_bus(net, vn_kv=110) - bus1 = pp.create_bus(net, vn_kv=20) - bus2 = pp.create_bus(net, vn_kv=10) - bus3 = pp.create_bus(net, vn_kv=0.4) - bus4 = pp.create_bus(net, vn_kv=0.4) - bus5 = pp.create_bus(net, vn_kv=20) - - trafo0 = pp.create_transformer3w(net, hv_bus=bus0, mv_bus=bus1, lv_bus=bus2, name='trafo0', - std_type='63/25/38 MVA 110/20/10 kV') - trafo1 = pp.create_transformer(net, hv_bus=bus2, lv_bus=bus3, std_type='0.4 MVA 10/0.4 kV') - - line1 = pp.create_line(net, from_bus=bus3, to_bus=bus4, length_km=20.1, - std_type='24-AL1/4-ST1A 0.4', name='line1') - - # switch0=pp.create_switch(net, bus = bus0, element = trafo0, et = 't3') #~~~~~ not implementable now - switch1 = pp.create_switch(net, bus=bus1, element=bus5, et='b') - switch2 = pp.create_switch(net, bus=bus2, element=trafo1, et='t') - switch3 = pp.create_switch(net, bus=bus3, element=line1, et='l') - - # assert pp.next_bus(net,bus0,trafo0,et='trafo3w')==bus1 # not implemented in existing toolbox - # assert pp.next_bus(net,bus0,trafo0,et='trafo3w',choice_for_trafo3w='lv')==bus2 # not implemented in existing toolbox - assert pp.next_bus(net, bus1, switch1, et='switch') == bus5 # Switch with bus2bus connection - # assert not pp.next_bus(net,bus2,switch2,et='switch')==bus3 # Switch with bus2trafo connection:- gives trasformer id instead of bus id - assert pp.next_bus(net, bus2, trafo1, et='trafo') == bus3 - # assert pp.next_bus(net,bus3,switch3,et='switch') ==bus4 # Switch with bus2line connection :- gives line id instead of bus id - assert pp.next_bus(net, bus3, line1, et='line') == bus4 + net = create_empty_network() + + bus0 = create_bus(net, vn_kv=110) + bus1 = create_bus(net, vn_kv=20) + bus2 = create_bus(net, vn_kv=10) + bus3 = create_bus(net, vn_kv=0.4) + bus4 = create_bus(net, vn_kv=0.4) + bus5 = create_bus(net, vn_kv=20) + + trafo0 = create_transformer3w(net, hv_bus=bus0, mv_bus=bus1, lv_bus=bus2, name='trafo0', + std_type='63/25/38 MVA 110/20/10 kV') + trafo1 = create_transformer(net, hv_bus=bus2, lv_bus=bus3, std_type='0.4 MVA 10/0.4 kV') + + line1 = create_line(net, from_bus=bus3, to_bus=bus4, length_km=20.1, + std_type='24-AL1/4-ST1A 0.4', name='line1') + + # switch0=create_switch(net, bus = bus0, element = trafo0, et = 't3') #~~~~~ not implementable now + switch1 = create_switch(net, bus=bus1, element=bus5, et='b') + switch2 = create_switch(net, bus=bus2, element=trafo1, et='t') + switch3 = create_switch(net, bus=bus3, element=line1, et='l') + + # assert next_bus(net,bus0,trafo0,et='trafo3w')==bus1 # not implemented in existing toolbox + # assert next_bus(net,bus0,trafo0,et='trafo3w',choice_for_trafo3w='lv')==bus2 # not implemented in existing toolbox + assert next_bus(net, bus1, switch1, et='switch') == bus5 # Switch with bus2bus connection + # assert not next_bus(net,bus2,switch2,et='switch')==bus3 + # Switch with bus2trafo connection:- gives trasformer id instead of bus id + assert next_bus(net, bus2, trafo1, et='trafo') == bus3 + # assert next_bus(net,bus3,switch3,et='switch') ==bus4 + # Switch with bus2line connection :- gives line id instead of bus id + assert next_bus(net, bus3, line1, et='line') == bus4 def test_get_connected_lines_at_bus(): - net = pp.create_empty_network() + net = create_empty_network() - bus0 = pp.create_bus(net, 0.4) - bus1 = pp.create_bus(net, 0.4) + bus0 = create_bus(net, 0.4) + bus1 = create_bus(net, 0.4) - line0 = pp.create_line(net, bus0, bus1, length_km=1., std_type="NAYY 4x50 SE") - line1 = pp.create_line(net, bus0, bus1, length_km=1., std_type="NAYY 4x50 SE") - line2 = pp.create_line(net, bus0, bus1, in_service=False, length_km=1., std_type="NAYY 4x50 SE") - line3 = pp.create_line(net, bus0, bus1, length_km=1., std_type="NAYY 4x50 SE") + line0 = create_line(net, bus0, bus1, length_km=1., std_type="NAYY 4x50 SE") + line1 = create_line(net, bus0, bus1, length_km=1., std_type="NAYY 4x50 SE") + line2 = create_line(net, bus0, bus1, in_service=False, length_km=1., std_type="NAYY 4x50 SE") + line3 = create_line(net, bus0, bus1, length_km=1., std_type="NAYY 4x50 SE") - pp.create_switch(net, bus0, line0, "l") - pp.create_switch(net, bus0, line1, "l", closed=False) - pp.create_switch(net, bus0, line2, "l") + create_switch(net, bus0, line0, "l") + create_switch(net, bus0, line1, "l", closed=False) + create_switch(net, bus0, line2, "l") - lines = pp.get_connected_elements(net, "line", bus0, respect_switches=False, - respect_in_service=False) + lines = get_connected_elements(net, "line", bus0, respect_switches=False, + respect_in_service=False) assert set(lines) == {line0, line1, line2, line3} - lines = pp.get_connected_elements(net, "line", bus0, respect_switches=True, - respect_in_service=False) + lines = get_connected_elements(net, "line", bus0, respect_switches=True, + respect_in_service=False) assert set(lines) == {line0, line2, line3} - lines = pp.get_connected_elements(net, "line", bus0, respect_switches=True, - respect_in_service=True) + lines = get_connected_elements(net, "line", bus0, respect_switches=True, + respect_in_service=True) assert set(lines) == {line0, line3} - lines = pp.get_connected_elements(net, "line", bus0, respect_switches=False, - respect_in_service=True) + lines = get_connected_elements(net, "line", bus0, respect_switches=False, + respect_in_service=True) assert set(lines) == {line0, line1, line3} def test_get_connected_buses(): - net = pp.create_empty_network() - - bus0 = pp.create_bus(net, vn_kv=110) - bus1 = pp.create_bus(net, vn_kv=20) - bus2 = pp.create_bus(net, vn_kv=10) - bus3 = pp.create_bus(net, vn_kv=0.4) - bus4 = pp.create_bus(net, vn_kv=0.4) - bus5 = pp.create_bus(net, vn_kv=20) - - trafo0 = pp.create_transformer3w(net, hv_bus=bus0, mv_bus=bus1, lv_bus=bus2, - std_type='63/25/38 MVA 110/20/10 kV') - trafo1 = pp.create_transformer(net, hv_bus=bus2, lv_bus=bus3, std_type='0.4 MVA 10/0.4 kV') - line1 = pp.create_line(net, from_bus=bus3, to_bus=bus4, length_km=20.1, - std_type='24-AL1/4-ST1A 0.4') - - switch0a = pp.create_switch(net, bus=bus0, element=trafo0, et='t3') - switch0b = pp.create_switch(net, bus=bus2, element=trafo0, et='t3') - switch1 = pp.create_switch(net, bus=bus1, element=bus5, et='b') - switch2 = pp.create_switch(net, bus=bus2, element=trafo1, et='t') - switch3 = pp.create_switch(net, bus=bus3, element=line1, et='l') - - assert list(pp.get_connected_buses(net, [bus0])) == [bus1, bus2] - assert list(pp.get_connected_buses(net, [bus1])) == [bus0, bus2, bus5] - assert list(pp.get_connected_buses(net, [bus2])) == [bus0, bus1, bus3] - assert list(pp.get_connected_buses(net, [bus3])) == [bus2, bus4] - assert list(pp.get_connected_buses(net, [bus4])) == [bus3] - assert list(pp.get_connected_buses(net, [bus5])) == [bus1] - assert list(pp.get_connected_buses(net, [bus0, bus1])) == [bus2, bus5] - assert list(pp.get_connected_buses(net, [bus2, bus3])) == [bus0, bus1, bus4] + net = create_empty_network() + + bus0 = create_bus(net, vn_kv=110) + bus1 = create_bus(net, vn_kv=20) + bus2 = create_bus(net, vn_kv=10) + bus3 = create_bus(net, vn_kv=0.4) + bus4 = create_bus(net, vn_kv=0.4) + bus5 = create_bus(net, vn_kv=20) + + trafo0 = create_transformer3w(net, hv_bus=bus0, mv_bus=bus1, lv_bus=bus2, + std_type='63/25/38 MVA 110/20/10 kV') + trafo1 = create_transformer(net, hv_bus=bus2, lv_bus=bus3, std_type='0.4 MVA 10/0.4 kV') + line1 = create_line(net, from_bus=bus3, to_bus=bus4, length_km=20.1, + std_type='24-AL1/4-ST1A 0.4') + + switch0a = create_switch(net, bus=bus0, element=trafo0, et='t3') + switch0b = create_switch(net, bus=bus2, element=trafo0, et='t3') + switch1 = create_switch(net, bus=bus1, element=bus5, et='b') + switch2 = create_switch(net, bus=bus2, element=trafo1, et='t') + switch3 = create_switch(net, bus=bus3, element=line1, et='l') + + assert list(get_connected_buses(net, [bus0])) == [bus1, bus2] + assert list(get_connected_buses(net, [bus1])) == [bus0, bus2, bus5] + assert list(get_connected_buses(net, [bus2])) == [bus0, bus1, bus3] + assert list(get_connected_buses(net, [bus3])) == [bus2, bus4] + assert list(get_connected_buses(net, [bus4])) == [bus3] + assert list(get_connected_buses(net, [bus5])) == [bus1] + assert list(get_connected_buses(net, [bus0, bus1])) == [bus2, bus5] + assert list(get_connected_buses(net, [bus2, bus3])) == [bus0, bus1, bus4] net.switch.loc[[switch0b, switch1, switch2, switch3], 'closed'] = False - assert list(pp.get_connected_buses(net, [bus0])) == [bus1] - assert list(pp.get_connected_buses(net, [bus1])) == [bus0] - assert list(pp.get_connected_buses(net, [bus3])) == [] - assert list(pp.get_connected_buses(net, [bus4])) == [] + assert list(get_connected_buses(net, [bus0])) == [bus1] + assert list(get_connected_buses(net, [bus1])) == [bus0] + assert list(get_connected_buses(net, [bus3])) == [] + assert list(get_connected_buses(net, [bus4])) == [] def test_get_connected_buses_at_switches(): - net = pp.networks.example_multivoltage() + net = example_multivoltage() switches = [net.switch.index[net.switch.et == et][0] for et in "blt"] expected = set(net.switch.loc[switches[0], ["bus", "element"]]) expected |= set(net.switch.loc[switches, "bus"]) expected |= set(net.line.loc[net.switch.at[switches[1], "element"], ["from_bus", "to_bus"]]) expected |= set(net.trafo.loc[net.switch.at[switches[1], "element"], ["hv_bus", "lv_bus"]]) - assert not bool(len(expected - pp.toolbox.get_connected_buses_at_switches(net, switches))) + assert not bool(len(expected - get_connected_buses_at_switches(net, switches))) def test_get_false_links(): - net = pp.create_empty_network() - pp.create_buses(net, 6, 10, index=[0, 1, 3, 4, 6, 7]) + net = create_empty_network() + create_buses(net, 6, 10, index=[0, 1, 3, 4, 6, 7]) # --- gens - pp.create_gens(net, [0, 1, 3], 5) + create_gens(net, [0, 1, 3], 5) # manipulate to not existing net.gen.at[1, "bus"] = 999 # --- sgens - pp.create_sgens(net, [0, 1, 3], 5) + create_sgens(net, [0, 1, 3], 5) # --- lines for fbus, tbus in zip([0, 1, 4, 6, 7], [1, 4, 6, 7, 3]): - pp.create_line(net, fbus, tbus, 2., "NA2XS2Y 1x185 RM/25 6/10 kV") + create_line(net, fbus, tbus, 2., "NA2XS2Y 1x185 RM/25 6/10 kV") # manipulate to not existing net.line.at[1, "from_bus"] = 2 net.line.at[4, "to_bus"] = 999 # --- measurements - pp.create_measurement(net, "v", "bus", 1.01, 5, 1) - pp.create_measurement(net, "i", "line", 0.41, 1, 0, side="from") - pp.create_measurement(net, "i", "line", 0.41, 1, 2, side="from") - pp.create_measurement(net, "v", "bus", 1.01, 5, 6) - pp.create_measurement(net, "i", "line", 0.41, 1, 1, side="from") + create_measurement(net, "v", "bus", 1.01, 5, 1) + create_measurement(net, "i", "line", 0.41, 1, 0, side="from") + create_measurement(net, "i", "line", 0.41, 1, 2, side="from") + create_measurement(net, "v", "bus", 1.01, 5, 6) + create_measurement(net, "i", "line", 0.41, 1, 1, side="from") # manipulate to not existing net.measurement.at[1, "element"] = 999 net.measurement.at[3, "element"] = 999 # --- poly_cost - pp.create_poly_cost(net, 0, "gen", 5) - pp.create_poly_cost(net, 1, "gen", 5) - pp.create_poly_cost(net, 0, "sgen", 5) - pp.create_poly_cost(net, 1, "sgen", 5) + create_poly_cost(net, 0, "gen", 5) + create_poly_cost(net, 1, "gen", 5) + create_poly_cost(net, 0, "sgen", 5) + create_poly_cost(net, 1, "sgen", 5) # manipulate to not existing net.poly_cost.at[1, "element"] = 999 net.poly_cost.at[2, "element"] = 999 @@ -175,12 +182,12 @@ def test_get_false_links(): "line": {1, 4}, "measurement": {1, 3}, "poly_cost": {1, 2}} - determined = pp.false_elm_links_loop(net) + determined = false_elm_links_loop(net) assert {elm: set(idx) for elm, idx in determined.items()} == expected def test_element_bus_tuples(): - ebts = pandapower.toolbox.element_bus_tuples() + ebts = element_bus_tuples() assert isinstance(ebts, list) assert len(ebts) >= 20 item = next(iter(ebts)) @@ -189,45 +196,45 @@ def test_element_bus_tuples(): assert len({"line", "gen"} & {elm for (elm, buses) in ebts}) == 2 assert {buses for (elm, buses) in ebts} == {"bus", "to_bus", "from_bus", 'hv_bus', 'mv_bus', 'lv_bus'} - assert len(pandapower.toolbox.element_bus_tuples(bus_elements=False, res_elements=True)) > \ + assert len(element_bus_tuples(bus_elements=False, res_elements=True)) > \ 1.5 * len( - pandapower.toolbox.element_bus_tuples(bus_elements=False, res_elements=False)) > 0 + element_bus_tuples(bus_elements=False, res_elements=False)) > 0 def test_pp_elements(): - elms = pandapower.toolbox.pp_elements() + elms = pp_elements() assert isinstance(elms, set) assert "bus" in elms assert "measurement" in elms assert "sgen" in elms - assert len(pandapower.toolbox.pp_elements(bus=False, other_elements=False, bus_elements=True, - branch_elements=False)) == \ - len(pandapower.toolbox.element_bus_tuples(bus_elements=True, branch_elements=False)) + assert len(pp_elements(bus=False, other_elements=False, bus_elements=True, + branch_elements=False)) == \ + len(element_bus_tuples(bus_elements=True, branch_elements=False)) def test_branch_element_bus_dict(): - bebd = pandapower.toolbox.branch_element_bus_dict() + bebd = branch_element_bus_dict() assert isinstance(bebd, dict) assert len(bebd) >= 5 assert bebd["trafo"] == ["hv_bus", "lv_bus"] - bebd = pandapower.toolbox.branch_element_bus_dict(include_switch=True) + bebd = branch_element_bus_dict(include_switch=True) assert "bus" in bebd["switch"] def test_count_elements(): case9_counts = {"bus": 9, "line": 9, "ext_grid": 1, "gen": 2, "load": 3} - net = nw.case9() - received = pandapower.toolbox.count_elements(net) + net = case9() + received = count_elements(net) assert isinstance(received, pd.Series) assert received.to_dict() == case9_counts - assert pandapower.toolbox.count_elements(net, bus=False).to_dict() == { + assert count_elements(net, bus=False).to_dict() == { et: num for et, num in case9_counts.items() if et not in ["bus"]} - assert pandapower.toolbox.count_elements(net, bus=False, branch_elements=False).to_dict() == { + assert count_elements(net, bus=False, branch_elements=False).to_dict() == { et: num for et, num in case9_counts.items() if et not in ["bus", "line"]} - received = pandapower.toolbox.count_elements(net, return_empties=True) - assert len(received.index) == len(pandapower.toolbox.pp_elements()) - assert set(received.index) == pandapower.toolbox.pp_elements() + received = count_elements(net, return_empties=True) + assert len(received.index) == len(pp_elements()) + assert set(received.index) == pp_elements() if __name__ == '__main__': - pytest.main([__file__, "-xs"]) \ No newline at end of file + pytest.main([__file__, "-xs"]) diff --git a/pandapower/test/toolbox/test_grid_modification.py b/pandapower/test/toolbox/test_grid_modification.py index bb19022db..06236653b 100644 --- a/pandapower/test/toolbox/test_grid_modification.py +++ b/pandapower/test/toolbox/test_grid_modification.py @@ -3,38 +3,48 @@ # Copyright (c) 2016-2024 by University of Kassel and Fraunhofer Institute for Energy Economics # and Energy System Technology (IEE), Kassel. All rights reserved. -import copy -import numpy as np -import pandas as pd -from pandas._testing import assert_series_equal import pytest +from pandas._testing import assert_series_equal -import pandapower as pp -import pandapower.networks as nw -import pandapower.toolbox +from pandapower.create import create_transformer, create_line, create_transformer3w_from_parameters, create_pwl_cost, \ + create_poly_cost, create_group, create_transformer3w, create_measurement, create_buses, create_loads, \ + create_xward, create_group_from_dict +from pandapower.groups import group_element_index, count_group_elements +from pandapower.networks.cigre_networks import create_cigre_network_mv, create_cigre_network_lv +from pandapower.networks.create_examples import example_simple, example_multivoltage +from pandapower.networks.ieee_europen_lv_asymmetric import ieee_european_lv_asymmetric +from pandapower.networks.mv_oberrhein import mv_oberrhein +from pandapower.networks.power_system_test_cases import case9, case24_ieee_rts +from pandapower.networks.simple_pandapower_test_networks import simple_four_bus_system +from pandapower.run import runpp +from pandapower.test.helper_functions import assert_net_equal +from pandapower.toolbox.comparison import nets_equal, dataframes_equal +from pandapower.toolbox.data_modification import reindex_buses, add_zones_to_elements +from pandapower.toolbox.element_selection import count_elements +from pandapower.toolbox.grid_modification import * def test_drop_inactive_elements(): for service in (False, True): - net = pp.create_empty_network() - bus_sl = pp.create_bus(net, vn_kv=.4, in_service=service) - pp.create_ext_grid(net, bus_sl, in_service=service) - bus0 = pp.create_bus(net, vn_kv=.4, in_service=service) - pp.create_switch(net, bus_sl, bus0, 'b', not service) - bus1 = pp.create_bus(net, vn_kv=.4, in_service=service) - pp.create_transformer(net, bus0, bus1, in_service=service, - std_type='63 MVA 110/20 kV') - bus2 = pp.create_bus(net, vn_kv=.4, in_service=service) - pp.create_line(net, bus1, bus2, length_km=1, in_service=service, - std_type='149-AL1/24-ST1A 10.0') - pp.create_load(net, bus2, p_mw=0., in_service=service) - pp.create_sgen(net, bus2, p_mw=0., in_service=service) - bus3 = pp.create_bus(net, vn_kv=.4, in_service=service) - bus4 = pp.create_bus(net, vn_kv=.4, in_service=service) - pp.create_transformer3w_from_parameters(net, bus2, bus3, bus4, 0.4, 0.4, 0.4, 100, 50, 50, - 3, 3, 3, 1, 1, 1, 5, 1) + net = create_empty_network() + bus_sl = create_bus(net, vn_kv=.4, in_service=service) + create_ext_grid(net, bus_sl, in_service=service) + bus0 = create_bus(net, vn_kv=.4, in_service=service) + create_switch(net, bus_sl, bus0, 'b', not service) + bus1 = create_bus(net, vn_kv=.4, in_service=service) + create_transformer(net, bus0, bus1, in_service=service, + std_type='63 MVA 110/20 kV') + bus2 = create_bus(net, vn_kv=.4, in_service=service) + create_line(net, bus1, bus2, length_km=1, in_service=service, + std_type='149-AL1/24-ST1A 10.0') + create_load(net, bus2, p_mw=0., in_service=service) + create_sgen(net, bus2, p_mw=0., in_service=service) + bus3 = create_bus(net, vn_kv=.4, in_service=service) + bus4 = create_bus(net, vn_kv=.4, in_service=service) + create_transformer3w_from_parameters(net, bus2, bus3, bus4, 0.4, 0.4, 0.4, 100, 50, 50, + 3, 3, 3, 1, 1, 1, 5, 1) # drop them - pp.drop_inactive_elements(net) + drop_inactive_elements(net) sum_of_elements = 0 for element, table in net.items(): @@ -58,66 +68,66 @@ def test_drop_inactive_elements(): assert len(net.bus) == 1 assert bus_sl in net.bus.index.values - net = pp.create_empty_network() + net = create_empty_network() - bus0 = pp.create_bus(net, vn_kv=.4, in_service=True) - pp.create_ext_grid(net, bus0, in_service=True) - bus1 = pp.create_bus(net, vn_kv=.4, in_service=False) - pp.create_line(net, bus0, bus1, length_km=1, in_service=False, - std_type='149-AL1/24-ST1A 10.0') - gen0 = pp.create_gen(net, bus=bus1, p_mw=0.001) + bus0 = create_bus(net, vn_kv=.4, in_service=True) + create_ext_grid(net, bus0, in_service=True) + bus1 = create_bus(net, vn_kv=.4, in_service=False) + create_line(net, bus0, bus1, length_km=1, in_service=False, + std_type='149-AL1/24-ST1A 10.0') + gen0 = create_gen(net, bus=bus1, p_mw=0.001) - pp.drop_inactive_elements(net) + drop_inactive_elements(net) assert gen0 not in net.gen.index def test_merge_indices(): - net1 = nw.create_cigre_network_mv() - pp.create_pwl_cost(net1, 0, "load", [[0, 20, 1], [20, 30, 2]]) - pp.create_pwl_cost(net1, 2, "load", [[0, 20, 0.5], [20, 30, 2]]) - pp.reindex_buses(net1, {3: 29}) + net1 = create_cigre_network_mv() + create_pwl_cost(net1, 0, "load", [[0, 20, 1], [20, 30, 2]]) + create_pwl_cost(net1, 2, "load", [[0, 20, 0.5], [20, 30, 2]]) + reindex_buses(net1, {3: 29}) assert 29 in net1.bus.index.values assert 29 in net1.load.bus.values - net2 = nw.create_cigre_network_mv(with_der="pv_wind") - pp.create_pwl_cost(net2, 1, "load", [[0, 20, 1], [20, 30, 2]], index=5) - pp.create_pwl_cost(net2, 2, "sgen", [[0, 20, 0.5], [20, 30, 2]]) + net2 = create_cigre_network_mv(with_der="pv_wind") + create_pwl_cost(net2, 1, "load", [[0, 20, 1], [20, 30, 2]], index=5) + create_pwl_cost(net2, 2, "sgen", [[0, 20, 0.5], [20, 30, 2]]) - net = pp.merge_nets(net1, net2, net2_reindex_log_level="debug") + net = merge_nets(net1, net2, net2_reindex_log_level="debug") # check - for et in pandapower.toolbox.pp_elements(cost_tables=True): + for et in pp_elements(cost_tables=True): assert net[et].shape[0] == net1[et].shape[0] + net2[et].shape[0] assert net.bus.index.tolist() == net1.bus.index.tolist() + [ - i+29+1 if i < 3 else i+29 if i > 3 else 3 for i in net2.bus.index] + i + 29 + 1 if i < 3 else i + 29 if i > 3 else 3 for i in net2.bus.index] assert net.load.index.tolist() == list(range(net.load.shape[0])) assert net.load.bus.tolist() == net1.load.bus.tolist() + [ - i+29+1 if i < 3 else i+29 if i > 3 else 3 for i in net2.load.bus] + i + 29 + 1 if i < 3 else i + 29 if i > 3 else 3 for i in net2.load.bus] assert net.pwl_cost.index.tolist() == [0, 1, 5, 6] assert net.pwl_cost.element.tolist() == [0, 2, 19, 2] - assert net.pwl_cost.et.tolist() == ["load"]*3 + ["sgen"] + assert net.pwl_cost.et.tolist() == ["load"] * 3 + ["sgen"] def test_merge_and_split_nets(): - net1 = nw.mv_oberrhein() - pp.create_poly_cost(net1, 2, "sgen", 8) - pp.create_poly_cost(net1, 0, "sgen", 9) + net1 = mv_oberrhein() + create_poly_cost(net1, 2, "sgen", 8) + create_poly_cost(net1, 0, "sgen", 9) n1 = len(net1.bus) - pp.runpp(net1) - net2 = nw.create_cigre_network_mv(with_der="pv_wind") - pp.create_poly_cost(net2, 3, "sgen", 10) - pp.create_poly_cost(net2, 0, "sgen", 11) - pp.runpp(net2) + runpp(net1) + net2 = create_cigre_network_mv(with_der="pv_wind") + create_poly_cost(net2, 3, "sgen", 10) + create_poly_cost(net2, 0, "sgen", 11) + runpp(net2) net1_before = copy.deepcopy(net1) net2_before = copy.deepcopy(net2) - _net = pp.merge_nets(net1, net2, net2_reindex_log_level="debug") - pp.runpp(_net) + _net = merge_nets(net1, net2, net2_reindex_log_level="debug") + runpp(_net) # check that merge_nets() doesn't change inputs (but result tables) - pp.test.assert_net_equal(net1, net1_before, check_without_results=True) - pp.test.assert_net_equal(net2, net2_before, check_without_results=True) + assert_net_equal(net1, net1_before, check_without_results=True) + assert_net_equal(net2, net2_before, check_without_results=True) # check that results of merge_nets() fit assert np.allclose(_net.res_bus.vm_pu.iloc[:n1].values, net1.res_bus.vm_pu.values) @@ -130,27 +140,27 @@ def test_merge_and_split_nets(): _net.sgen.name.loc[_net.poly_cost.element].values) # check that results stay the same after net split - net3 = pp.select_subnet(_net, _net.bus.index[:n1], include_results=True) - assert pandapower.toolbox.dataframes_equal(net3.res_bus[["vm_pu"]], net1.res_bus[["vm_pu"]]) + net3 = select_subnet(_net, _net.bus.index[:n1], include_results=True) + assert dataframes_equal(net3.res_bus[["vm_pu"]], net1.res_bus[["vm_pu"]]) - net4 = pp.select_subnet(_net, _net.bus.index[n1:], include_results=True) + net4 = select_subnet(_net, _net.bus.index[n1:], include_results=True) assert np.allclose(net4.res_bus.vm_pu.values, net2.res_bus.vm_pu.values) def test_merge_asymmetric(): """Test that merging nets properly handles bus IDs for asymmetric elements """ - net1 = nw.ieee_european_lv_asymmetric() - net2 = nw.ieee_european_lv_asymmetric() + net1 = ieee_european_lv_asymmetric() + net2 = ieee_european_lv_asymmetric() n_load_busses = len(net1.asymmetric_load.bus.unique()) n_sgen_busses = len(net1.asymmetric_sgen.bus.unique()) net1_before = copy.deepcopy(net1) net2_before = copy.deepcopy(net2) - net = pp.merge_nets(net1, net2, net2_reindex_log_level="debug") + net = merge_nets(net1, net2, net2_reindex_log_level="debug") - pp.test.assert_net_equal(net1, net1_before, check_without_results=True) - pp.test.assert_net_equal(net2, net2_before, check_without_results=True) + assert_net_equal(net1, net1_before, check_without_results=True) + assert_net_equal(net2, net2_before, check_without_results=True) assert len(net.asymmetric_load.bus.unique()) == 2 * n_load_busses assert len(net.asymmetric_sgen.bus.unique()) == 2 * n_sgen_busses @@ -158,15 +168,15 @@ def test_merge_asymmetric(): def test_merge_with_groups(): """Test that group data are correctly considered by merge_nets() """ - net1 = nw.create_cigre_network_mv() - net2 = nw.create_cigre_network_mv() + net1 = create_cigre_network_mv() + net2 = create_cigre_network_mv() for elm in ["bus", "load", "line"]: net2[elm].name = "new " + net2[elm].name - pp.create_group(net1, "bus", [[0, 2]], name="group of net1") - pp.create_group(net2, ["bus", "load"], [[1], [0, 3]], name="group1 of net2") - pp.create_group(net2, ["line"], [[1, 3]], name="group2 of net2", index=4) + create_group(net1, "bus", [[0, 2]], name="group of net1") + create_group(net2, ["bus", "load"], [[1], [0, 3]], name="group1 of net2") + create_group(net2, ["line"], [[1, 3]], name="group2 of net2", index=4) - net = pp.merge_nets(net1, net2, net2_reindex_log_level="debug") + net = merge_nets(net1, net2, net2_reindex_log_level="debug") # check that all group lines are available assert net.group.shape[0] == net1.group.shape[0] + net2.group.shape[0] @@ -175,20 +185,21 @@ def test_merge_with_groups(): assert set(net.group.index) == {0, 5, 4} # check that net2 groups link to the same elements as later in net.group (checking by element names) - assert net2.bus.name.loc[pp.group_element_index(net2, 0, "bus")].tolist() == \ - net.bus.name.loc[pp.group_element_index(net, 5, "bus")].tolist() - assert net2.load.name.loc[pp.group_element_index(net2, 0, "load")].tolist() == \ - net.load.name.loc[pp.group_element_index(net, 5, "load")].tolist() - assert net2.trafo.name.loc[pp.group_element_index(net2, 4, "trafo")].tolist() == \ - net.trafo.name.loc[pp.group_element_index(net, 4, "trafo")].tolist() + assert net2.bus.name.loc[group_element_index(net2, 0, "bus")].tolist() == \ + net.bus.name.loc[group_element_index(net, 5, "bus")].tolist() + assert net2.load.name.loc[group_element_index(net2, 0, "load")].tolist() == \ + net.load.name.loc[group_element_index(net, 5, "load")].tolist() + assert net2.trafo.name.loc[group_element_index(net2, 4, "trafo")].tolist() == \ + net.trafo.name.loc[group_element_index(net, 4, "trafo")].tolist() # check that net2 groups link to the same elements as later in net.group (checking by element index) - assert list(pp.group_element_index(net, 0, "bus")) == [0, 2] - assert list(pp.group_element_index(net, 5, "bus")) == [net1.bus.shape[0]+1] - assert list(pp.group_element_index(net, 5, "load")) == list(np.array([0, 3], dtype=np.int64) + \ - net1.load.shape[0]) - assert list(pp.group_element_index(net, 4, "line")) == list(np.array([1, 3], dtype=np.int64) + \ - net1.line.shape[0]) + assert list(group_element_index(net, 0, "bus")) == [0, 2] + assert list(group_element_index(net, 5, "bus")) == [net1.bus.shape[0] + 1] + assert list(group_element_index(net, 5, "load")) == list(np.array([0, 3], dtype=np.int64) + + net1.load.shape[0]) + assert list(group_element_index(net, 4, "line")) == list(np.array([1, 3], dtype=np.int64) + + net1.line.shape[0]) + def test_merge_with_characteristics(): from pandapower.networks.simple_pandapower_test_networks import simple_four_bus_system @@ -207,7 +218,7 @@ def test_merge_with_characteristics(): net2.trafo.loc[:, "vk_percent_characteristic"] = 0 # merge networks - merged, lookup = pp.merge_nets(net1, net2, validate=False, return_net2_reindex_lookup=True) + merged, lookup = merge_nets(net1, net2, validate=False, return_net2_reindex_lookup=True) # The second transformer should have the second characteristic assert merged.trafo.loc[1, "vk_percent_characteristic"] == 1 @@ -222,31 +233,31 @@ def test_merge_nets_with_custom_elements(): net2 = simple_four_bus_system() net2["test"] = df.copy() - res_net1 = pp.merge_nets(net1, net2, validate=False) - res_net2 = pp.merge_nets(net2, net1, validate=False) + res_net1 = merge_nets(net1, net2, validate=False) + res_net2 = merge_nets(net2, net1, validate=False) assert df.equals(res_net1["test"]) assert df.equals(res_net2["test"]) - assert pp.nets_equal(res_net1, res_net2) + assert nets_equal(res_net1, res_net2) def test_select_subnet(): # This network has switches of type 'l' and 't' - net = nw.create_cigre_network_mv() + net = create_cigre_network_mv() # Do nothing - same_net = pp.select_subnet(net, net.bus.index) - assert pandapower.toolbox.dataframes_equal(net.bus, same_net.bus) - assert pandapower.toolbox.dataframes_equal(net.switch, same_net.switch) - assert pandapower.toolbox.dataframes_equal(net.trafo, same_net.trafo) - assert pandapower.toolbox.dataframes_equal(net.line, same_net.line) - assert pandapower.toolbox.dataframes_equal(net.load, same_net.load) - assert pandapower.toolbox.dataframes_equal(net.ext_grid, same_net.ext_grid) - same_net2 = pp.select_subnet(net, net.bus.index, include_results=True, - keep_everything_else=True) - assert pandapower.toolbox.nets_equal(net, same_net2) + same_net = select_subnet(net, net.bus.index) + assert dataframes_equal(net.bus, same_net.bus) + assert dataframes_equal(net.switch, same_net.switch) + assert dataframes_equal(net.trafo, same_net.trafo) + assert dataframes_equal(net.line, same_net.line) + assert dataframes_equal(net.load, same_net.load) + assert dataframes_equal(net.ext_grid, same_net.ext_grid) + same_net2 = select_subnet(net, net.bus.index, include_results=True, + keep_everything_else=True) + assert nets_equal(net, same_net2) # Remove everything - empty = pp.select_subnet(net, set()) + empty = select_subnet(net, set()) assert len(empty.bus) == 0 assert len(empty.line) == 0 assert len(empty.load) == 0 @@ -258,35 +269,35 @@ def test_select_subnet(): hv_buses = set(net.trafo.hv_bus) lv_buses = set(net.trafo.lv_bus) trafo_switch_buses = set(net.switch[net.switch.et == 't'].bus) - subnet = pp.select_subnet(net, hv_buses | lv_buses | trafo_switch_buses) + subnet = select_subnet(net, hv_buses | lv_buses | trafo_switch_buses) assert net.switch[net.switch.et == 't'].index.isin(subnet.switch.index).all() # Should keep all line ('l') switches when buses are included from_bus = set(net.line.from_bus) to_bus = set(net.line.to_bus) line_switch_buses = set(net.switch[net.switch.et == 'l'].bus) - subnet = pp.select_subnet(net, from_bus | to_bus | line_switch_buses) + subnet = select_subnet(net, from_bus | to_bus | line_switch_buses) assert net.switch[net.switch.et == 'l'].index.isin(subnet.switch.index).all() ls = net.switch.loc[net.switch.et == "l"] - subnet = pp.select_subnet(net, list(ls.bus.values)[::2], include_switch_buses=True) + subnet = select_subnet(net, list(ls.bus.values)[::2], include_switch_buses=True) assert net.switch[net.switch.et == 'l'].index.isin(subnet.switch.index).all() assert net.switch[net.switch.et == 'l'].bus.isin(subnet.bus.index).all() # This network has switches of type 'b' - net2 = nw.create_cigre_network_lv() + net2 = create_cigre_network_lv() # Should keep all bus-to-bus ('b') switches when buses are included buses = set(net2.switch[net2.switch.et == 'b'].bus) elements = set(net2.switch[net2.switch.et == 'b'].element) - subnet = pp.select_subnet(net2, buses | elements) + subnet = select_subnet(net2, buses | elements) assert net2.switch[net2.switch.et == 'b'].index.isin(subnet.switch.index).all() def test_add_zones_to_elements(): - net = nw.create_cigre_network_mv() + net = create_cigre_network_mv() # add zones to lines and switchs - pp.add_zones_to_elements(net, elements=["line", "switch"]) + add_zones_to_elements(net, elements=["line", "switch"]) # create 2 arrays which include "zone" in lines and switches zone_line = net["line"]["zone"].values @@ -299,22 +310,22 @@ def test_add_zones_to_elements(): def test_drop_inner_branches(): def check_elm_number(net1, net2, excerpt_elms=None): excerpt_elms = set() if excerpt_elms is None else set(excerpt_elms) - for elm in set(pandapower.toolbox.pp_elements()) - excerpt_elms: + for elm in set(pp_elements()) - excerpt_elms: assert net1[elm].shape[0] == net2[elm].shape[0] - net = nw.example_simple() - new_bus = pp.create_bus(net, 10) - pp.create_transformer3w(net, 2, 3, new_bus, "63/25/38 MVA 110/20/10 kV") + net = example_simple() + new_bus = create_bus(net, 10) + create_transformer3w(net, 2, 3, new_bus, "63/25/38 MVA 110/20/10 kV") net1 = copy.deepcopy(net) - pp.drop_inner_branches(net1, [2, 3], branch_elements=["line"]) + drop_inner_branches(net1, [2, 3], branch_elements=["line"]) check_elm_number(net1, net) - pp.drop_inner_branches(net1, [0, 1], branch_elements=["line"]) + drop_inner_branches(net1, [0, 1], branch_elements=["line"]) check_elm_number(net1, net, ["line"]) assert all(net.line.index.difference({0}) == net1.line.index) net2 = copy.deepcopy(net) - pp.drop_inner_branches(net2, [2, 3, 4, 5]) + drop_inner_branches(net2, [2, 3, 4, 5]) assert all(net.line.index.difference({1}) == net2.line.index) assert all(net.trafo.index.difference({0}) == net2.trafo.index) assert all(net.switch.index.difference({1, 2, 3}) == net2.switch.index) @@ -322,26 +333,26 @@ def check_elm_number(net1, net2, excerpt_elms=None): def test_fuse_buses(): - net = pp.create_empty_network() - b1 = pp.create_bus(net, vn_kv=1, name="b1") - b2 = pp.create_bus(net, vn_kv=1.5, name="b2") - b3 = pp.create_bus(net, vn_kv=2, name="b2") + net = create_empty_network() + b1 = create_bus(net, vn_kv=1, name="b1") + b2 = create_bus(net, vn_kv=1.5, name="b2") + b3 = create_bus(net, vn_kv=2, name="b2") - line1 = pp.create_line(net, b2, b1, length_km=1, std_type="NAYY 4x50 SE") - line2 = pp.create_line(net, b2, b3, length_km=1, std_type="NAYY 4x50 SE") + line1 = create_line(net, b2, b1, length_km=1, std_type="NAYY 4x50 SE") + line2 = create_line(net, b2, b3, length_km=1, std_type="NAYY 4x50 SE") - sw1 = pp.create_switch(net, b2, line1, et="l") - sw2 = pp.create_switch(net, b1, b2, et="b") + sw1 = create_switch(net, b2, line1, et="l") + sw2 = create_switch(net, b1, b2, et="b") - pp.create_load(net, b1, p_mw=0.006) - pp.create_load(net, b2, p_mw=0.005) - pp.create_load(net, b3, p_mw=0.005) + create_load(net, b1, p_mw=0.006) + create_load(net, b2, p_mw=0.005) + create_load(net, b3, p_mw=0.005) - pp.create_measurement(net, "v", "bus", 1.2, 0.03, b2) + create_measurement(net, "v", "bus", 1.2, 0.03, b2) # --- drop = True net1 = copy.deepcopy(net) - pp.fuse_buses(net1, b1, b2, drop=True) + fuse_buses(net1, b1, b2, drop=True) # assertion: elements connected to b2 are given to b1 instead assert line1 not in net1.line.index @@ -356,7 +367,7 @@ def test_fuse_buses(): # --- drop = False net2 = copy.deepcopy(net) - pp.fuse_buses(net2, b1, b2, drop=False) + fuse_buses(net2, b1, b2, drop=False) # assertion: elements connected to b2 are given to b1 instead assert net2["line"]["from_bus"].at[0] == b1 @@ -370,55 +381,55 @@ def test_fuse_buses(): def test_close_switch_at_line_with_two_open_switches(): - net = pp.create_empty_network() + net = create_empty_network() - bus1 = pp.create_bus(net, vn_kv=.4) - bus2 = pp.create_bus(net, vn_kv=.4) - bus3 = pp.create_bus(net, vn_kv=.4) + bus1 = create_bus(net, vn_kv=.4) + bus2 = create_bus(net, vn_kv=.4) + bus3 = create_bus(net, vn_kv=.4) - line1 = pp.create_line(net, bus2, bus3, length_km=1., std_type="NAYY 4x50 SE") - line2 = pp.create_line(net, bus2, bus3, length_km=1., std_type="NAYY 4x50 SE") - pp.create_line(net, bus2, bus3, length_km=1., std_type="NAYY 4x50 SE") # line3 + line1 = create_line(net, bus2, bus3, length_km=1., std_type="NAYY 4x50 SE") + line2 = create_line(net, bus2, bus3, length_km=1., std_type="NAYY 4x50 SE") + create_line(net, bus2, bus3, length_km=1., std_type="NAYY 4x50 SE") # line3 - pp.create_switch(net, bus1, bus2, et="b", closed=True) # sw0 + create_switch(net, bus1, bus2, et="b", closed=True) # sw0 - pp.create_switch(net, bus2, line1, et="l", closed=False) # sw1 - pp.create_switch(net, bus3, line1, et="l", closed=False) # sw2 + create_switch(net, bus2, line1, et="l", closed=False) # sw1 + create_switch(net, bus3, line1, et="l", closed=False) # sw2 - pp.create_switch(net, bus2, line2, et="l", closed=True) # sw3 - pp.create_switch(net, bus3, line2, et="l", closed=False) # sw4 + create_switch(net, bus2, line2, et="l", closed=True) # sw3 + create_switch(net, bus3, line2, et="l", closed=False) # sw4 - pp.create_switch(net, bus3, line2, et="l", closed=True) # sw5 - pp.create_switch(net, bus3, line2, et="l", closed=True) # sw6 + create_switch(net, bus3, line2, et="l", closed=True) # sw5 + create_switch(net, bus3, line2, et="l", closed=True) # sw6 - pp.close_switch_at_line_with_two_open_switches(net) + close_switch_at_line_with_two_open_switches(net) # assertion: sw2 closed assert net.switch.closed.loc[1] def test_create_replacement_switch_for_branch(): - net = pp.create_empty_network() + net = create_empty_network() - bus0 = pp.create_bus(net, vn_kv=0.4) - bus1 = pp.create_bus(net, vn_kv=0.4) - bus2 = pp.create_bus(net, vn_kv=0.4) - bus3 = pp.create_bus(net, vn_kv=0.4) + bus0 = create_bus(net, vn_kv=0.4) + bus1 = create_bus(net, vn_kv=0.4) + bus2 = create_bus(net, vn_kv=0.4) + bus3 = create_bus(net, vn_kv=0.4) - pp.create_ext_grid(net, bus0, vm_pu=0.4) + create_ext_grid(net, bus0, vm_pu=0.4) - line0 = pp.create_line(net, bus0, bus1, length_km=1, std_type="NAYY 4x50 SE") - line1 = pp.create_line(net, bus2, bus3, length_km=1, std_type="NAYY 4x50 SE") - impedance0 = pp.create_impedance(net, bus1, bus2, 0.01, 0.01, sn_mva=100) - impedance1 = pp.create_impedance(net, bus1, bus2, 0.01, 0.01, sn_mva=100) + line0 = create_line(net, bus0, bus1, length_km=1, std_type="NAYY 4x50 SE") + line1 = create_line(net, bus2, bus3, length_km=1, std_type="NAYY 4x50 SE") + impedance0 = create_impedance(net, bus1, bus2, 0.01, 0.01, sn_mva=100) + impedance1 = create_impedance(net, bus1, bus2, 0.01, 0.01, sn_mva=100) - pp.create_load(net, bus2, 0.001) + create_load(net, bus2, 0.001) - pp.runpp(net) + runpp(net) # look that the switch is created properly - pp.create_replacement_switch_for_branch(net, 'line', line0) - pp.create_replacement_switch_for_branch(net, 'impedance', impedance0) + create_replacement_switch_for_branch(net, 'line', line0) + create_replacement_switch_for_branch(net, 'impedance', impedance0) net.line.at[line0, "in_service"] = False net.impedance.at[impedance0, "in_service"] = False @@ -426,13 +437,13 @@ def test_create_replacement_switch_for_branch(): assert 'REPLACEMENT_impedance_0' in net.switch.name.values assert net.switch.closed.at[0] assert net.switch.closed.at[1] - pp.runpp(net) + runpp(net) # look that the switch is created with the correct closed status net.line.at[line1, "in_service"] = False net.impedance.at[impedance1, "in_service"] = False - pp.create_replacement_switch_for_branch(net, 'line', line1) - pp.create_replacement_switch_for_branch(net, 'impedance', impedance1) + create_replacement_switch_for_branch(net, 'line', line1) + create_replacement_switch_for_branch(net, 'impedance', impedance1) assert 'REPLACEMENT_line_1' in net.switch.name.values assert 'REPLACEMENT_impedance_1' in net.switch.name.values @@ -442,69 +453,69 @@ def test_create_replacement_switch_for_branch(): @pytest.fixture def net(): - net = pp.create_empty_network() - - bus0 = pp.create_bus(net, vn_kv=0.4) - bus1 = pp.create_bus(net, vn_kv=0.4) - bus2 = pp.create_bus(net, vn_kv=0.4) - bus3 = pp.create_bus(net, vn_kv=0.4) - bus4 = pp.create_bus(net, vn_kv=0.4) - bus5 = pp.create_bus(net, vn_kv=0.4) - bus6 = pp.create_bus(net, vn_kv=0.4) - - pp.create_ext_grid(net, bus0, vm_pu=0.4) - - pp.create_line(net, bus0, bus1, length_km=0, std_type="NAYY 4x50 SE") # line0 - pp.create_line_from_parameters(net, bus2, bus3, length_km=1, r_ohm_per_km=0, x_ohm_per_km=0.1, - c_nf_per_km=0, max_i_ka=1) # line1 - pp.create_line_from_parameters(net, bus3, bus4, length_km=1, r_ohm_per_km=0, x_ohm_per_km=0, - c_nf_per_km=0, max_i_ka=1) # line2 - - pp.create_impedance(net, bus1, bus2, 0.01, 0.01, sn_mva=100) # impedance0 - pp.create_impedance(net, bus4, bus5, 0, 0, sn_mva=100) # impedance1 - pp.create_impedance(net, bus5, bus6, 0, 0, rtf_pu=0.1, sn_mva=100) # impedance2 + net = create_empty_network() + + bus0 = create_bus(net, vn_kv=0.4) + bus1 = create_bus(net, vn_kv=0.4) + bus2 = create_bus(net, vn_kv=0.4) + bus3 = create_bus(net, vn_kv=0.4) + bus4 = create_bus(net, vn_kv=0.4) + bus5 = create_bus(net, vn_kv=0.4) + bus6 = create_bus(net, vn_kv=0.4) + + create_ext_grid(net, bus0, vm_pu=0.4) + + create_line(net, bus0, bus1, length_km=0, std_type="NAYY 4x50 SE") # line0 + create_line_from_parameters(net, bus2, bus3, length_km=1, r_ohm_per_km=0, x_ohm_per_km=0.1, + c_nf_per_km=0, max_i_ka=1) # line1 + create_line_from_parameters(net, bus3, bus4, length_km=1, r_ohm_per_km=0, x_ohm_per_km=0, + c_nf_per_km=0, max_i_ka=1) # line2 + + create_impedance(net, bus1, bus2, 0.01, 0.01, sn_mva=100) # impedance0 + create_impedance(net, bus4, bus5, 0, 0, sn_mva=100) # impedance1 + create_impedance(net, bus5, bus6, 0, 0, rtf_pu=0.1, sn_mva=100) # impedance2 return net def test_for_line_with_zero_length(net): - pp.replace_zero_branches_with_switches(net, elements=('line',), zero_impedance=False) + replace_zero_branches_with_switches(net, elements=('line',), zero_impedance=False) assert 'REPLACEMENT_line_0' in net.switch.name.values assert ~net.line.in_service.at[0] assert 'REPLACEMENT_line_2' not in net.switch.name.values def test_drop(net): - pp.replace_zero_branches_with_switches(net, elements=('line', 'impedance'), drop_affected=True) + replace_zero_branches_with_switches(net, elements=('line', 'impedance'), drop_affected=True) assert len(net.line) == 1 assert len(net.impedance) == 2 def test_in_service_only(net): - pp.replace_zero_branches_with_switches(net, elements=('line',)) + replace_zero_branches_with_switches(net, elements=('line',)) assert len(net.switch.loc[net.switch.name == 'REPLACEMENT_line_0']) == 1 - pp.replace_zero_branches_with_switches(net, elements=('line',), in_service_only=False) + replace_zero_branches_with_switches(net, elements=('line',), in_service_only=False) assert len(net.switch.loc[net.switch.name == 'REPLACEMENT_line_0']) == 2 assert ~net.switch.closed.at[2] def test_line_with_zero_impediance(net): # test for line with zero impedance - pp.replace_zero_branches_with_switches(net, elements=('line',), zero_length=False) + replace_zero_branches_with_switches(net, elements=('line',), zero_length=False) assert 'REPLACEMENT_line_1' not in net.switch.name.values assert 'REPLACEMENT_line_2' in net.switch.name.values def test_impedance(net): - pp.replace_zero_branches_with_switches(net, elements=('impedance',), zero_length=False, - zero_impedance=True, in_service_only=True) + replace_zero_branches_with_switches(net, elements=('impedance',), zero_length=False, + zero_impedance=True, in_service_only=True) assert 'REPLACEMENT_impedance_0' not in net.switch.name.values assert 'REPLACEMENT_impedance_1' in net.switch.name.values assert 'REPLACEMENT_impedance_2' not in net.switch.name.values def test_all(net): - pp.replace_zero_branches_with_switches(net, elements=('impedance', 'line'), zero_length=True, - zero_impedance=True, in_service_only=True) + replace_zero_branches_with_switches(net, elements=('impedance', 'line'), zero_length=True, + zero_impedance=True, in_service_only=True) assert 'REPLACEMENT_impedance_1' in net.switch.name.values assert 'REPLACEMENT_line_0' in net.switch.name.values assert 'REPLACEMENT_line_2' in net.switch.name.values @@ -520,38 +531,38 @@ def test_all(net): def test_drop_elements_at_buses(): - net = pp.create_empty_network() - - bus0 = pp.create_bus(net, vn_kv=110) - bus1 = pp.create_bus(net, vn_kv=20) - bus2 = pp.create_bus(net, vn_kv=10) - bus3 = pp.create_bus(net, vn_kv=0.4) - bus4 = pp.create_bus(net, vn_kv=0.4) - bus5 = pp.create_bus(net, vn_kv=20) - - pp.create_ext_grid(net, 0) - - trafo0 = pp.create_transformer3w(net, hv_bus=bus0, mv_bus=bus1, lv_bus=bus2, name='trafo0', - std_type='63/25/38 MVA 110/20/10 kV') - trafo1 = pp.create_transformer(net, hv_bus=bus2, lv_bus=bus3, std_type='0.4 MVA 10/0.4 kV') - - line1 = pp.create_line(net, from_bus=bus3, to_bus=bus4, length_km=20.1, - std_type='24-AL1/4-ST1A 0.4', name='line1') - pp.create_sgen(net, 1, 0) - - switch0a = pp.create_switch(net, bus=bus0, element=trafo0, et='t3') - switch0b = pp.create_switch(net, bus=bus1, element=trafo0, et='t3') - switch0c = pp.create_switch(net, bus=bus2, element=trafo0, et='t3') - switch1 = pp.create_switch(net, bus=bus1, element=bus5, et='b') - switch2a = pp.create_switch(net, bus=bus2, element=trafo1, et='t') - switch2b = pp.create_switch(net, bus=bus3, element=trafo1, et='t') - switch3a = pp.create_switch(net, bus=bus3, element=line1, et='l') - switch3b = pp.create_switch(net, bus=bus4, element=line1, et='l') + net = create_empty_network() + + bus0 = create_bus(net, vn_kv=110) + bus1 = create_bus(net, vn_kv=20) + bus2 = create_bus(net, vn_kv=10) + bus3 = create_bus(net, vn_kv=0.4) + bus4 = create_bus(net, vn_kv=0.4) + bus5 = create_bus(net, vn_kv=20) + + create_ext_grid(net, 0) + + trafo0 = create_transformer3w(net, hv_bus=bus0, mv_bus=bus1, lv_bus=bus2, name='trafo0', + std_type='63/25/38 MVA 110/20/10 kV') + trafo1 = create_transformer(net, hv_bus=bus2, lv_bus=bus3, std_type='0.4 MVA 10/0.4 kV') + + line1 = create_line(net, from_bus=bus3, to_bus=bus4, length_km=20.1, + std_type='24-AL1/4-ST1A 0.4', name='line1') + create_sgen(net, 1, 0) + + switch0a = create_switch(net, bus=bus0, element=trafo0, et='t3') + switch0b = create_switch(net, bus=bus1, element=trafo0, et='t3') + switch0c = create_switch(net, bus=bus2, element=trafo0, et='t3') + switch1 = create_switch(net, bus=bus1, element=bus5, et='b') + switch2a = create_switch(net, bus=bus2, element=trafo1, et='t') + switch2b = create_switch(net, bus=bus3, element=trafo1, et='t') + switch3a = create_switch(net, bus=bus3, element=line1, et='l') + switch3b = create_switch(net, bus=bus4, element=line1, et='l') # bus id needs to be entered as iterable, not done in the function for b in net.bus.index.values: net1 = net.deepcopy() - cd = pp.get_connected_elements_dict(net1, b, connected_buses=False) + cd = get_connected_elements_dict(net1, b, connected_buses=False) swt3w = set(net1.switch.loc[net1.switch.element.isin(cd.get('trafo3w', [1000])) & (net1.switch.et == 't3')].index) swt = set(net1.switch.loc[net1.switch.element.isin(cd.get('trafo', [1000])) & @@ -559,57 +570,57 @@ def test_drop_elements_at_buses(): swl = set(net1.switch.loc[net1.switch.element.isin(cd.get('line', [1000])) & (net1.switch.et == 'l')].index) sw = swt3w | swt | swl - pp.drop_elements_at_buses(net1, [b]) + drop_elements_at_buses(net1, [b]) assert b not in net1.switch.bus.values assert b not in net1.switch.query("et=='b'").element.values assert sw.isdisjoint(set(net1.switch.index)) - for elm, id in cd.items(): - assert len(net1[elm].loc[net1[elm].index.isin(id)]) == 0 + for elm, id_ in cd.items(): + assert len(net1[elm].loc[net1[elm].index.isin(id_)]) == 0 def test_impedance_line_replacement(): # create test net - net1 = pp.create_empty_network(sn_mva=1.1) - pp.create_buses(net1, 2, 10) - pp.create_ext_grid(net1, 0) - pp.create_impedance(net1, 0, 1, 0.1, 0.1, 8.7e-3) - pp.create_load(net1, 1, 7e-3, 2e-3) + net1 = create_empty_network(sn_mva=1.1) + create_buses(net1, 2, 10) + create_ext_grid(net1, 0) + create_impedance(net1, 0, 1, 0.1, 0.1, 8.7e-3) + create_load(net1, 1, 7e-3, 2e-3) # validate loadflow results - pp.runpp(net1) + runpp(net1) net2 = copy.deepcopy(net1) - pp.replace_impedance_by_line(net2) + replace_impedance_by_line(net2) - pp.runpp(net2) + runpp(net2) - assert pandapower.toolbox.nets_equal(net1, net2, exclude_elms={"line", "impedance"}) + assert nets_equal(net1, net2, exclude_elms={"line", "impedance"}) cols = ["p_from_mw", "q_from_mvar", "p_to_mw", "q_to_mvar", "pl_mw", "ql_mvar", "i_from_ka", "i_to_ka"] assert np.allclose(net1.res_impedance[cols].values, net2.res_line[cols].values) net3 = copy.deepcopy(net2) - pp.replace_line_by_impedance(net3) + replace_line_by_impedance(net3) - pp.runpp(net3) + runpp(net3) - assert pandapower.toolbox.nets_equal(net2, net3, exclude_elms={"line", "impedance"}) + assert nets_equal(net2, net3, exclude_elms={"line", "impedance"}) assert np.allclose(net3.res_impedance[cols].values, net2.res_line[cols].values) def test_replace_ext_grid_gen(): for i in range(2): - net = nw.example_simple() + net = example_simple() net.ext_grid["uuid"] = "test" - pp.runpp(net, calculate_voltage_angles="auto") + runpp(net, calculate_voltage_angles="auto") assert list(net.res_ext_grid.index.values) == [0] - pp.create_group(net, ["line", "ext_grid"], [[0], [0]]) + create_group(net, ["line", "ext_grid"], [[0], [0]]) # replace_ext_grid_by_gen if i == 0: - pp.replace_ext_grid_by_gen(net, 0, gen_indices=[4], add_cols_to_keep=["uuid"]) + replace_ext_grid_by_gen(net, 0, gen_indices=[4], add_cols_to_keep=["uuid"]) elif i == 1: - pp.replace_ext_grid_by_gen(net, [0], gen_indices=[4], cols_to_keep=["uuid", "max_p_mw"]) + replace_ext_grid_by_gen(net, [0], gen_indices=[4], cols_to_keep=["uuid", "max_p_mw"]) assert not net.ext_grid.shape[0] assert not net.res_ext_grid.shape[0] assert np.allclose(net.gen.vm_pu.values, [1.03, 1.02]) @@ -621,9 +632,9 @@ def test_replace_ext_grid_gen(): # replace_gen_by_ext_grid if i == 0: - pp.replace_gen_by_ext_grid(net) + replace_gen_by_ext_grid(net) elif i == 1: - pp.replace_gen_by_ext_grid(net, [0, 4], ext_grid_indices=[2, 3]) + replace_gen_by_ext_grid(net, [0, 4], ext_grid_indices=[2, 3]) assert np.allclose(net.ext_grid.index.values, [2, 3]) assert not net.gen.shape[0] assert not net.res_gen.shape[0] @@ -634,18 +645,18 @@ def test_replace_ext_grid_gen(): def test_replace_gen_sgen(): for i in range(2): - net = nw.case9() + net = case9() vm_set = [1.03, 1.02] net.gen["vm_pu"] = vm_set net.gen["slack_weight"] = 1 - pp.runpp(net) + runpp(net) assert list(net.res_gen.index.values) == [0, 1] # replace_gen_by_sgen if i == 0: - pp.replace_gen_by_sgen(net) + replace_gen_by_sgen(net) elif i == 1: - pp.replace_gen_by_sgen(net, [0, 1], sgen_indices=[4, 1], cols_to_keep=[ + replace_gen_by_sgen(net, [0, 1], sgen_indices=[4, 1], cols_to_keep=[ "max_p_mw"], add_cols_to_keep=["slack_weight"]) # min_p_mw is not in cols_to_keep assert np.allclose(net.sgen.index.values, [4, 1]) assert np.allclose(net.sgen.slack_weight.values, 1) @@ -655,15 +666,15 @@ def test_replace_gen_sgen(): assert not net.res_gen.shape[0] assert not np.allclose(net.sgen.q_mvar.values, 0) assert net.res_gen.shape[0] == 0 - pp.runpp(net) + runpp(net) assert np.allclose(net.res_bus.loc[net.sgen.bus, "vm_pu"].values, vm_set) # replace_sgen_by_gen net2 = copy.deepcopy(net) if i == 0: - pp.replace_sgen_by_gen(net2, [1]) + replace_sgen_by_gen(net2, [1]) elif i == 1: - pp.replace_sgen_by_gen(net2, 1, gen_indices=[2], add_cols_to_keep=["slack_weight"]) + replace_sgen_by_gen(net2, 1, gen_indices=[2], add_cols_to_keep=["slack_weight"]) assert np.allclose(net2.gen.index.values, [2]) assert np.allclose(net2.gen.slack_weight.values, 1) assert net2.gen.shape[0] == 1 @@ -672,8 +683,8 @@ def test_replace_gen_sgen(): assert net2.res_gen.shape[0] == 1 if i == 0: - pp.replace_sgen_by_gen(net, 1) - assert pandapower.toolbox.nets_equal(net, net2) + replace_sgen_by_gen(net, 1) + assert nets_equal(net, net2) def test_replace_pq_elmtype(): @@ -681,24 +692,24 @@ def check_elm_shape(net, elm_shape: dict): for elm, no in elm_shape.items(): assert net[elm].shape[0] == no - net = pp.create_empty_network() - pp.create_buses(net, 3, 20) - pp.create_ext_grid(net, 0) + net = create_empty_network() + create_buses(net, 3, 20) + create_ext_grid(net, 0) for to_bus in [1, 2]: - pp.create_line(net, 0, to_bus, 0.6, 'NA2XS2Y 1x95 RM/25 12/20 kV') + create_line(net, 0, to_bus, 0.6, 'NA2XS2Y 1x95 RM/25 12/20 kV') names = ["load 1", "load 2"] types = ["house", "commercial"] - pp.create_loads(net, [1, 2], 0.8, 0.1, sn_mva=1, min_p_mw=0.5, max_p_mw=1.0, controllable=True, - name=names, scaling=[0.8, 1], type=types) - pp.create_poly_cost(net, 0, "load", 7) - pp.create_poly_cost(net, 1, "load", 3) - pp.runpp(net) + create_loads(net, [1, 2], 0.8, 0.1, sn_mva=1, min_p_mw=0.5, max_p_mw=1.0, controllable=True, + name=names, scaling=[0.8, 1], type=types) + create_poly_cost(net, 0, "load", 7) + create_poly_cost(net, 1, "load", 3) + runpp(net) net.load["controllable"] = net.load["controllable"].astype(bool) net_orig = copy.deepcopy(net) # --- test unset old_indices, cols_to_keep and add_cols_to_keep - pp.replace_pq_elmtype(net, "load", "sgen", new_indices=[2, 7], cols_to_keep=["type"], - add_cols_to_keep=["scaling"]) # cols_to_keep is not + replace_pq_elmtype(net, "load", "sgen", new_indices=[2, 7], cols_to_keep=["type"], + add_cols_to_keep=["scaling"]) # cols_to_keep is not # default but ["type"] -> min/max p_mw get lost check_elm_shape(net, {"load": 0, "sgen": 2}) assert list(net.sgen.index) == [2, 7] @@ -706,36 +717,36 @@ def check_elm_shape(net, elm_shape: dict): assert list(net.sgen.name.values) == names assert net.sgen.controllable.astype(bool).all() assert "min_p_mw" not in net.sgen.columns - pp.runpp(net) - assert pandapower.toolbox.dataframes_equal(net_orig.res_bus, net.res_bus) + runpp(net) + assert dataframes_equal(net_orig.res_bus, net.res_bus) # --- test set old_indices and add_cols_to_keep for different element types net = copy.deepcopy(net_orig) add_cols_to_keep = ["scaling", "type", "sn_mva"] - pp.replace_pq_elmtype(net, "load", "sgen", old_indices=1, add_cols_to_keep=add_cols_to_keep) + replace_pq_elmtype(net, "load", "sgen", old_indices=1, add_cols_to_keep=add_cols_to_keep) check_elm_shape(net, {"load": 1, "sgen": 1}) - pp.runpp(net) - assert pandapower.toolbox.dataframes_equal(net_orig.res_bus, net.res_bus) + runpp(net) + assert dataframes_equal(net_orig.res_bus, net.res_bus) assert net.sgen.max_p_mw.at[0] == - 0.5 assert net.sgen.min_p_mw.at[0] == - 1.0 - pp.replace_pq_elmtype(net, "sgen", "storage", old_indices=0, add_cols_to_keep=add_cols_to_keep) + replace_pq_elmtype(net, "sgen", "storage", old_indices=0, add_cols_to_keep=add_cols_to_keep) check_elm_shape(net, {"load": 1, "storage": 1}) - pp.runpp(net) - assert pandapower.toolbox.dataframes_equal(net_orig.res_bus, net.res_bus) + runpp(net) + assert dataframes_equal(net_orig.res_bus, net.res_bus) - pp.replace_pq_elmtype(net, "storage", "load", add_cols_to_keep=add_cols_to_keep) - pp.runpp(net) + replace_pq_elmtype(net, "storage", "load", add_cols_to_keep=add_cols_to_keep) + runpp(net) check_elm_shape(net, {"storage": 0, "sgen": 0}) net.poly_cost.element = net.poly_cost.element.astype(net_orig.poly_cost.dtypes["element"]) - assert pandapower.toolbox.nets_equal(net_orig, net, exclude_elms={"sgen", "storage"}) + assert nets_equal(net_orig, net, exclude_elms={"sgen", "storage"}) def test_get_connected_elements_dict(): - net = nw.example_simple() - conn = pp.get_connected_elements_dict(net, [0]) + net = example_simple() + conn = get_connected_elements_dict(net, [0]) assert conn == {"line": [0], 'ext_grid': [0], 'bus': [1]} - conn = pp.get_connected_elements_dict(net, [3, 4]) + conn = get_connected_elements_dict(net, [3, 4]) assert conn == {'line': [1, 3], 'switch': [1, 2, 7], 'trafo': [0], 'bus': [2, 5, 6]} @@ -745,53 +756,53 @@ def test_get_connected_elements_empty_in_service(): # - element tables without in_service column (e.g. measurement) # - element_table was unbound for the element table measurement # see #1592 - net = nw.example_simple() + net = example_simple() net.bus.at[6, "in_service"] = False - conn = pp.get_connected_elements_dict(net, [0], respect_switches=False, respect_in_service=True) + conn = get_connected_elements_dict(net, [0], respect_switches=False, respect_in_service=True) assert conn == {"line": [0], 'ext_grid': [0], 'bus': [1]} - conn = pp.get_connected_elements_dict(net, [3, 4], respect_switches=False, respect_in_service=True) + conn = get_connected_elements_dict(net, [3, 4], respect_switches=False, respect_in_service=True) assert conn == {'line': [1, 3], 'switch': [1, 2, 7], 'trafo': [0], 'bus': [2, 5]} def test_replace_ward_by_internal_elements(): - net = nw.example_simple() - pp.create_ward(net, 1, 10, 5, -20, -10, name="ward_1") - pp.create_ward(net, 5, 6, 8, 10, 5, name="ward_2") - pp.create_ward(net, 6, -1, 9, 11, 6, name="ward_3", in_service=False) - pp.create_group_from_dict(net, {"ward": [0]}, name="test group") - pp.runpp(net) + net = example_simple() + create_ward(net, 1, 10, 5, -20, -10, name="ward_1") + create_ward(net, 5, 6, 8, 10, 5, name="ward_2") + create_ward(net, 6, -1, 9, 11, 6, name="ward_3", in_service=False) + create_group_from_dict(net, {"ward": [0]}, name="test group") + runpp(net) net_org = copy.deepcopy(net) - pp.replace_ward_by_internal_elements(net) + replace_ward_by_internal_elements(net) for elm in ["load", "shunt"]: assert net[elm].shape[0] == 4 res_load_created, res_shunt_created = copy.deepcopy(net.res_load), copy.deepcopy(net.res_shunt) - pp.runpp(net) + runpp(net) assert np.allclose(net_org.res_ext_grid.p_mw, net.res_ext_grid.p_mw) assert np.allclose(net_org.res_ext_grid.q_mvar, net.res_ext_grid.q_mvar) assert np.allclose(res_load_created, net.res_load) assert np.allclose(res_shunt_created, net.res_shunt) new_ets = pd.Index(["load", "shunt"]) - assert pp.count_group_elements(net_org, 0).to_dict() == {"ward": 1} - assert pp.count_group_elements(net, 0).to_dict() == {et: 1 for et in new_ets} - elm_change = pandapower.toolbox.count_elements(net, return_empties=True) - pandapower.toolbox.count_elements( + assert count_group_elements(net_org, 0).to_dict() == {"ward": 1} + assert count_group_elements(net, 0).to_dict() == {et: 1 for et in new_ets} + elm_change = count_elements(net, return_empties=True) - count_elements( net_org, return_empties=True) assert set(elm_change.loc[new_ets]) == {3} assert elm_change.at["ward"] == -3 assert set(elm_change.loc[elm_change.index.difference(new_ets).difference(pd.Index([ "ward"]))]) == {0} - net = nw.example_simple() - pp.create_ward(net, 1, 10, 5, -20, -10, name="ward_1") - pp.create_ward(net, 5, 6, 8, 10, 5, name="ward_2") - pp.create_ward(net, 6, -1, 9, 11, 6, name="ward_3", in_service=False) - pp.runpp(net) + net = example_simple() + create_ward(net, 1, 10, 5, -20, -10, name="ward_1") + create_ward(net, 5, 6, 8, 10, 5, name="ward_2") + create_ward(net, 6, -1, 9, 11, 6, name="ward_3", in_service=False) + runpp(net) net_org = copy.deepcopy(net) - pp.replace_ward_by_internal_elements(net, [1]) + replace_ward_by_internal_elements(net, [1]) for elm in ["load", "shunt"]: assert net[elm].shape[0] == 2 res_load_created, res_shunt_created = copy.deepcopy(net.res_load), copy.deepcopy(net.res_shunt) - pp.runpp(net) + runpp(net) assert np.allclose(net_org.res_ext_grid.p_mw, net.res_ext_grid.p_mw) assert np.allclose(net_org.res_ext_grid.q_mvar, net.res_ext_grid.q_mvar) assert np.allclose(res_load_created, net.res_load) @@ -799,53 +810,53 @@ def test_replace_ward_by_internal_elements(): def test_replace_xward_by_internal_elements(): - net = nw.example_simple() - pp.create_xward(net, 1, 10, 5, -20, -10, 0.1, 0.55, 1.02, name="xward_1") - pp.create_xward(net, 5, 6, 8, 10, 5, 0.009, 0.678, 1.03, name="xward_2") - pp.create_xward(net, 6, 6, 8, 10, 5, 0.009, 0.678, 1.03, in_service=False, name="xward_3") - pp.create_group_from_dict(net, {"xward": [0]}, name="test group") - pp.runpp(net) + net = example_simple() + create_xward(net, 1, 10, 5, -20, -10, 0.1, 0.55, 1.02, name="xward_1") + create_xward(net, 5, 6, 8, 10, 5, 0.009, 0.678, 1.03, name="xward_2") + create_xward(net, 6, 6, 8, 10, 5, 0.009, 0.678, 1.03, in_service=False, name="xward_3") + create_group_from_dict(net, {"xward": [0]}, name="test group") + runpp(net) net_org = copy.deepcopy(net) - pp.replace_xward_by_internal_elements(net) - pp.runpp(net) + replace_xward_by_internal_elements(net) + runpp(net) assert abs(max(net_org.res_ext_grid.p_mw - net.res_ext_grid.p_mw)) < 1e-10 assert abs(max(net_org.res_ext_grid.q_mvar - net.res_ext_grid.q_mvar)) < 1e-10 new_ets = pd.Index(["load", "shunt", "gen", "impedance", "bus"]) - assert pp.count_group_elements(net_org, 0).to_dict() == {"xward": 1} - assert pp.count_group_elements(net, 0).to_dict() == {et: 1 for et in new_ets} - elm_change = pandapower.toolbox.count_elements(net, return_empties=True) - pandapower.toolbox.count_elements( + assert count_group_elements(net_org, 0).to_dict() == {"xward": 1} + assert count_group_elements(net, 0).to_dict() == {et: 1 for et in new_ets} + elm_change = count_elements(net, return_empties=True) - count_elements( net_org, return_empties=True) assert set(elm_change.loc[new_ets]) == {3} assert elm_change.at["xward"] == -3 assert set(elm_change.loc[elm_change.index.difference(new_ets).difference(pd.Index([ "xward"]))]) == {0} - net = nw.example_simple() - pp.create_xward(net, 1, 10, 5, -20, -10, 0.1, 0.55, 1.02, name="xward_1") - pp.create_xward(net, 5, 6, 8, 10, 5, 0.009, 0.678, 1.03, name="xward_2") - pp.create_xward(net, 6, 6, 8, 10, 5, 0.009, 0.678, 1.03, in_service=False, name="xward_3") - pp.runpp(net) + net = example_simple() + create_xward(net, 1, 10, 5, -20, -10, 0.1, 0.55, 1.02, name="xward_1") + create_xward(net, 5, 6, 8, 10, 5, 0.009, 0.678, 1.03, name="xward_2") + create_xward(net, 6, 6, 8, 10, 5, 0.009, 0.678, 1.03, in_service=False, name="xward_3") + runpp(net) net_org = copy.deepcopy(net) - pp.replace_xward_by_internal_elements(net, [0, 1]) - pp.runpp(net) + replace_xward_by_internal_elements(net, [0, 1]) + runpp(net) assert abs(max(net_org.res_ext_grid.p_mw - net.res_ext_grid.p_mw)) < 1e-10 assert abs(max(net_org.res_ext_grid.q_mvar - net.res_ext_grid.q_mvar)) < 1e-10 def test_repl_to_line(): - net = nw.simple_four_bus_system() + net = simple_four_bus_system() idx = 0 std_type = "NAYY 4x150 SE" - new_idx = pp.repl_to_line(net, idx, std_type, in_service=True) - pp.runpp(net) + new_idx = repl_to_line(net, idx, std_type, in_service=True) + runpp(net) vm1 = net.res_bus.vm_pu.values va1 = net.res_bus.va_degree.values net.line.at[new_idx, "in_service"] = False - pp.change_std_type(net, idx, std_type) - pp.runpp(net) + change_std_type(net, idx, std_type) + runpp(net) vm0 = net.res_bus.vm_pu.values va0 = net.res_bus.va_degree.values @@ -858,15 +869,15 @@ def test_repl_to_line_with_switch(): """ Same test as above, but this time in comparison to actual replacement """ - net = nw.example_multivoltage() - pp.runpp(net) + net = example_multivoltage() + runpp(net) for testindex in net.line.index: if net.line.in_service.loc[testindex]: line = net.line.loc[testindex] fbus = line.from_bus tbus = line.to_bus - len = line.length_km + len_ = line.length_km if "184-AL1/30-ST1A" in net.line.std_type.loc[testindex]: std = "243-AL1/39-ST1A 110.0" @@ -878,16 +889,16 @@ def test_repl_to_line_with_switch(): std = "24-AL1/4-ST1A 0.4" # create an oos line at the same buses - REPL = pp.create_line(net, from_bus=fbus, to_bus=tbus, length_km=len, std_type=std) + REPL = create_line(net, from_bus=fbus, to_bus=tbus, length_km=len_, std_type=std) for bus in fbus, tbus: if bus in net.switch[~net.switch.closed & (net.switch.element == testindex)].bus.values: - pp.create_switch(net, bus=bus, element=REPL, closed=False, et="l", type="LBS") + create_switch(net, bus=bus, element=REPL, closed=False, et="l", type="LBS") # calculate runpp with REPL net.line.loc[testindex, "in_service"] = False net.line.loc[REPL, "in_service"] = True - pp.runpp(net) + runpp(net) fbus_repl = net.res_bus.loc[fbus] tbus_repl = net.res_bus.loc[tbus] @@ -896,12 +907,12 @@ def test_repl_to_line_with_switch(): qloss_repl = (net.res_line.loc[REPL].q_from_mvar - net.res_line.loc[REPL].q_to_mvar) # get ne line impedances - new_idx = pp.repl_to_line(net, testindex, std, in_service=True) + new_idx = repl_to_line(net, testindex, std, in_service=True) # activate new idx line net.line.loc[REPL, "in_service"] = False net.line.loc[testindex, "in_service"] = True net.line.loc[new_idx, "in_service"] = True - pp.runpp(net) + runpp(net) # compare lf results fbus_ne = net.res_bus.loc[fbus] tbus_ne = net.res_bus.loc[tbus] @@ -924,8 +935,8 @@ def test_repl_to_line_with_switch(): def test_merge_parallel_line(): - net = nw.example_multivoltage() - pp.runpp(net) + net = example_multivoltage() + runpp(net) assert net.line.parallel.at[5] == 2 line = net.line.loc[5] @@ -937,10 +948,10 @@ def test_merge_parallel_line(): ploss_0 = (net.res_line.loc[5].p_from_mw - net.res_line.loc[5].p_to_mw) qloss_0 = (net.res_line.loc[5].q_from_mvar - net.res_line.loc[5].q_to_mvar) - net = pp.merge_parallel_line(net, 5) + net = merge_parallel_line(net, 5) assert net.line.parallel.at[5] == 1 - pp.runpp(net) + runpp(net) fbus_1 = net.res_bus.loc[fbus] tbus_1 = net.res_bus.loc[tbus] ploss_1 = (net.res_line.loc[5].p_from_mw - net.res_line.loc[5].p_to_mw) @@ -956,16 +967,16 @@ def test_merge_same_bus_generation_plants(): gen_elms = ["ext_grid", "gen", "sgen"] # --- test with case9 - net = nw.case9() + net = case9() buses = np.hstack([net[elm].bus.values for elm in gen_elms]) has_dupls = len(buses) > len(set(buses)) - something_merged = pp.merge_same_bus_generation_plants(net) + something_merged = merge_same_bus_generation_plants(net) assert has_dupls == something_merged # --- test with case24_ieee_rts - net = nw.case24_ieee_rts() + net = case24_ieee_rts() # manipulate net for different functionality checks # 1) q_mvar should be summed which is only possible if no gen or ext_grid has the same bus @@ -980,11 +991,10 @@ def test_merge_same_bus_generation_plants(): dupl_buses = [0, 1, 6, 12, 14, 21, 22] n_plants = sum([net[elm].bus.isin(dupl_buses).sum() for elm in gen_elms]) assert n_plants > len(dupl_buses) # check that in net are plants with same buses - expected_no_of_plants = sum([net[elm].shape[0] for elm in gen_elms]) - n_plants + \ - len(dupl_buses) + expected_no_of_plants = sum([net[elm].shape[0] for elm in gen_elms]) - n_plants + len(dupl_buses) # run function - something_merged = pp.merge_same_bus_generation_plants(net) + something_merged = merge_same_bus_generation_plants(net) # check results assert something_merged @@ -1006,11 +1016,11 @@ def test_merge_same_bus_generation_plants(): def test_set_isolated_areas_out_of_service(): - net = nw.case9() - pp.create_switch(net, 6, 5, "l", False) - pp.create_switch(net, 8, 7, "l", False) + net = case9() + create_switch(net, 6, 5, "l", False) + create_switch(net, 8, 7, "l", False) - pp.toolbox.set_isolated_areas_out_of_service(net) + set_isolated_areas_out_of_service(net) isolated_buses = [7, 1] isolated_lines = [5, 7, 6] diff --git a/pandapower/test/toolbox/test_power_factor.py b/pandapower/test/toolbox/test_power_factor.py index 79c5b7511..5c9e541a0 100644 --- a/pandapower/test/toolbox/test_power_factor.py +++ b/pandapower/test/toolbox/test_power_factor.py @@ -1,21 +1,28 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2016-2024 by University of Kassel and Fraunhofer Institute for Energy Economics +# and Energy System Technology (IEE), Kassel. All rights reserved. + import numpy as np import pandas as pd import pytest -import pandapower as pp +from pandapower.toolbox.element_selection import pp_elements +from pandapower.toolbox.power_factor import signing_system_value, cosphi_pos_neg_from_pq, pq_from_cosphi, \ + cosphi_to_pos, cosphi_from_pq, cosphi_from_pos def test_signing_system_value(): - assert pp.toolbox.signing_system_value("sgen") == -1 - assert pp.toolbox.signing_system_value("load") == 1 - for bus_elm in pp.toolbox.pp_elements(bus=False, branch_elements=False, other_elements=False): - assert pp.toolbox.signing_system_value(bus_elm) in [1, -1] + assert signing_system_value("sgen") == -1 + assert signing_system_value("load") == 1 + for bus_elm in pp_elements(bus=False, branch_elements=False, other_elements=False): + assert signing_system_value(bus_elm) in [1, -1] with pytest.raises(ValueError): - pp.toolbox.signing_system_value("sdfjio") + signing_system_value("sdfjio") def test_pq_from_cosphi(): - p, q = pp.toolbox.pq_from_cosphi(1 / 0.95, 0.95, "underexcited", "load") + p, q = pq_from_cosphi(1 / 0.95, 0.95, "underexcited", "load") assert np.isclose(p, 1) assert np.isclose(q, 0.3286841051788632) @@ -23,31 +30,31 @@ def test_pq_from_cosphi(): cosphi = np.array([1, 0.5, 0]) pmode = np.array(["load", "load", "load"]) qmode = np.array(["underexcited", "underexcited", "underexcited"]) - p, q = pp.toolbox.pq_from_cosphi(s, cosphi, qmode, pmode) + p, q = pq_from_cosphi(s, cosphi, qmode, pmode) excpected_values = (np.array([1, 0.5, 0]), np.array([0, 0.8660254037844386, 1])) assert np.allclose(p, excpected_values[0]) assert np.allclose(q, excpected_values[1]) pmode = "gen" - p, q = pp.toolbox.pq_from_cosphi(s, cosphi, qmode, pmode) + p, q = pq_from_cosphi(s, cosphi, qmode, pmode) assert np.allclose(p, excpected_values[0]) assert np.allclose(q, -excpected_values[1]) qmode = "overexcited" - p, q = pp.toolbox.pq_from_cosphi(s, cosphi, qmode, pmode) + p, q = pq_from_cosphi(s, cosphi, qmode, pmode) assert np.allclose(p, excpected_values[0]) assert np.allclose(q, excpected_values[1]) with pytest.raises(ValueError): - pp.toolbox.pq_from_cosphi(1, 0.95, "ohm", "gen") + pq_from_cosphi(1, 0.95, "ohm", "gen") - p, q = pp.toolbox.pq_from_cosphi(0, 0.8, "overexcited", "gen") + p, q = pq_from_cosphi(0, 0.8, "overexcited", "gen") assert np.isclose(p, 0) assert np.isclose(q, 0) def test_cosphi_from_pq(): - cosphi, s, qmode, pmode = pp.toolbox.cosphi_from_pq(1, 0.4) + cosphi, s, qmode, pmode = cosphi_from_pq(1, 0.4) assert np.isclose(cosphi, 0.9284766908852593) assert np.isclose(s, 1.077032961426901) assert qmode == 'underexcited' @@ -55,7 +62,7 @@ def test_cosphi_from_pq(): p = np.array([1, 1, 1, 1, 1, 0, 0, 0, -1, -1, -1]) q = np.array([1, -1, 0, 0.5, -0.5, 1, -1, 0, 1, -1, 0]) - cosphi, s, qmode, pmode = pp.toolbox.cosphi_from_pq(p, q) + cosphi, s, qmode, pmode = cosphi_from_pq(p, q) assert np.allclose(cosphi[[0, 1, 8, 9]], 2 ** 0.5 / 2) assert np.allclose(cosphi[[3, 4]], 0.89442719) assert np.allclose(cosphi[[2, 10]], 1) @@ -67,33 +74,33 @@ def test_cosphi_from_pq(): def test_cosphi_to_pos(): - assert np.isclose(pp.toolbox.cosphi_to_pos(0.96), 0.96) - assert np.isclose(pp.toolbox.cosphi_to_pos(-0.94), 1.06) - assert np.isclose(pp.toolbox.cosphi_to_pos(-0.96), 1.04) - assert np.allclose(pp.toolbox.cosphi_to_pos([0.96, -0.94, -0.96]), np.array([0.96, 1.06, 1.04])) + assert np.isclose(cosphi_to_pos(0.96), 0.96) + assert np.isclose(cosphi_to_pos(-0.94), 1.06) + assert np.isclose(cosphi_to_pos(-0.96), 1.04) + assert np.allclose(cosphi_to_pos([0.96, -0.94, -0.96]), np.array([0.96, 1.06, 1.04])) def test_cosphi_from_pos(): - assert np.isclose(pp.toolbox.cosphi_from_pos(0.96), 0.96) - assert np.isclose(pp.toolbox.cosphi_from_pos(1.06), -0.94) - assert np.isclose(pp.toolbox.cosphi_from_pos(1.04), -0.96) - assert np.allclose(pp.toolbox.cosphi_from_pos([0.96, 1.06, 1.04]), np.array([0.96, -0.94, -0.96])) + assert np.isclose(cosphi_from_pos(0.96), 0.96) + assert np.isclose(cosphi_from_pos(1.06), -0.94) + assert np.isclose(cosphi_from_pos(1.04), -0.96) + assert np.allclose(cosphi_from_pos([0.96, 1.06, 1.04]), np.array([0.96, -0.94, -0.96])) def test_cosphi_pos_neg(): - assert np.isclose(np.round(pp.toolbox.cosphi_pos_neg_from_pq(2, 0.), 5), 1) - assert np.isclose(np.round(pp.toolbox.cosphi_pos_neg_from_pq(0.76, 0.25), 5), 0.94993) - assert np.isclose(np.round(pp.toolbox.cosphi_pos_neg_from_pq(-0.76, 0.25), 5), 0.94993) - assert np.isclose(np.round(pp.toolbox.cosphi_pos_neg_from_pq(0.76, -0.25), 5), -0.94993) + assert np.isclose(np.round(cosphi_pos_neg_from_pq(2, 0.), 5), 1) + assert np.isclose(np.round(cosphi_pos_neg_from_pq(0.76, 0.25), 5), 0.94993) + assert np.isclose(np.round(cosphi_pos_neg_from_pq(-0.76, 0.25), 5), 0.94993) + assert np.isclose(np.round(cosphi_pos_neg_from_pq(0.76, -0.25), 5), -0.94993) assert np.allclose( - np.round(pp.toolbox.cosphi_pos_neg_from_pq([0.76, 0.76, 0.76, 0.76], [0.25, -0.25, 0, 0.1]), 5), - np.array([ 0.94993, -0.94993, 1. , 0.99145])) + np.round(cosphi_pos_neg_from_pq([0.76, 0.76, 0.76, 0.76], [0.25, -0.25, 0, 0.1]), 5), + np.array([0.94993, -0.94993, 1., 0.99145])) assert np.allclose( - np.round(pp.toolbox.cosphi_pos_neg_from_pq( + np.round(cosphi_pos_neg_from_pq( [0.76, 0.76, -0.76, 0.76, 0, 0.1], [0.25, -0.25, 0.25, 0.1, 0.1, 0]), 5), - np.array([ 0.94993, -0.94993, 0.94993, 0.99145, np.nan, 1]), equal_nan=True) + np.array([0.94993, -0.94993, 0.94993, 0.99145, np.nan, 1]), equal_nan=True) if __name__ == '__main__': - pytest.main([__file__, "-xs"]) \ No newline at end of file + pytest.main([__file__, "-xs"]) diff --git a/pandapower/test/toolbox/test_result_info.py b/pandapower/test/toolbox/test_result_info.py index a26cc806b..a6ef04a39 100644 --- a/pandapower/test/toolbox/test_result_info.py +++ b/pandapower/test/toolbox/test_result_info.py @@ -6,32 +6,34 @@ import numpy as np import pytest -import pandapower as pp -import pandapower.networks as nw -import pandapower.toolbox +from pandapower import create_empty_network, create_buses, create_ext_grid, create_gen, create_load, create_sgen, \ + create_storage, create_dcline, create_line, create_transformer, opf_task, runpp, overloaded_lines, create_bus, \ + create_poly_cost, create_pwl_cost, violated_buses, clear_result_tables +from pandapower.networks import create_cigre_network_lv, case9 +from pandapower.toolbox import dataframes_equal, res_power_columns def test_opf_task(): - net = pp.create_empty_network() - pp.create_buses(net, 6, [10, 10, 10, 0.4, 7, 7], + net = create_empty_network() + create_buses(net, 6, [10, 10, 10, 0.4, 7, 7], min_vm_pu=[0.9, 0.9, 0.88, 0.9, np.nan, np.nan]) idx_ext_grid = 1 - pp.create_ext_grid(net, 0, max_q_mvar=80, min_p_mw=0, index=idx_ext_grid) - pp.create_gen(net, 1, 10, min_q_mvar=-50, max_q_mvar=-10, min_p_mw=0, max_p_mw=60) - pp.create_gen(net, 2, 8) - pp.create_gen(net, 3, 5) - pp.create_load(net, 3, 120, max_p_mw=8) - pp.create_sgen(net, 1, 8, min_q_mvar=-50, max_q_mvar=-10, controllable=False) - pp.create_sgen(net, 2, 8) - pp.create_storage(net, 3, 2, 100, min_q_mvar=-10, max_q_mvar=-50, min_p_mw=0, max_p_mw=60, + create_ext_grid(net, 0, max_q_mvar=80, min_p_mw=0, index=idx_ext_grid) + create_gen(net, 1, 10, min_q_mvar=-50, max_q_mvar=-10, min_p_mw=0, max_p_mw=60) + create_gen(net, 2, 8) + create_gen(net, 3, 5) + create_load(net, 3, 120, max_p_mw=8) + create_sgen(net, 1, 8, min_q_mvar=-50, max_q_mvar=-10, controllable=False) + create_sgen(net, 2, 8) + create_storage(net, 3, 2, 100, min_q_mvar=-10, max_q_mvar=-50, min_p_mw=0, max_p_mw=60, controllable=True) - pp.create_dcline(net, 4, 5, 0.3, 1e-4, 1e-2, 1.01, 1.02, min_q_from_mvar=-10, + create_dcline(net, 4, 5, 0.3, 1e-4, 1e-2, 1.01, 1.02, min_q_from_mvar=-10, min_q_to_mvar=-10) - pp.create_line(net, 3, 4, 5, "122-AL1/20-ST1A 10.0", max_loading_percent=50) - pp.create_transformer(net, 2, 3, "0.25 MVA 10/0.4 kV") + create_line(net, 3, 4, 5, "122-AL1/20-ST1A 10.0", max_loading_percent=50) + create_transformer(net, 2, 3, "0.25 MVA 10/0.4 kV") # --- run and check opf_task() - out1 = pp.opf_task(net, keep=True) + out1 = opf_task(net, keep=True) assert out1["flexibilities_without_costs"] == "all" assert sorted(out1["flexibilities"].keys()) == [i1 + i2 for i1 in ["P", "Q"] for i2 in [ "dcline", "ext_grid", "gen", "storage"]] @@ -49,25 +51,25 @@ def test_opf_task(): # check delta_pq net.gen.loc[0, "min_p_mw"] = net.gen.loc[0, "max_p_mw"] - 1e-5 - out2 = pp.opf_task(net, delta_pq=1e-3, keep=True) + out2 = opf_task(net, delta_pq=1e-3, keep=True) assert out2["flexibilities"]["Pgen"].shape[0] == 1 net.gen.loc[0, "min_p_mw"] = net.gen.loc[0, "max_p_mw"] - 1e-1 out1["flexibilities"]["Pgen"].loc[0, "min"] = out1["flexibilities"]["Pgen"].loc[ 0, "max"] - 1e-1 - out3 = pp.opf_task(net, delta_pq=1e-3, keep=True) + out3 = opf_task(net, delta_pq=1e-3, keep=True) for key in out3["flexibilities"]: - assert pandapower.toolbox.dataframes_equal(out3["flexibilities"][key], out1["flexibilities"][key]) + assert dataframes_equal(out3["flexibilities"][key], out1["flexibilities"][key]) # check costs - pp.create_poly_cost(net, idx_ext_grid, "ext_grid", 2) - pp.create_poly_cost(net, 1, "gen", 1.7) - pp.create_poly_cost(net, 0, "dcline", 2) - pp.create_pwl_cost(net, 2, "gen", [[-1e9, 1, 3.1], [1, 1e9, 0.5]], power_type="q") - out4 = pp.opf_task(net) + create_poly_cost(net, idx_ext_grid, "ext_grid", 2) + create_poly_cost(net, 1, "gen", 1.7) + create_poly_cost(net, 0, "dcline", 2) + create_pwl_cost(net, 2, "gen", [[-1e9, 1, 3.1], [1, 1e9, 0.5]], power_type="q") + out4 = opf_task(net) for dict_key in ["flexibilities", "network_constraints"]: for key in out4[dict_key]: - assert pandapower.toolbox.dataframes_equal(out4[dict_key][key], out1[dict_key][key]) + assert dataframes_equal(out4[dict_key][key], out1[dict_key][key]) assert isinstance(out4["flexibilities_without_costs"], dict) expected_elm_without_cost = ["gen", "storage"] assert sorted(out4["flexibilities_without_costs"].keys()) == expected_elm_without_cost @@ -76,65 +78,65 @@ def test_opf_task(): def test_overloaded_lines(): - net = pp.create_empty_network() + net = create_empty_network() - bus0 = pp.create_bus(net, vn_kv=.4) - bus1 = pp.create_bus(net, vn_kv=.4) + bus0 = create_bus(net, vn_kv=.4) + bus1 = create_bus(net, vn_kv=.4) - pp.create_ext_grid(net, bus0) + create_ext_grid(net, bus0) - line0 = pp.create_line(net, bus0, bus1, length_km=1, std_type="NAYY 4x50 SE") - line1 = pp.create_line(net, bus0, bus1, length_km=1, std_type="NA2XS2Y 1x95 RM/25 12/20 kV") - line2 = pp.create_line(net, bus0, bus1, length_km=1, std_type="15-AL1/3-ST1A 0.4") - pp.create_line(net, bus0, bus1, length_km=10, std_type="149-AL1/24-ST1A 10.0") + line0 = create_line(net, bus0, bus1, length_km=1, std_type="NAYY 4x50 SE") + line1 = create_line(net, bus0, bus1, length_km=1, std_type="NA2XS2Y 1x95 RM/25 12/20 kV") + line2 = create_line(net, bus0, bus1, length_km=1, std_type="15-AL1/3-ST1A 0.4") + create_line(net, bus0, bus1, length_km=10, std_type="149-AL1/24-ST1A 10.0") - pp.create_load(net, bus1, p_mw=0.2, q_mvar=0.05) + create_load(net, bus1, p_mw=0.2, q_mvar=0.05) - pp.runpp(net) + runpp(net) # test the overloaded lines by default value of max_load=100 - overloaded_lines = pp.overloaded_lines(net, max_load=100) + overloaded_lines_ = overloaded_lines(net, max_load=100) - assert set(overloaded_lines) == {line0, line1} + assert set(overloaded_lines_) == {line0, line1} # test the overloaded lines by a self defined value of max_load=50 - overloaded_lines = pp.overloaded_lines(net, max_load=50) + overloaded_lines_ = overloaded_lines(net, max_load=50) - assert set(overloaded_lines) == {line0, line1, line2} + assert set(overloaded_lines_) == {line0, line1, line2} def test_violated_buses(): - net = nw.create_cigre_network_lv() + net = create_cigre_network_lv() - pp.runpp(net) + runpp(net) # set the range of vm.pu min_vm_pu = 0.92 max_vm_pu = 1.1 # print out the list of violated_bus's index - violated_bus = pp.violated_buses(net, min_vm_pu, max_vm_pu) + violated_bus = violated_buses(net, min_vm_pu, max_vm_pu) assert set(violated_bus) == set(net["bus"].index[[16, 35, 36, 40]]) def test_clear_result_tables(): - net = nw.case9() - pp.runpp(net) + net = case9() + runpp(net) elms_to_check = ["bus", "line", "load"] for elm in elms_to_check: assert net["res_%s" % elm].shape[0] - pp.clear_result_tables(net) + clear_result_tables(net) for elm in elms_to_check: assert not net["res_%s" % elm].shape[0] def test_res_power_columns(): - assert pandapower.toolbox.res_power_columns("gen") == ["p_mw", "q_mvar"] - assert pandapower.toolbox.res_power_columns("line") == pandapower.toolbox.res_power_columns("line", side="from") == \ - pandapower.toolbox.res_power_columns("line", side=0) == ["p_from_mw", "q_from_mvar"] - assert pandapower.toolbox.res_power_columns("line", side="all") == [ + assert res_power_columns("gen") == ["p_mw", "q_mvar"] + assert res_power_columns("line") == res_power_columns("line", side="from") == \ + res_power_columns("line", side=0) == ["p_from_mw", "q_from_mvar"] + assert res_power_columns("line", side="all") == [ "p_from_mw", "q_from_mvar", "p_to_mw", "q_to_mvar"] - assert pandapower.toolbox.res_power_columns("trafo3w", side="all") == [ + assert res_power_columns("trafo3w", side="all") == [ "p_hv_mw", "q_hv_mvar", "p_mv_mw", "q_mv_mvar", "p_lv_mw", "q_lv_mvar"] diff --git a/pandapower/test/topology/test_create_graph.py b/pandapower/test/topology/test_create_graph.py index a42293383..1534351a0 100644 --- a/pandapower/test/topology/test_create_graph.py +++ b/pandapower/test/topology/test_create_graph.py @@ -8,16 +8,15 @@ import numpy as np import pytest -import pandapower as pp +from pandapower.create import create_empty_network, create_switch from pandapower.pypower.idx_brch import BR_R, BR_X +from pandapower.run import runpp from pandapower.test.loadflow.result_test_network_generator import add_test_trafo3w, \ add_test_trafo, add_test_line, \ add_test_impedance, \ add_test_bus_bus_switch from pandapower.test.loadflow.test_scenarios import network_with_trafo3ws -from pandapower.topology import create_nxgraph -from pandapower.topology.create_graph import graph_tool_available - +from pandapower.topology.create_graph import create_nxgraph, graph_tool_available libraries = ["networkx"] if graph_tool_available: @@ -25,7 +24,7 @@ def test_line(): - net = pp.create_empty_network() + net = create_empty_network() add_test_line(net) line, open_loop_line, oos_line = net.line.index f, t = net.line.from_bus.at[line], net.line.to_bus.at[line] @@ -62,14 +61,14 @@ def test_line(): mg = create_nxgraph(net, calc_branch_impedances=True, branch_impedance_unit="pu", library=library) line_tab = net.line.loc[line] par = mg.get_edge_data(f, t, key=("line", line)) - pp.runpp(net) + runpp(net) f, t = net._pd2ppc_lookups["branch"]["line"] assert np.isclose(par["r_pu"], net._ppc["branch"][f, BR_R]) assert np.isclose(par["x_pu"], net._ppc["branch"][f, BR_X]) def test_trafo(): - net = pp.create_empty_network() + net = create_empty_network() add_test_trafo(net) for library in libraries: @@ -98,7 +97,7 @@ def test_trafo(): mg = create_nxgraph(net, calc_branch_impedances=True, library=library) trafo_tab = net.trafo.loc[trafo] par = mg.get_edge_data(f, t, key=("trafo", trafo)) - base_Z = (trafo_tab.sn_mva) / (trafo_tab.vn_hv_kv ** 2) + base_Z = trafo_tab.sn_mva / (trafo_tab.vn_hv_kv ** 2) r = (trafo_tab.vkr_percent / 100) / base_Z / trafo_tab.parallel z = (trafo_tab.vk_percent / 100) / base_Z / trafo_tab.parallel assert np.isclose(par["r_ohm"], r) @@ -108,7 +107,7 @@ def test_trafo(): mg = create_nxgraph(net, calc_branch_impedances=True, branch_impedance_unit="pu", library=library) par = mg.get_edge_data(f, t, key=("trafo", trafo)) - pp.runpp(net) + runpp(net) f, t = net._pd2ppc_lookups["branch"]["trafo"] assert np.isclose(par["r_pu"], net._ppc["branch"][f, BR_R]) assert np.isclose(par["x_pu"], net._ppc["branch"][f, BR_X]) @@ -116,7 +115,7 @@ def test_trafo(): def test_trafo3w(): for library in libraries: - net = pp.create_empty_network() + net = create_empty_network() add_test_trafo3w(net) t1, t2 = net.trafo3w.index @@ -134,7 +133,7 @@ def test_trafo3w(): assert set(mg.nodes()) == set(net.bus.index) for sb in [hv, mv, lv]: - sw = pp.create_switch(net, bus=sb, element=t1, et="t3", closed=False) + sw = create_switch(net, bus=sb, element=t1, et="t3", closed=False) mg = create_nxgraph(net, library=library) for f, t in combinations([hv, mv, lv], 2): if sb == f or t == sb: @@ -179,7 +178,7 @@ def test_trafo3w_impedances(network_with_trafo3ws): def test_impedance(): - net = pp.create_empty_network() + net = create_empty_network() add_test_impedance(net) for library in libraries: @@ -197,7 +196,7 @@ def test_impedance(): # check edge attributes mg = create_nxgraph(net, calc_branch_impedances=True, branch_impedance_unit="pu", library=library) - pp.runpp(net) + runpp(net) par = mg.get_edge_data(f, t, key=("impedance", impedance)) assert np.isclose(par["weight"], 0) @@ -208,7 +207,7 @@ def test_impedance(): def test_bus_bus_switches(): - net = pp.create_empty_network() + net = create_empty_network() add_test_bus_bus_switch(net) for library in libraries: @@ -239,7 +238,7 @@ def test_bus_bus_switches(): def test_nogo(): - net = pp.create_empty_network() + net = create_empty_network() add_test_line(net) mg = create_nxgraph(net) assert set(mg.nodes()) == set(net.bus.index) @@ -248,7 +247,7 @@ def test_nogo(): def test_branch_impedance_unit(): - net = pp.create_empty_network() + net = create_empty_network() with pytest.raises(ValueError) as exception_info: mg = create_nxgraph(net, branch_impedance_unit="p.u.") assert str(exception_info.value) == "branch impedance unit can be either 'ohm' or 'pu'" @@ -257,7 +256,7 @@ def test_branch_impedance_unit(): @pytest.mark.xfail(reason="This test fails, since graph_tool bus indices must be a range(0, n_buses). " "If a bus is removed, graph-tool is not working.") def test_nogo_graph_tool(): - net = pp.create_empty_network() + net = create_empty_network() add_test_line(net) mg = create_nxgraph(net, library="graph_tool") assert set(mg.nodes()) == set(net.bus.index) @@ -266,4 +265,4 @@ def test_nogo_graph_tool(): if __name__ == '__main__': - pytest.main([__file__, "-xs"]) \ No newline at end of file + pytest.main([__file__, "-xs"]) diff --git a/pandapower/test/topology/test_graph_searches.py b/pandapower/test/topology/test_graph_searches.py index 731cec104..f2c59a531 100644 --- a/pandapower/test/topology/test_graph_searches.py +++ b/pandapower/test/topology/test_graph_searches.py @@ -3,214 +3,222 @@ # Copyright (c) 2016-2024 by University of Kassel and Fraunhofer Institute for Energy Economics # and Energy System Technology (IEE), Kassel. All rights reserved. - +import networkx as nx import numpy as np -import pandapower as pp import pytest -import pandapower.topology as top -import pandapower.networks as nw -import networkx as nx + +from pandapower.create import create_empty_network, create_bus, create_line, create_ext_grid, create_switch, \ + create_transformer, create_buses, create_impedance +from pandapower.networks.create_examples import example_simple +from pandapower.topology.create_graph import create_nxgraph +from pandapower.topology.graph_searches import connected_components, determine_stubs, calc_distance_to_bus, \ + unsupplied_buses, find_graph_characteristics, elements_on_path, lines_on_path, \ + get_end_points_of_continuously_connected_lines @pytest.fixture def feeder_network(): - net = pp.create_empty_network() - current_bus = pp.create_bus(net, vn_kv=20.) - pp.create_ext_grid(net, current_bus) + net = create_empty_network() + current_bus = create_bus(net, vn_kv=20.) + create_ext_grid(net, current_bus) for length in [12, 6, 8]: - new_bus = pp.create_bus(net, vn_kv=20.) - pp.create_line(net, current_bus, new_bus, length_km=length, - std_type="NA2XS2Y 1x185 RM/25 12/20 kV") + new_bus = create_bus(net, vn_kv=20.) + create_line(net, current_bus, new_bus, length_km=length, + std_type="NA2XS2Y 1x185 RM/25 12/20 kV") current_bus = new_bus - pp.create_line(net, current_bus, 0, length_km=5, std_type="NA2XS2Y 1x185 RM/25 12/20 kV") + create_line(net, current_bus, 0, length_km=5, std_type="NA2XS2Y 1x185 RM/25 12/20 kV") return net @pytest.fixture def meshed_network(): - net = pp.create_empty_network("7bus_system") + net = create_empty_network("7bus_system") # ext grid - b = [] - b.append(pp.create_bus(net, vn_kv=380., name="exi", geodata=(0, 0))) - pp.create_ext_grid(net, b[0], name="exi") + b = [create_bus(net, vn_kv=380., name="exi", geodata=(0, 0))] + create_ext_grid(net, b[0], name="exi") # create 110kV buses for i in range(1, 7): - b.append(pp.create_bus(net, vn_kv=110., name="bus" + str(i), geodata=(0, 0))) + b.append(create_bus(net, vn_kv=110., name="bus" + str(i), geodata=(0, 0))) # connect buses b1 to b6 with overhead lines for i in range(1, 6): - l = pp.create_line(net, b[i], b[i + 1], length_km=10. * i * 2., + line = create_line(net, b[i], b[i + 1], length_km=10. * i * 2., std_type="149-AL1/24-ST1A 110.0", name="line" + str(i), index=i + 2) - pp.create_switch(net, b[i], l, et="l", name="bl_switch_" + str(i), index=i + 3) + create_switch(net, b[i], line, et="l", name="bl_switch_" + str(i), index=i + 3) # create trafo - pp.create_transformer(net, hv_bus=b[0], lv_bus=b[1], std_type="160 MVA 380/110 kV", name="trafo") + create_transformer(net, hv_bus=b[0], lv_bus=b[1], std_type="160 MVA 380/110 kV", name="trafo") # create some more lines between b6-b1 and b1-b4 - pp.create_line(net, b[1], b[4], length_km=100., std_type="149-AL1/24-ST1A 110.0", name="line6") - pp.create_line(net, b[6], b[1], length_km=100., std_type="149-AL1/24-ST1A 110.0", name="line7") + create_line(net, b[1], b[4], length_km=100., std_type="149-AL1/24-ST1A 110.0", name="line6") + create_line(net, b[6], b[1], length_km=100., std_type="149-AL1/24-ST1A 110.0", name="line7") return net + @pytest.fixture def mixed_network(): - net = pp.create_empty_network() - pp.create_buses(net, nr_buses=5, vn_kv=20.) + net = create_empty_network() + create_buses(net, nr_buses=5, vn_kv=20.) connections = [(0, 1), (1, 2), (2, 3), (2, 4)] for fb, tb in connections: - pp.create_line(net, fb, tb, length_km=1, std_type="NA2XS2Y 1x185 RM/25 12/20 kV") + create_line(net, fb, tb, length_km=1, std_type="NA2XS2Y 1x185 RM/25 12/20 kV") for b in [1, 4, 3]: - pp.create_ext_grid(net, b) + create_ext_grid(net, b) return net + def test_connected_components(feeder_network): net = feeder_network - mg = top.create_nxgraph(net) - cc = top.connected_components(mg) + mg = create_nxgraph(net) + cc = connected_components(mg) assert list(cc) == [{0, 1, 2, 3}] - cc_notrav = top.connected_components(mg, notravbuses={0,2}) + cc_notrav = connected_components(mg, notravbuses={0, 2}) assert list(cc_notrav) == [{0, 1, 2}, {0, 2, 3}] + def test_determine_stubs(feeder_network): net = feeder_network - sec_bus = pp.create_bus(net, vn_kv=20.) - sec_line = pp.create_line(net, 3, sec_bus, length_km=3, std_type="NA2XS2Y 1x185 RM/25 12/20 kV") - top.determine_stubs(net) + sec_bus = create_bus(net, vn_kv=20.) + sec_line = create_line(net, 3, sec_bus, length_km=3, std_type="NA2XS2Y 1x185 RM/25 12/20 kV") + determine_stubs(net) assert not np.any(net.bus.on_stub.loc[list(set(net.bus.index) - {sec_bus})].values) assert not np.any(net.line.is_stub.loc[list(set(net.line.index) - {sec_line})].values) assert net.bus.on_stub.at[sec_bus] assert net.line.is_stub.at[sec_line] + def test_determine_stubs_meshed(meshed_network): net = meshed_network # root == LV side of trafo at ext_grid. Then ext_grid bus itself (0) == stub - stubs = top.determine_stubs(net, roots=[1]) + stubs = determine_stubs(net, roots=[1]) assert len(stubs) == 1 assert stubs.pop() == 0 + def test_determine_stubs_mixed(mixed_network): net = mixed_network - stubs = top.determine_stubs(net, roots=[1, 4, 3]) + stubs = determine_stubs(net, roots=[1, 4, 3]) assert stubs == {0} - stubs = top.determine_stubs(net, roots=[4, 3, 1]) + stubs = determine_stubs(net, roots=[4, 3, 1]) assert stubs == {0} + def test_distance(feeder_network): net = feeder_network - dist = top.calc_distance_to_bus(net, 0) + dist = calc_distance_to_bus(net, 0) assert np.allclose(dist.sort_index().values, [0, 12, 13, 5]) - dist = top.calc_distance_to_bus(net, 0, notravbuses={3}) + dist = calc_distance_to_bus(net, 0, notravbuses={3}) assert np.allclose(dist.sort_index().values, [0, 12, 18, 5]) - pp.create_switch(net, bus=3, element=2, et="l", closed=False) - dist = top.calc_distance_to_bus(net, 0) + create_switch(net, bus=3, element=2, et="l", closed=False) + dist = calc_distance_to_bus(net, 0) assert np.allclose(dist.sort_index().values, [0, 12, 18, 5]) - - dist = top.calc_distance_to_bus(net, 0, weight=None) + + dist = calc_distance_to_bus(net, 0, weight=None) assert np.allclose(dist.sort_index().values, [0, 1, 2, 1]) + def test_unsupplied_buses_with_in_service(): # IS ext_grid --- open switch --- OOS bus --- open switch --- IS bus - net = pp.create_empty_network() + net = create_empty_network() - slack_bus = pp.create_bus(net, 0.4) - pp.create_ext_grid(net, slack_bus) + slack_bus = create_bus(net, 0.4) + create_ext_grid(net, slack_bus) - bus0 = pp.create_bus(net, 0.4, in_service=False) - pp.create_switch(net, slack_bus, bus0, 'b', False) + bus0 = create_bus(net, 0.4, in_service=False) + create_switch(net, slack_bus, bus0, 'b', False) - bus1 = pp.create_bus(net, 0.4, in_service=True) - pp.create_switch(net, bus0, bus1, 'b', False) + bus1 = create_bus(net, 0.4, in_service=True) + create_switch(net, bus0, bus1, 'b', False) - ub = top.unsupplied_buses(net) + ub = unsupplied_buses(net) assert ub == {2} - - # OOS ext_grid --- closed switch --- IS bus - net = pp.create_empty_network() + net = create_empty_network() - bus_sl = pp.create_bus(net, 0.4) - pp.create_ext_grid(net, bus_sl, in_service=False) + bus_sl = create_bus(net, 0.4) + create_ext_grid(net, bus_sl, in_service=False) - bus0 = pp.create_bus(net, 0.4, in_service=True) - pp.create_switch(net, bus_sl, bus0, 'b', True) + bus0 = create_bus(net, 0.4, in_service=True) + create_switch(net, bus_sl, bus0, 'b', True) - ub = top.unsupplied_buses(net) + ub = unsupplied_buses(net) assert ub == {0, 1} def test_unsupplied_buses_with_switches(): - net = pp.create_empty_network() - pp.create_buses(net, 8, 20) - pp.create_buses(net, 5, 0.4) - pp.create_ext_grid(net, 0) - pp.create_line(net, 0, 1, 1.2, "NA2XS2Y 1x185 RM/25 12/20 kV") - pp.create_switch(net, 0, 0, "l", closed=True) - pp.create_switch(net, 1, 0, "l", closed=False) - pp.create_line(net, 0, 2, 1.2, "NA2XS2Y 1x185 RM/25 12/20 kV") - pp.create_switch(net, 0, 1, "l", closed=False) - pp.create_switch(net, 2, 1, "l", closed=True) - pp.create_line(net, 0, 3, 1.2, "NA2XS2Y 1x185 RM/25 12/20 kV") - pp.create_switch(net, 0, 2, "l", closed=False) - pp.create_switch(net, 3, 2, "l", closed=False) - pp.create_line(net, 0, 4, 1.2, "NA2XS2Y 1x185 RM/25 12/20 kV") - pp.create_switch(net, 0, 3, "l", closed=True) - pp.create_switch(net, 4, 3, "l", closed=True) - pp.create_line(net, 0, 5, 1.2, "NA2XS2Y 1x185 RM/25 12/20 kV") - - pp.create_switch(net, 0, 6, "b", closed=True) - pp.create_switch(net, 0, 7, "b", closed=False) - - pp.create_transformer(net, 0, 8, "0.63 MVA 20/0.4 kV") - pp.create_switch(net, 0, 0, "t", closed=True) - pp.create_switch(net, 8, 0, "t", closed=False) - pp.create_transformer(net, 0, 9, "0.63 MVA 20/0.4 kV") - pp.create_switch(net, 0, 1, "t", closed=False) - pp.create_switch(net, 9, 1, "t", closed=True) - pp.create_transformer(net, 0, 10, "0.63 MVA 20/0.4 kV") - pp.create_switch(net, 0, 2, "t", closed=False) - pp.create_switch(net, 10, 2, "t", closed=False) - pp.create_transformer(net, 0, 11, "0.63 MVA 20/0.4 kV") - pp.create_switch(net, 0, 3, "t", closed=True) - pp.create_switch(net, 11, 3, "t", closed=True) - pp.create_transformer(net, 0, 12, "0.63 MVA 20/0.4 kV") - - pp.create_buses(net, 2, 20) - pp.create_impedance(net, 0, 13, 1, 1, 10) - pp.create_impedance(net, 0, 14, 1, 1, 10, in_service=False) - - ub = top.unsupplied_buses(net) + net = create_empty_network() + create_buses(net, 8, 20) + create_buses(net, 5, 0.4) + create_ext_grid(net, 0) + create_line(net, 0, 1, 1.2, "NA2XS2Y 1x185 RM/25 12/20 kV") + create_switch(net, 0, 0, "l", closed=True) + create_switch(net, 1, 0, "l", closed=False) + create_line(net, 0, 2, 1.2, "NA2XS2Y 1x185 RM/25 12/20 kV") + create_switch(net, 0, 1, "l", closed=False) + create_switch(net, 2, 1, "l", closed=True) + create_line(net, 0, 3, 1.2, "NA2XS2Y 1x185 RM/25 12/20 kV") + create_switch(net, 0, 2, "l", closed=False) + create_switch(net, 3, 2, "l", closed=False) + create_line(net, 0, 4, 1.2, "NA2XS2Y 1x185 RM/25 12/20 kV") + create_switch(net, 0, 3, "l", closed=True) + create_switch(net, 4, 3, "l", closed=True) + create_line(net, 0, 5, 1.2, "NA2XS2Y 1x185 RM/25 12/20 kV") + + create_switch(net, 0, 6, "b", closed=True) + create_switch(net, 0, 7, "b", closed=False) + + create_transformer(net, 0, 8, "0.63 MVA 20/0.4 kV") + create_switch(net, 0, 0, "t", closed=True) + create_switch(net, 8, 0, "t", closed=False) + create_transformer(net, 0, 9, "0.63 MVA 20/0.4 kV") + create_switch(net, 0, 1, "t", closed=False) + create_switch(net, 9, 1, "t", closed=True) + create_transformer(net, 0, 10, "0.63 MVA 20/0.4 kV") + create_switch(net, 0, 2, "t", closed=False) + create_switch(net, 10, 2, "t", closed=False) + create_transformer(net, 0, 11, "0.63 MVA 20/0.4 kV") + create_switch(net, 0, 3, "t", closed=True) + create_switch(net, 11, 3, "t", closed=True) + create_transformer(net, 0, 12, "0.63 MVA 20/0.4 kV") + + create_buses(net, 2, 20) + create_impedance(net, 0, 13, 1, 1, 10) + create_impedance(net, 0, 14, 1, 1, 10, in_service=False) + + ub = unsupplied_buses(net) assert ub == {1, 2, 3, 7, 8, 9, 10, 14} - ub = top.unsupplied_buses(net, respect_switches=False) + ub = unsupplied_buses(net, respect_switches=False) assert ub == {14} def test_graph_characteristics(feeder_network): # adapt network net = feeder_network - bus0 = pp.create_bus(net, vn_kv=20.0) - bus1 = pp.create_bus(net, vn_kv=20.0) - bus2 = pp.create_bus(net, vn_kv=20.0) - bus3 = pp.create_bus(net, vn_kv=20.0) - bus4 = pp.create_bus(net, vn_kv=20.0) - bus5 = pp.create_bus(net, vn_kv=20.0) - bus6 = pp.create_bus(net, vn_kv=20.0) - bus7 = pp.create_bus(net, vn_kv=20.0) - bus8 = pp.create_bus(net, vn_kv=20.0) - bus9 = pp.create_bus(net, vn_kv=20.0) + bus0 = create_bus(net, vn_kv=20.0) + bus1 = create_bus(net, vn_kv=20.0) + bus2 = create_bus(net, vn_kv=20.0) + bus3 = create_bus(net, vn_kv=20.0) + bus4 = create_bus(net, vn_kv=20.0) + bus5 = create_bus(net, vn_kv=20.0) + bus6 = create_bus(net, vn_kv=20.0) + bus7 = create_bus(net, vn_kv=20.0) + bus8 = create_bus(net, vn_kv=20.0) + bus9 = create_bus(net, vn_kv=20.0) new_connections = [(3, bus0), (bus0, bus1), (bus0, bus2), (1, bus3), (2, bus4), (bus3, bus4), (bus4, bus5), (bus4, bus6), (bus5, bus6), (2, bus7), (bus7, bus8), (bus8, bus9), (bus9, bus7)] for fb, tb in new_connections: - pp.create_line(net, fb, tb, length_km=1.0, std_type="NA2XS2Y 1x185 RM/25 12/20 kV") + create_line(net, fb, tb, length_km=1.0, std_type="NA2XS2Y 1x185 RM/25 12/20 kV") # get characteristics - mg = top.create_nxgraph(net, respect_switches=False) + mg = create_nxgraph(net, respect_switches=False) characteristics = ["bridges", "articulation_points", "connected", "stub_buses", "required_bridges", "notn1_areas"] - char_dict = top.find_graph_characteristics(mg, net.ext_grid.bus, characteristics) + char_dict = find_graph_characteristics(mg, net.ext_grid.bus, characteristics) bridges = char_dict["bridges"] articulation_points = char_dict["articulation_points"] connected = char_dict["connected"] @@ -227,62 +235,62 @@ def test_graph_characteristics(feeder_network): def test_elements_on_path(): - net = nw.example_simple() + net = example_simple() for multi in [True, False]: - mg = top.create_nxgraph(net, multi=multi) + mg = create_nxgraph(net, multi=multi) path = nx.shortest_path(mg, 0, 6) - assert top.elements_on_path(mg, path, "line") == [0, 3] - assert top.lines_on_path(mg, path) == [0, 3] - assert top.elements_on_path(mg, path, "trafo") == [0] - assert top.elements_on_path(mg, path, "trafo3w") == [] - assert top.elements_on_path(mg, path, "switch") == [0, 1] + assert elements_on_path(mg, path, "line") == [0, 3] + assert lines_on_path(mg, path) == [0, 3] + assert elements_on_path(mg, path, "trafo") == [0] + assert elements_on_path(mg, path, "trafo3w") == [] + assert elements_on_path(mg, path, "switch") == [0, 1] with pytest.raises(ValueError) as exception_info: - top.elements_on_path(mg, path, element="sgen") + elements_on_path(mg, path, element="sgen") assert str(exception_info.value) == "Invalid element type sgen" def test_end_points_of_continuously_connected_lines(): - net = pp.create_empty_network() - b0 = pp.create_bus(net, vn_kv=20.) - b1 = pp.create_bus(net, vn_kv=20.) - b2 = pp.create_bus(net, vn_kv=20.) - b3 = pp.create_bus(net, vn_kv=20.) - b4 = pp.create_bus(net, vn_kv=20.) - b5 = pp.create_bus(net, vn_kv=20.) - b5 = pp.create_bus(net, vn_kv=20.) - b5 = pp.create_bus(net, vn_kv=20.) - b6 = pp.create_bus(net, vn_kv=20.) - b7 = pp.create_bus(net, vn_kv=20.) - - l1 = pp.create_line(net, from_bus=b0, to_bus=b1, length_km=2., std_type="34-AL1/6-ST1A 20.0") - l2 = pp.create_line(net, from_bus=b1, to_bus=b2, length_km=2., std_type="34-AL1/6-ST1A 20.0") - pp.create_switch(net, bus=b2, element=b3, et="b") - pp.create_switch(net, bus=b3, element=b4, et="b") - pp.create_switch(net, bus=b4, element=b5, et="b") - l3 = pp.create_line(net, from_bus=b5, to_bus=b6, length_km=2., std_type="34-AL1/6-ST1A 20.0") - l4 = pp.create_line(net, from_bus=b6, to_bus=b7, length_km=2., std_type="34-AL1/6-ST1A 20.0") - - f, t = top.get_end_points_of_continuously_connected_lines(net, lines=[l2, l1]) + net = create_empty_network() + b0 = create_bus(net, vn_kv=20.) + b1 = create_bus(net, vn_kv=20.) + b2 = create_bus(net, vn_kv=20.) + b3 = create_bus(net, vn_kv=20.) + b4 = create_bus(net, vn_kv=20.) + b5 = create_bus(net, vn_kv=20.) + b5 = create_bus(net, vn_kv=20.) + b5 = create_bus(net, vn_kv=20.) + b6 = create_bus(net, vn_kv=20.) + b7 = create_bus(net, vn_kv=20.) + + l1 = create_line(net, from_bus=b0, to_bus=b1, length_km=2., std_type="34-AL1/6-ST1A 20.0") + l2 = create_line(net, from_bus=b1, to_bus=b2, length_km=2., std_type="34-AL1/6-ST1A 20.0") + create_switch(net, bus=b2, element=b3, et="b") + create_switch(net, bus=b3, element=b4, et="b") + create_switch(net, bus=b4, element=b5, et="b") + l3 = create_line(net, from_bus=b5, to_bus=b6, length_km=2., std_type="34-AL1/6-ST1A 20.0") + l4 = create_line(net, from_bus=b6, to_bus=b7, length_km=2., std_type="34-AL1/6-ST1A 20.0") + + f, t = get_end_points_of_continuously_connected_lines(net, lines=[l2, l1]) assert {f, t} == {b0, b2} - f, t = top.get_end_points_of_continuously_connected_lines(net, lines=[l2, l1, l3]) + f, t = get_end_points_of_continuously_connected_lines(net, lines=[l2, l1, l3]) assert {f, t} == {b0, b6} - f, t = top.get_end_points_of_continuously_connected_lines(net, lines=[l3]) + f, t = get_end_points_of_continuously_connected_lines(net, lines=[l3]) assert {f, t} == {b5, b6} with pytest.raises(UserWarning) as exception_info: - top.get_end_points_of_continuously_connected_lines(net, lines=[l1, l2, l4]) + get_end_points_of_continuously_connected_lines(net, lines=[l1, l2, l4]) assert str(exception_info.value) == "Lines not continuously connected" with pytest.raises(UserWarning) as exception_info: - top.get_end_points_of_continuously_connected_lines(net, lines=[l1, l4]) + get_end_points_of_continuously_connected_lines(net, lines=[l1, l4]) assert str(exception_info.value) == "Lines not continuously connected" - b8 = pp.create_bus(net, vn_kv=20.) - l5 = pp.create_line(net, 8, b8, length_km=1., std_type="34-AL1/6-ST1A 20.0") + b8 = create_bus(net, vn_kv=20.) + l5 = create_line(net, 8, b8, length_km=1., std_type="34-AL1/6-ST1A 20.0") with pytest.raises(UserWarning) as exception_info: - top.get_end_points_of_continuously_connected_lines(net, lines=[l1, l2, l3, l4, l5]) + get_end_points_of_continuously_connected_lines(net, lines=[l1, l2, l3, l4, l5]) assert str(exception_info.value) == "Lines have branching points" diff --git a/pandapower/timeseries/run_time_series.py b/pandapower/timeseries/run_time_series.py index d382cb8cd..18caf807b 100644 --- a/pandapower/timeseries/run_time_series.py +++ b/pandapower/timeseries/run_time_series.py @@ -2,14 +2,16 @@ # Copyright (c) 2016-2023 by University of Kassel and Fraunhofer Institute for Energy Economics # and Energy System Technology (IEE), Kassel. All rights reserved. + import tempfile from collections.abc import Iterable + import tqdm -import pandapower as pp from pandapower.auxiliary import ControllerNotConverged from pandapower.control import prepare_run_ctrl, run_control from pandapower.control.util.diagnostic import control_diagnostic +from pandapower.run import runpp from pandapower.timeseries.output_writer import OutputWriter try: @@ -266,7 +268,7 @@ def init_time_series(net, time_steps, continue_on_divergence=False, verbose=True init_default_outputwriter(net, time_steps, **kwargs) # get run function - run = kwargs.pop("run", pp.runpp) + run = kwargs.pop("run", runpp) recycle_options = None if hasattr(run, "__name__") and (run.__name__ == "runpp" or run.__name__ == "rundcpp"): # use faster runpp options if possible @@ -294,7 +296,8 @@ def init_time_series(net, time_steps, continue_on_divergence=False, verbose=True def cleanup(net, ts_variables): if isinstance(ts_variables["recycle_options"], dict): # Todo: delete internal variables and dumped results which are not needed - net._ppc = None # remove _ppc because if recycle == True and a new timeseries calculation is started with a different setup (in_service of lines or trafos, open switches etc.) it can lead to a disaster + net._ppc = None # remove _ppc because if recycle == True and a new timeseries calculation is started with a + # different setup (in_service of lines or trafos, open switches etc.) it can lead to a disaster def print_progress(i, time_step, time_steps, verbose, **kwargs): @@ -314,7 +317,7 @@ def print_progress(i, time_step, time_steps, verbose, **kwargs): def run_loop(net, ts_variables, run_control_fct=run_control, output_writer_fct=_call_output_writer, **kwargs): """ - runs the time series loop which calls pp.runpp (or another run function) in each iteration + runs the time series loop which calls runpp (or another run function) in each iteration Parameters ---------- @@ -333,7 +336,8 @@ def run_timeseries(net, time_steps=None, continue_on_divergence=False, verbose=T Time Series main function Runs multiple PANDAPOWER AC power flows based on time series which are stored in a **DataSource** inside - **Controllers**. Optionally other functions than the pp power flow can be called by setting the run function in kwargs + **Controllers**. Optionally other functions than the pp power flow can be called by setting the run function in + kwargs INPUT: **net** - The pandapower format network @@ -346,7 +350,7 @@ def run_timeseries(net, time_steps=None, continue_on_divergence=False, verbose=T **verbose** (bool, True) - prints progress bar or if logger.level == Debug it prints debug messages - **kwargs** - Keyword arguments for run_control and runpp. If "run" is in kwargs the default call to runpp() + **kwargs** - Keyword arguments for run_control and run If "run" is in kwargs the default call to runpp() is replaced by the function kwargs["run"] """ @@ -356,7 +360,7 @@ def run_timeseries(net, time_steps=None, continue_on_divergence=False, verbose=T cleanup(net, ts_variables) if check_controllers: - control_diagnostic(net) # produces significant overhead if you run many timeseries of short duration + control_diagnostic(net) # produces significant overhead if you run many timeseries of short duration run_loop(net, ts_variables, **kwargs) # cleanup functions after the last time step was calculated diff --git a/pandapower/timeseries/ts_runpp.py b/pandapower/timeseries/ts_runpp.py index 708eeb3b6..af49a2b95 100644 --- a/pandapower/timeseries/ts_runpp.py +++ b/pandapower/timeseries/ts_runpp.py @@ -3,24 +3,23 @@ import numpy as np from numpy import complex128, zeros -import pandapower as pp -import pandapower.pf.run_newton_raphson_pf as nr_pf - -from pandapower.control.controller.const_control import ConstControl -from pandapower.control.controller.trafo_control import TrafoController from pandapower.auxiliary import _clean_up from pandapower.build_branch import _calc_trafo_parameter, _calc_trafo3w_parameter from pandapower.build_bus import _calc_pq_elements_and_add_on_ppc -from pandapower.pypower.idx_bus import PD, QD +from pandapower.control.controller.const_control import ConstControl +from pandapower.control.controller.trafo_control import TrafoController from pandapower.pd2ppc import _pd2ppc -from pandapower.pypower.idx_bus_dc import DC_PD -from pandapower.pypower.makeSbus import makeSbus from pandapower.pf.pfsoln_numba import pfsoln as pfsoln_full, pf_solution_single_slack +from pandapower.pf.run_newton_raphson_pf import newtonpf, _get_pf_variables_from_ppci, _get_Y_bus, makeYbus_numba from pandapower.powerflow import LoadflowNotConverged, _add_auxiliary_elements +from pandapower.pypower.idx_bus import PD, QD +from pandapower.pypower.idx_bus_dc import DC_PD +from pandapower.pypower.makeSbus import makeSbus from pandapower.results import _copy_results_ppci_to_ppc, _extract_results, _get_aranged_lookup from pandapower.results_branch import _get_branch_flows, _get_line_results, _get_trafo3w_results, _get_trafo_results from pandapower.results_bus import _get_bus_results, _get_bus_dc_results from pandapower.results_gen import _get_gen_results +from pandapower.run import runpp try: import pandaplan.core.pplog as logging @@ -35,8 +34,8 @@ class TimeSeriesRunpp: Class for time series runpp. The goal of this class is a runpp function, which reuses many NR variables in each time step of a time series calculation. - Also not all powerflow results are calculated in each runpp. Instead only the results the output writer wants - are calculated. Therefore this class must be initiliazed with an output writer + Also, not all power flow results are calculated in each runpp. Instead, only the results the output writer wants + are calculated. Therefore, this class must be initialized with an output writer """ def __init__(self, net): @@ -63,8 +62,15 @@ def ts_newtonpf(self, net): # Sbus = _get_Sbus(self.baseMVA, bus, gen, self.Cg) Sbus = makeSbus(self.baseMVA, bus, gen) - # run the newton power flow - V, success, _, _, _, _, _ = nr_pf.newtonpf(self.Ybus, Sbus, self.V, self.pv, self.pq, self.ppci, options) + # run the newton power flow + V, success, _, _, _, _, _ = newtonpf(Ybus=self.Ybus, + Sbus=Sbus, + V0=self.V, + ref=self.ref, + pv=self.pv, + pq=self.pq, + ppci=self.ppci, + options=options) if not success: logger.warning("Loadflow not converged") @@ -77,8 +83,8 @@ def ts_newtonpf(self, net): else: pfsoln = pfsoln_full - bus, gen, branch = pfsoln(self.baseMVA, bus, gen, branch, svc, tcsc, ssc, vsc, self.Ybus, self.Yf, self.Yt, V, self.ref, - self.ref_gens, Ibus=self.Ibus) + bus, gen, branch = pfsoln(self.baseMVA, bus, gen, branch, svc, tcsc, ssc, vsc, self.Ybus, self.Yf, self.Yt, V, + self.ref, self.ref_gens, Ibus=self.Ibus) self.ppci["bus"] = bus self.ppci["branch"] = branch @@ -142,10 +148,10 @@ def init_timeseries_newton(self): self.init_newton_variables() net = self.net # get ppc and ppci - # pp.runpp(net, init_vm_pu="flat", init_va_degree="dc") - # pp.runpp(net, init_vm_pu="results", init_va_degree="results") - pp.runpp(net, init="dc") - pp.runpp(net, init="results") + # runpp(net, init_vm_pu="flat", init_va_degree="dc") + # runpp(net, init_vm_pu="results", init_va_degree="results") + runpp(net, init="dc") + runpp(net, init="results") net._options["init_results"] = True net._options["init_vm_pu"] = "results" net._options["init_va_degree"] = "results" @@ -155,9 +161,9 @@ def init_timeseries_newton(self): net["_ppc"] = self.ppc self.baseMVA, bus, gen, branch, self.ref, self.pv, self.pq, _, _, self.V, self.ref_gens = \ - nr_pf._get_pf_variables_from_ppci(self.ppci) + _get_pf_variables_from_ppci(self.ppci) self.ppci, self.Ybus, self.Yf, self.Yt = \ - nr_pf._get_Y_bus(self.ppci, options, nr_pf.makeYbus_numba, self.baseMVA, bus, branch) + _get_Y_bus(self.ppci, options, makeYbus_numba, self.baseMVA, bus, branch) self.Ibus = zeros(len(self.V), dtype=complex128) # self.Cg = _get_Cg(gen, bus) # assumes that all gens are on! @@ -237,9 +243,9 @@ def update_trafos(self): # update Ybus based on this options = net._options - baseMVA, bus, gen, branch, svc, tcsc, ssc, vsc, ref, pv, pq, _, _, V, _ = nr_pf._get_pf_variables_from_ppci(ppci) - self.ppci, self.Ybus, self.Yf, self.Yt = nr_pf._get_Y_bus(ppci, options, nr_pf.makeYbus_numba, baseMVA, bus, - branch) + baseMVA, bus, gen, branch, svc, tcsc, ssc, vsc, ref, pv, pq, _, _, V, _ = _get_pf_variables_from_ppci(ppci) + self.ppci, self.Ybus, self.Yf, self.Yt = _get_Y_bus(ppci, options, makeYbus_numba, baseMVA, bus, + branch) def get_update_ctrl(self): controllers = self.net.controller["object"] diff --git a/pandapower/toolbox/data_modification.py b/pandapower/toolbox/data_modification.py index 87e2f6b77..bf95fba33 100644 --- a/pandapower/toolbox/data_modification.py +++ b/pandapower/toolbox/data_modification.py @@ -3,11 +3,12 @@ # Copyright (c) 2016-2024 by University of Kassel and Fraunhofer Institute for Energy Economics # and Energy System Technology (IEE), Kassel. All rights reserved. -from collections import defaultdict import uuid +from collections import defaultdict import numpy as np import pandas as pd + from pandapower.auxiliary import get_indices from pandapower.create import create_empty_network from pandapower.toolbox.comparison import compare_arrays @@ -101,15 +102,16 @@ def add_column_from_element_to_elements(net, column, replace, elements=None, 'continue_on_missing_column' acts. EXAMPLE: - import pandapower as pp - import pandapower.networks as pn - net = pn.create_cigre_network_mv() - pp.create_measurement(net, "i", "trafo", 5, 3, 0, side="hv") - pp.create_measurement(net, "i", "line", 5, 3, 0, side="to") - pp.create_measurement(net, "p", "bus", 5, 3, 2) - print(net.measurement.name.values, net.switch.name.values) - pp.add_column_from_element_to_elements(net, "name", True) - print(net.measurement.name.values, net.switch.name.values) + >>> from pandapower.create import create_measurement + >>> from pandapower import add_column_from_element_to_elements + >>> from pandapower.networks.cigre_networks import create_cigre_network_mv + >>> net = create_cigre_network_mv() + >>> create_measurement(net, "i", "trafo", 5, 3, 0, side="hv") + >>> create_measurement(net, "i", "line", 5, 3, 0, side="to") + >>> create_measurement(net, "p", "bus", 5, 3, 2) + >>> print(net.measurement.name.values, net.switch.name.values) + >>> add_column_from_element_to_elements(net, "name", True) + >>> print(net.measurement.name.values, net.switch.name.values) """ elements = elements if elements is not None else pp_elements() elements_with_el_and_et_column = [el for el in elements if "element" in net[el].columns and ( @@ -178,7 +180,7 @@ def reindex_buses(net, bus_lookup): # --- adapt group link if net.group.shape[0]: for row in np.arange(net.group.shape[0], dtype=np.int64)[ - (net.group.element_type == "bus").values & net.group.reference_column.isnull().values]: + (net.group.element_type == "bus").values & net.group.reference_column.isnull().values]: net.group.iat[row, net.group.columns.get_loc("element_index")] = list( get_indices(net.group.element_index.iat[row], bus_lookup)) @@ -291,7 +293,8 @@ def reindex_elements(net, element_type, new_indices=None, old_indices=None, look net.trafo.loc[net.trafo[ele] == old_id, ele] = new_id for ele in ['vk_hv_percent_characteristic', 'vkr_hv_percent_characteristic', 'vk_mv_percent_characteristic', - 'vkr_mv_percent_characteristic', 'vk_lv_percent_characteristic', 'vkr_lv_percent_characteristic']: + 'vkr_mv_percent_characteristic', 'vk_lv_percent_characteristic', + 'vkr_lv_percent_characteristic']: if ele in net.trafo3w: net.trafo3w.loc[net.trafo3w[ele] == old_id, ele] = new_id @@ -306,8 +309,8 @@ def reindex_elements(net, element_type, new_indices=None, old_indices=None, look # --- adapt group link if net.group.shape[0]: for row in np.arange(net.group.shape[0], dtype=np.int64)[ - (net.group.element_type == element_type).values & \ - net.group.reference_column.isnull().values]: + (net.group.element_type == element_type).values & \ + net.group.reference_column.isnull().values]: net.group.iat[row, net.group.columns.get_loc("element_index")] = list( get_indices(net.group.element_index.iat[row], lookup)) @@ -340,7 +343,7 @@ def reindex_elements(net, element_type, new_indices=None, old_indices=None, look element_in_cost_df = (net[cost_df].et == element_type) & net[cost_df].element.isin(old_indices) if sum(element_in_cost_df): net[cost_df].loc[element_in_cost_df, "element"] = get_indices(net[cost_df].element[ - element_in_cost_df], lookup) + element_in_cost_df], lookup) def create_continuous_elements_index(net, start=0, add_df_to_reindex=set()): diff --git a/pandapower/toolbox/element_selection.py b/pandapower/toolbox/element_selection.py index dc606e7dd..9664683d6 100644 --- a/pandapower/toolbox/element_selection.py +++ b/pandapower/toolbox/element_selection.py @@ -10,9 +10,8 @@ import pandas as pd from packaging.version import Version -from pandapower.auxiliary import ets_to_element_types - from pandapower._version import __version__ +from pandapower.auxiliary import ets_to_element_types try: import pandaplan.core.pplog as logging @@ -75,16 +74,16 @@ def get_element_indices(net, element_type, name, exact_match=True): **index** (list) - List of the indices of matching element(s). EXAMPLE: - >>> import pandapower.networks as pn - >>> import pandapower as pp - >>> net = pn.example_multivoltage() + >>> from pandapower.networks.create_examples import example_multivoltage + >>> from pandapower import get_element_indices + >>> net = example_multivoltage() >>> # get indices of only one element type (buses in this example): - >>> pp.get_element_indices(net, "bus", ["Bus HV%i" % i for i in range(1, 4)]) + >>> get_element_indices(net, "bus", ["Bus HV%i" % i for i in range(1, 4)]) [32, 33, 34] >>> # get indices of only two element type (first buses, second lines): - >>> pp.get_element_indices(net, ["bus", "line"], "HV", exact_match=False) + >>> get_element_indices(net, ["bus", "line"], "HV", exact_match=False) [Int64Index([32, 33, 34, 35], dtype='int64'), Int64Index([0, 1, 2, 3, 4, 5], dtype='int64')] - >>> pp.get_element_indices(net, ["bus", "line"], ["Bus HV3", "MV Line6"]) + >>> get_element_indices(net, ["bus", "line"], ["Bus HV3", "MV Line6"]) [34, 11] """ if isinstance(element_type, str) and isinstance(name, str): @@ -265,12 +264,14 @@ def get_connected_buses(net, buses, consider=("l", "s", "t", "t3", "i"), respect if "l" in consider or 'line' in consider: in_service_constr = net.line.in_service if respect_in_service else True opened_lines = set(net.switch.loc[(~net.switch.closed) & ( - net.switch.et == "l")].element.unique()) if respect_switches else set() + net.switch.et == "l")].element.unique()) if respect_switches else set() connected_fb_lines = set(net.line.index[( - net.line.from_bus.isin(buses)) & ~net.line.index.isin(opened_lines) & - in_service_constr]) + net.line.from_bus.isin(buses)) & ~net.line.index.isin( + opened_lines) & + in_service_constr]) connected_tb_lines = set(net.line.index[( - net.line.to_bus.isin(buses)) & ~net.line.index.isin(opened_lines) & in_service_constr]) + net.line.to_bus.isin(buses)) & ~net.line.index.isin( + opened_lines) & in_service_constr]) cb |= set(net.line[net.line.index.isin(connected_tb_lines)].from_bus) cb |= set(net.line[net.line.index.isin(connected_fb_lines)].to_bus) @@ -283,13 +284,15 @@ def get_connected_buses(net, buses, consider=("l", "s", "t", "t3", "i"), respect if "t" in consider or 'trafo' in consider: in_service_constr = net.trafo.in_service if respect_in_service else True opened_trafos = set(net.switch.loc[(~net.switch.closed) & ( - net.switch.et == "t")].element.unique()) if respect_switches else set() + net.switch.et == "t")].element.unique()) if respect_switches else set() connected_hvb_trafos = set(net.trafo.index[( - net.trafo.hv_bus.isin(buses)) & ~net.trafo.index.isin(opened_trafos) & - in_service_constr]) + net.trafo.hv_bus.isin(buses)) & ~net.trafo.index.isin( + opened_trafos) & + in_service_constr]) connected_lvb_trafos = set(net.trafo.index[( - net.trafo.lv_bus.isin(buses)) & ~net.trafo.index.isin(opened_trafos) & - in_service_constr]) + net.trafo.lv_bus.isin(buses)) & ~net.trafo.index.isin( + opened_trafos) & + in_service_constr]) cb |= set(net.trafo.loc[net.trafo.index.isin(connected_lvb_trafos)].hv_bus.values) cb |= set(net.trafo.loc[net.trafo.index.isin(connected_hvb_trafos)].lv_bus.values) @@ -298,14 +301,14 @@ def get_connected_buses(net, buses, consider=("l", "s", "t", "t3", "i"), respect in_service_constr3w = net.trafo3w.in_service if respect_in_service else True if respect_switches: opened_buses_hv = set(net.switch.loc[ - ~net.switch.closed & (net.switch.et == "t3") & - net.switch.bus.isin(net.trafo3w.hv_bus)].bus.unique()) + ~net.switch.closed & (net.switch.et == "t3") & + net.switch.bus.isin(net.trafo3w.hv_bus)].bus.unique()) opened_buses_mv = set(net.switch.loc[ - ~net.switch.closed & (net.switch.et == "t3") & - net.switch.bus.isin(net.trafo3w.mv_bus)].bus.unique()) + ~net.switch.closed & (net.switch.et == "t3") & + net.switch.bus.isin(net.trafo3w.mv_bus)].bus.unique()) opened_buses_lv = set(net.switch.loc[ - ~net.switch.closed & (net.switch.et == "t3") & - net.switch.bus.isin(net.trafo3w.lv_bus)].bus.unique()) + ~net.switch.closed & (net.switch.et == "t3") & + net.switch.bus.isin(net.trafo3w.lv_bus)].bus.unique()) else: opened_buses_hv = opened_buses_mv = opened_buses_lv = set() @@ -488,7 +491,7 @@ def get_connected_switches(net, buses, consider=('b', 'l', 't', 't3', 'i'), stat element_type = ets_to_element_types(et) sw_idx = net.switch.index[(net.switch.et == et) & switch_selection] element_buses = net[element_type].loc[list(net.switch.element.loc[sw_idx]), - bebd[element_type]] + bebd[element_type]] isin_df = pd.concat([element_buses[col].isin(buses) for col in element_buses], axis=1) cs |= set(sw_idx[isin_df.any(axis=1)]) @@ -600,7 +603,7 @@ def false_elm_links(net, element_type, col, target_element_type): """ if isinstance(target_element_type, str): return net[element_type][col].index[~net[element_type][col].isin(net[ - target_element_type].index)] + target_element_type].index)] else: # target_element_type is an iterable, e.g. a Series such as net["poly_cost"]["et"] df = pd.DataFrame({"element": net[element_type][col].values, "et": target_element_type, "indices": net[element_type][col].index.values}) @@ -608,7 +611,7 @@ def false_elm_links(net, element_type, col, target_element_type): false_links = pd.Index([]) for et in df.index: false_links = false_links.union(pd.Index(df.loc[et].indices.loc[ - ~df.loc[et].element.isin(net[et].index)])) + ~df.loc[et].element.isin(net[et].index)])) return false_links @@ -708,9 +711,9 @@ def element_bus_tuples(bus_elements=True, branch_elements=True, res_elements=Fal ("motor", "bus")] if branch_elements: ebts += [("line", "from_bus"), ("line", "to_bus"), ("impedance", "from_bus"), - ("impedance", "to_bus"), ("switch", "bus"), ("trafo", "hv_bus"), - ("trafo", "lv_bus"), ("trafo3w", "hv_bus"), ("trafo3w", "mv_bus"), - ("trafo3w", "lv_bus"), ("dcline", "from_bus"), ("dcline", "to_bus")] + ("impedance", "to_bus"), ("switch", "bus"), ("trafo", "hv_bus"), + ("trafo", "lv_bus"), ("trafo3w", "hv_bus"), ("trafo3w", "mv_bus"), + ("trafo3w", "lv_bus"), ("dcline", "from_bus"), ("dcline", "to_bus")] if res_elements: elements_without_res = ["switch", "measurement", "asymmetric_load", "asymmetric_sgen"] ebts += [("res_" + ebt[0], ebt[1]) for ebt in ebts if ebt[0] not in elements_without_res] @@ -744,12 +747,12 @@ def count_elements(net, return_empties=False, **kwargs): Examples -------- - >>> import pandapower as pp - >>> import pandapower.networks as nw - >>> pp.count_elements(nw.case9(), bus_elements=False) + >>> from pandapower import count_elements + >>> from pandapower.networks.power_system_test_cases import case9 + >>> count_elements(case9(), bus_elements=False) bus 9 line 9 dtype: int32 """ return pd.Series({et: net[et].shape[0] for et in pp_elements(**kwargs) if return_empties or \ - bool(net[et].shape[0])}, dtype=np.int64) \ No newline at end of file + bool(net[et].shape[0])}, dtype=np.int64) diff --git a/pandapower/topology/create_graph.py b/pandapower/topology/create_graph.py index a8b6ade2f..57464fb04 100644 --- a/pandapower/topology/create_graph.py +++ b/pandapower/topology/create_graph.py @@ -111,9 +111,8 @@ def create_nxgraph(net, respect_switches=True, include_lines=True, include_imped **mg** - Returns the required NetworkX graph EXAMPLE: - import pandapower.topology as top - - mg = top.create_nx_graph(net, respect_switches = False) + >>> from pandapower.topology.create_graph import create_nxgraph + >>> mg = create_nxgraph(net, respect_switches = False) # converts the pandapower network "net" to a MultiGraph. Open switches will be ignored. Parameters @@ -188,7 +187,8 @@ def create_nxgraph(net, respect_switches=True, include_lines=True, include_imped if calc_branch_impedances: baseR = get_baseR(net, ppc, tcsc.from_bus.values) - x = 1 / calc_y_svc_pu(net.tcsc.thyristor_firing_angle_degree, net.tcsc.x_l_ohm / baseR, net.tcsc.x_cvar_ohm / baseR) + x = 1 / calc_y_svc_pu(net.tcsc.thyristor_firing_angle_degree, net.tcsc.x_l_ohm / baseR, + net.tcsc.x_cvar_ohm / baseR) parameter[:, BR_R] = 0 parameter[:, BR_X] = x * (baseR if branch_impedance_unit == "ohm" else 1) diff --git a/pandapower/topology/graph_searches.py b/pandapower/topology/graph_searches.py index eab891610..de8ad74ca 100644 --- a/pandapower/topology/graph_searches.py +++ b/pandapower/topology/graph_searches.py @@ -4,11 +4,12 @@ # and Energy System Technology (IEE), Kassel. All rights reserved. -import networkx as nx -import pandas as pd from collections import deque from itertools import combinations +import networkx as nx +import pandas as pd + from pandapower.topology.create_graph import create_nxgraph @@ -30,12 +31,10 @@ def connected_component(mg, bus, notravbuses=[]): **cc** (generator) - Returns a generator that yields all buses connected to the input bus EXAMPLE: - import pandapower.topology as top - - mg = top.create_nxgraph(net) - - cc = top.connected_component(mg, 5) - + >>> from pandapower.topology.create_graph import create_nxgraph + >>> from pandapower.topology.graph_searches import connected_component + >>> mg = create_nxgraph(net) + >>> cc = connected_component(mg, 5) """ yield bus visited = {bus} @@ -66,12 +65,10 @@ def connected_components(mg, notravbuses=set()): to each other. EXAMPLE: - import pandapower.topology as top - - mg = top.create_nxgraph(net) - - cc = top.connected_components(mg, 5) - + >>> from pandapower.topology.create_graph import create_nxgraph + >>> from pandapower.topology.graph_searches import connected_components + >>> mg = create_nxgraph(net) + >>> cc = connected_components(mg, 5) """ nodes = set(mg.nodes()) - notravbuses @@ -117,9 +114,8 @@ def calc_distance_to_bus(net, bus, respect_switches=True, nogobuses=None, in km. If weight=None dist is the topological distance (int). EXAMPLE: - import pandapower.topology as top - - dist = top.calc_distance_to_bus(net, 5) + >>> from pandapower.topology.graph_searches import calc_distance_to_bus + >>> dist = calc_distance_to_bus(net, 5) """ if g is None: @@ -152,9 +148,8 @@ def unsupplied_buses(net, mg=None, slacks=None, respect_switches=True): **ub** (set) - unsupplied buses EXAMPLE: - import pandapower.topology as top - - top.unsupplied_buses(net) + >>> from pandapower.topology.graph_searches import unsupplied_buses + >>> unsupplied_buses(net) """ mg = mg or create_nxgraph(net, respect_switches=respect_switches) @@ -176,7 +171,6 @@ def find_basic_graph_characteristics(g, roots, characteristics): and articulation points. .. note:: - This is the base function for find_graph_characteristics. Please use the latter function instead! """ @@ -328,7 +322,7 @@ def find_graph_characteristics(g, roots, characteristics): if len(visited_bridges) > 0: char_dict['required_bridges'][parent] = visited_bridges[:] if ((parent, grandparent) in char_dict['bridges'] or - (grandparent, parent) in char_dict['bridges']): + (grandparent, parent) in char_dict['bridges']): visited_bridges.pop() if notn1_areas and grandparent == notn1_area_start: @@ -371,11 +365,8 @@ def determine_stubs(net, roots=None, mg=None, respect_switches=False): ext_grid buses will be set as roots) EXAMPLE: - import pandapower.topology as top - - top.determine_stubs(net, roots = [0, 1]) - - + >>> from pandapower.topology.graph_searches import determine_stubs + >>> determine_stubs(net, roots = [0, 1]) """ if mg is None: mg = create_nxgraph(net, respect_switches=respect_switches) @@ -445,20 +436,20 @@ def elements_on_path(mg, path, element="line"): """ if element not in ["line", "switch", "trafo", "trafo3w"]: - raise ValueError("Invalid element type %s"%element) + raise ValueError("Invalid element type %s" % element) if isinstance(mg, nx.MultiGraph): return [edge[1] for b1, b2 in zip(path, path[1:]) for edge in mg.get_edge_data(b1, b2).keys() - if edge[0]==element] + if edge[0] == element] else: return [mg.get_edge_data(b1, b2)["key"][1] for b1, b2 in zip(path, path[1:]) - if mg.get_edge_data(b1, b2)["key"][0]==element] + if mg.get_edge_data(b1, b2)["key"][0] == element] def get_end_points_of_continuously_connected_lines(net, lines): mg = nx.MultiGraph() line_buses = net.line.loc[lines, ["from_bus", "to_bus"]].values mg.add_edges_from(line_buses) - switch_buses = net.switch[["bus", "element"]].values[net.switch.et.values=="b"] + switch_buses = net.switch[["bus", "element"]].values[net.switch.et.values == "b"] mg.add_edges_from(switch_buses) all_buses = set(line_buses.flatten()) diff --git a/tutorials/internal_datastructure.ipynb b/tutorials/internal_datastructure.ipynb index bb0d060b1..908d8926f 100644 --- a/tutorials/internal_datastructure.ipynb +++ b/tutorials/internal_datastructure.ipynb @@ -3,7 +3,10 @@ { "cell_type": "markdown", "metadata": { - "collapsed": true + "collapsed": true, + "jupyter": { + "outputs_hidden": true + } }, "source": [ "# Internal Datastructure: Bus branch model, Admittance and Jacobian Matrix\n" @@ -32,8 +35,8 @@ "execution_count": 1, "metadata": { "ExecuteTime": { - "end_time": "2024-03-30T10:51:35.863414Z", - "start_time": "2024-03-30T10:51:31.939777Z" + "end_time": "2024-11-27T09:35:26.587184Z", + "start_time": "2024-11-27T09:35:23.416105Z" } }, "outputs": [ @@ -41,11 +44,6 @@ "name": "stdout", "output_type": "stream", "text": [ - "LightSimBackend import error: No module named 'grid2op'\n", - "PhysicalLawChecker import error: No module named 'grid2op'\n", - "TimeSerie import error: cannot import name 'TimeSerie' from 'lightsim2grid.timeSerie' (C:\\ProgramData\\miniconda3\\envs\\py3.11\\Lib\\site-packages\\lightsim2grid\\timeSerie.py)\n", - "ContingencyAnalysis import error: cannot import name 'ContingencyAnalysis' from 'lightsim2grid.contingencyAnalysis' (C:\\ProgramData\\miniconda3\\envs\\py3.11\\Lib\\site-packages\\lightsim2grid\\contingencyAnalysis.py)\n", - "rewards import error: No module named 'grid2op'\n", "This pandapower network includes the following parameter tables:\n", " - bus (7 elements)\n", " - load (1 element)\n", @@ -79,8 +77,8 @@ "execution_count": 2, "metadata": { "ExecuteTime": { - "end_time": "2024-03-30T10:51:40.154189Z", - "start_time": "2024-03-30T10:51:35.865424Z" + "end_time": "2024-11-27T09:35:28.055288Z", + "start_time": "2024-11-27T09:35:26.591192Z" } }, "outputs": [], @@ -99,16 +97,254 @@ "cell_type": "code", "execution_count": 3, "metadata": { - "scrolled": false, "ExecuteTime": { - "end_time": "2024-03-30T10:51:40.172601Z", - "start_time": "2024-03-30T10:51:40.155198Z" + "end_time": "2024-11-27T09:35:28.182082Z", + "start_time": "2024-11-27T09:35:28.173031Z" } }, "outputs": [ { "data": { - "text/plain": "{'baseMVA': 1,\n 'version': 2,\n 'bus': array([[ 0. , 3. , 0. , 0. ,\n 0. , 0. , 1. , 1.02 ,\n 50. , 110. , 1. , 2. ,\n 0. , 0. , 0. , 0. ],\n [ 1. , 1. , 0. , 0. ,\n 0. , 0.96 , 1. , 1.02082951,\n 50.03241357, 110. , 1. , 2. ,\n 0. , 0. , 0. , 0. ],\n [ 2. , 1. , 0. , 0. ,\n 0. , 0. , 1. , 1.02456241,\n -98.19715207, 20. , 1. , 2. ,\n 0. , 0. , 0. , 0. ],\n [ 3. , 2. , 0. , 0. ,\n 0. , 0. , 1. , 1.03 ,\n -98.12954543, 20. , 1. , 2. ,\n 0. , 0. , 0. , 0. ],\n [ 4. , 1. , -0.8 , 2.9 ,\n 0. , 0. , 1. , 1.02320534,\n -98.04777562, 20. , 1. , 2. ,\n 0. , 0. , 0. , 0. ],\n [ 5. , 1. , 0. , 0. ,\n 0. , 0. , 1. , 1.030007 ,\n -98.13016747, 20. , 1. , 1.1 ,\n 0.9 , 0. , 0. , 0. ],\n [ 6. , 4. , 0. , 0. ,\n 0. , 0. , 1. , nan,\n nan, 110. , 1. , 2. ,\n 0. , 0. , 0. , 0. ],\n [ 7. , 4. , 0. , 0. ,\n 0. , 0. , 1. , nan,\n nan, 20. , 1. , 2. ,\n 0. , 0. , 0. , 0. ]]),\n 'branch': array([[ 0.00000000e+00+0.j , 1.00000000e+00+0.j ,\n 4.95867769e-05+0.j , 1.19008264e-04+0.j ,\n 5.47391104e+00+0.j , 0.00000000e+00+0.j ,\n 2.50000000e+02+0.j , 2.50000000e+02+0.j ,\n 1.00000000e+00+0.j , 0.00000000e+00+0.j ,\n 1.00000000e+00+0.j , -3.60000000e+02+0.j ,\n 3.60000000e+02+0.j , -6.74111530e+00+0.j ,\n -7.14688297e+00+0.j , 6.74416214e+00+0.j ,\n 1.45450502e+00+0.j , 0.00000000e+00+0.j ,\n 0.00000000e+00+0.j , 0.00000000e+00+0.j ,\n 0.00000000e+00+0.j , 0.00000000e+00+0.j ,\n 0.00000000e+00+0.j ],\n [ 2.00000000e+00+0.j , 3.00000000e+00+0.j ,\n 6.10000000e-04+0.j , 5.60000000e-04+0.j ,\n 7.64035333e-02+0.j , 0.00000000e+00+0.j ,\n 2.50000000e+02+0.j , 2.50000000e+02+0.j ,\n 1.00000000e+00+0.j , 0.00000000e+00+0.j ,\n 1.00000000e+00+0.j , -3.60000000e+02+0.j ,\n 3.60000000e+02+0.j , -5.97238973e+00+0.j ,\n -3.48162502e+00+0.j , 5.99999998e+00+0.j ,\n 3.42634241e+00+0.j , 0.00000000e+00+0.j ,\n 0.00000000e+00+0.j , 0.00000000e+00+0.j ,\n 0.00000000e+00+0.j , 0.00000000e+00+0.j ,\n 0.00000000e+00+0.j ],\n [ 3.00000000e+00+0.j , 5.00000000e+00+0.j ,\n 5.19662500e-03+0.j , 3.25500000e-03+0.j ,\n 4.17831823e-03+0.j , 0.00000000e+00+0.j ,\n 2.50000000e+02+0.j , 2.50000000e+02+0.j ,\n 1.00000000e+00+0.j , 0.00000000e+00+0.j ,\n 1.00000000e+00+0.j , -3.60000000e+02+0.j ,\n 3.60000000e+02+0.j , 2.40627158e-08+0.j ,\n -4.43279288e-03+0.j , 0.00000000e+00+0.j ,\n -0.00000000e+00+0.j , 0.00000000e+00+0.j ,\n 0.00000000e+00+0.j , 0.00000000e+00+0.j ,\n 0.00000000e+00+0.j , 0.00000000e+00+0.j ,\n 0.00000000e+00+0.j ],\n [ 4.00000000e+00+0.j , 2.00000000e+00+0.j ,\n 7.62500000e-04+0.j , 7.00000000e-04+0.j ,\n 9.55044167e-02+0.j , 0.00000000e+00+0.j ,\n 2.50000000e+02+0.j , 2.50000000e+02+0.j ,\n 1.00000000e+00+0.j , 0.00000000e+00+0.j ,\n 1.00000000e+00+0.j , -3.60000000e+02+0.j ,\n 3.60000000e+02+0.j , 8.00000000e-01+0.j ,\n -2.90000000e+00+0.j , -7.93618189e-01+0.j ,\n 2.80573774e+00+0.j , 0.00000000e+00+0.j ,\n 0.00000000e+00+0.j , 0.00000000e+00+0.j ,\n 0.00000000e+00+0.j , 0.00000000e+00+0.j ,\n 0.00000000e+00+0.j ],\n [ 1.00000000e+00+0.j , 2.00000000e+00+0.j ,\n 1.63923679e-04+0.j , 4.79726336e-03+0.j ,\n -1.05000908e-02-0.01399964j, 0.00000000e+00+0.j ,\n 2.50000000e+02+0.j , 2.50000000e+02+0.j ,\n 1.00000000e+00+0.j , 1.50000000e+02+0.j ,\n 1.00000000e+00+0.j , -3.60000000e+02+0.j ,\n 3.60000000e+02+0.j , -6.74416214e+00+0.j ,\n -4.54095852e-01+0.j , 6.76600792e+00+0.j ,\n 6.75887284e-01+0.j , 0.00000000e+00+0.j ,\n 0.00000000e+00+0.j , 0.00000000e+00+0.j ,\n 0.00000000e+00+0.j , 0.00000000e+00+0.j ,\n 0.00000000e+00+0.j ]]),\n 'tcsc': array([], shape=(0, 17), dtype=float64),\n 'svc': array([], shape=(0, 11), dtype=float64),\n 'ssc': array([], shape=(0, 10), dtype=float64),\n 'gen': array([[ 0.00000000e+00, -6.74111530e+00, -7.14688297e+00,\n 0.00000000e+00, 0.00000000e+00, 1.02000000e+00,\n 1.00000000e+00, 1.00000000e+00, 1.00000000e+09,\n -1.00000000e+09, 0.00000000e+00, 0.00000000e+00,\n 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n 0.00000000e+00, 1.00000000e+00],\n [ 3.00000000e+00, 6.00000000e+00, 3.42190962e+00,\n 3.00000000e+00, -3.00000000e+00, 1.03000000e+00,\n nan, 1.00000000e+00, 1.00000000e+09,\n -1.00000000e+09, 0.00000000e+00, 0.00000000e+00,\n 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n 0.00000000e+00, 0.00000000e+00]]),\n 'internal': {'Ybus': <6x6 sparse matrix of type ''\n \twith 16 stored elements in Compressed Sparse Row format>,\n 'Yf': <5x6 sparse matrix of type ''\n \twith 10 stored elements in Compressed Sparse Row format>,\n 'Yt': <5x6 sparse matrix of type ''\n \twith 10 stored elements in Compressed Sparse Row format>,\n 'branch_is': array([ True, True, True, True, True]),\n 'gen_is': array([ True, True]),\n 'DLF': array([], dtype=complex128),\n 'buses_ord_bfs_nets': array([], dtype=float64),\n 'svc_is': array([], dtype=bool),\n 'ssc_is': array([], dtype=bool),\n 'tcsc_is': array([], dtype=bool),\n 'ref_gens': array([0], dtype=int64),\n 'baseMVA': 1,\n 'bus': array([[ 0. , 3. , 0. , 0. ,\n 0. , 0. , 1. , 1.02 ,\n 50. , 110. , 1. , 2. ,\n 0. , 0. , 0. , 0. ],\n [ 1. , 1. , 0. , 0. ,\n 0. , 0.96 , 1. , 1.02082951,\n 50.03241357, 110. , 1. , 2. ,\n 0. , 0. , 0. , 0. ],\n [ 2. , 1. , 0. , 0. ,\n 0. , 0. , 1. , 1.02456241,\n -98.19715207, 20. , 1. , 2. ,\n 0. , 0. , 0. , 0. ],\n [ 3. , 2. , 0. , 0. ,\n 0. , 0. , 1. , 1.03 ,\n -98.12954543, 20. , 1. , 2. ,\n 0. , 0. , 0. , 0. ],\n [ 4. , 1. , -0.8 , 2.9 ,\n 0. , 0. , 1. , 1.02320534,\n -98.04777562, 20. , 1. , 2. ,\n 0. , 0. , 0. , 0. ],\n [ 5. , 1. , 0. , 0. ,\n 0. , 0. , 1. , 1.030007 ,\n -98.13016747, 20. , 1. , 1.1 ,\n 0.9 , 0. , 0. , 0. ]]),\n 'gen': array([[ 0.00000000e+00, -6.74111530e+00, -7.14688297e+00,\n 0.00000000e+00, 0.00000000e+00, 1.02000000e+00,\n 1.00000000e+00, 1.00000000e+00, 1.00000000e+09,\n -1.00000000e+09, 0.00000000e+00, 0.00000000e+00,\n 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n 0.00000000e+00, 1.00000000e+00],\n [ 3.00000000e+00, 6.00000000e+00, 3.42190962e+00,\n 3.00000000e+00, -3.00000000e+00, 1.03000000e+00,\n nan, 1.00000000e+00, 1.00000000e+09,\n -1.00000000e+09, 0.00000000e+00, 0.00000000e+00,\n 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n 0.00000000e+00, 0.00000000e+00]]),\n 'branch': array([[ 0.00000000e+00+0.j , 1.00000000e+00+0.j ,\n 4.95867769e-05+0.j , 1.19008264e-04+0.j ,\n 5.47391104e+00+0.j , 0.00000000e+00+0.j ,\n 2.50000000e+02+0.j , 2.50000000e+02+0.j ,\n 1.00000000e+00+0.j , 0.00000000e+00+0.j ,\n 1.00000000e+00+0.j , -3.60000000e+02+0.j ,\n 3.60000000e+02+0.j , -6.74111530e+00+0.j ,\n -7.14688297e+00+0.j , 6.74416214e+00+0.j ,\n 1.45450502e+00+0.j , 0.00000000e+00+0.j ,\n 0.00000000e+00+0.j , 0.00000000e+00+0.j ,\n 0.00000000e+00+0.j , 0.00000000e+00+0.j ,\n 0.00000000e+00+0.j ],\n [ 2.00000000e+00+0.j , 3.00000000e+00+0.j ,\n 6.10000000e-04+0.j , 5.60000000e-04+0.j ,\n 7.64035333e-02+0.j , 0.00000000e+00+0.j ,\n 2.50000000e+02+0.j , 2.50000000e+02+0.j ,\n 1.00000000e+00+0.j , 0.00000000e+00+0.j ,\n 1.00000000e+00+0.j , -3.60000000e+02+0.j ,\n 3.60000000e+02+0.j , -5.97238973e+00+0.j ,\n -3.48162502e+00+0.j , 5.99999998e+00+0.j ,\n 3.42634241e+00+0.j , 0.00000000e+00+0.j ,\n 0.00000000e+00+0.j , 0.00000000e+00+0.j ,\n 0.00000000e+00+0.j , 0.00000000e+00+0.j ,\n 0.00000000e+00+0.j ],\n [ 3.00000000e+00+0.j , 5.00000000e+00+0.j ,\n 5.19662500e-03+0.j , 3.25500000e-03+0.j ,\n 4.17831823e-03+0.j , 0.00000000e+00+0.j ,\n 2.50000000e+02+0.j , 2.50000000e+02+0.j ,\n 1.00000000e+00+0.j , 0.00000000e+00+0.j ,\n 1.00000000e+00+0.j , -3.60000000e+02+0.j ,\n 3.60000000e+02+0.j , 2.40627158e-08+0.j ,\n -4.43279288e-03+0.j , 0.00000000e+00+0.j ,\n -0.00000000e+00+0.j , 0.00000000e+00+0.j ,\n 0.00000000e+00+0.j , 0.00000000e+00+0.j ,\n 0.00000000e+00+0.j , 0.00000000e+00+0.j ,\n 0.00000000e+00+0.j ],\n [ 4.00000000e+00+0.j , 2.00000000e+00+0.j ,\n 7.62500000e-04+0.j , 7.00000000e-04+0.j ,\n 9.55044167e-02+0.j , 0.00000000e+00+0.j ,\n 2.50000000e+02+0.j , 2.50000000e+02+0.j ,\n 1.00000000e+00+0.j , 0.00000000e+00+0.j ,\n 1.00000000e+00+0.j , -3.60000000e+02+0.j ,\n 3.60000000e+02+0.j , 8.00000000e-01+0.j ,\n -2.90000000e+00+0.j , -7.93618189e-01+0.j ,\n 2.80573774e+00+0.j , 0.00000000e+00+0.j ,\n 0.00000000e+00+0.j , 0.00000000e+00+0.j ,\n 0.00000000e+00+0.j , 0.00000000e+00+0.j ,\n 0.00000000e+00+0.j ],\n [ 1.00000000e+00+0.j , 2.00000000e+00+0.j ,\n 1.63923679e-04+0.j , 4.79726336e-03+0.j ,\n -1.05000908e-02-0.01399964j, 0.00000000e+00+0.j ,\n 2.50000000e+02+0.j , 2.50000000e+02+0.j ,\n 1.00000000e+00+0.j , 1.50000000e+02+0.j ,\n 1.00000000e+00+0.j , -3.60000000e+02+0.j ,\n 3.60000000e+02+0.j , -6.74416214e+00+0.j ,\n -4.54095852e-01+0.j , 6.76600792e+00+0.j ,\n 6.75887284e-01+0.j , 0.00000000e+00+0.j ,\n 0.00000000e+00+0.j , 0.00000000e+00+0.j ,\n 0.00000000e+00+0.j , 0.00000000e+00+0.j ,\n 0.00000000e+00+0.j ]]),\n 'ref': array([0], dtype=int64),\n 'pv': array([3], dtype=int64),\n 'pq': array([1, 2, 4, 5], dtype=int64),\n 'Bbus': <6x6 sparse matrix of type ''\n \twith 16 stored elements in Compressed Sparse Column format>,\n 'Bf': <5x6 sparse matrix of type ''\n \twith 10 stored elements in Compressed Sparse Row format>,\n 'Pbusinj': array([ 0. +0.j, -545.726528+0.j, 545.726528+0.j, 0. +0.j,\n 0. +0.j, 0. +0.j]),\n 'Pfinj': array([ 0. +0.j, 0. +0.j, 0. +0.j, 0. +0.j,\n -545.726528+0.j]),\n 'Cft': <5x6 sparse matrix of type ''\n \twith 10 stored elements in Compressed Sparse Row format>,\n 'shift': array([ 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 150.+0.j]),\n 'V': array([ 0.65564336+0.78136533j, 0.65573406+0.78237186j,\n -0.14608184-1.01409479j, -0.14565409-1.01964939j,\n -0.1432475 -1.01312848j, -0.14566615-1.01965475j]),\n 'J': <9x9 sparse matrix of type ''\n \twith 41 stored elements in Compressed Sparse Column format>,\n 'Vm_it': None,\n 'Va_it': None,\n 'svc': array([], shape=(0, 11), dtype=float64),\n 'tcsc': array([], shape=(0, 17), dtype=float64),\n 'ssc': array([], shape=(0, 10), dtype=float64),\n 'Sbus': array([-6.8+0.j , 0. +0.j , 0. +0.j , 6. +0.j , 0.8-2.9j, 0. +0.j ]),\n 'r_theta_kelvin_per_mw': None,\n 'T': None},\n 'success': True,\n 'et': 2.052844199934043,\n 'iterations': 3}" + "text/plain": [ + "{'baseMVA': 1,\n", + " 'version': 2,\n", + " 'bus': array([[ 0. , 3. , 0. , 0. ,\n", + " 0. , 0. , 1. , 1.02 ,\n", + " 50. , 110. , 1. , 2. ,\n", + " 0. , 0. , 0. , 0. ],\n", + " [ 1. , 1. , 0. , 0. ,\n", + " 0. , 0.96 , 1. , 1.02082951,\n", + " 50.03241357, 110. , 1. , 2. ,\n", + " 0. , 0. , 0. , 0. ],\n", + " [ 2. , 1. , 0. , 0. ,\n", + " 0. , 0. , 1. , 1.02456241,\n", + " -98.19715207, 20. , 1. , 2. ,\n", + " 0. , 0. , 0. , 0. ],\n", + " [ 3. , 2. , 0. , 0. ,\n", + " 0. , 0. , 1. , 1.03 ,\n", + " -98.12954543, 20. , 1. , 2. ,\n", + " 0. , 0. , 0. , 0. ],\n", + " [ 4. , 1. , -0.8 , 2.9 ,\n", + " 0. , 0. , 1. , 1.02320534,\n", + " -98.04777562, 20. , 1. , 2. ,\n", + " 0. , 0. , 0. , 0. ],\n", + " [ 5. , 1. , 0. , 0. ,\n", + " 0. , 0. , 1. , 1.030007 ,\n", + " -98.13016747, 20. , 1. , 1.1 ,\n", + " 0.9 , 0. , 0. , 0. ],\n", + " [ 6. , 4. , 0. , 0. ,\n", + " 0. , 0. , 1. , nan,\n", + " nan, 110. , 1. , 2. ,\n", + " 0. , 0. , 0. , 0. ],\n", + " [ 7. , 4. , 0. , 0. ,\n", + " 0. , 0. , 1. , nan,\n", + " nan, 20. , 1. , 2. ,\n", + " 0. , 0. , 0. , 0. ]]),\n", + " 'bus_dc': array([], shape=(0, 11), dtype=float64),\n", + " 'branch': array([[ 0.00000000e+00, 1.00000000e+00, 4.95867769e-05,\n", + " 1.19008264e-04, 5.47391104e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 1.00000000e+00,\n", + " 0.00000000e+00, 1.00000000e+00, -3.60000000e+02,\n", + " 3.60000000e+02, -6.74111530e+00, -7.14688297e+00,\n", + " 6.74416214e+00, 1.45450502e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00],\n", + " [ 2.00000000e+00, 3.00000000e+00, 6.10000000e-04,\n", + " 5.60000000e-04, 7.64035333e-02, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 1.00000000e+00,\n", + " 0.00000000e+00, 1.00000000e+00, -3.60000000e+02,\n", + " 3.60000000e+02, -5.97238973e+00, -3.48162502e+00,\n", + " 5.99999998e+00, 3.42634241e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00],\n", + " [ 3.00000000e+00, 5.00000000e+00, 5.19662500e-03,\n", + " 3.25500000e-03, 4.17831823e-03, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 1.00000000e+00,\n", + " 0.00000000e+00, 1.00000000e+00, -3.60000000e+02,\n", + " 3.60000000e+02, 2.40627138e-08, -4.43279288e-03,\n", + " -2.48402500e-14, 3.31204118e-14, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00],\n", + " [ 4.00000000e+00, 2.00000000e+00, 7.62500000e-04,\n", + " 7.00000000e-04, 9.55044167e-02, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 1.00000000e+00,\n", + " 0.00000000e+00, 1.00000000e+00, -3.60000000e+02,\n", + " 3.60000000e+02, 8.00000000e-01, -2.90000000e+00,\n", + " -7.93618189e-01, 2.80573774e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00],\n", + " [ 1.00000000e+00, 2.00000000e+00, 1.63923679e-04,\n", + " 4.79726336e-03, -1.05000908e-02, 2.50000000e+01,\n", + " 0.00000000e+00, 0.00000000e+00, 1.00000000e+00,\n", + " 1.50000000e+02, 1.00000000e+00, -3.60000000e+02,\n", + " 3.60000000e+02, -6.74416214e+00, -4.54095852e-01,\n", + " 6.76600792e+00, 6.75887284e-01, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 1.39996439e-02,\n", + " 0.00000000e+00, 0.00000000e+00]]),\n", + " 'branch_dc': array([], shape=(0, 15), dtype=float64),\n", + " 'tcsc': array([], shape=(0, 17), dtype=float64),\n", + " 'svc': array([], shape=(0, 11), dtype=float64),\n", + " 'ssc': array([], shape=(0, 10), dtype=float64),\n", + " 'vsc': array([], shape=(0, 17), dtype=float64),\n", + " 'gen': array([[ 0.00000000e+00, -6.74111530e+00, -7.14688297e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 1.02000000e+00,\n", + " 1.00000000e+00, 1.00000000e+00, 1.00000000e+09,\n", + " -1.00000000e+09, 0.00000000e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 1.00000000e+00],\n", + " [ 3.00000000e+00, 6.00000000e+00, 3.42190962e+00,\n", + " 3.00000000e+00, -3.00000000e+00, 1.03000000e+00,\n", + " nan, 1.00000000e+00, 1.00000000e+09,\n", + " -1.00000000e+09, 0.00000000e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00]]),\n", + " 'internal': {'Ybus': <6x6 sparse matrix of type ''\n", + " \twith 16 stored elements in Compressed Sparse Row format>,\n", + " 'Yf': <5x6 sparse matrix of type ''\n", + " \twith 10 stored elements in Compressed Sparse Row format>,\n", + " 'Yt': <5x6 sparse matrix of type ''\n", + " \twith 10 stored elements in Compressed Sparse Row format>,\n", + " 'branch_is': array([ True, True, True, True, True]),\n", + " 'branch_dc_is': array([], dtype=bool),\n", + " 'gen_is': array([ True, True]),\n", + " 'DLF': array([], dtype=complex128),\n", + " 'buses_ord_bfs_nets': array([], dtype=float64),\n", + " 'ac_slack_buses': [0],\n", + " 'svc_is': array([], dtype=bool),\n", + " 'ssc_is': array([], dtype=bool),\n", + " 'vsc_is': array([], dtype=bool),\n", + " 'tcsc_is': array([], dtype=bool),\n", + " 'ref_gens': array([0], dtype=int64),\n", + " 'baseMVA': 1,\n", + " 'bus': array([[ 0. , 3. , 0. , 0. ,\n", + " 0. , 0. , 1. , 1.02 ,\n", + " 50. , 110. , 1. , 2. ,\n", + " 0. , 0. , 0. , 0. ],\n", + " [ 1. , 1. , 0. , 0. ,\n", + " 0. , 0.96 , 1. , 1.02082951,\n", + " 50.03241357, 110. , 1. , 2. ,\n", + " 0. , 0. , 0. , 0. ],\n", + " [ 2. , 1. , 0. , 0. ,\n", + " 0. , 0. , 1. , 1.02456241,\n", + " -98.19715207, 20. , 1. , 2. ,\n", + " 0. , 0. , 0. , 0. ],\n", + " [ 3. , 2. , 0. , 0. ,\n", + " 0. , 0. , 1. , 1.03 ,\n", + " -98.12954543, 20. , 1. , 2. ,\n", + " 0. , 0. , 0. , 0. ],\n", + " [ 4. , 1. , -0.8 , 2.9 ,\n", + " 0. , 0. , 1. , 1.02320534,\n", + " -98.04777562, 20. , 1. , 2. ,\n", + " 0. , 0. , 0. , 0. ],\n", + " [ 5. , 1. , 0. , 0. ,\n", + " 0. , 0. , 1. , 1.030007 ,\n", + " -98.13016747, 20. , 1. , 1.1 ,\n", + " 0.9 , 0. , 0. , 0. ]]),\n", + " 'gen': array([[ 0.00000000e+00, -6.74111530e+00, -7.14688297e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 1.02000000e+00,\n", + " 1.00000000e+00, 1.00000000e+00, 1.00000000e+09,\n", + " -1.00000000e+09, 0.00000000e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 1.00000000e+00],\n", + " [ 3.00000000e+00, 6.00000000e+00, 3.42190962e+00,\n", + " 3.00000000e+00, -3.00000000e+00, 1.03000000e+00,\n", + " nan, 1.00000000e+00, 1.00000000e+09,\n", + " -1.00000000e+09, 0.00000000e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00]]),\n", + " 'branch': array([[ 0.00000000e+00, 1.00000000e+00, 4.95867769e-05,\n", + " 1.19008264e-04, 5.47391104e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 1.00000000e+00,\n", + " 0.00000000e+00, 1.00000000e+00, -3.60000000e+02,\n", + " 3.60000000e+02, -6.74111530e+00, -7.14688297e+00,\n", + " 6.74416214e+00, 1.45450502e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00],\n", + " [ 2.00000000e+00, 3.00000000e+00, 6.10000000e-04,\n", + " 5.60000000e-04, 7.64035333e-02, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 1.00000000e+00,\n", + " 0.00000000e+00, 1.00000000e+00, -3.60000000e+02,\n", + " 3.60000000e+02, -5.97238973e+00, -3.48162502e+00,\n", + " 5.99999998e+00, 3.42634241e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00],\n", + " [ 3.00000000e+00, 5.00000000e+00, 5.19662500e-03,\n", + " 3.25500000e-03, 4.17831823e-03, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 1.00000000e+00,\n", + " 0.00000000e+00, 1.00000000e+00, -3.60000000e+02,\n", + " 3.60000000e+02, 2.40627138e-08, -4.43279288e-03,\n", + " -2.48402500e-14, 3.31204118e-14, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00],\n", + " [ 4.00000000e+00, 2.00000000e+00, 7.62500000e-04,\n", + " 7.00000000e-04, 9.55044167e-02, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 1.00000000e+00,\n", + " 0.00000000e+00, 1.00000000e+00, -3.60000000e+02,\n", + " 3.60000000e+02, 8.00000000e-01, -2.90000000e+00,\n", + " -7.93618189e-01, 2.80573774e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00],\n", + " [ 1.00000000e+00, 2.00000000e+00, 1.63923679e-04,\n", + " 4.79726336e-03, -1.05000908e-02, 2.50000000e+01,\n", + " 0.00000000e+00, 0.00000000e+00, 1.00000000e+00,\n", + " 1.50000000e+02, 1.00000000e+00, -3.60000000e+02,\n", + " 3.60000000e+02, -6.74416214e+00, -4.54095852e-01,\n", + " 6.76600792e+00, 6.75887284e-01, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 1.39996439e-02,\n", + " 0.00000000e+00, 0.00000000e+00]]),\n", + " 'ref': array([0], dtype=int64),\n", + " 'pv': array([3], dtype=int64),\n", + " 'pq': array([1, 2, 4, 5], dtype=int64),\n", + " 'Bbus': <6x6 sparse matrix of type ''\n", + " \twith 16 stored elements in Compressed Sparse Column format>,\n", + " 'Bf': <5x6 sparse matrix of type ''\n", + " \twith 10 stored elements in Compressed Sparse Row format>,\n", + " 'Pbusinj': array([ 0. , -545.726528, 545.726528, 0. , 0. ,\n", + " 0. ]),\n", + " 'Pfinj': array([ -0. , -0. , -0. , -0. , -545.726528]),\n", + " 'Cft': <5x6 sparse matrix of type ''\n", + " \twith 10 stored elements in Compressed Sparse Row format>,\n", + " 'shift': array([ 0., 0., 0., 0., 150.]),\n", + " 'V': array([ 0.65564336+0.78136533j, 0.65573406+0.78237186j,\n", + " -0.14608184-1.01409479j, -0.14565409-1.01964939j,\n", + " -0.1432475 -1.01312848j, -0.14566615-1.01965475j]),\n", + " 'J': <9x9 sparse matrix of type ''\n", + " \twith 41 stored elements in Compressed Sparse Column format>,\n", + " 'Vm_it': None,\n", + " 'Va_it': None,\n", + " 'svc': array([], shape=(0, 11), dtype=float64),\n", + " 'tcsc': array([], shape=(0, 17), dtype=float64),\n", + " 'ssc': array([], shape=(0, 10), dtype=float64),\n", + " 'vsc': array([], shape=(0, 17), dtype=float64),\n", + " 'Sbus': array([-6.8+0.j , 0. +0.j , 0. +0.j , 6. +0.j , 0.8-2.9j, 0. +0.j ]),\n", + " 'r_theta_kelvin_per_mw': None,\n", + " 'T': None},\n", + " 'success': True,\n", + " 'et': 3.377016900005401,\n", + " 'iterations': 3}" + ] }, "execution_count": 3, "metadata": {}, @@ -138,14 +374,27 @@ "execution_count": 4, "metadata": { "ExecuteTime": { - "end_time": "2024-03-30T10:51:40.193610Z", - "start_time": "2024-03-30T10:51:40.174610Z" + "end_time": "2024-11-27T09:35:28.203075Z", + "start_time": "2024-11-27T09:35:28.190515Z" } }, "outputs": [ { "data": { - "text/plain": "array([[ 8402.77777778+0.j, -8402.77777778+0.j, 0. +0.j,\n 0. +0.j, 0. +0.j, 0. +0.j],\n [-8402.77777778+0.j, 8611.22995659+0.j, -208.45217882+0.j,\n 0. +0.j, 0. +0.j, 0. +0.j],\n [ 0. +0.j, -208.45217882+0.j, 3422.7378931 +0.j,\n -1785.71428571+0.j, -1428.57142857+0.j, 0. +0.j],\n [ 0. +0.j, 0. +0.j, -1785.71428571+0.j,\n 2092.93394777+0.j, 0. +0.j, -307.21966206+0.j],\n [ 0. +0.j, 0. +0.j, -1428.57142857+0.j,\n 0. +0.j, 1428.57142857+0.j, 0. +0.j],\n [ 0. +0.j, 0. +0.j, 0. +0.j,\n -307.21966206+0.j, 0. +0.j, 307.21966206+0.j]])" + "text/plain": [ + "array([[ 8402.77777778, -8402.77777778, 0. , 0. ,\n", + " 0. , 0. ],\n", + " [-8402.77777778, 8611.22995659, -208.45217882, 0. ,\n", + " 0. , 0. ],\n", + " [ 0. , -208.45217882, 3422.7378931 , -1785.71428571,\n", + " -1428.57142857, 0. ],\n", + " [ 0. , 0. , -1785.71428571, 2092.93394777,\n", + " 0. , -307.21966206],\n", + " [ 0. , 0. , -1428.57142857, 0. ,\n", + " 1428.57142857, 0. ],\n", + " [ 0. , 0. , 0. , -307.21966206,\n", + " 0. , 307.21966206]])" + ] }, "execution_count": 4, "metadata": {}, @@ -171,14 +420,33 @@ "execution_count": 5, "metadata": { "ExecuteTime": { - "end_time": "2024-03-30T10:51:40.224863Z", - "start_time": "2024-03-30T10:51:40.194632Z" + "end_time": "2024-11-27T09:35:28.234805Z", + "start_time": "2024-11-27T09:35:28.210522Z" } }, "outputs": [ { "data": { - "text/plain": "matrix([[ 2983.234714 -7157.02635809j, -2983.234714 +7159.76331361j,\n 0. +0.j , 0. +0.j ,\n 0. +0.j , 0. +0.j ],\n [-2983.234714 +7159.76331361j, 2990.35626947-7364.28068082j,\n -97.94315042 -183.87162407j, 0. +0.j ,\n 0. +0.j , 0. +0.j ],\n [ 0. +0.j , 110.26592227 -176.75706842j,\n 1608.40491554-1678.15899439j, -889.60186671 +816.68368091j,\n -711.68149336 +653.34694473j, 0. +0.j ],\n [ 0. +0.j , 0. +0.j ,\n -889.60186671 +816.68368091j, 1027.81021222 -903.21268537j,\n 0. +0.j , -138.20834551 +86.56929539j],\n [ 0. +0.j , 0. +0.j ,\n -711.68149336 +653.34694473j, 0. +0.j ,\n 711.68149336 -653.29919252j, 0. +0.j ],\n [ 0. +0.j , 0. +0.j ,\n 0. +0.j , -138.20834551 +86.56929539j,\n 0. +0.j , 138.20834551 -86.56720623j]])" + "text/plain": [ + "matrix([[ 2983.234714 -7157.02635809j, -2983.234714 +7159.76331361j,\n", + " 0. +0.j , 0. +0.j ,\n", + " 0. +0.j , 0. +0.j ],\n", + " [-2983.234714 +7159.76331361j, 2990.35626947-7364.28068082j,\n", + " -97.94315042 -183.87162407j, 0. +0.j ,\n", + " 0. +0.j , 0. +0.j ],\n", + " [ 0. +0.j , 110.26592227 -176.75706842j,\n", + " 1608.40491554-1678.15899439j, -889.60186671 +816.68368091j,\n", + " -711.68149336 +653.34694473j, 0. +0.j ],\n", + " [ 0. +0.j , 0. +0.j ,\n", + " -889.60186671 +816.68368091j, 1027.81021222 -903.21268537j,\n", + " 0. +0.j , -138.20834551 +86.56929539j],\n", + " [ 0. +0.j , 0. +0.j ,\n", + " -711.68149336 +653.34694473j, 0. +0.j ,\n", + " 711.68149336 -653.29919252j, 0. +0.j ],\n", + " [ 0. +0.j , 0. +0.j ,\n", + " 0. +0.j , -138.20834551 +86.56929539j,\n", + " 0. +0.j , 138.20834551 -86.56720623j]])" + ] }, "execution_count": 5, "metadata": {}, @@ -211,14 +479,42 @@ "execution_count": 6, "metadata": { "ExecuteTime": { - "end_time": "2024-03-30T10:51:40.232737Z", - "start_time": "2024-03-30T10:51:40.225872Z" + "end_time": "2024-11-27T09:35:28.269614Z", + "start_time": "2024-11-27T09:35:28.264612Z" } }, "outputs": [ { "data": { - "text/plain": "matrix([[ 9.54796429e+02, 0.00000000e+00, -8.62952847e+02,\n 0.00000000e+00, -9.18435819e+01, 0.00000000e+00,\n -9.15296722e+02, 0.00000000e+00, -1.42353628e+02],\n [ 0.00000000e+00, 7.67426446e+03, -2.17432759e+02,\n 0.00000000e+00, 0.00000000e+00, 3.05264391e+03,\n -1.38258877e+01, 0.00000000e+00, 0.00000000e+00],\n [-8.60737366e+02, -2.17892547e+02, 1.76161072e+03,\n -6.82980810e+02, 0.00000000e+00, -6.95207957e-01,\n 1.64791122e+03, -7.30904816e+02, 0.00000000e+00],\n [ 0.00000000e+00, 0.00000000e+00, -6.86871045e+02,\n 6.86871045e+02, 0.00000000e+00, 0.00000000e+00,\n -7.26450957e+02, 7.28978161e+02, 0.00000000e+00],\n [-9.18403982e+01, 0.00000000e+00, 0.00000000e+00,\n 0.00000000e+00, 9.18403982e+01, 0.00000000e+00,\n 0.00000000e+00, 0.00000000e+00, 1.42355564e+02],\n [ 0.00000000e+00, -3.11622898e+03, 1.41654849e+01,\n 0.00000000e+00, 0.00000000e+00, 7.51767501e+03,\n -2.12220120e+02, 0.00000000e+00, 0.00000000e+00],\n [ 9.39812505e+02, 7.09688796e-01, -1.68838790e+03,\n 7.47865710e+02, 0.00000000e+00, -2.13446561e+02,\n 1.71937863e+03, -6.67491444e+02, 0.00000000e+00],\n [ 0.00000000e+00, 0.00000000e+00, 7.44294346e+02,\n -7.44294346e+02, 0.00000000e+00, 0.00000000e+00,\n -6.70404297e+02, 6.65624991e+02, 0.00000000e+00],\n [ 1.46627228e+02, 0.00000000e+00, 0.00000000e+00,\n 0.00000000e+00, -1.46627228e+02, 0.00000000e+00,\n 0.00000000e+00, 0.00000000e+00, 8.91648289e+01]])" + "text/plain": [ + "matrix([[ 9.54796429e+02, 0.00000000e+00, -8.62952847e+02,\n", + " 0.00000000e+00, -9.18435819e+01, 0.00000000e+00,\n", + " -9.15296722e+02, 0.00000000e+00, -1.42353628e+02],\n", + " [ 0.00000000e+00, 7.67426446e+03, -2.17432759e+02,\n", + " 0.00000000e+00, 0.00000000e+00, 3.05264391e+03,\n", + " -1.38258877e+01, 0.00000000e+00, 0.00000000e+00],\n", + " [-8.60737366e+02, -2.17892547e+02, 1.76161072e+03,\n", + " -6.82980810e+02, 0.00000000e+00, -6.95207957e-01,\n", + " 1.64791122e+03, -7.30904816e+02, 0.00000000e+00],\n", + " [ 0.00000000e+00, 0.00000000e+00, -6.86871045e+02,\n", + " 6.86871045e+02, 0.00000000e+00, 0.00000000e+00,\n", + " -7.26450957e+02, 7.28978161e+02, 0.00000000e+00],\n", + " [-9.18403982e+01, 0.00000000e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 9.18403982e+01, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 1.42355564e+02],\n", + " [ 0.00000000e+00, -3.11622898e+03, 1.41654849e+01,\n", + " 0.00000000e+00, 0.00000000e+00, 7.51767501e+03,\n", + " -2.12220120e+02, 0.00000000e+00, 0.00000000e+00],\n", + " [ 9.39812505e+02, 7.09688796e-01, -1.68838790e+03,\n", + " 7.47865710e+02, 0.00000000e+00, -2.13446561e+02,\n", + " 1.71937863e+03, -6.67491444e+02, 0.00000000e+00],\n", + " [ 0.00000000e+00, 0.00000000e+00, 7.44294346e+02,\n", + " -7.44294346e+02, 0.00000000e+00, 0.00000000e+00,\n", + " -6.70404297e+02, 6.65624991e+02, 0.00000000e+00],\n", + " [ 1.46627228e+02, 0.00000000e+00, 0.00000000e+00,\n", + " 0.00000000e+00, -1.46627228e+02, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 8.91648289e+01]])" + ] }, "execution_count": 6, "metadata": {}, @@ -253,14 +549,16 @@ "execution_count": 7, "metadata": { "ExecuteTime": { - "end_time": "2024-03-30T10:51:40.241491Z", - "start_time": "2024-03-30T10:51:40.234750Z" + "end_time": "2024-11-27T09:35:28.318474Z", + "start_time": "2024-11-27T09:35:28.313473Z" } }, "outputs": [ { "data": { - "text/plain": "array([0, 1, 1, 2, 2, 3, 4], dtype=int64)" + "text/plain": [ + "array([0, 1, 1, 2, 2, 3, 4], dtype=int64)" + ] }, "execution_count": 7, "metadata": {}, @@ -283,8 +581,8 @@ "execution_count": 8, "metadata": { "ExecuteTime": { - "end_time": "2024-03-30T10:51:40.249297Z", - "start_time": "2024-03-30T10:51:40.242504Z" + "end_time": "2024-11-27T09:35:28.386430Z", + "start_time": "2024-11-27T09:35:28.382136Z" } }, "outputs": [ @@ -314,14 +612,16 @@ "execution_count": 9, "metadata": { "ExecuteTime": { - "end_time": "2024-03-30T10:51:40.258281Z", - "start_time": "2024-03-30T10:51:40.251310Z" + "end_time": "2024-11-27T09:35:28.413120Z", + "start_time": "2024-11-27T09:35:28.407729Z" } }, "outputs": [ { "data": { - "text/plain": "(2990.356269470474-7364.280680821408j)" + "text/plain": [ + "(2990.356269470474-7364.280680821408j)" + ] }, "execution_count": 9, "metadata": {}, @@ -346,8 +646,8 @@ "execution_count": 10, "metadata": { "ExecuteTime": { - "end_time": "2024-03-30T10:51:40.267788Z", - "start_time": "2024-03-30T10:51:40.261350Z" + "end_time": "2024-11-27T09:35:28.427645Z", + "start_time": "2024-11-27T09:35:28.422644Z" } }, "outputs": [ @@ -377,14 +677,24 @@ "execution_count": 11, "metadata": { "ExecuteTime": { - "end_time": "2024-03-30T10:51:40.276542Z", - "start_time": "2024-03-30T10:51:40.268796Z" + "end_time": "2024-11-27T09:35:28.453037Z", + "start_time": "2024-11-27T09:35:28.446517Z" } }, "outputs": [ { "data": { - "text/plain": "bus 1\nelement 2\net b\ntype CB\nclosed True\nname None\nz_ohm 0.0\nin_ka NaN\nName: 0, dtype: object" + "text/plain": [ + "bus 1\n", + "element 2\n", + "et b\n", + "type CB\n", + "closed True\n", + "name None\n", + "z_ohm 0.0\n", + "in_ka NaN\n", + "Name: 0, dtype: object" + ] }, "execution_count": 11, "metadata": {}, @@ -409,8 +719,8 @@ "execution_count": 12, "metadata": { "ExecuteTime": { - "end_time": "2024-03-30T10:51:40.284228Z", - "start_time": "2024-03-30T10:51:40.277557Z" + "end_time": "2024-11-27T09:35:28.504149Z", + "start_time": "2024-11-27T09:35:28.499049Z" } }, "outputs": [ @@ -439,8 +749,8 @@ "execution_count": 13, "metadata": { "ExecuteTime": { - "end_time": "2024-03-30T10:51:40.291248Z", - "start_time": "2024-03-30T10:51:40.285169Z" + "end_time": "2024-11-27T09:35:28.557809Z", + "start_time": "2024-11-27T09:35:28.553234Z" } }, "outputs": [ @@ -491,8 +801,8 @@ "execution_count": 14, "metadata": { "ExecuteTime": { - "end_time": "2024-03-30T10:51:40.300214Z", - "start_time": "2024-03-30T10:51:40.292195Z" + "end_time": "2024-11-27T09:35:28.607093Z", + "start_time": "2024-11-27T09:35:28.598759Z" } }, "outputs": [ @@ -521,30 +831,14 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": null, "metadata": { "ExecuteTime": { - "end_time": "2024-03-30T10:51:40.320713Z", - "start_time": "2024-03-30T10:51:40.302226Z" + "end_time": "2024-11-27T09:35:28.653480Z", + "start_time": "2024-11-27T09:35:28.638719Z" } }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "pv and pq nodes as in the newtonpf() function\n", - "pv buses: [3]\n", - "pq buses: [1 2 4 5]\n", - "pvpq buses: [3 1 2 4 5]\n", - "shape of J sub-matrices:\n", - "j11 = (5, 5)\n", - "j12 = (5, 4)\n", - "j21 = (4, 5)\n", - "j22 = (4, 4)\n" - ] - } - ], + "outputs": [], "source": [ "import numpy as np\n", "\n", @@ -586,8 +880,8 @@ "execution_count": 16, "metadata": { "ExecuteTime": { - "end_time": "2024-03-30T10:51:40.332920Z", - "start_time": "2024-03-30T10:51:40.322679Z" + "end_time": "2024-11-27T09:35:28.780210Z", + "start_time": "2024-11-27T09:35:28.771222Z" } }, "outputs": [ @@ -625,8 +919,8 @@ "execution_count": 17, "metadata": { "ExecuteTime": { - "end_time": "2024-03-30T10:51:40.342410Z", - "start_time": "2024-03-30T10:51:40.334935Z" + "end_time": "2024-11-27T09:35:28.806554Z", + "start_time": "2024-11-27T09:35:28.801552Z" } }, "outputs": [], @@ -666,8 +960,8 @@ "execution_count": 18, "metadata": { "ExecuteTime": { - "end_time": "2024-03-30T10:51:40.352770Z", - "start_time": "2024-03-30T10:51:40.344422Z" + "end_time": "2024-11-27T09:35:28.833882Z", + "start_time": "2024-11-27T09:35:28.828034Z" } }, "outputs": [], @@ -712,8 +1006,8 @@ "execution_count": 19, "metadata": { "ExecuteTime": { - "end_time": "2024-03-30T10:51:40.360146Z", - "start_time": "2024-03-30T10:51:40.353781Z" + "end_time": "2024-11-27T09:35:28.851657Z", + "start_time": "2024-11-27T09:35:28.847362Z" } }, "outputs": [], @@ -743,8 +1037,8 @@ "execution_count": 20, "metadata": { "ExecuteTime": { - "end_time": "2024-03-30T10:51:41.739192Z", - "start_time": "2024-03-30T10:51:40.361157Z" + "end_time": "2024-11-27T09:35:29.422981Z", + "start_time": "2024-11-27T09:35:28.871680Z" } }, "outputs": [ @@ -752,16 +1046,18 @@ "name": "stderr", "output_type": "stream", "text": [ - "C:\\Users\\mvogt\\AppData\\Local\\Temp\\ipykernel_17836\\3533381797.py:18: UserWarning: FixedFormatter should only be used together with FixedLocator\n", + "C:\\Users\\hkoertge\\AppData\\Local\\Temp\\ipykernel_26300\\1313666249.py:18: UserWarning: set_ticklabels() should only be used with a fixed number of ticks, i.e. after set_ticks() or using a FixedLocator.\n", " ax.set_yticklabels(np.arange(ybus.shape[1]))\n", - "C:\\Users\\mvogt\\AppData\\Local\\Temp\\ipykernel_17836\\3533381797.py:18: UserWarning: FixedFormatter should only be used together with FixedLocator\n", + "C:\\Users\\hkoertge\\AppData\\Local\\Temp\\ipykernel_26300\\1313666249.py:18: UserWarning: set_ticklabels() should only be used with a fixed number of ticks, i.e. after set_ticks() or using a FixedLocator.\n", " ax.set_yticklabels(np.arange(ybus.shape[1]))\n" ] }, { "data": { - "text/plain": "
", - "image/png": "iVBORw0KGgoAAAANSUhEUgAABioAAAL4CAYAAADlH68VAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAA9hAAAPYQGoP6dpAAEAAElEQVR4nOzdeXwTdf4/8NdMkh6UUlpuSjlEuSygK3ILiILihaIoXovX/lQQr1V3V3eVdVVc11XZdUVF5et9K7pQoEihpa1QjiIUCxQsUEqhlJ4Uckxmfn90Ext6kDTJTPLJ6/l49MGnaZrX5z0znQnzmflE0jRNAxERERERERERERERkQFkoztARERERERERERERESRiwMVRERERERERERERERkGA5UEBERERERERERERGRYThQQUREREREREREREREhuFABRERERERERERERERGYYDFUREREREREREREREZBgOVBARERERERERERERkWE4UEFERERERERERERERIbhQAURERERERERERERERmGAxVERERERERERERERGQYDlQQEREREREREREREZFhOFBBRERERERERERERESG4UAFEREREREREREREREZhgMVRERERERERERERERkGA5UEBERERERERERERGRYThQQUREREREREREREREhuFABRERERERERERERERGYYDFUREREREREREREREZBgOVBARERERERERERERkWE4UEFERERERERERERERIbhQAURERERERERERERERmGAxVERERERERERERERGQYDlQQEREREREREREREZFhOFBBRERERERERERERESG4UAFEREREREREREREREZhgMVRERERERERERERERkGA5UEBERERERERERERGRYThQQUREREREREREREREhuFABRERERERERERERERGYYDFUREREREREREREREZBgOVBARERERERERERERkWE4UEFERERERERERERERIbhQAURERERERERERERERmGAxVERERERERERERERGQYDlQQEREREREREREREZFhOFBBRERERERERERERESG4UAFEREREREREREREREZhgMVRERERERERERERERkGA5UEBERERERERERERGRYThQQUREREREREREREREhuFABRERERERERERERERGYYDFUREREREREREREREZBgOVBARERERERERERERkWE4UEFERERERERERERERIbhQAURERERERERERERERmGAxVERERERERERERERGQYDlQQEREREREREREREZFhOFBBRERERERERERERESG4UAFEREREREREREREREZhgMVRERERERERERERERkGA5UEBERERERERERERGRYThQQUREREREREREREREhuFABRERERERERERERERGYYDFUREREREREREREREZBgOVBARERERERERERERkWE4UEFERERERERERERERIbhQAURERERERERERERERmGAxVERERERERERERERGQYDlQQEREREREREREREZFhOFBBRERERERERERERESG4UAFEREREREREREREREZhgMVRERERERERERERERkGA5UEFFkO3ECePhhoGdPICYGOO884LPPjO4VERERERERERFRxDAb3QEiIkPNmAFs2gS8+CIwYADwySfAzTcDqgrccovRvSMiIiIiIiIiIhKepGmaZnQniIgMkZYGXHnlr4MTLlOnAjt3AgcPAiaTcf0jIiIiIiIiIiKKAJz6iYgi17ffAu3bAzNnej5+553A4cPAxo3G9IuIiIiIiIiIiCiCcKCCiCJXQQEweDBgPm0WvGHDfv05ERERERERERERBRU/o4KIItfx48BZZzV9PCnp15+3wGq1orKy0uPr+PHjTR5r/FVfX4877rgDL7/8cpAKIiIiIiIiIiIiCj8cqCCiyCZJXv9s/fr1mDNnDvbt24dTp061Ke6f//wnnnjiCXTt2rVNv09ERERERERERCQaTv1ERJGrU6fm75qorGz413Vnxf8sXLgQBQUFPg9SWCwWyPKvu9vy8nKfu0pERERERERERCQqDlQQUeQaOhQoLAQUxfPxHTsa/k1NbfFXR44ciauuusrjzogJEybg888/x5o1a5Cfn48DBw7gxIkTsNlseOihh9zPq3QNhBARERERERERERGnfiKiCHbddcDixcDXXwM33fTr4++/D/TsCYwa5fH0pEZ3WLz99tsYPnw4/vWvf7kHIV566SWMOu13XLp06eJuc6CCiIiIiIiIiIjoVxyoIKLINW0aMGUKcP/9QG0tcPbZwKefAitXAh99BJhMHk9vPFBRWVmJ9957Dw8//DBuvfVW/PLLL5g6dSpWr16NkSNHNokqLS11t4+38iHdREREREREREREkYYDFUQUMXYersH7ufuRuecYFKeG1OQEzH7+TUz+aCHw9NMNn00xaFDDYMWsWU1+v/FAxZdffok333wT9957L/7zn/+gvr4el19+OaZMmdJksGL58uV466233N/zjgoiIiIiIiIiIqJf8TMqiCgifLG5BNe8noMvNh/C0VobjtfbkbnnGO76uhBPXHQXtMOHAZsN+OmnZgcpAM+BikWLFrkHKWRZRnx8PFauXInU1FRMmTIFeXl5ABoGKWbMmOExJRQHKoiIiIiIiIiIiH7FgQoiEt7uI3X40zc74FS1Zn/+xeZD+GjjwSaPa5qGkydPoqSkBD/99BMOHz7s/tnIkSPdgxQupw9WPPPMM5gxYwauuOIKvPrqq+7ncaCCiIiIiIiIiIjoV5z6iYiE98GP+z0GKU7uzYOtpACmhG7QbPVQrSfwh4yT+LpnNCorKz2+bDZbs6/ZpUsXj0EKF9dgRYcOHfDss8+iZ8+e+Pzzz3HkyBH3czhQQURERERERERE9CveUUFEwsveWwH7sQOozv4Yh966B8e+fha1ed+gavUiVGd9gNq8b1C2aSW+++47rF+/Hjt37kRZWVmLgxQAcPTo0RZ/lpWV5W5XVVVh27ZtHtNG8cO0iYhCx1VXXYWOHTuipKSkyc8qKyvRo0cPjBs3Du+99x4kScLmzZsN6KXv5s+fD0mSUFFRYXRX2uyuu+7C5Zdf7vHYa6+9hhkzZqBfv36QJAmTJk1q9nf/7//+D5IkNfvV+OIBX/35z3/GVVddheTkZEiShDvuuKPZ57mW/+lfMTExHs+rqqpCx44dsXTp0jb3iYiIQhvfa4Quf95rAMDatWsxZcoUdO3aFe3bt8ewYcPwr3/9C06ns8198va9BgB8/fXXGDduHJKSktCxY0eMHDkSH374ocdz+F6DwgkHKohIWDt37sT8+fOx6eU7UPbeXNTkfApn9ZlPTrRr1w69evXCsGHDMGnSJFx//fX43e9+hzlz5rifs2PHDuzZs6fJ77o+k+Laa69FRUUFzj//fEyZMgU7d+6ExWIBwDsqiIhCyTvvvAOz2Yx77rmnyc8eeOAB1NXV4f3332/2LjoKnvz8fLz//vt47rnnPB5/8803ceDAAUyePBldunQ54+ssWbIEP/74o8dXp06d2tyvV199FcePH8c111yDqKioMz5/5cqVHtmNL2YAgMTERDzyyCN4/PHHYbfb29wvIiIKXXyvEZr8fa/xww8/4NJLL4WiKFi8eDGWLl2KSZMm4aGHHsKjjz7a5n55+17jvffeww033IAePXrg448/xmeffYb+/fvjt7/9rcfU03yvQWFFIyISSEFBgfbMM89ogwcP1gA08yVppo7dNVP7ThpkU7PP6datm3b//fdra9eu1RRFcb/2yZMn3c9p166d1rNnT2337t3uny9btkyLiorSrr32Ws1ms2mapmm1tbXa2LFjtQ4dOmhJSUkaAC0lJUX35UJERC37/PPPNQDam2++6X7sm2++0QBob7zxhqZpmrZkyRINgLZp0yajuumTZ555RgOgHTt2zOiutMmNN96ojR49usnjTqfT3T733HO1iRMnNvv7wVpfjfPj4uK02bNnN/s8X5b/kSNHNLPZrH388ceB6iYREYUYvtcIPf6+17j11lu16Oho7cSJEx6PT506VevQoUOb++Xte41x48Zpffr08Xi+qqraoEGDtGHDhnk8l+81KFxwuJaIwp7rzokhQ4YgNTUVf/3rX1FYWOj+uSRJiO41BImX/D8kz1mCXve+g15z30fKg5+i89WPI3bAGJijot3PP3r0KBYtWoSLL74YycnJmDNnDtatW4eoqCj3lA19+vRBQkICLr74YuzZs8d9J8UVV1yBzz//3H3lQ+MP2K6urgbAOyqIiELNjTfeiFmzZuGxxx7D/v37cfz4cdx3332YMmUK7r//fo/nVlVV4c4770RSUhLi4uJw9dVX45dffvF4Tt++fZu9TX/SpEke0weoqornnnsOAwcORGxsLDp27Ihhw4Zh4cKFrfbXl987evQobr75ZiQkJKBbt2646667UFNT4/Gc//znP5gwYQK6du2KuLg4DB06FC+99BIcDkeT/qempmL9+vUYPXo0YmNjkZycjL/85S9Npjiw2+147rnnMGjQIERHR6NLly648847cezYsVZrc/X522+/xe23397kZ0ZfbRqM/G7dumHKlCl48803A/7aREQUGvheQ7z3GhaLBVFRUYiNjfV4vGPHjk2mevSFL/nt27f3eL4kSejQoUOTfL7XoHDBgQoiCkveDE6MHz8eCxcuRElJCZ5+6yt0GHENzPGd3c+Ro9shbshEXPnIyzhcdgSffvoprrvuOo+D+umDFq43ATU1NcjIyEBCQgIGDhyIq666qskghYtrsCIuLg4AUF9f3+rnXxARkf7+85//ID4+HnfddRfmzJkDu92O9957r8nz7r77bsiyjE8++QSvvfYa8vLyMGnSJPdgtC9eeuklzJ8/HzfffDOWL1+Ozz//HHffffcZX8uX37v++usxYMAAfP311/jjH/+ITz75BI888ojHc/bt24dbbrkFH374IZYtW4a7774b//jHP3Dvvfc2eb0jR45g1qxZuPXWW/Hdd9/hhhtuwHPPPYeHHnrI/RxVVTF9+nS8+OKLuOWWW7B8+XK8+OKLWL16NSZNmoRTp061Wl96ejocDgcuvvjiVp/njauuugomkwlJSUmYMWMGCgoK/H5NXwwdOhQmkwndunXDb3/7Wxw8eLDZ502aNAk5OTlt2o6IiCg88L2GWO817rvvPtjtdjz44IM4fPgwqqur8eGHH+Lbb7/FE0880ebX9da8efNQWFiI559/HseOHUNFRQVefvllbNmyBY899liT5/O9BoUFo2/pICLy1pmmdZIkSRs/fry2cOFC7dChQ01+f2n+Ie3qf6/X+vxhmdbnD8u0MS/8oP17zR7tlF3xeF5tba326aefatddd50WExPTwhRS0O677z7t4Ycfdn//3nvvaV999ZX21ltvaQsWLNAef/xx7e6779auu+46beLEiVq7du3czz18+LBei42IiLyUlpbm3k9/+OGHHj9zTcdw3XXXeTyek5OjAdCee+4592N9+vRp9jb9iRMnekwfcNVVV2nnnXeez/305vdc0zG89NJLHo/PmTNHi4mJ0VRVbfb3nE6n5nA4tA8++EAzmUxaZWWlR/8BaN99953H7/zud7/TZFnWDhw4oGmapn366acaAO3rr7/2eN6mTZs8prhoyf3336/Fxsa22EeX1qZjWLFihfbUU09p//3vf7XMzEzt9ddf13r16qXFxcVp27Zta/V1vdXadAwffPCB9vzzz2tpaWlaRkaG9uKLL2pJSUlat27dmn2Psnr1ag2AtmLFioD0jYiIQhPfa4jzXkPTGtZNz5493evUZDI1WR7+aO29hqZp2tKlS7WEhAR3fmxsrPbRRx81+1y+16BwYA7qKAgRkZ927tyJL7/8El988YXHHRMukiRh3LhxmDlzJq6//nokJye3+FrTz0vG9POSUVVvh0NV0TkuGrIsNXlefHw8Zs2a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A6a2tlb79NNPteuuu06LiYlptvZu3bpp999/v5aRkaEpimJ0l4mIIt7EiRO1c889t8njS5Ys0QBo6enp2u2336517NhRi42N1a644gqtqKjI47mqqmovvfSSdtZZZ2kxMTHaiBEjtIyMDG3ixInaxIkT3c/75z//qY0dO1br3LmzFhUVpfXu3Vu7++67tf3797faR29+75lnntEAaMeOHWu2juLiYvdj//3vf7Xhw4drMTExWnJysvb4449rK1as0ABoa9eubbJs1q1bp40YMUKLjo7WevTooT355JOaw+HwyHE4HNrLL7/sft327dtrgwYN0u69994my+t0TqdT69u3rzZnzpwmP5s9e3azx1MA2pIlS9zPe/jhh7UhQ4Zo8fHxmtls1nr27Knddttt2u7du5u85u9//3tNkiStsLCw1X65lkFL+Y2X1axZs7Szzz5bi4uL0ywWi9anTx/tvvvu0w4fPtzkNVVV1fr06aPNmzfvjPlERBT++F5DjPcamqZpX3/9tTZ+/Hitc+fOWlxcnHbuuedqf/vb37QTJ054PC8Y7zWcTqe2ePFibcSIEVrHjh21Dh06aOeff772+uuva3a73eM1+V6DwoWkaZoWrEEQIopcIt454Y+W7rRojHdaEBFRKJs0aRIqKipQUFAQ9Kx//vOfeP7551FaWorY2NigZo0cORJ9+vTBl19+GdSclqxZswZTp07Fzp07MWjQIEP6QEREFAr4XiM4+F6DwgUHKogoYDg44R0OWhARUTjS8+SB1WrF4MGDMXfuXDz22GNBy6mtrUWXLl2wbds2DB48OGg5rbn44otx9tlntzhXNxERUaTge43g4HsNChf8jAoi8gsHJ3zHz7QgIiJqXUxMDD788EPk5+cHNadDhw6w2WxBzWhNVVUVJk6c6DHvOBEREQUf32sQhR7eUUFEPuPgRHDwTgsiIiIiIiIiIopEHKggihCapkHTNMiy3Kbf5+CEvvQatPB3uyAiIiIiIiIiIvIXByqIBGaz2fDFF1/gzTffxKZNm+BwOJCSkoLbbrsN9913H3r37t3q73NwIjQEetCirq4OH374Id5++20UFBRA0zT0798fd911F+6++2506dIlmOUQERERERERERF54EAFkWDq6+vxySefYPHixdi2bRscDkezz4uOjsaSJUtw8803ezzOwYnQ5u+gxY4dO3DllVeipKSk2deXJAn9+vXDb3/7W/zud79Dz549g1YLERERERERERERwIEKIqHk5ORgxowZKC8vb/bn7du3h9VqhaIoAABZlvH999+jb9++HJwIQ74OWvTt2xejR4/22D4SExNRVVXV7OtbLBa8+uqrmDt3btBqICIiIiIiIiIi4kAFkSC2bt2Kiy66CCdPnvR4XJIkNP4zT01NxbBhw/DJJ58AaDgZ3dxdFxycCC/eDFrExMS4Hx8xYgT69u2Lr776yv3z07cVl0WLFuG+++4LXueJiIiIiIiIiCiicaCCSBCjR4/Gxo0bAQBRUVGw2+2QZRk//fQTfv75Zzz88MMoKysDADz77LP4/PPPsXPnTo/X4OCEGM40aBEVFYXvvvsO06ZNA9AwWPXss8/izjvvxLhx47Bv3z6P58fExODQoUPo1KmTbjUQEREREREREVHkkI3uABH5b8uWLe5BirPOOgt2ux0AMHXqVKSmpuLGG2/EypUrIUkSAGDx4sW444473L+fnJyMhQsXoqSkBOvXr8eDDz7IQYowFh8fj1mzZuGbb75BeXk5Pv30U4wZM8b983HjxuGjjz5yf//KK6/gj3/8I7p164b/9//+n/vx0aNHAwCsViuWLFmiXwFERERERERERBRROFBBJIDly5e729dff727fc4557jbw4YNw2WXXQYAKCkpQa9evdw/u+qqqzg4ISjXoMWDDz7ofuyqq67CsmXLAAAJCQm455573D9rvM00HtxovI0REREREREREREFEgcqiATQ+MOQL7jgAnd706ZNHs8bPny4u52Xl+duc0of8XXu3NndzsvLQ01NDQBgwIABiImJ8fiZy+DBg2GxWAAAlZWVOvWUiIiIiIiIiIgiDQcqiMLYzp07MX/+fI9pfLZu3YrU1FQAwIYNG7BmzRr3zwoKCtztb775xt2eMWOGDr0lI40fP949IPXNN98gLi4OALB3717YbDYAQHl5ORYvXgwAMJvN6Nu3r/uD1gsLCzFnzhysXbsWTqfTgAqIiIiIiIiIiEhU/DBtojCzc+dOfPnll/jiiy9QWFjY5Od9+vTB448/jgceeABAw9Q/zz77LEaPHo2xY8dC0zRYLBb3CehRo0Zhw4YNutZAxvjTn/6EF198EUDDB2S7PmT79ddfR/fu3fGnP/0JRUVFAICbbroJMTExeP/995u8Trdu3TBjxgzMnDkTEyZMgMlk0q8IIiIiIiIiIiISDgcqiMLAmQYnAKB9+/Y4ceIEAODSSy/FyZMnkZub2+rrxsfHIycnB0OHDg14nyn01NXV4aKLLsJPP/3U6vN69OiBq666yn13hSzLiIqKcg9sNMZBCyIiIiIiIiIi8hcHKohClDeDE+PHj8fMmTNx/fXX49ChQ5g0aZLHyeTY2FicOnWq2d/t27cvvv76a/zmN78JSv8pNB0/fhw33ngjMjIymv15VFQUFEWBqqruxxYuXIg777wTy5cvxxdffIEVK1Zw0IKIiIiIiIiIiAKGAxVEIcTXwYnk5GSPn61duxY33HBDix983K5dO1x00UX43e9+h2uuucb9QckUWTRNw8aNG/Hmm28iLS0Nx44da/Z5JpMJf//73/H73//e4/G6ujoOWhARERERERERUcBwoILIYP4OTpyupqYGH374Id5//33s378fUVFROP/883Hfffdh2rRpPGFMTWzduhWLFi3CDz/8gLq6OnTq1AkzZszAvffei759+7b6uxy0ICIiIiIiIiIif3GggsRWVwf87W/Atm1Afj5QUQE88wwwf76h3Qr04ARRKBB20MKb/YjTCSxcCKSnAwUFQGUl0KcPMH068Mc/Ah07GtR5IiIiIiIiIqLQx4EKEtv+/cB55wHDhwMDBgDvvGPYQAUHJyiSCDVo4c1+5MQJoGdP4OabgSlTgM6dga1bgeeeA3r0ADZvBmJjDSqAiIiIiIiIiCi0caCCxObavCWp4SroLl10Hajg4ASRAIMW3uxHnE6guhro1Mnzd7/6Cpg5E/jwQ+C22/TqMRERERERERFRWDEb3QGioJIk3SM5OEHkKT4+HrNmzcKsWbNaHLQ4evQoFi1ahEWLFoXeoIU3+xGTqekgBQCMHNnwb0lJYPtERERERERERCQQDlQQBQAHJ4i8E/aDFr7KyGj499xzje0HEREREREREVEI49RPFDkCPPUTByeIAidspofyZT9SWgpccAGQkgJs3AjIsi5dJCIiIiIiIiIKNxyooMgRgIGKMw1OSJKEcePGcXCCyA+uQYsvv/wSaWlpoTVo4e1+pLISuPhi4MgR4McfgbPO0qd/RERERERERERhiAMVFDnaOFDBwQki45w4cQLLli0LnUELb/YjVVXApZcCBw40TP00bFjw+kNERERERERE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bv2vDTG5zho3MqJx2nnoGDe/OPyDMG8/eCnTJ42JaZw0TQu7XsRz7mVkZKDrOocPH7autEnU3LMzUyRroGQKnyncGpiITIFtdujQIfLz8wetgeEytbe3k5+ff8LPGrL3RQiJ3JciMSy+9kz+sv0g9YePsuSdbTx/52ynuyQIgqAEmqYxbtw48Ytf/GnoT4Y+iF/86ey3g//93//ljTfe4M0332T69OlUVVXxyCOPMGnSJO65556Qz8nKyiIrK2vQ4263O+jf49uBHTYAmZmZTJgwASDoINDA38nIyBhW2+VyWW1N08jMzBw0joGdUMe3w/U9kkyB9vGu4WaKtTS05wTj4USmge3jxykwBgPLMSVynAAmTpwYl0wDnztcIs008PvhEm2+4eJ2u61tE8s4hVsv4j33PB5P0JxI5NyzK1Mka6BkCp8p3BqYiEyBdmAbDifTUEjpJ2EQcl+KxCEloARBEBKDz+dj1apVcalTK37xiz+1/MnQB/GLP539dvD444/z7//+79x5553MnDmTL33pSyxevJilS5cm1GvntlXVZReqbj8Vx0pV7BorVeefbD9xgRyoEEIg96VILLMn5/HVK04H4InlNXQci62mpyAIgtB/hsacOXPicvaW+MUv/tTyJ0MfxC/+dPbbwbFjxwaVtXK73daNPBOFndtWVZddqLr9VBwrVbFrrFSdf7L9xAVyoEI4jq1NHTxV1H/DliduPIfzTs11tkOKsvjaM5k2dhSHu70seWeb090RBEFIeTRNIz8/37H6+OIXv/id8ydDH8Qv/nT228Ett9zCD3/4Q9577z327NnDW2+9xXPPPcfnPve5hHrt3LaquuxC1e2n4lipil1jper8k+0nLpADFcIA5L4U9iEloARBEOKLz+fjvffec7TshvjFr7q/uaOHmubOQV9Vez/l5f99j6q9n4b8eXNHj1J9CEW6zAHxi98pXnzxRRYuXMiDDz7IOeecw2OPPcb999/PD37wg4R67dy2qrrsQtXtp+JYqYpdY6Xq/JPtJy4Al9/v98f9VYWUw+/387U3NrNq20EK87NZsehyKflkA0tX1vJq6W7Gjs5i9eIryB2Z6XSXBCHtOdanc+53VwGw/fvXMzIz9pvOCSemq6uLnJwcOjs7GTNmTNTP9/v9dHd3M3r0aEfuqyR+8avub+7o4epnP8SrR19mJcuj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+94f/Rl7a9b0/fspwroae1u3bu33a/dXT8tMVlVVtbv93//9nzwejy677LK49su2bVVWVjp2NqxpWSbWZGqWiTWZmmViTU5nOYXt13t8mTYAJAGOf0gUHo+n3Zdpb9iwQRdffLE2btwY+W6K8ePH65Zbbun2y7Sbm5vV3Nwc+bm2tla5ubk6cOCAhg4dGjm70+fztWtbliWPxxNpe71eeb1eNTU1ad26dTrrrLMkKXJ/a2urfD5fpO33++XxeCJtKXSGa9t2Wlpa5OzVtLQ02batQCAQadu2Lb/f367d0tKid999V2eddZY8Hk/kKoeu6oimpq7andUUCAT0zjvv6Mwzz4xcVdLfmtq2A4FAtzUFg0G98847Ov3005WRkRGTmnqznzwej9555x2ddtppGjBgQExq6s1+Ck/UzJw5U+np6Y6OPdu21dLSouLiYp122mny+XyOjj2Px6PDhw+ruLhYZ555piQ5OvbCbcuytG7dOp122mny+/2Ojb1wHeF9cPrpp8vr9To29jo7BoavMHBi7IXbzc3NWrt2beQY6NTYC7cty1JRUVG7Y2Csx15p5SF987fvdnxDi9KKm2dp8lGZfR577+85oAW/W9uv/CkjB3U69g4ePKicnJyE+ZLpL/+3RmcWLFiguro6vfXWW1G/bl++TPvLYyueTMwysSZTs0ysydQsE2uKdVZp5SFd8pu+T/CvuHmWpo3J7lcfpOTdflLst2G078FMVABAEuD4h0Tx5Q8PHnvsMd12223yer+4SDMQCMjr9So3N1e7du2K6nX78uEBAABOcftDj3jmJ9p7cE8TFfv27dPRRx+tp59+WldffXWXrxPrkyLiPeEZj0lcaqImaqKmVKyp7NP6fr1nLv/+6Zo+NiehanJ6P8XqBIlw36M9KYKlnwAAQJ9dc8012rx5s0pKSiK30aNH684779Trr7/uWD9s29bu3btdu9SVfPLJdy8/EfpAfmrnw1lPP/20srKytHDhwm6fF6tlJktKSmTbtiNLyO3evduRJeR2796t3bt3U1Mfa7JtWx9++KFWrVoV15oqKipk27befvtt7d27l5r6sHzh/v379dZbb8m2bUeWZPzggw9k2/FditbEmqqrq7Vq1Srt3r1be/fujUlN/fHu2rUJWVNPS9Hu3r07ZkvRvru275MUYX1ZZpIrKgAgCXD8g5vq6+u1fft2SdLJJ5+sRx99VHPnzlVOTo7Gjh3b4fnRLP30Zf09m9OyLBUXF2vmzJlxv6yWfPLJT6z8ROgD+ebnc0WFc3q6omLy5Mk6//zz9Zvf/Kbb14nFFRVNTU3asGGDTjvtNEmK65nFLS0t2rhxo7761a/GfQk527a1fv16nXLKKZElC6kp+rOlPR6P1q1bp1NPPbXbJSdjcba0bdtat26dZsyYofT0dGrqRU1paWlqaWnRe++9p9NOOy2SHa+z2rs6XlBTdFcf9HS8SMYrKmJZUzRL0X75GJiMV1QwUQEASYDjH9y0cuVKzZ07t8P9ixcv1rJlyzrc78ZEBQAA8cREhXO6m6hYvXq1Zs+erZKSEk2fPr1Xr5todQIA4sPt92wTuPUdFSz9BAAAujVnzhwFg8EOt84mKSRp165dvZqkiIVAIKDt27dHzjhxGvnkk+9efiL0gfzUzodznnzySZ166qm9nqToKyfHlolZJtZkapaJNZmaZWJNTmc5he3Xe0xUAACApBcMBnXw4EG5daEo+eST715+IvSBfPPzh2amK8Pft/99zvB7NTQzPanz462+vj7yXVdSaN3ukpIS7dmzJ/Kc2tpa/e1vf9MNN9zgWL+cHNsmZplYk6lZJtZkapaJNTmd5RS2X++x9BMAJAGOfzAdyzEAABJdZc1hHWxo6fXvDc1M15ghAxM2PxHeg6NZZvKJJ57QLbfcoqqqKmVn935JjkSoEwAQfyz91H8s/QQAANBHgUBAW7ZscXXZEfLJJ9/dpZ9SeRuQ70z+mCEDNW1MdofblJGD5K+r0pSRgzp9PBaTFImQH0/RLDP53e9+V42NjX2apOgrJ8e2iVkm1mRqlok1mZplYk1OZzmF7dd7TFQAAAAjHD58mHzyyU/R/EToA/nkp3K+yZzctiZmmViTqVkm1mRqlok1xTIrkZZLTMbtJ7m3DVn6CQCSAMc/mI7lGAAAcEeqvAenSp0AAPeXazRBLLchSz8BAICUEQgEVFpa6uqyI+STT767Sz+l8jYgn3y3/wZN5eS2NTHLxJpMzTKxJlOzTKwpHlndLZeogxWOLJeYzNtPcmcbMlEBAAAAAAAAAABcw9JPAJAEOP7BdCzHAACAO1LlPThV6gQAINFE+x7MJ10AAMB14fMmamtr+/T74Utdp02bJp/PF8uukU8++Qmenwh9IJ/8ZM4Pv/cm0TmMfdKX/9Zwct+amGViTaZmmViTqVkm1uRklok1JUNWtP+twUQFAABwXV1dnSQpNzfX5Z4AAJCa6urqlJ2d7XY34ob/1gAAwF09/bcGExUAAMB1o0ePVkVFhbKysuTxeHr9+7W1tcrNzVVFRYUryzmQTz757uUnQh/IJz+Z84PBoOrq6jR69Og49C5x9OW/NZzctyZmmViTqVkm1mRqlok1OZllYk3JkBXtf2swUQEAAFzn9Xp19NFH9/t1Bg8e7Oq60+STT76767673QfyyU/WfJOvpAjrz39rOLlvTcwysSZTs0ysydQsE2tyMsvEmhI9K5r/1vD2p0MAAAAAAAAAAAD9wUQFAAAAAAAAAABwDRMVAAAg6WVkZOhnP/uZMjIyyCef/BTLT4Q+kE9+KuebzMlta2KWiTWZmmViTaZmmViTk1km1mRSlicYDAZj/qpx0thi6YR7XpckffSLC3REOl+xASA1cPwDAAAAAACAqbiiAgAAAAAAAAAAuIaJCgAAAAAAAAAA4BomKgAAAAAAAAAAgGuYqAAAAAAAAAAAAK5hogIAAAAAAAAAALiGiQoAAAAAAAAAAOAaJioAAAAAAAAAAIBrmKgAAAAAAAAAAACuYaICAAAAAAAAAAC4hokKAAAAAAAAAADgGiYqAAAAAAAAAACAa5ioAAAAAAAAAAAArmGiAgAAAAAAAAAAuIaJCgAAAAAAAAAA4BomKgAAAAAAAAAAgGuYqAAAAAAAAAAAAK5hogIAAAAAAAAAALiGiQoAAAAAAAAAAOAaJioAAAAAAAAAAIBrmKgAAAAAAAAAAACuYaICAAAAAAAAAAC4hokKAAAAAAAAAADgGiYqAAAAAAAAAACAa5ioAAAAAAAAAAAArmGiAgAAAAAAAAAAuIaJCgAAAAAAAAAA4BomKgAAAAAAAAAAgGuYqAAAAAAAAAAAAK5hogIAAAAAAAAAALiGiQoAAAAAAAAAAOCa5J+oWLNGuugiaehQaeBAaeJE6b773O4VAMRN+g3XSx5P17e1a93uIgAAAAAAABA1v9sd6Je//EW65hrpiiukP/5RGjRI2rFD2rvX7Z4BQNy0/vtP5P/BDzo+MH++lJEhzZjhfKcAAAAAAACAPkraiQpPZaX03e9K3/ue9NvffvHA3LnudQoAHBA87jgp/UuH71WrpOpq6T/+Q/L53OkYAAAAAAAA0AdJu/ST76n/kxoapLvucrsrAOC+J58MLft0/fVu9wQAAAAAAADoleSdqFi9WsrJkbZskU46SfL7pREjpJtukmpr3e4eADjn0CHp+eelc8+VjjnG7d4AAAAAAAAAvZK0ExWevXulxkbp8sulb31LevNN6c47Q99VcdFFUjDodhcBwBl//at0+LD0ne+43RMAAAAAAACg15L2Oypk21JTk/Szn0l33x26b84cKT1duuUW6a23pPPOc7OHAOCMJ5+Uhg2TLr3U7Z4AAAAAAAAAvZa0V1QEh+WEGhdc0P6BCy8M/btxo7MdAgA3bN4srV8vLVokZWS43RsAAAAAAACg15J2osKedmLnD4SXfPImbWkAEL0nnwz9e8MN7vYDAAAAAAAA6KOk/TQ/cOnCUOPVV9s/kJcX+vf0053tEAA4rblZeuYZaeZMado0t3sDAAAAAAAA9EnSfkeFff750vz50i9+Efq+itNPDy1/8vOfS5dcIs2a5XYXASC+li+XDhzgagoAAAAAAAAktaSaqCjfVx9pt1i2jnj22dDExBNPKPjzn6tl+HAdvOoqVX33uwp28R0VWVlZmjhxolNdBoAOysvLVVdX1+Pz2h6vKg8ejtxf19SqI9L9oWWfMjOlK6+MW18BAAAAAACAePMEg+EvdUhcm/Yc1C9WfKRNe2oi9w3LTNMNZx+nm845Vtu3b9ekSZOifr1t27YxWQHAFeXl5b06Xq0qfl9Pf9isgi37FT5YH5Hm1RUzxuruCydrQJovPh0FAAAAAAAAHJLwV1Rs2nNQV/9+nQ63Btrd/3lDqx56bYv21zVp/pjmXr1mNGcyA0A8hI8/zzzzjKZMmdLl88rKyrRo0SL9cFmR6rJy2z3W2GprWdEufVzdoKeunSGf1xPXPgMAAAAAAADxlPATFfet+KjDJEVbT72zSyedN9jBHgFA/02ZMkWnnHJKj8+rbmhWRlbnjxVu+0yvlX6qi78yKsa9AwAAAAAAAJyT0BMVWz+t08Y2yz115R+b98mTlhH16zZZthpbrH70DAD6psmy5UnL6PE4FH6ePN1fLfHX4j1MVAAAAAAAACCpJfR3VLxW+qluemZDu/satqxRbfHfNXjmZcqcPMulngGA8zo7/o0ZMlDv3D3P5Z4BAAAAAAAAfed1uwPdGZTR8YKPmtXPqKWqXDWrn3GhRwDgns6Of50dJwEAAAAAAIBkktCfcM08JkfDB6Wrur4lcl+w5XC7fyXpX7/i0x3XLoj6ddesWaOTTjopVt0EgKiVlJRo1qxZPR6Hws876ttLlHHUcZI6P/5deOLIuPYXAAAAAAAAiLeEnqhI93v1nVnH6qHXtnT5nAkjBmnWxEwFW5ujft0Bfq+OSE/o0gEYaoDfq2Brc4/HofDzPOp6db4hR6Tp6tPGxqObAAAAAAAAgGMSeuknSbrpnGN13VnjO31swohBevr6mfL7Er4MAOiT78+ZIL+34xdqD8tM11PXztCIrAEu9AoAAAAAAACInYS/rMDj8ehn86fq6plj9dfiCj30hE+NkoYcka7X/u1s+X1e7XO7kwDQS2VlZVE9fvGJo3TjghP01+I9+o9/Hv+yB6ZpzV3zNDDd50BPAQAAAAAAgPhK+ImKsIlHZeme+SfoiSPS1HhQGpDmjVxJkZWV1avX6u3zASBWwsefRYsWRf38kdkDdOv5k/Rf/zz+DUz3MUkBAAAAAAAAYyT0REUwGNSePXvU2toauc+yrMi/27dvlyQdffTR2rZtm+rq6np8zaysLE2cODE+HQaAHkycODHq49Xhw4fl8Xgix7rOjn9HHnmksrOz49dhAAAAAAAAIM48wWCw629qdVEwGNT8+fP1yiuv9PjcwYMH67333tOkSZMc6BkAxN9dd92lJUuW9Pi89PR0vfDCC7r44osd6BUAAAAAAAAQewn9LdSrV6+O6nm1tbV6//3349wbAHBOtMe/lpYWrVu3Ls69AQAAAAAAAOInYScqPB6PbrzxxsjPWVlZWrRokc4++2wNGzZM48ePjzw2ZswYXXTRRS70EgDi43vf+167n6+88srI8W/q1KmR+9PT03Xttdc63DsAAAAAAAAgdhJ2okKSfvrTn+rII4+UJNXV1enGG29UYWGhqqqqNGDAgMjzlixZoszMTLe6CQAxd80112jGjBmRn2fPnq3CwkJVV1e3W+bu9ttv17HHHutGFwEAAAAAAICYSNjvqAj7wx/+ELmy4qSTTtL69eu1dOlS3XLLLZKkM844Q++88448Ho+LvQSA2Hv33Xd15plnSpKGDRumbdu2adOmTTrvvPMkSSNHjtS2bduUlZXlZjcBAAAAAACAfkn4iYpAIKAZM2Zo06ZNkqRf/vKXWrJkiWpqaiRJxcXF7c46BgCTLFq0SH/+858lST/4wQ9UWFio0tJSSdKyZcu0ePFiN7sHAAAAAAAA9FvCT1RIoS+VnT17dof7r732Wj311FMu9AgAnPHJJ5/o+OOPV2NjY7v7Z8yYobVr18rrTegV/AAAAAAAAIAeJcUnXGeffbauuOKKdvcNGjRIv/zlL13qEQA44+ijj9a///u/d7j/v//7v5mkAAAAAAAAgBGS5lOuJUuWtPsC7Z/85CcaNWqUiz0CAGfcfvvtGjduXOTnb3/72zrjjDNc7BEAAAAAAAAQO0kzUTFu3DgtWbJEkjRz5szIl2kDgOkGDhyoxx9/XOnp6Ro7dqweeught7sEAAAAAAAAxExSfEdFW/v379eQIUOUnp7udlcAwFEHDhxQRkaGMjMz3e4KAAAAAAAAEDNJN1EBAAAAAAAAAADMkTRLPwEAAAAAAAAAAPMwUQEAAAAAAAAAAFzDRAUAAAAAAAAAAHANExUAAAAAAAAAAMA1TFQAAAAAAAAAAADXMFEBAAAAAAAAAABcw0QFAAAAAAAAAABwDRMVAAAAAAAAAADANUxUAAAAAAAAAAAA1zBRAQAAAAAAAAAAXMNEBQAAAAAAAAAAcA0TFQAAAAAAAAAAwDVMVAAAAAAAAAAAANcwUQEAAAAAAAAAAFzDRAUAAAAAAAAAAHANExUAAAAAAAAAAMA1TFQAAAAAAAAAAADXMFEBAAAAAAAAAABcw0QFAAAAAAAAAABwDRMVAAAAAAAAAADANUxUAAAAAAAAAAAA1zBRAQAAAAAAAAAAXMNEBQAAAAAAAAAAcA0TFQAAAAAAAAAAwDVMVAAAAAAAAAAAANcwUQEAAAAAAAAAAFzDRAUAAAAAAAAAAHANExUAAAAAAAAAAMA1TFQAAAAAAAAAAADXMFEBAAAAAAAAAABcw0QFAAAAAAAAAABwDRMVAAAAAAAAAADANUxUAAAAAAAAAAAA1zBRAQAAAAAAAAAAXMNEBQAAAAAAAAAAcA0TFQAAAAAAAAAAwDVMVAAAAAAAAAAAANcwUQEAAAAAAAAAAFzDRAUAAAAAAAAAAHANExUAAAAAAAAAAMA1TFQAAAAAAAAAAADXMFEBAAAAAAAAAABcw0QFAAAAAAAAAABwDRMVAAAAAAAAAADANUxUAAAAAAAAAAAA1zBRAQAAAAAAAAAAXMNEBQAAAAAAAAAAcA0TFQAAAAAAAAAAwDVMVAAAAAAAAAAAANcwUQEAAAAAAAAAAFzDRAUAAAAAAAAAAHANExUAAAAAAAAAAMA1TFQAAAAAAAAAAADXMFEBAAAAAAAAAABcw0QFAAAAAAAAAABwDRMVAAAAAAAAAADANUxUAAAAAAAAAAAA1zBRAQAAAAAAAAAAXMNEBQAAAAAAAAAAcA0TFQAAAAAAAAAAwDVMVAAAAAAAAAAAANcwUQEAAAAAAAAAAFzDRAUAAAAAAAAAAHANExUAAAAAAAAAAMA1TFQAAAAAAAAAAADXMFEBAAAAAAAAAABcw0QFAAAAAAAAAABwzf8HFyIosdlknREAAAAASUVORK5CYII=" + "image/png": "iVBORw0KGgoAAAANSUhEUgAABisAAAL4CAYAAAAK3cQrAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8fJSN1AAAACXBIWXMAAA9hAAAPYQGoP6dpAAEAAElEQVR4nOzdeXwU5f0H8M/Obi4ChATkiuGQUwkgIiCHgggiIiLUA0st3lXBaj1b/SlWpWA9qlXBC7Fqvc+KQa5IYggQjiBEIQQIEEMghpwk2WN25vdHutMs2Rx7zew++3m/Xnn5ZLO7n+e7M8yM88w8a1JVVQUREREREREREREREZFBJKM7QEREREREREREREREkY2DFUREREREREREREREZCgOVhARERERERERERERkaE4WEFERERERERERERERIbiYAURERERERERERERERmKgxVERERERERERERERGQoDlYQEREREREREREREZGhOFhBRERERERERERERESG4mAFEREREREREREREREZioMVRERERERERERERERkKA5WEBERERERERERERGRoThYQUREREREREREREREhuJgBRERERERERERERERGYqDFUREREREREREREREZCgOVhARERERERERERERkaE4WEFERERERERERERERIbiYAURERERERERERERERmKgxVERERERERERERERGQoDlYQEREREREREREREZGhOFhBRERERERERERERESG4mAFEREREREREREREREZioMVRERERERERERERERkKA5WEBERERERERERERGRoThYQUREREREREREREREhuJgBRERERERERERERERGYqDFUREREREREREREREZCgOVhARERERERERERERkaE4WEFERERERERERERERIbiYAURERERERERERERERmKgxVERERERERERERERGQoDlYQEREREREREREREZGhOFhBRERERERERERERESG4mAFEREREREREREREREZioMVRERERERERERERERkKA5WEBERERERERERERGRoThYQUREREREREREREREhuJgBRERERERERERERERGYqDFUREREREREREREREZCgOVhARERERERERERERkaE4WEFERERERERERERERIbiYAURERERERERERERERmKgxVERERERERERERERGQoDlYQEREREREREREREZGhOFhBRERERERERERERESG4mAFEREREREREREREREZioMVRERERERERERERERkKA5WEBERERERERERERGRoThYQUREREREREREREREhuJgBRERERERERERERERGYqDFUREREREREREREREZCgOVhARERERERERERERkaE4WEFERERERERERERERIbiYAURERERERERERERERmKgxVERERERERERERERGQoDlYQEREREREREREREZGhOFhBRERERERERERERESG4mAFEREREREREREREREZioMVRERERERERERERERkKA5WEBERERERERERERGRoThYQUREREREREREREREhuJgBRERERERERERERERGYqDFUQU2Ww24OGHgZ49gbg4YMwYYN06o3tFREREREREREQUUThYQUSR7cYbgRdeAObNA156CTCbgcsvB7KyjO4ZERERERERERFRxDCpqqoa3QkiIkPk5DTcSfHss8ADDzQ8ZrUCqalA165Adrax/SMiIiIiIiIiIooQvLOCiCLXZ5813Elx++3/eyw2FrjlFmDzZqCoyLi+ERERERERERERRRAOVhBR5MrNBQYOBDp2dH989OiG/+7apXuXiIiIiIiIiIiIIhEHK4gocpWUAD16NH3c9dixY/r2h4iIiIiIiIiIKEJZjO4AEZFh6uuBmJimj8fG/u/vzbDZbCgvL/f4c/LkSY+P19TUYM6cOXjzzTeDVBAREREREREREVF44mAFEUWuuDjAZmv6uNX6v783kpubi1tvvRX5+fmora31KfKtt97C/fffj8GDB/v0eiIiIiIiIiIiIhFxGigiilw9ejRMBXU612M9e7o9vHz5cuzcudPrgQqLxQJJ+t/m9sSJE153lYiIiIiIiIiISGQcrCCiyHXuucD+/UB1tfvjW7f+7+/NGDFiBGbMmIGuXbtqj1100UX46KOPsH79euzcuROHDx9GdXU17HY7nnzySe155eXlASyCiIiIiIiIiIgo/HGwgogi19VXA04n8MYb/3vMZgNWrgTGjAFSUtyenpSUpLWfe+45rFq1Co8++qj22N///ndcd911uOSSSzBixAj07t0bHTp0gMlkwhlnnKE9j4MVRERERERERERE7jhYQUSRa8wY4JprgL/8BXjooYZBi8mTgcOHgb//vcnTGw9WlJeX4+2338a9996LefPmYezYsbj00kuRk5PjMaqwsNDttUREFF7eeecdmEwmbN++3eiutMmNN96I9u3bG90Nn506dQpdu3bFv//9b6O7ElRz587Ftddea3Q3iIgoBPBYQ1881iAKTRysIKKIcaC0Bv/31R6MXbIB5z21Dte/sQVpDy6Fes89wHvvAX/8I+BwAKtWARdd1OT1jQcrvvnmG9x66634wx/+gHfffRdr1qxBamoqpk6d2mTA4ttvv8Vzzz2n/c7BCiKi0DF9+nQkJiZ6/D6hqqoq9OjRA2PGjIGiKAb0LnK99NJL6NChA+bOnas9VlJSgj//+c+4+OKLtTsXN27c6PH1kyZNgslkavJz2WWX+dynnJwc3HXXXRg5ciSioqJgMpmafa6nbJPJhKVLl7o97+GHH8bnn3+OH3/80ed+ERFRaOOxRmjy91hDURS89tprOPfcc9G+fXt069YN06dPR3Z2ts998uZYo6qqCg899BAGDBiAuLg49O7dG7fccguOHj3q9jwea1C44WAFEUWE7/KO4/KXsvD+lqMoqbKivNaOzYdO4q7P9+LO4ddD/qUYsFqBnBxg2jSP79G5c2et/e677+IPf/gDXn31VUiShA4dOuC7775rMmDx7bffYs6cObjwwgu113KwgogodCxbtgx2ux1/+tOfmvztkUceQVlZGd544w1IEg+b9eJwOPDSSy/h1ltvhdls1h7Pz8/HM888g+LiYgwdOrTV9znzzDPx3nvvuf089NBDPvcrLS0Nb731FkwmE84666xWnz916tQm+TNnznR7zogRI3D++efj+eef97lfREQU2nisEXoCcazx4IMP4s4778TQoUPxwgsv4P7778f+/fsxceLEZmdcaE1bjzUURcHUqVOxbNkyzJ49Gy+//DKuv/56fPrppxg3bhxqamq05/JYg8INt4REJLxjlfX440e5sDs9X6ny3U/HsXzjQY9/q6+vR3FxMfbs2eN2hcKwYcO0gQqX0wcsFi1ahDlz5uDyyy/Hm2++qT3v5MmTAaqMiIj81bdvXyxatAgffvgh1q5dqz2+bds2vPbaa7jvvvswfPhwA3sYeVatWoVff/21yZQFI0eOxMmTJ7F//37cd999rb5PQkICfve737n9TJ482ed+3XnnnaiqqsL27dsxderUVp8/cODAJvlDhgxp8rxrr70WX3zxBU6dOuVz34iIKHTxWCP0+HusIcsyli9fjquvvhrvvfcebr/9djz00ENYv349ZFn2eWqpth5rbNmyBdu2bcMzzzyDv//977j11luxdOlSvPTSSyguLsb69evdns9jDQonHKwgIuH9e+sR2OX/DVTUHdmN8vQVqNn5Laq2fIqK79/GUw//EbNnz8bEiRMxdOhQJCcnIy4uDu3atcOZZ56JYcOG4d5779XeIy4uzuOVL64Bi+rqajz55JPo0qULPv74Y3Tv3l17Du+sICIKLffddx+GDRuGu+66C1arFU6nE3fccQd69+6NRYsWuT23rq4Of/jDH9C5c2d07NgRv//971FRUeH2HJPJhCeeeKJJTp8+fXDjjTdqvzscDvz1r3/FgAEDEBsbi86dO2PChAlYt25di/315nXFxcW46qqr0L59e5xxxhl44IEH4HQ63Z7z3HPPYdy4cejcuTPi4uIwcuRIfPbZZ03ey2QyYeHChfj3v/+NQYMGITY2FiNHjkRmZqbH3JtvvhndunVDTEwMhgwZgrfffrvFuly++uor9OnTB/369XN7vEOHDm5TMraFLMsB+x/zbt26IS4uzqvX1NfXw2q1tvicqVOnora2ttXlTkRE4YvHGmIdazgcDtTX16Nbt25uj3ft2hWSJHl9vODS1mON6upq7fmN9ejRAwCavAePNSicWIzuABFRsGUVlMFRXoy6/E2o+SkDzpNHPD7vqx1tf8+WBhwaH0hVVFRg165dGDVqFKKjo2G32zlYQUQUYiwWC9544w2MGzcOTz31FLp27YqdO3fiu+++Q7t27dyeu3DhQnTq1AlPPPEE8vPzsXz5chw5cgQbN25scV5hT5544gksWbIEt956K0aPHo3q6mps374dO3fubPFqura+zul0Ytq0aRgzZgyee+45rF+/Hs8//zz69euHO++8U3veSy+9hCuvvBLz5s2D3W7HRx99hGuuuQarVq3CjBkz3LIzMjLw8ccf449//CNiYmKwbNkyXHbZZcjJyUFqaioA4MSJE7jgggu0Ew5nnHEGVq9ejVtuuQXV1dVug/+eZGdn47zzzvPqs/Rk//79iI+Ph91uR7du3XDbbbfh8ccfR1RUlN/v3RbvvPMOli1bBlVVcfbZZ+P//u//8Nvf/rbJ88455xzExcVh06ZNmD17ti59IyIiffFYQ6xjjbi4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Ju+XlJSEm266CTfddBNOnTqFiy66CE888QRuvfXWFvvh6+tO9/nnnyM2NhZr1qxxu+Nv5cqVHp/vaTqI/fv3o127dtqVlR06dIDT6Wzy5Y5tYbFY0K9fPxQWFnr92ta4pqQ4/QpQvTSXL8syioqKmpzwICKiyMRjjdA/1jhx4gSApoNDAOBwOCDLss/v3dZ8VVWb5LvOOZyez2MNCiccrCCikObPAMXppg3pjmlDuqOqzgGb04nO8TEwS01vg4yLi2t14AIA/vWvf7m97uabb25zXbz9kogoPL3xxhu46aabtLmkly9fDlmW3W6179evHzIzM5u87vT/oTx58iQ6d+6s/d6+fXv0798fRUVFLfbB19d5YjabYTKZ3Pp2+PBhfPXVVx6fv3nzZuzcuRPnnXceAKCoqAhff/01LrvsMu3qyt/85jf44IMPkJeXh9TUVLfX//rrr60OFowdOxYbN270uhaX6upqxMTEuJ0QUVUVTz/9NABg2rRpPr93W3iqsaamBi+++CK6dOniNg83APz888+wWq0YN25cUPtFREThgccaoX+sMXDgQADARx99hMsuu0x7fOfOncjPz8ftt9/u83u3NV9VVXzyySe48cYbtcc//PBDAMCIESPcns9jDQonHKwgopATyAEKTxLaRQGIavV5QNOBi9mzZ2PNmjVe5blER0ejc+fOmDNnDs4++2yf3oOIiIxlt9txySWX4Nprr0V+fj6WLVuGCRMmuF2pduutt+KOO+7Ab37zG0ydOhU//vgj1qxZ0+TW+3POOQeTJk3CyJEjkZSUhO3bt+Ozzz7DwoULW+yDr6/zZMaMGXjhhRdw2WWX4be//S1KS0vx6quvon///ti9e3eT56empmLatGn44x//iJiYGCxbtgwA8Ne//lV7ztKlS/H9999jzJgxuO2223DOOeegvLwcO3fuxPr161udhmnWrFl47733sH//fu1kgItrwOGnn34CALz33nvIysoCAPzf//0fgIYTBddffz2uv/569O/fH/X19fjyyy+xadMm3H777drJDxeTyYSJEye2etLiyJEjeO+99wAA27dvd+tP7969ccMNNwAAXn31VXz11VeYOXMmevXqhZKSErz99ts4evQo3nvvvSbTRa5btw7t2rXD1KlTW8wnIqLIwGON0D/WGDlyJKZOnYp//etfqK6uxqWXXoqSkhK8/PLLiIuLw7333uv2noE+1rjxxhvx3HPP4Q9/+ANyc3MxZMgQ7Ny5E2+99RaGDBmC2bNnu70vjzUorKhERCFg//796uLFi9Vzzz1XBeDxZ/To0eqzzz6rFhYWGtbPvLw8dcSIEWqPHj3UXr16qWeccYZqNps99rdjx47q7Nmz1ffee0+trKxUFUUxrN9ERNQ2EydOVIcMGdLk8ZUrV6oA1IyMDPX2229XExMT1fbt26vz5s1TT5486fZcp9OpPvzww2qXLl3Udu3aqdOmTVMPHDig9u7dW50/f772vKefflodPXq02qlTJzUuLk4dPHiwunjxYtVut7fYx7a8bv78+Wp8fHyT1y5atEg9/X8BVqxYoQ4YMECNiYlRBw8erK5cudLj8wCoCxYsUN9//33t+SNGjFC///77JjknTpxQFyxYoKakpKhRUVFq9+7d1UsuuUR94403WqxNVVXVZrOpXbp0UZ966qkmf2vuGKFxXw8dOqRec801ap8+fdTY2Fi1Xbt26siRI9XXXnutyb64pqZGBaDOnTu31X59//33zWZPnDhRe97atWvVqVOnqt27d1ejoqLUTp06qZdeeqm6YcMGj+87ZswY9Xe/+12r+UREJAYea4T/sYaqqmpdXZ365JNPquecc44aFxenJiQkqFdccYWam5vr9rxgHGuoqqr+8ssv6s0336z27dtXjY6OVnv06KHedttt6q+//trkfXmsQeHEpKo+fJsNEVEABPsOCr20NFWUS1JSEmbPno1rrrkGkydP1m7pJSIiChcmkwkLFizAK6+8EvSsp556CitXrkRBQUGbvrzTV2lpabjiiivw448/YujQoUHLac6uXbtw3nnnYefOnTj33HN1zyciIgolPNYIPB5rULjhYAUR6co1QPHJJ5/gxx9/9PiccBigaA4HLoiISFR6nkA4deoUzjrrLPzjH//AvHnzgpbz4IMPori4GB988EHQMloyd+5cKIqCTz75xJB8IiKiUMJjjcDjsQaFGw5WEFHQiT5A0RwOXBARkUj0PIFAREREkYfHGkTEL9gmoqCI1AGKxk7/cm5PAxfl5eVYsWIFVqxYwYELIiIiIiIiIiKKWLyzgogChgMUbcM7LoiIiIiIiIiIiNxxsIKI/MIBCv9w4IKIiIiIiIiIiIiDFUTkAw5QBAcHLoiIiIiIiIiIKFJxsIIoQqiqClVVIUmST6/nAIW+9Bq48He9ICIiIiIiIiIiCgQOVhAJzOFw4Msvv8Rrr72G7Oxs2Gw2dO/eHb/97W9x5513on///i2+ngMUoSHQAxf19fX44IMP8PrrryM3NxdOpxO9e/fG/Pnzcfvtt6Nnz57BLIeIiIiIiIiIiKgJDlYQCcZqteLTTz/F66+/jm3btsFut3t8ntlsxiuvvII77rjD7XEOUIQ2fwcuDh48iMsvvxz79+/3+P4mkwlnnnkm5s2bhz/84Q9cvkREREREREREpAsOVhAJZNeuXZg1axaOHj3q8e/t2rWDLMtuAxjvvfcexowZwwGKMOTtwMXQoUMxbtw4HDlyxO3v5eXlHt9fkiQ8+eSTeOSRR2AymYJWBxEREREREREREQcriASxf/9+XHDBBaioqHB73GQyofE/87POOguTJ0/GW2+9BaDhDgun0+nxPTlAET7aMnARGxsLq9UKADj77LMxZswYvPPOO9rfT19XXBYvXoxHHnkkaH0nIiIiIiIiIiLiYAWRIGbMmIG0tDQAQFxcHOrr6wEAmzZtwsmTJ3HPPfegsLAQAPCnP/0JO3bsQGZmZpP34QBF+Gtt4EKSJKxbtw6XXHIJgIZBikcffRQLFizAjBkzsHPnzibPP3jwINcHIiIiIiIiIiIKGsnoDhCR/w4dOoTVq1cDALp3764NVIwePRrjxo3DzJkzsWHDBsTExAAAVq5ciRtvvFF7fZcuXfDss8+isLAQW7duxQMPPMAT02EsLi4Oc+bMwYcffohff/0Vn3/+OaZOnar9fejQofj666+13xctWoSnnnoK3bt3x1133aU9Pn78eACAoih444039CuAiIiIiIiIiIgiDgcriASQlpamTd8zd+5c7fH+/ftr7b59++Lqq68GAFRWVmoDFwAwadIkDlAIyjVw8eCDD2qPXX755Vi1ahUAIDo6Gn/84x+1vw0YMEBrDxs2TPuuCtfziYiIiIiIiIiIgoGDFUQCaPw9FaNGjdLa27Ztc/sOguHDh2vtHTt2aO3OnTsHuYdktC5dumjt7du3a+tMSkoKEhMTtb/l5ORo7V69eqFr164A0OyXcBMREREREREREQUCByuIwlhBQQH+9re/4fXXX9ceW79+PSZOnKj9/bPPPtP+lpeXp7W//fZbrT1nzhwdektGGjZsGPr27QsAWLduHWJjYwEARUVFqKqqAgBUVVXh5Zdf1l4zduxYnDhxAgBw/Phx3HrrrVizZg0cDofOvSciIiIiIiIiItHxC7aJwkxBQQE+/fRTfPrpp9i1a1eTvyclJeHFF1/E73//ewBATEwMHn/8ccyYMQNjxoyBzWaD2WyG0+kE0DDtz759+yBJHLsU3bPPPouHHnoIQMN6YbPZAABPPfUURowYgUceeQS7d+8GAEyZMgXnn38+li5d2uR9kpKSMHv2bFxzzTWYPHkyoqKi9CuCiIiIiIiIiIiExMEKojDQ2gAFAHTs2BHV1dUAGq6Ij4+Px/r161t835iYGKSnp2PcuHGB7jKFIKvViqlTpyIrK6vF5yUlJeH666/HsmXLtGnE2rVrh7q6Oo/P5cAFERERERERERH5i4MVRCGqLQMUo0aNwrXXXourr74adXV1GDdunDalD9D8CWYA6NGjBz7++GNceOGFweg+haiamhrccMMN+Prrrz3+PSoqCoqiaHfeAMDjjz+Ohx9+GN999x0++eQTrFq1CrW1tU1ey4ELIiIiIiIiIiLyFQcriEKItwMUffr0cfvbtm3bMGvWLJSUlHh8bWxsLMaOHYtbbrkFV199NWJiYgJcAYWL3NxcvPbaa/jPf/6D48ePe3yOyWTCo48+iieffBImk0l7vK6ujgMXREREREREREQUUBysILGdOgU8+yywdSuQkwNUVAArVwI33mh0zzT+DlCcrra2Fh9++CHefvttHDx4EJIkYejQobj99tsxa9YsnjSmJn7++WcsW7YMq1evRlVVFRITEzFjxgzceeedGDRoUIuvjYiBi7ZsRxQFePdd4IsvgNxcoLwc6NsXmDsXeOAB4L9faE5ERERERERERJ5xsILEdvhwwwnDXr2As84CNm4MicGKQA9QEIUCYQcu2rIdOXUK6NABuOAC4IorgK5dgc2bgX/9C7joIiA9HWh0dwoREREREREREbnjYAWJzWZruAq6e3dg+3Zg1CjDBis4QEGRRKiBi7ZsR+z2hr+d/mX1Tz4JLFoErFsHTJmia7eJiIiIiIiIiMIJBysochgwWMEBCiLBBi683Y7s2QMMGwb885/A3XcHvXtEREREREREROHKYnQHiETTlgGK0aNH45prruEABUWEdu3aYc6cOZgzZ06zAxfl5eVYsWIFVqxYET4DF23h+vLyLl2M7QcRERER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Rl3+Jny4Mgvvlh7y+FoOUBCJy9uBC3NcB8QNGIt2g8YjtvdwmMz/20XW2p14+PPdWPun4OzciQJhwYIFyMvL0/2K7kGDBmHXrl2oqqrCZ599hvnz5yMjI0OXAYuioiLcc889WLdundfzsAZC4ysBhw0bhjFjxqB379745JNPAnZlUUsURcH555+Pv/3tbwCAESNGIC8vD6+99prugxUrVqzA9OnTdZ0j/5NPPsG///1vfPDBBxgyZAh27dqFe++9Fz179tSt/vfeew8333wzkpOTYTabcd555+H666/Hjh07dMknzxwOB6699lqoqorlrrsidXLxxRdj165dKCsrw5tvvolrr70WW7duRdeuXYOau2PHDrz00kvYuXOnbnc3UfjS45hBj+MDvY8D9NrvG7V/D/a+XM/9NvfPwaHH/lWP/aje+8y5c+dq7aFDh2LYsGHo168fNm7ciEsuuSRgOYqiAABmzZqFP/3pTwCAc889F9nZ2XjttdeCNljx9ttvY968eQHbDnMaKAp772/9322XqqqiZtd3OLbyjzj25h9QmfkuHKcNVHCKJ6LI05apopz1NTi1ey1KP12EX165ASe/exnOuirt7/tPnMK2w+VGdJ+a0aVLF5jNZpw4ccLt8RMnTqB79+4G9coYCxcuxKpVq/D999/jzDPP1DU7Ojoa/fv3x8iRI7FkyRIMHz4cL730ki7ZO3bsQGlpKc477zxYLBZYLBZkZGTgn//8JywWC5xOpy79cOnUqRMGDhyIAwcO6JLXo0ePJid9zj77bF2nogKAI0eOYP369bj11lt1zX3wwQfx5z//GXPnzsXQoUNxww034E9/+hOWLFmiWx/69euHjIwMnDp1CkVFRcjJyYHD4cBZZ52lWx8AaNs8bg//dyLlyJEjWLduna53VQBAfHw8+vfvjwsuuAArVqyAxWLBihUrgp77ww8/oLS0FL169dK2h0eOHMH999/P/9fxgcjHGHodM+hxfGD0cUCw9vtG7N/12Jfrud82Yv8s+r5Yr/2rHvtRo/eZZ511Frp06RLwbUeXLl1gsVh03X788MMPyM/PD+i2g4MVFNbssoIDpae0361Hd6N8zStNBihiegzkAAURAfA8cHHOhMtgivrfVQCKtQanflyD4+8/6Pban49V691dakF0dDRGjhyJDRs2aI8pioINGzbo/p0JRlFV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MrEmU7NMrCnZsypqDqn6QFO7OY1NTcpIT283J6t/ukYO7tvr/HBWsi4/t3PilZWs20V3PoP5th9JbeXKlbr22mtVW1sbuc+27cjPCRMmSJIGDx6sP/7xjzrxxBNd6acpnn76aS1dujTye3V1deRn+JRsj8ejc845RxdeeKErfTTFli1b9PDDD2v//v2SpIA+PUOopsXyHjp0qK6//vqUG4SIVjTLxbZtXX755SouLm51X/hneD/i8Xh04YUX6re//W18Ootec3suUPLJT+X8ROgD+eSTj3hwctmamGViTaZmmVhTMmeNHNy33S+Xg8GgLMuS3+93ZIA8WZdfIuTEIysVtgumgUJSu+iii7RmzRqVlZVFbi2F71u9erUuueQSl3pphvfee09XXHGFnnzyycjt4MGDkqSDBw9G7vvrX/+q//f//p927drlco+T249//GM9+OCDkeX6zLPPRB5rubzvvvtu3XnnnS72NPk9/fTT+vvf/97lfmTTpk268847tXXrVpd6is5YlqW8vDxZlkU++eSnYB/IJ598d/cBpnJy2ZqYZWJNpmaZWJOpWSbW5GSWiTWZlsU0UEhqs2bN0vLly6N67umnn6433ngjzj0y1969e3XkkUeqoaGhy+dmZWVp165d6tOnjwM9M9P111+vBx98MPK7Jy1DvoGHy9q3U5JH0qe77gceeEDXXXed0100xjvvvKPp06dH9Vyv16tDhw4pPT02cz3iU7GYBsrJI0nIJ5/8xOoD+eST3/N8poHqmJPr1sQsE2syNcvEmkzNMrEmJ7NMrCkZsrrzGcyZFUhqzz77bKs3xl/+8hctWLBAffv21dy5cyP3e71ePfPMM+29BKI0ZMgQ/eQnP4n8fsIJJ+iBBx7Qcccdp/vvv1/jxo2LPHb77bczUNFLt9xyS6sd+BNPPKHBsy5V+vAJ+kaLs4TGjBmja665xo0uGuPEE0/UCSecEPl91qxZkf3IZZddppycnMhjCxYsYKAigbl9RCn55KdyfiL0gXzyyUc8OLlsTcwysSZTs0ysydQsE2tyMsvEmkzKYrACSW306NG66KKLIr//6U9/0l//+lfV1tZq9+7dkfu/9a1vadiwYW500Sg/+clPdOSRR0qS1qxZo6OPPlrr16/XYYcdps2bN0uSJk2axJfnMTB06FDddtttkd8ff/wJ9T9mpoZffr+K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ALiKwQoAAAAAAAAAAOAqBisAAAAAAAAAAICrGKwAAAAAAAAAAACuYrACAAAAAAAAAAC4isEKAAAAAAAAAADgKgYrAAAAAAAAAACAqxisAAAAAAAAAAAArmKwAgAAAAAAAAAAuIrBCgAAAAAAAAAA4CoGKwAAAAAAAAAAgKsYrAAAAAAAAAAAAK5isAIAAAAAAAAAALiKwQoAAAAAAAAAAOAqBisAAAAAAAAAAICrGKwAAAAAAAAAAACuYrACAAAAAAAAAAC4isEKAAAAAAAAAADgKgYrAAAAAAAAAACAqxisAAAAAAAAAAAArmKwAgAAAAAAAAAAuIrBCgAAAAAAAAAA4CoGKwAAAAAAAAAAgKsYrAAAAAAAAAAAAK5isAIAAAAAAAAAALiKwQoAAAAAAAAAAOAqBisAAAAAAAAAAICrGKwAAAAAAAAAAACuYrACAAAAAAAAAAC4isEKAAAAAAAAAADgKgYrAAAAAAAAAACAqxisAAAAAAAAAAAArmKwAgAAAAAAAAAAuIrBCgAAAAAAAAAA4CoGKwAAAAAAAAAAgKsYrAAAAAAAAAAAAK5isAIAAAAAAAAAALjq/wOVOWAaybfw6AAAAABJRU5ErkJggg==", + "text/plain": [ + "
" + ] }, "metadata": {}, "output_type": "display_data" @@ -797,9 +1093,9 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.13" + "version": "3.12.7" } }, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 4 }