diff --git a/build-aux/setup-Darwin-20.sh b/build-aux/setup-Darwin-20.sh old mode 100644 new mode 100755 diff --git a/build-aux/setup-Linux-amzn-2.sh b/build-aux/setup-Linux-amzn-2.sh index a9c737451..b70b4b1ac 100755 --- a/build-aux/setup-Linux-amzn-2.sh +++ b/build-aux/setup-Linux-amzn-2.sh @@ -15,15 +15,23 @@ yum -q install ncurses-devel -y #yum -q install epel-release -y yum -q install libcurl-devel -y -# python3 support needed as of 4.2 -yum -q install python37 python3-devel python3-tkinter -y -[ -f /bin/python3 -a ! -f /usr/local/bin/python3 ] && ln -s /bin/python3 /usr/local/bin/python3 -[ -f /bin/python3-config -a ! -f /usr/local/bin/python3-config ] && echo '#!/bin/bash -/bin/python3-config $*' > /usr/local/bin/python3-config -chmod +x /usr/local/bin/python3-config -[ ! -f /usr/local/include/python3.7m ] && ln -sf /usr/include/python3.7m /usr/local/include/python3.7m -/usr/local/bin/python3 -m pip install --quiet --user matplotlib pandas mysql-connector Pillow -chmod -R a+w /usr/local/lib64/python3.7/site-packages +# python3.9.x support needed as of 4.2 +if [ ! -x /usr/local/bin/python3 -o $(/usr/local/bin/python3 --version | cut -f-2 -d.) != "Python 3.9" ]; then + yum install openssl-devel bzip2-devel libffi-devel zlib-devel -q -y + cd /usr/local/src + curl https://www.python.org/ftp/python/3.9.6/Python-3.9.6.tgz | tar xz + cd Python-3.9.6 + ./configure --prefix=/usr/local --enable-optimizations --with-system-ffi --with-computed-gotos --enable-loadable-sqlite-extensions CFLAGS="-fPIC" + make -j $(nproc) + make altinstall + ln -sf /usr/local/bin/python3.9 /usr/local/bin/python3 + ln -sf /usr/local/bin/python3.9-config /usr/local/bin/python3-config + ln -sf /usr/local/bin/pydoc3.9 /usr/local/bin/pydoc + ln -sf /usr/local/bin/idle3.9 /usr/local/bin/idle + ln -sf /usr/local/bin/pip3.9 /usr/local/bin/pip3 + curl -sSL https://bootstrap.pypa.io/get-pip.py | /usr/local/bin/python3 + /usr/local/bin/python3 pip -m install mysql-connector mysql-client matplotlib numpy pandas Pillow networkx +fi # mono if [ ! -f /usr/bin/mono ]; then @@ -45,8 +53,7 @@ mono /usr/local/natural_docs/NaturalDocs.exe \$*' > /usr/local/bin/natural_docs fi # converter support -/usr/local/bin/python3 -m pip install --quiet --user networkx # cd /tmp # curl http://download-ib01.fedoraproject.org/pub/epel/7/x86_64/Packages/m/mdbtools-0.7.1-3.el7.x86_64.rpm > mdbtools-0.7.1-3.el7.x86_64.rpm # rpm -Uvh mdbtools-0.7.1-3.el7.x86_64.rpm -# yum -q install mdbtools -y +yum -q install mdbtools -y diff --git a/build-aux/setup-Linux-ubuntu-20.sh b/build-aux/setup-Linux-ubuntu-20.sh new file mode 100755 index 000000000..bc22c8aeb --- /dev/null +++ b/build-aux/setup-Linux-ubuntu-20.sh @@ -0,0 +1,83 @@ +#!/bin/bash + +# Install needed system tools +# update first +apt-get -q update +apt-get -q install tzdata -y + +# install system build tools needed by gridlabd +apt-get -q install git -y +apt-get -q install unzip -y +apt-get -q install autoconf -y +apt-get -q install libtool -y +apt-get -q install g++ -y +apt-get -q install cmake -y +apt-get -q install flex -y +apt-get -q install bison -y +apt-get -q install libcurl4-gnutls-dev -y +apt-get -q install libncurses5-dev -y +apt-get -q install liblzma-dev -y +apt-get -q install libssl-dev -y +apt-get -q install libbz2-dev -y +apt-get -q install libffi-dev -y +apt-get -q install zlib1g-dev -y + +# install python 3.9 +if [ ! -x /usr/local/bin/python3 -o $(/usr/local/bin/python3 --version | cut -f-2 -d.) != "Python 3.9" ]; then + cd /usr/local/src + curl https://www.python.org/ftp/python/3.9.6/Python-3.9.6.tgz | tar xz + cd Python-3.9.6 + ./configure --prefix=/usr/local --enable-optimizations --with-system-ffi --with-computed-gotos --enable-loadable-sqlite-extensions CFLAGS="-fPIC" + make -j $(nproc) + make altinstall + ln -sf /usr/local/bin/python3.9 /usr/local/bin/python3 + ln -sf /usr/local/bin/python3.9-config /usr/local/bin/python3-config + ln -sf /usr/local/bin/pydoc3.9 /usr/local/bin/pydoc + ln -sf /usr/local/bin/idle3.9 /usr/local/bin/idle + curl -sSL https://bootstrap.pypa.io/get-pip.py | /usr/local/bin/python3 +fi + +# install python libraries by validation +/usr/local/bin/python3 pip -m install --upgrade pip +/usr/local/bin/python3 pip -m install mysql-connector mysql-client matplotlib numpy pandas Pillow + +# doxggen +apt-get -q install gawk -y +if [ ! -x /usr/bin/doxygen ]; then + if [ ! -d /usr/local/src/doxygen ]; then + git clone https://github.com/doxygen/doxygen.git /usr/local/src/doxygen + fi + if [ ! -d /usr/local/src/doxygen/build ]; then + mkdir /usr/local/src/doxygen/build + fi + cd /usr/local/src/doxygen/build + cmake -G "Unix Makefiles" .. + make + make install +fi + +# mono +apt-get -q install curl -y +if [ ! -f /usr/bin/mono ]; then + cd /tmp + apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF + echo "deb http://download.mono-project.com/repo/ubuntu wheezy/snapshots/4.8.0 main" | tee /etc/apt/sources.list.d/mono-official.list + apt-get -q update -y + apt-get -q install mono-devel -y +fi + +# natural_docs +if [ ! -x /usr/local/bin/natural_docs ]; then + cd /usr/local + curl https://www.naturaldocs.org/download/natural_docs/2.0.2/Natural_Docs_2.0.2.zip > natural_docs.zip + unzip -qq natural_docs + rm -f natural_docs.zip + mv Natural\ Docs natural_docs + echo '#!/bin/bash +mono /usr/local/natural_docs/NaturalDocs.exe \$*' > /usr/local/bin/natural_docs + chmod a+x /usr/local/bin/natural_docs +fi + +# converter support +/usr/local/bin/python3 pip -m install networkx +apt-get -q install mdbtools -y diff --git a/module/powerflow/Makefile.mk b/module/powerflow/Makefile.mk index c2d2d0899..dca35eb48 100644 --- a/module/powerflow/Makefile.mk +++ b/module/powerflow/Makefile.mk @@ -1,6 +1,6 @@ pkglib_LTLIBRARIES += module/powerflow/powerflow.la -module_powerflow_powerflow_la_CPPFLAGS = -DSOLVER_PY +module_powerflow_powerflow_la_CPPFLAGS = -DSOLVER_PY -I$(shell python3 -c 'import numpy; print(numpy.get_include())') module_powerflow_powerflow_la_CPPFLAGS += -I$(top_srcdir)/third_party/superLU_MT module_powerflow_powerflow_la_CPPFLAGS += -I$(top_srcdir)/module/powerflow module_powerflow_powerflow_la_CPPFLAGS += $(AM_CPPFLAGS) diff --git a/module/powerflow/autotest/solver_mle.conf b/module/powerflow/autotest/solver_mle.conf new file mode 100644 index 000000000..0a5f0d83e --- /dev/null +++ b/module/powerflow/autotest/solver_mle.conf @@ -0,0 +1,23 @@ +# comments are helpful +solver enable + +logfile ./solver_mle.log +loglevel 9 + +import_path .. + +import solver_py + +busdata name,type,phases,volt_base,mva_base,VAr,VAi,VBr,VBi,VCr,VCi,SAr,SAi,SBr,SBi,SCr,SCi,YAr,YAi,YBr,YBi,YCr,YCi,IAr,IAi,IBr,IBi,ICr,ICi +branchdata phases,from,to,lnk_type,v_ratio,YfromAr,YfromAi,YfromBr,YfromBi,YfromCr,YfromCi,YtoAr,YtoAi,YtoBr,YtoBi,YtoCr,YtoCi,YSfromAr,YSfromAi,YSfromBr,YSfromBi,YSfromCr,YSfromCi,YStoAr,YStoAi,YStoBr,YStoBi,YStoCr,YStoCi + +#learndata powerflow_values +#learndata powerflow_values.deltaI_NR,powerflow_values.BA_diag,powerflow_values.Y_offdiag_PQ,powerflow_values.Y_diag_fixed,powerflow_values.Y_diag_update,powerflow_values.Y_Amatrix +learndata powerflow_values.deltaI_NR,powerflow_values.Y_offdiag_PQ,powerflow_values.Y_diag_fixed,powerflow_values.Y_diag_update + +profiler solver_py.csv + +option dump=dataframe + +mle_data_only true + diff --git a/module/powerflow/autotest/solver_py.py b/module/powerflow/autotest/solver_py.py index b40fef563..e1da21c57 100644 --- a/module/powerflow/autotest/solver_py.py +++ b/module/powerflow/autotest/solver_py.py @@ -3,6 +3,9 @@ import pprint as pp import datetime as dt +pd.options.display.max_rows = None +pd.options.display.max_columns = None + def solve(gridlabd,**kwargs): """solve(gridlabd,kwargs) @@ -32,12 +35,12 @@ def solve(gridlabd,**kwargs): if kwargs['options']['dump'] == 'dataframe': branch = pd.DataFrame(data=kwargs['branchdata'],index=kwargs['branchtags']) bus = pd.DataFrame(data=kwargs['busdata'],index=kwargs['bustags']) - print(branch) - print(bus) + print(branch,file=output_stream) + print(bus,file=output_stream) elif kwargs['options']['dump'] == 'pretty': pp.PrettyPrinter(indent=4,stream=output_stream).pprint(kwargs) elif kwargs['options']['dump'] == 'print': - print(kwargs) + print(kwargs,file=output_stream) return -1 def learn(gridlabd,**kwargs): @@ -77,10 +80,10 @@ def learn(gridlabd,**kwargs): if kwargs['options']['dump'] == 'dataframe': branch = pd.DataFrame(data=kwargs['branchdata'],index=kwargs['branchtags']) bus = pd.DataFrame(data=kwargs['busdata'],index=kwargs['bustags']) - print(branch) - print(bus) + print(branch,file=output_stream) + print(bus,file=output_stream) elif kwargs['options']['dump'] == 'pretty': pp.PrettyPrinter(indent=4,stream=output_stream).pprint(kwargs) elif kwargs['options']['dump'] == 'print': - print(kwargs) + print(kwargs,file=output_stream) return None diff --git a/module/powerflow/autotest/test_IEEE_13_MLE.glm b/module/powerflow/autotest/test_IEEE_13_MLE.glm new file mode 100644 index 000000000..be13e2708 --- /dev/null +++ b/module/powerflow/autotest/test_IEEE_13_MLE.glm @@ -0,0 +1,714 @@ +// $Id: IEEE13-Feb27.glm +// Copyright (C) 2011 Battelle Memorial Institute + +#set iteration_limit=100 +#define MAX_VERR=6 + +clock { + timezone EST+5EDT; + starttime '2000-01-01 00:00:00 EST'; + stoptime '2000-01-02 00:00:00 EST'; +} + +module powerflow { + solver_method NR; + line_capacitance true; +#ifexist "../solver_py.conf" +#define DIR=.. +#endif + solver_py_config "${DIR:-.}/solver_mle.conf"; + } +module assert; + +module tape; + +// Phase Conductor for 601: 556,500 26/7 ACSR +object overhead_line_conductor { + name olc6010; + geometric_mean_radius 0.031300; + diameter 0.927 in; + resistance 0.185900; +} + +// Phase Conductor for 602: 4/0 6/1 ACSR +object overhead_line_conductor { + name olc6020; + geometric_mean_radius 0.00814; + diameter 0.56 in; + resistance 0.592000; +} + +// Phase Conductor for 603, 604, 605: 1/0 ACSR +object overhead_line_conductor { + name olc6030; + geometric_mean_radius 0.004460; + diameter 0.4 in; + resistance 1.120000; +} + + +// Phase Conductor for 606: 250,000 AA,CN +object underground_line_conductor { + name ulc6060; + outer_diameter 1.290000; + conductor_gmr 0.017100; + conductor_diameter 0.567000; + conductor_resistance 0.410000; + neutral_gmr 0.0020800; + neutral_resistance 14.87200; + neutral_diameter 0.0640837; + neutral_strands 13.000000; + insulation_relative_permitivitty 2.3; + shield_gmr 0.000000; + shield_resistance 0.000000; +} + +// Phase Conductor for 607: 1/0 AA,TS N: 1/0 Cu +object underground_line_conductor { + name ulc6070; + outer_diameter 1.060000; + conductor_gmr 0.011100; + conductor_diameter 0.368000; + conductor_resistance 0.970000; + neutral_gmr 0.011100; + neutral_resistance 0.970000; // Unsure whether this is correct + neutral_diameter 0.0640837; + neutral_strands 6.000000; + insulation_relative_permitivitty 2.3; + shield_gmr 0.000000; + shield_resistance 0.000000; +} + +// Overhead line configurations +object line_spacing { + name ls500601; + distance_AB 2.5; + distance_AC 4.5; + distance_BC 7.0; + distance_BN 5.656854; + distance_AN 4.272002; + distance_CN 5.0; + distance_AE 28.0; + distance_BE 28.0; + distance_CE 28.0; + distance_NE 24.0; +} + +// Overhead line configurations +object line_spacing { + name ls500602; + distance_AC 2.5; + distance_AB 4.5; + distance_BC 7.0; + distance_CN 5.656854; + distance_AN 4.272002; + distance_BN 5.0; + distance_AE 28.0; + distance_BE 28.0; + distance_CE 28.0; + distance_NE 24.0; +} + +object line_spacing { + name ls505603; + distance_BC 7.0; + distance_CN 5.656854; + distance_BN 5.0; + distance_BE 28.0; + distance_CE 28.0; + distance_NE 24.0; +} + +object line_spacing { + name ls505604; + distance_AC 7.0; + distance_AN 5.656854; + distance_CN 5.0; + distance_AE 28.0; + distance_CE 28.0; + distance_NE 24.0; +} + +object line_spacing { + name ls510; + distance_CN 5.0; + distance_CE 28.0; + distance_NE 24.0; +} + +object line_configuration { + name lc601; + conductor_A olc6010; + conductor_B olc6010; + conductor_C olc6010; + conductor_N olc6020; + spacing ls500601; +} + +object line_configuration { + name lc602; + conductor_A olc6020; + conductor_B olc6020; + conductor_C olc6020; + conductor_N olc6020; + spacing ls500602; +} + +object line_configuration { + name lc603; + conductor_B olc6030; + conductor_C olc6030; + conductor_N olc6030; + spacing ls505603; +} + +object line_configuration { + name lc604; + conductor_A olc6030; + conductor_C olc6030; + conductor_N olc6030; + spacing ls505604; +} + +object line_configuration { + name lc605; + conductor_C olc6030; + conductor_N olc6030; + spacing ls510; +} + +//Underground line configuration +object line_spacing { + name ls515; + distance_AB 0.500000; + distance_BC 0.500000; + distance_AC 1.000000; +} + +object line_spacing { + name ls520; + distance_AN 0.083333; +} + +object line_configuration { + name lc606; + conductor_A ulc6060; + conductor_B ulc6060; + conductor_C ulc6060; + spacing ls515; +} + +object line_configuration { + name lc607; + conductor_A ulc6070; + conductor_N ulc6070; + spacing ls520; +} + +// Define line objects +object overhead_line { + phases "BCN"; + name line_632-645; + from n632; + to l645; + length 500; + configuration lc603; +} + +object overhead_line { + phases "BCN"; + name line_645-646; + from l645; + to l646; + length 300; + configuration lc603; +} + +object overhead_line { //630632 { + phases "ABCN"; + name line_630-632; + from n630; + to n632; + length 2000; + configuration lc601; +} + +//Split line for distributed load +object overhead_line { //6326321 { + phases "ABCN"; + name line_632-6321; + from n632; + to l6321; + length 500; + configuration lc601; +} + +object overhead_line { //6321671 { + phases "ABCN"; + name line_6321-671; + from l6321; + to l671; + length 1500; + configuration lc601; +} +//End split line + +object overhead_line { //671680 { + phases "ABCN"; + name line_671-680; + from l671; + to n680; + length 1000; + configuration lc601; +} + +object overhead_line { //671684 { + phases "ACN"; + name line_671-684; + from l671; + to n684; + length 300; + configuration lc604; +} + + object overhead_line { //684611 { + phases "CN"; + name line_684-611; + from n684; + to l611; + length 300; + configuration lc605; +} + +object underground_line { //684652 { + phases "AN"; + name line_684-652; + from n684; + to l652; + length 800; + configuration lc607; +} + +object underground_line { //692675 { + phases "ABC"; + name line_692-675; + from l692; + to l675; + length 500; + configuration lc606; +} + +object overhead_line { //632633 { + phases "ABCN"; + name line_632-633; + from n632; + to n633; + length 500; + configuration lc602; +} + +// Create node objects +object node { //633 { + name n633; + phases "ABCN"; + voltage_A 2401.7771; + voltage_B -1200.8886-2080.000j; + voltage_C -1200.8886+2080.000j; + nominal_voltage 2401.7771; + object complex_assert { + target voltage_A; + value 2445.01-2.56d; + within ${MAX_VERR:-5}; + }; object complex_assert { + target voltage_B; + value 2498.09-121.77d; + within ${MAX_VERR:-5}; + }; object complex_assert { + target voltage_C; + value 2437.32+117.82d; + within ${MAX_VERR:-5}; + }; +} + +object node { //630 { + name n630; + phases "ABCN"; + voltage_A 2401.7771+0j; + voltage_B -1200.8886-2080.000j; + voltage_C -1200.8886+2080.000j; + nominal_voltage 2401.7771; +} + +object node { //632 { + name n632; + phases "ABCN"; + voltage_A 2401.7771; + voltage_B -1200.8886-2080.000j; + voltage_C -1200.8886+2080.000j; + nominal_voltage 2401.7771; + object complex_assert { + target voltage_A; + value 2452.21-2.49d; + within ${MAX_VERR:-5}; + }; object complex_assert { + target voltage_B; + value 2502.56-121.72d; + within ${MAX_VERR:-5}; + }; object complex_assert { + target voltage_C; + value 2443.56+117.83d; + within ${MAX_VERR:-5}; + }; +} + +object node { //650 { + name n650; + phases "ABCN"; + bustype SWING; + voltage_A 2401.7771; + voltage_B -1200.8886-2080.000j; + voltage_C -1200.8886+2080.000j; + nominal_voltage 2401.7771; + object complex_assert { + target voltage_A; + value 2401.7771; + within ${MAX_VERR:-5}; + }; object complex_assert { + target voltage_B; + value 2401.7771-120.0d; + within ${MAX_VERR:-5}; + }; object complex_assert { + target voltage_C; + value 2401.7771+120.0d; + within ${MAX_VERR:-5}; + }; + object recorder { + property "voltage_A,voltage_B,voltage_C"; + file "voltage.csv"; + interval 1h; + }; +} + +object node { //680 { + name n680; + phases "ABCN"; + voltage_A 2401.7771; + voltage_B -1200.8886-2080.000j; + voltage_C -1200.8886+2080.000j; + nominal_voltage 2401.7771; + object complex_assert { + target voltage_A; + value 2377.75-5.3d; + within ${MAX_VERR:-5}; + }; + object complex_assert { + target voltage_B; + value 2528.82-122.34dd; + within ${MAX_VERR:-5}; + }; + object complex_assert { + target voltage_C; + value 2348.46+116.02d; + within 10; //@note: V_C not exactly matching with IEEE 13-node test feeder + }; +} + + +object node { //684 { + name n684; + phases "ACN"; + voltage_A 2401.7771; + voltage_B -1200.8886-2080.000j; + voltage_C -1200.8886+2080.000j; + nominal_voltage 2401.7771; + object complex_assert { + target voltage_A; + value 2373.65-5.32d; + within ${MAX_VERR:-5}; + }; + object complex_assert { + target voltage_C; + value 2343.65+115.78d; + within ${MAX_VERR:-5}; + }; +} + + + +// Create load objects + +object load { //634 { + name l634; + phases "ABCN"; + voltage_A 480.000+0j; + voltage_B -240.000-415.6922j; + voltage_C -240.000+415.6922j; + constant_power_A 160000+110000j; + constant_power_B 120000+90000j; + constant_power_C 120000+90000j; + nominal_voltage 480.000; + object complex_assert { + target voltage_A; + within ${MAX_VERR:-5}; + value 275-3.23d; + }; + object complex_assert { + target voltage_B; + within ${MAX_VERR:-5}; + value 283.16-122.22d; + }; + object complex_assert { + target voltage_C; + within ${MAX_VERR:-5}; + value 276.02+117.34d; + }; +} + +object load { //645 { + name l645; + phases "BCN"; + voltage_A 2401.7771; + voltage_B -1200.8886-2080.000j; + voltage_C -1200.8886+2080.000j; + constant_power_B 170000+125000j; + nominal_voltage 2401.7771; + object complex_assert { + target voltage_B; + within ${MAX_VERR:-5}; + value 2480.798-121.90d; + }; + object complex_assert { + target voltage_C; + within ${MAX_VERR:-5}; + value 2439.00+117.86d; + }; +} + +object load { //646 { + name l646; + phases "BCD"; + voltage_B -1200.8886-2080.000j; + voltage_C -1200.8886+2080.000j; + constant_impedance_B 56.5993+32.4831j; + nominal_voltage 2401.7771; + object complex_assert { + target voltage_B; + within ${MAX_VERR:-5}; + value 2476.47-121.98d; + }; + object complex_assert { + target voltage_C; + within ${MAX_VERR:-5}; + value 2433.96+117.90d; + }; +} + + +object load { //652 { + name l652; + phases "AN"; + voltage_A 2401.7771; + voltage_B -1200.8886-2080.000j; + voltage_C -1200.8886+2080.000j; + constant_impedance_A 31.0501+20.8618j; + nominal_voltage 2401.7771; + object complex_assert { + target voltage_A; + within ${MAX_VERR:-5}; + value 2359.74-5.25d; + }; +} + +object load { //671 { + name l671; + phases "ABCD"; + voltage_A 2401.7771; + voltage_B -1200.8886-2080.000j; + voltage_C -1200.8886+2080.000j; + constant_power_A 385000+220000j; + constant_power_B 385000+220000j; + constant_power_C 385000+220000j; + nominal_voltage 2401.7771; + object complex_assert { + target voltage_A; + within ${MAX_VERR:-5}; + value 2377.76-5.3d; + }; + object complex_assert { + target voltage_B; + within ${MAX_VERR:-5}; + value 2526.67-122.34d; + }; + object complex_assert { + target voltage_C; + within 8; + value 2348.46+116.02d; + }; +} + +object load { //675 { + name l675; + phases "ABC"; + voltage_A 2401.7771; + voltage_B -1200.8886-2080.000j; + voltage_C -1200.8886+2080.000j; + constant_power_A 485000+190000j; + constant_power_B 68000+60000j; + constant_power_C 290000+212000j; + constant_impedance_A 0.00-28.8427j; //Shunt Capacitors + constant_impedance_B 0.00-28.8427j; + constant_impedance_C 0.00-28.8427j; + nominal_voltage 2401.7771; + object complex_assert { + target voltage_A; + within ${MAX_VERR:-5}; + value 2362.15-5.56d; + }; + object complex_assert { + target voltage_B; + within ${MAX_VERR:-5}; + value 2534.59-122.52d; + }; + object complex_assert { + target voltage_C; + within 8; + value 2343.65+116.03d; + }; +} + +object load { //692 { + name l692; + phases "ABCD"; + voltage_A 2401.7771; + voltage_B -1200.8886-2080.000j; + voltage_C -1200.8886+2080.000j; + constant_current_A 0+0j; + constant_current_B 0+0j; + constant_current_C -17.2414+51.8677j; + nominal_voltage 2401.7771; + object complex_assert { + target voltage_A; + within ${MAX_VERR:-5}; + value 2377.76-5.31d; + }; + object complex_assert { + target voltage_B; + within ${MAX_VERR:-5}; + value 2526.67-122.34d; + }; + object complex_assert { + target voltage_C; + within 8; + value 2348.22+116.02d; + }; +} + +object load { //611 { + name l611; + phases "CN"; + voltage_A 2401.7771; + voltage_B -1200.8886-2080.000j; + voltage_C -1200.8886+2080.000j; + constant_current_C -6.5443+77.9524j; + constant_impedance_C 0.00-57.6854j; //Shunt Capacitor + nominal_voltage 2401.7771; + object complex_assert { + target voltage_C; + within 8; + value 2338.85+115.78d; + }; +} + +// distributed load between node 632 and 671 +// 2/3 of load 1/4 of length down line: Kersting p.56 +object load { //6711 { + name l6711; + parent l671; + phases "ABC"; + voltage_A 2401.7771; + voltage_B -1200.8886-2080.000j; + voltage_C -1200.8886+2080.000j; + constant_power_A 5666.6667+3333.3333j; + constant_power_B 22000+12666.6667j; + constant_power_C 39000+22666.6667j; + nominal_voltage 2401.7771; +} + +object load { //6321 { + name l6321; + phases "ABCN"; + voltage_A 2401.7771; + voltage_B -1200.8886-2080.000j; + voltage_C -1200.8886+2080.000j; + constant_power_A 11333.333+6666.6667j; + constant_power_B 44000+25333.3333j; + constant_power_C 78000+45333.3333j; + nominal_voltage 2401.7771; +} + + + +// Switch +object switch { + phases "ABCN"; + name switch_671-692; + from l671; + to l692; + status CLOSED; +} + +// Transformer +object transformer_configuration { + name tc400; + connect_type WYE_WYE; + install_type PADMOUNT; + power_rating 500; + primary_voltage 4160; + secondary_voltage 480; + resistance 0.011; + reactance 0.02; +} + +object transformer { + phases "ABCN"; + name transformer_633-634; + from n633; + to l634; + configuration tc400; +} + + +// Regulator +object regulator_configuration { + name regconfig6506321; + connect_type 1; + band_center 122.000; + band_width 2.0; + time_delay 30.0; + raise_taps 16; + lower_taps 16; + current_transducer_ratio 700; + power_transducer_ratio 20; + compensator_r_setting_A 3.0; + compensator_r_setting_B 3.0; + compensator_r_setting_C 3.0; + compensator_x_setting_A 9.0; + compensator_x_setting_B 9.0; + compensator_x_setting_C 9.0; + CT_phase "ABC"; + PT_phase "ABC"; + regulation 0.10; + Control MANUAL; + Type A; + tap_pos_A 10; + tap_pos_B 8; + tap_pos_C 11; +} + +object regulator { + name fregn650n630; + phases "ABC"; + from n650; + to n630; + configuration regconfig6506321; +} \ No newline at end of file diff --git a/module/powerflow/solver_py.conf b/module/powerflow/solver_py.conf index 316173839..7b2528b13 100644 --- a/module/powerflow/solver_py.conf +++ b/module/powerflow/solver_py.conf @@ -59,6 +59,14 @@ #import solver_py +# +# mle_data_only +# +# Specifies that only the ML enhanced busdata is copied. +# + +#mle_data_only + # # busdump # diff --git a/module/powerflow/solver_py.cpp b/module/powerflow/solver_py.cpp index 4c38f2241..fa5ff1805 100644 --- a/module/powerflow/solver_py.cpp +++ b/module/powerflow/solver_py.cpp @@ -7,6 +7,9 @@ #include #include +#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION +#include + #include "solver_py.h" // #undef Py_INCREF @@ -29,6 +32,7 @@ static const char *module_import_name = NULL; // module name to import (python o static PyObject *pModule = NULL; static int solver_python_loglevel = 0; // -1=disable, 0 = minimal ... 9 = everything, static FILE *solver_python_logfh = NULL; +static bool python_mle_data_only = false; static const char *python_busdata = "name,type,phases," "volt_base,mva_base,origphases," "SAr,SAi,SBr,SBi,SCr,SCi," @@ -215,6 +219,23 @@ SOLVERPYTHONSTATUS solver_python_config ( fprintf(stderr,"solver_python_config(configname='%s'): tag '%s' value '%s' is invalid\n",configname,tag,value); status = SPS_FAILED; } + solver_python_log(1,"solver_python_config(configname='%s'): solver status = %d",configname,status); + } + else if ( strcmp(tag,"mle_data_only") == 0 ) + { + if ( strcmp(value,"true") == 0 ) + { + python_mle_data_only = true; + } + else if ( strcmp(value,"false") == 0 ) + { + python_mle_data_only = false; + } + else { + fprintf(stderr,"solver_python_config(configname='%s'): tag '%s' value '%s' is invalid\n",configname,tag,value); + status = SPS_FAILED; + } + solver_python_log(1,"solver_python_config(configname='%s'): python_mle_data_only = true",configname); } else if ( strcmp(tag,"busdata") == 0 ) { @@ -425,9 +446,15 @@ void init_learndata(void) } } +void *numpy_init() +{ + import_array(); + return NULL; +} int solver_python_init(void) { errno = 0; + numpy_init(); if ( solver_py_status == SPS_INIT ) { solver_py_status = solver_python_config(); @@ -461,21 +488,24 @@ int solver_python_init(void) } PyDict_SetItemString(pModel,"options",pKwargs); } - if ( pBusdata == NULL ) - { - init_busdata(); - } - if ( pBranchdata == NULL ) - { - init_branchdata(); - } - if ( pLearndata == NULL ) + if ( ! python_mle_data_only ) { - init_learndata(); - } - if ( pSolution == NULL ) - { - pSolution = PyDict_Copy(pModel); + if ( pBusdata == NULL ) + { + init_busdata(); + } + if ( pBranchdata == NULL ) + { + init_branchdata(); + } + if ( pLearndata == NULL ) + { + init_learndata(); + } + if ( pSolution == NULL ) + { + pSolution = PyDict_Copy(pModel); + } } return 0; } @@ -615,7 +645,7 @@ void ref_to_ang(void *x, void *c, bool inverse) // bus/branch data mapping static BUSDATA bus_t; static BRANCHDATA branch_t; -#define DATA(S,T,X,D,C) {T, (int64)(&(S##_t.X))-(int64)(&S##_t),sizeof(S##_t),D,C} +#define DATA(S,T,X,D,C) {T, (int64)(&(S##_t.X))-(int64)(&S##_t),sizeof(S##_t),D,C,s_map::NONE} #define DATA_R(S,T,X,R,D,C) {T, (int64)(&(S##_t.X))-(int64)(&S##_t),sizeof(S##_t),D,C,s_map::DOUBLE,true,(int64)&(S##_t.X R)-(int64)(S##_t.X)} #define DATA_X(S,T,X,R,D,C) {T, (int64)(&(S##_t.X))-(int64)(&S##_t),sizeof(S##_t),D,C,s_map::PDOUBLE,true,(int64)&(S##_t.X R)-(int64)(S##_t.X)} #define DATA_C(S,T,X,R,D,C) {T, (int64)(&(S##_t.X))-(int64)(&S##_t),sizeof(S##_t),D,C,s_map::PCOMPLEX,true,(int64)&(S##_t.X R)-(int64)(S##_t.X)} @@ -673,10 +703,11 @@ static struct s_map e_dir dir; void (*convert)(void*,void*,bool); enum { - DOUBLE =0, // value is at offset - PDOUBLE =1, // pointer to value is at offset - PCOMPLEX =2, // pointer to value is converted using a method - } type; + NONE = 0, // no value + DOUBLE = 1, // value is at offset + PDOUBLE = 2, // pointer to value is at offset + PCOMPLEX = 3, // pointer to value is converted using a method + } dtype; bool is_ref; int64 ref_offset; } busmap[] = @@ -879,7 +910,80 @@ void sync_data(PyObject *data, size_t n, void *source, struct s_map *map, e_dir } } -void sync_busdata(PyObject *pModel,unsigned int &bus_count,BUSDATA *&bus,e_dir dir) +void sync_busdata_raw(PyObject *pModel,unsigned int &bus_count,BUSDATA *&bus,e_dir dir) +{ + PyObject *busdata = PyDict_GetItemString(pModel,"busdata"); + if ( busdata == NULL ) + { + const char *tags[] = { + "SAr","SAi","SBr","SBi","SCr","SCi", + "YAr","YAi","YBr","YBi","YCr","YCi", + "IAr","IAi","IBr","IBi","ICr","ICi", + "VAr","VAi","VBr","VBi","VCr","VCi", + }; + size_t ntags = sizeof(tags)/sizeof(tags[0]); + PyObject *taglist = PyList_New(ntags); + for ( size_t m = 0 ; m < ntags ; m++ ) + { + PyObject *tag = PyUnicode_FromString(tags[m]); + PyList_SetItem(taglist,m,tag); + } + PyDict_SetItemString(pModel,"bustags",taglist); + + npy_intp dims[] = {ntags,bus_count}; + busdata = PyArray_ZEROS(sizeof(dims)/sizeof(dims[0]),dims,NPY_DOUBLE,0); + PyDict_SetItemString(pModel,"busdata",busdata); + } +#define SET_BUS(N,I,X) (*(npy_double*)PyArray_GETPTR2((PyArrayObject*)busdata,I,n)=X) +#define GET_BUS(N,I,X) (X=*(npy_double*)PyArray_GETPTR2((PyArrayObject*)busdata,I,n)) + if ( dir == ED_INIT || dir == ED_OUT ) + { + for ( size_t n = 0 ; n < bus_count ; n++ ) + { + SET_BUS(n,0,bus[n].S[0].r); + SET_BUS(n,1,bus[n].S[0].i); + SET_BUS(n,2,bus[n].S[1].r); + SET_BUS(n,3,bus[n].S[1].i); + SET_BUS(n,4,bus[n].S[2].r); + SET_BUS(n,5,bus[n].S[2].i); + + SET_BUS(n,6,bus[n].Y[0].r); + SET_BUS(n,7,bus[n].Y[0].i); + SET_BUS(n,8,bus[n].Y[1].r); + SET_BUS(n,9,bus[n].Y[1].i); + SET_BUS(n,10,bus[n].Y[2].r); + SET_BUS(n,11,bus[n].Y[2].i); + + SET_BUS(n,12,bus[n].I[0].r); + SET_BUS(n,13,bus[n].I[0].i); + SET_BUS(n,14,bus[n].I[1].r); + SET_BUS(n,15,bus[n].I[1].i); + SET_BUS(n,16,bus[n].I[2].r); + SET_BUS(n,17,bus[n].I[2].i); + + SET_BUS(n,18,bus[n].V[0].r); + SET_BUS(n,19,bus[n].V[0].i); + SET_BUS(n,20,bus[n].V[1].r); + SET_BUS(n,21,bus[n].V[1].i); + SET_BUS(n,22,bus[n].V[2].r); + SET_BUS(n,23,bus[n].V[2].i); + } + } + else if ( dir == ED_IN ) + { + for ( size_t n = 0 ; n < bus_count ; n++ ) + { + GET_BUS(n,18,bus[n].V[0].r); + GET_BUS(n,19,bus[n].V[0].i); + GET_BUS(n,20,bus[n].V[1].r); + GET_BUS(n,21,bus[n].V[1].i); + GET_BUS(n,22,bus[n].V[2].r); + GET_BUS(n,23,bus[n].V[2].i); + } + } +} + +void sync_busdata_mapped(PyObject *pModel,unsigned int &bus_count,BUSDATA *&bus,e_dir dir) { PyObject *busdata = PyDict_GetItemString(pModel,"busdata"); if ( busdata == NULL ) @@ -939,7 +1043,20 @@ void sync_busdata(PyObject *pModel,unsigned int &bus_count,BUSDATA *&bus,e_dir d } } -void sync_branchdata(PyObject *pModel,unsigned int &branch_count,BRANCHDATA *&branch,e_dir dir) +void sync_branchdata_raw(PyObject *pModel,unsigned int &branch_count,BRANCHDATA *&branch,e_dir dir) +{ + PyObject *branchdata = PyDict_GetItemString(pModel,"branchdata"); + if ( branchdata == NULL ) + { + PyDict_SetItemString(pModel,"branchdata",Py_None); + Py_INCREF(Py_None); + PyDict_SetItemString(pModel,"branchtags",Py_None); + Py_INCREF(Py_None); + } + return; +} + +void sync_branchdata_mapped(PyObject *pModel,unsigned int &branch_count,BRANCHDATA *&branch,e_dir dir) { PyObject *branchdata = PyDict_GetItemString(pModel,"branchdata"); if ( branchdata == NULL ) @@ -1009,8 +1126,18 @@ static PyObject *sync_model( { set_bustags(pModel); set_branchtags(pModel); - sync_busdata(pModel,bus_count,bus,dir); - sync_branchdata(pModel,branch_count,branch,dir); + if ( python_mle_data_only ) + { + set_dict_value(pModel,"mle_data_only",Py_True); + sync_busdata_raw(pModel,bus_count,bus,dir); + sync_branchdata_raw(pModel,branch_count,branch,dir); + } + else + { + set_dict_value(pModel,"mle_data_only",Py_False); + sync_busdata_mapped(pModel,bus_count,bus,dir); + sync_branchdata_mapped(pModel,branch_count,branch,dir); + } return pModel; } @@ -1335,12 +1462,25 @@ PyObject *sync_solution( bool *bad_computations, int64 iterations) { - sync_bad_computations(pSolution,bad_computations); - sync_iterations(pSolution,iterations); - sync_powerflow_values(pSolution,buscount,powerflow_values); - sync_powerflow_type(pSolution,powerflow_type); - sync_mesh_imped_values(pSolution,mesh_imped_values); - return pSolution; + if ( ! python_mle_data_only ) + { + sync_bad_computations(pSolution,bad_computations); + sync_iterations(pSolution,iterations); + sync_powerflow_values(pSolution,buscount,powerflow_values); + sync_powerflow_type(pSolution,powerflow_type); + sync_mesh_imped_values(pSolution,mesh_imped_values); + return pSolution; + } + else if ( pBusdata ) + { + Py_INCREF(pBusdata); + return pBusdata; + } + else + { + Py_INCREF(Py_None); + return Py_None; + } }