From 04f036e8f0ed5295f6268958e549472ea1931d23 Mon Sep 17 00:00:00 2001 From: "David P. Chassin" Date: Fri, 17 Sep 2021 13:22:21 -0700 Subject: [PATCH 01/28] Update solver_py.cpp --- module/powerflow/solver_py.cpp | 48 +++++++++++++++++++++++++++------- 1 file changed, 39 insertions(+), 9 deletions(-) diff --git a/module/powerflow/solver_py.cpp b/module/powerflow/solver_py.cpp index 2e2caaccf..7221a0344 100644 --- a/module/powerflow/solver_py.cpp +++ b/module/powerflow/solver_py.cpp @@ -7,6 +7,8 @@ #include #include +#define USE_CDATA + #include "solver_py.h" // #undef Py_INCREF @@ -615,7 +617,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 +675,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[] = @@ -781,6 +784,8 @@ void sync_property(PyObject *data, size_t n, void *ptr, void (*convert)(void*,vo void sync_property_ref(PyObject *data, size_t n, void *ptr, int64 offset, bool inverse) { + printf("sync_property_ref(PyObject *data=0x%p, size_t n=%ld, void *ptr=0x%p, int64 offset=%lld, bool inverse=<%s>)\n", + data, n, ptr, offset, inverse?"true":"false"); double **ppx = (double**)ptr; if ( ppx == NULL ) return; @@ -789,6 +794,9 @@ void sync_property_ref(PyObject *data, size_t n, void *ptr, int64 offset, bool i return; double &x = *px; PyObject *pValue = PyList_GetItem(data,n); + printf(" ppx=0x%p, px=0x%p", ppx, px); + fflush(stdout); + printf(", x=%lg, pValue=0x%p\n", x, pValue); if ( inverse ) { if ( pValue && PyFloat_Check(pValue) ) @@ -879,7 +887,19 @@ 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 ) + { + } + for ( size_t t = 0 ; t < python_nbustags ; t++ ) + { + int m = bus_index[t]; + } +} + +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 +959,11 @@ 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) +{ +} + +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 +1033,14 @@ static PyObject *sync_model( { set_bustags(pModel); set_branchtags(pModel); - sync_busdata(pModel,bus_count,bus,dir); - sync_branchdata(pModel,branch_count,branch,dir); +#ifdef USE_CDATA + set_dict_value(pModel,"mapping",Py_None); + sync_busdata_raw(pModel,bus_count,bus,dir); + sync_branchdata_raw(pModel,branch_count,branch,dir); +#else + sync_busdata_mapped(pModel,bus_count,bus,dir); + sync_branchdata_mapped(pModel,branch_count,branch,dir); +#endif return pModel; } From b60d7bcaadd020600d9bee912aa884032a83be82 Mon Sep 17 00:00:00 2001 From: "David P. Chassin" Date: Wed, 22 Sep 2021 12:40:57 -0700 Subject: [PATCH 02/28] Update solver_py.cpp --- module/powerflow/solver_py.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/module/powerflow/solver_py.cpp b/module/powerflow/solver_py.cpp index 7221a0344..d6b4071a7 100644 --- a/module/powerflow/solver_py.cpp +++ b/module/powerflow/solver_py.cpp @@ -892,6 +892,14 @@ void sync_busdata_raw(PyObject *pModel,unsigned int &bus_count,BUSDATA *&bus,e_d PyObject *busdata = PyDict_GetItemString(pModel,"busdata"); if ( busdata == NULL ) { + busdata = PyList_New(python_nbustags); + PyDict_SetItemString(pModel,"busdata",busdata); + bus_index = new int[python_nbustags]; + memset(bus_index,-1,python_nbustags*sizeof(int)); + for ( size_t m = 0 ; m < sizeof(busmap)/sizeof(busmap[0]) ; m++ ) + { + // TODO + } } for ( size_t t = 0 ; t < python_nbustags ; t++ ) { From b451570f55091ee4b1154e751fee52a48a7ab000 Mon Sep 17 00:00:00 2001 From: "David P. Chassin" Date: Thu, 23 Sep 2021 16:04:22 -0700 Subject: [PATCH 03/28] Added numpy array creation support --- module/powerflow/Makefile.mk | 2 +- module/powerflow/solver_py.cpp | 20 ++++++++++++++++---- 2 files changed, 17 insertions(+), 5 deletions(-) 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/solver_py.cpp b/module/powerflow/solver_py.cpp index d6b4071a7..65fc9f034 100644 --- a/module/powerflow/solver_py.cpp +++ b/module/powerflow/solver_py.cpp @@ -8,6 +8,8 @@ #include #define USE_CDATA +#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION +#include #include "solver_py.h" @@ -892,11 +894,19 @@ void sync_busdata_raw(PyObject *pModel,unsigned int &bus_count,BUSDATA *&bus,e_d PyObject *busdata = PyDict_GetItemString(pModel,"busdata"); if ( busdata == NULL ) { - busdata = PyList_New(python_nbustags); + size_t nbuses = sizeof(busmap)/sizeof(busmap[0]); + busdata = PyDict_New(); PyDict_SetItemString(pModel,"busdata",busdata); - bus_index = new int[python_nbustags]; - memset(bus_index,-1,python_nbustags*sizeof(int)); - for ( size_t m = 0 ; m < sizeof(busmap)/sizeof(busmap[0]) ; m++ ) + 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]); + npy_intp dims[] = {nbuses,ntags}; + PyObject *array = PyArray_SimpleNew(2,dims,NPY_COMPLEX128); + for ( size_t m = 0 ; m < nbuses ; m++ ) { // TODO } @@ -969,6 +979,8 @@ void sync_busdata_mapped(PyObject *pModel,unsigned int &bus_count,BUSDATA *&bus, void sync_branchdata_raw(PyObject *pModel,unsigned int &branch_count,BRANCHDATA *&branch,e_dir dir) { + // no branch data needed + return; } void sync_branchdata_mapped(PyObject *pModel,unsigned int &branch_count,BRANCHDATA *&branch,e_dir dir) From f209b9bee75dbd144cf0d4014eb67a647302bea9 Mon Sep 17 00:00:00 2001 From: "David P. Chassin" Date: Fri, 24 Sep 2021 08:52:07 -0700 Subject: [PATCH 04/28] Implement MLE solver bus mapping --- module/powerflow/autotest/solver_mle.conf | 12 + module/powerflow/autotest/solver_mle_check.py | 9 + .../powerflow/autotest/test_IEEE_13_MLE.glm | 712 ++++++++++++++++++ module/powerflow/solver_py.conf | 8 + module/powerflow/solver_py.cpp | 95 ++- 5 files changed, 814 insertions(+), 22 deletions(-) create mode 100644 module/powerflow/autotest/solver_mle.conf create mode 100644 module/powerflow/autotest/solver_mle_check.py create mode 100644 module/powerflow/autotest/test_IEEE_13_MLE.glm diff --git a/module/powerflow/autotest/solver_mle.conf b/module/powerflow/autotest/solver_mle.conf new file mode 100644 index 000000000..73cf6b746 --- /dev/null +++ b/module/powerflow/autotest/solver_mle.conf @@ -0,0 +1,12 @@ +# comments are helpful +maximum_metric 1e-9 +method basic +logfile ./solver_ml.log +loglevel 9 +mle_data_only +busdump ./solver_bus.csv +branchdump ./solver_branch.csv +import_path .. +import python:solver_mle_check +on_dump python:check_dumps + diff --git a/module/powerflow/autotest/solver_mle_check.py b/module/powerflow/autotest/solver_mle_check.py new file mode 100644 index 000000000..ff22c0c48 --- /dev/null +++ b/module/powerflow/autotest/solver_mle_check.py @@ -0,0 +1,9 @@ +import pandas as pd + +def check_dumps(gridlabd): + + bus = pd.read_csv("solver_bus.csv") + assert((bus["EOL"]=="EOL").all()) + + branch = pd.read_csv("solver_branch.csv") + assert((branch["EOL"]=="EOL").all()) 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..5e139b413 --- /dev/null +++ b/module/powerflow/autotest/test_IEEE_13_MLE.glm @@ -0,0 +1,712 @@ +// $Id: IEEE13-Feb27.glm +// Copyright (C) 2011 Battelle Memorial Institute + +#set iteration_limit=100000; + +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; +#ifdef powerflow::solver_ml_config + solver_ml_config "../solver_mle.conf"; +#endif + } +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 5; + }; object complex_assert { + target voltage_B; + value 2498.09-121.77d; + within 5; + }; object complex_assert { + target voltage_C; + value 2437.32+117.82d; + within 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 5; + }; object complex_assert { + target voltage_B; + value 2502.56-121.72d; + within 5; + }; object complex_assert { + target voltage_C; + value 2443.56+117.83d; + within 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 5; + }; object complex_assert { + target voltage_B; + value 2401.7771-120.0d; + within 5; + }; object complex_assert { + target voltage_C; + value 2401.7771+120.0d; + within 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 5; + }; + object complex_assert { + target voltage_B; + value 2528.82-122.34dd; + within 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 5; + }; + object complex_assert { + target voltage_C; + value 2343.65+115.78d; + within 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 5; + value 275-3.23d; + }; + object complex_assert { + target voltage_B; + within 5; + value 283.16-122.22d; + }; + object complex_assert { + target voltage_C; + within 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 5; + value 2480.798-121.90d; + }; + object complex_assert { + target voltage_C; + within 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 5; + value 2476.47-121.98d; + }; + object complex_assert { + target voltage_C; + within 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 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 5; + value 2377.76-5.3d; + }; + object complex_assert { + target voltage_B; + within 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 5; + value 2362.15-5.56d; + }; + object complex_assert { + target voltage_B; + within 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 5; + value 2377.76-5.31d; + }; + object complex_assert { + target voltage_B; + within 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 65fc9f034..7de33936a 100644 --- a/module/powerflow/solver_py.cpp +++ b/module/powerflow/solver_py.cpp @@ -7,7 +7,6 @@ #include #include -#define USE_CDATA #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION #include @@ -33,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," @@ -220,6 +220,11 @@ SOLVERPYTHONSTATUS solver_python_config ( status = SPS_FAILED; } } + else if ( strcmp(tag,"mle_data_only") == 0 ) + { + python_mle_data_only = true; + solver_python_log(1,"solver_python_config(configname='%s'): python_mle_data_only = true",configname); + } else if ( strcmp(tag,"busdata") == 0 ) { python_busdata = strdup(value); @@ -786,8 +791,6 @@ void sync_property(PyObject *data, size_t n, void *ptr, void (*convert)(void*,vo void sync_property_ref(PyObject *data, size_t n, void *ptr, int64 offset, bool inverse) { - printf("sync_property_ref(PyObject *data=0x%p, size_t n=%ld, void *ptr=0x%p, int64 offset=%lld, bool inverse=<%s>)\n", - data, n, ptr, offset, inverse?"true":"false"); double **ppx = (double**)ptr; if ( ppx == NULL ) return; @@ -796,9 +799,6 @@ void sync_property_ref(PyObject *data, size_t n, void *ptr, int64 offset, bool i return; double &x = *px; PyObject *pValue = PyList_GetItem(data,n); - printf(" ppx=0x%p, px=0x%p", ppx, px); - fflush(stdout); - printf(", x=%lg, pValue=0x%p\n", x, pValue); if ( inverse ) { if ( pValue && PyFloat_Check(pValue) ) @@ -892,10 +892,12 @@ void sync_data(PyObject *data, size_t n, void *source, struct s_map *map, e_dir void sync_busdata_raw(PyObject *pModel,unsigned int &bus_count,BUSDATA *&bus,e_dir dir) { PyObject *busdata = PyDict_GetItemString(pModel,"busdata"); + PyObject *array; if ( busdata == NULL ) { - size_t nbuses = sizeof(busmap)/sizeof(busmap[0]); busdata = PyDict_New(); + + // set tags PyDict_SetItemString(pModel,"busdata",busdata); const char *tags[] = { "SAr","SAi","SBr","SBi","SCr","SCi", @@ -904,17 +906,62 @@ void sync_busdata_raw(PyObject *pModel,unsigned int &bus_count,BUSDATA *&bus,e_d "VAr","VAi","VBr","VBi","VCr","VCi", }; size_t ntags = sizeof(tags)/sizeof(tags[0]); - npy_intp dims[] = {nbuses,ntags}; - PyObject *array = PyArray_SimpleNew(2,dims,NPY_COMPLEX128); - for ( size_t m = 0 ; m < nbuses ; m++ ) + PyObject *taglist = PyList_New(ntags); + for ( size_t m = 0 ; m < ntags ; m++ ) { - // TODO + PyObject *tag = PyUnicode_FromString(tags[m]); + PyList_SetItem(taglist,m,tag); } + PyDict_SetItemString(busdata,"tags",taglist); + + npy_intp dims[] = {bus_count,ntags}; + array = PyArray_ZEROS(2,dims,NPY_DOUBLE,0); + PyDict_SetItemString(busdata,"data",array); } - for ( size_t t = 0 ; t < python_nbustags ; t++ ) + else { - int m = bus_index[t]; - } + array = PyDict_GetItemString(busdata,"data"); + } +#define SET_BUS(N,I,X) (*(npy_double*)PyArray_GETPTR2((PyArrayObject*)array,n,0)=X) +#define GET_BUS(N,I,X) (X=*(npy_double*)PyArray_GETPTR2((PyArrayObject*)array,n,0)) + if ( dir == ED_INIT || dir == ED_OUT ) + { + for ( size_t n = 0 ; n < bus_count ; n++ ) + { + SET_BUS(N,0,bus->S[0].r); + SET_BUS(N,1,bus->S[0].i); + SET_BUS(N,2,bus->S[1].r); + SET_BUS(N,3,bus->S[1].i); + SET_BUS(N,4,bus->S[2].r); + SET_BUS(N,5,bus->S[2].i); + + SET_BUS(N,6,bus->Y[0].r); + SET_BUS(N,7,bus->Y[0].i); + SET_BUS(N,8,bus->Y[1].r); + SET_BUS(N,9,bus->Y[1].i); + SET_BUS(N,10,bus->Y[2].r); + SET_BUS(N,11,bus->Y[2].i); + + SET_BUS(N,12,bus->I[0].r); + SET_BUS(N,13,bus->I[0].i); + SET_BUS(N,14,bus->I[1].r); + SET_BUS(N,15,bus->I[1].i); + SET_BUS(N,16,bus->I[2].r); + SET_BUS(N,17,bus->I[2].i); + } + } + else if ( dir == ED_IN ) + { + for ( size_t n = 0 ; n < bus_count ; n++ ) + { + GET_BUS(N,18,bus->V[0].r); + GET_BUS(N,19,bus->V[0].i); + GET_BUS(N,20,bus->V[1].r); + GET_BUS(N,21,bus->V[1].i); + GET_BUS(N,22,bus->V[2].r); + GET_BUS(N,23,bus->V[2].i); + } + } } void sync_busdata_mapped(PyObject *pModel,unsigned int &bus_count,BUSDATA *&bus,e_dir dir) @@ -1053,14 +1100,18 @@ static PyObject *sync_model( { set_bustags(pModel); set_branchtags(pModel); -#ifdef USE_CDATA - set_dict_value(pModel,"mapping",Py_None); - sync_busdata_raw(pModel,bus_count,bus,dir); - sync_branchdata_raw(pModel,branch_count,branch,dir); -#else - sync_busdata_mapped(pModel,bus_count,bus,dir); - sync_branchdata_mapped(pModel,branch_count,branch,dir); -#endif + 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; } From 80c9358255b54b1a5042f8d0cea6154817bec1f5 Mon Sep 17 00:00:00 2001 From: "David P. Chassin" Date: Fri, 24 Sep 2021 10:33:13 -0700 Subject: [PATCH 05/28] Fix busdata mapping errors --- module/powerflow/autotest/solver_mle.conf | 27 ++- module/powerflow/autotest/solver_mle_check.py | 9 - module/powerflow/autotest/solver_py.py | 12 +- module/powerflow/solver_py.cpp | 156 +++++++++++------- 4 files changed, 119 insertions(+), 85 deletions(-) delete mode 100644 module/powerflow/autotest/solver_mle_check.py diff --git a/module/powerflow/autotest/solver_mle.conf b/module/powerflow/autotest/solver_mle.conf index 73cf6b746..28242cb9b 100644 --- a/module/powerflow/autotest/solver_mle.conf +++ b/module/powerflow/autotest/solver_mle.conf @@ -1,12 +1,23 @@ # comments are helpful -maximum_metric 1e-9 -method basic -logfile ./solver_ml.log +solver enable + +logfile ./solver_mle.log loglevel 9 -mle_data_only -busdump ./solver_bus.csv -branchdump ./solver_branch.csv + import_path .. -import python:solver_mle_check -on_dump python:check_dumps + +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=pretty + +mle_data_only true diff --git a/module/powerflow/autotest/solver_mle_check.py b/module/powerflow/autotest/solver_mle_check.py deleted file mode 100644 index ff22c0c48..000000000 --- a/module/powerflow/autotest/solver_mle_check.py +++ /dev/null @@ -1,9 +0,0 @@ -import pandas as pd - -def check_dumps(gridlabd): - - bus = pd.read_csv("solver_bus.csv") - assert((bus["EOL"]=="EOL").all()) - - branch = pd.read_csv("solver_branch.csv") - assert((branch["EOL"]=="EOL").all()) diff --git a/module/powerflow/autotest/solver_py.py b/module/powerflow/autotest/solver_py.py index b40fef563..bdb3ee60a 100644 --- a/module/powerflow/autotest/solver_py.py +++ b/module/powerflow/autotest/solver_py.py @@ -32,12 +32,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 +77,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/solver_py.cpp b/module/powerflow/solver_py.cpp index 7de33936a..896e1124b 100644 --- a/module/powerflow/solver_py.cpp +++ b/module/powerflow/solver_py.cpp @@ -219,10 +219,22 @@ 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 ) { - python_mle_data_only = true; + 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 ) @@ -434,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(); @@ -470,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 ) - { - init_learndata(); - } - if ( pSolution == NULL ) + if ( ! python_mle_data_only ) { - 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; } @@ -892,13 +913,8 @@ void sync_data(PyObject *data, size_t n, void *source, struct s_map *map, e_dir void sync_busdata_raw(PyObject *pModel,unsigned int &bus_count,BUSDATA *&bus,e_dir dir) { PyObject *busdata = PyDict_GetItemString(pModel,"busdata"); - PyObject *array; if ( busdata == NULL ) { - busdata = PyDict_New(); - - // set tags - PyDict_SetItemString(pModel,"busdata",busdata); const char *tags[] = { "SAr","SAi","SBr","SBi","SCr","SCi", "YAr","YAi","YBr","YBi","YCr","YCi", @@ -912,54 +928,50 @@ void sync_busdata_raw(PyObject *pModel,unsigned int &bus_count,BUSDATA *&bus,e_d PyObject *tag = PyUnicode_FromString(tags[m]); PyList_SetItem(taglist,m,tag); } - PyDict_SetItemString(busdata,"tags",taglist); + PyDict_SetItemString(pModel,"bustags",taglist); npy_intp dims[] = {bus_count,ntags}; - array = PyArray_ZEROS(2,dims,NPY_DOUBLE,0); - PyDict_SetItemString(busdata,"data",array); - } - else - { - array = PyDict_GetItemString(busdata,"data"); + 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*)array,n,0)=X) -#define GET_BUS(N,I,X) (X=*(npy_double*)PyArray_GETPTR2((PyArrayObject*)array,n,0)) +#define SET_BUS(N,I,X) (*(npy_double*)PyArray_GETPTR2((PyArrayObject*)busdata,n,I)=X) +#define GET_BUS(N,I,X) (X=*(npy_double*)PyArray_GETPTR2((PyArrayObject*)busdata,n,I)) if ( dir == ED_INIT || dir == ED_OUT ) { for ( size_t n = 0 ; n < bus_count ; n++ ) { - SET_BUS(N,0,bus->S[0].r); - SET_BUS(N,1,bus->S[0].i); - SET_BUS(N,2,bus->S[1].r); - SET_BUS(N,3,bus->S[1].i); - SET_BUS(N,4,bus->S[2].r); - SET_BUS(N,5,bus->S[2].i); - - SET_BUS(N,6,bus->Y[0].r); - SET_BUS(N,7,bus->Y[0].i); - SET_BUS(N,8,bus->Y[1].r); - SET_BUS(N,9,bus->Y[1].i); - SET_BUS(N,10,bus->Y[2].r); - SET_BUS(N,11,bus->Y[2].i); - - SET_BUS(N,12,bus->I[0].r); - SET_BUS(N,13,bus->I[0].i); - SET_BUS(N,14,bus->I[1].r); - SET_BUS(N,15,bus->I[1].i); - SET_BUS(N,16,bus->I[2].r); - SET_BUS(N,17,bus->I[2].i); + 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); } } else if ( dir == ED_IN ) { for ( size_t n = 0 ; n < bus_count ; n++ ) { - GET_BUS(N,18,bus->V[0].r); - GET_BUS(N,19,bus->V[0].i); - GET_BUS(N,20,bus->V[1].r); - GET_BUS(N,21,bus->V[1].i); - GET_BUS(N,22,bus->V[2].r); - GET_BUS(N,23,bus->V[2].i); + 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); } } } @@ -1026,7 +1038,14 @@ void sync_busdata_mapped(PyObject *pModel,unsigned int &bus_count,BUSDATA *&bus, void sync_branchdata_raw(PyObject *pModel,unsigned int &branch_count,BRANCHDATA *&branch,e_dir dir) { - // no branch data needed + 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; } @@ -1436,12 +1455,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; + } } From 47661d4c4e08707c8c10cfaa385160641528b89f Mon Sep 17 00:00:00 2001 From: "David P. Chassin" Date: Fri, 24 Sep 2021 10:43:30 -0700 Subject: [PATCH 06/28] Change output to dataframe for improved readability --- module/powerflow/autotest/solver_mle.conf | 2 +- module/powerflow/autotest/solver_py.py | 3 +++ module/powerflow/solver_py.cpp | 6 +++--- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/module/powerflow/autotest/solver_mle.conf b/module/powerflow/autotest/solver_mle.conf index 28242cb9b..0a5f0d83e 100644 --- a/module/powerflow/autotest/solver_mle.conf +++ b/module/powerflow/autotest/solver_mle.conf @@ -17,7 +17,7 @@ learndata powerflow_values.deltaI_NR,powerflow_values.Y_offdiag_PQ,powerflow_val profiler solver_py.csv -option dump=pretty +option dump=dataframe mle_data_only true diff --git a/module/powerflow/autotest/solver_py.py b/module/powerflow/autotest/solver_py.py index bdb3ee60a..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) diff --git a/module/powerflow/solver_py.cpp b/module/powerflow/solver_py.cpp index 896e1124b..e6e921ac1 100644 --- a/module/powerflow/solver_py.cpp +++ b/module/powerflow/solver_py.cpp @@ -930,12 +930,12 @@ void sync_busdata_raw(PyObject *pModel,unsigned int &bus_count,BUSDATA *&bus,e_d } PyDict_SetItemString(pModel,"bustags",taglist); - npy_intp dims[] = {bus_count,ntags}; + 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,n,I)=X) -#define GET_BUS(N,I,X) (X=*(npy_double*)PyArray_GETPTR2((PyArrayObject*)busdata,n,I)) +#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++ ) From e746e22825a439cc037e2bae578d6f13f2cb0d6d Mon Sep 17 00:00:00 2001 From: "David P. Chassin" Date: Fri, 24 Sep 2021 11:32:24 -0700 Subject: [PATCH 07/28] Update test_IEEE_13_MLE.glm --- module/powerflow/autotest/test_IEEE_13_MLE.glm | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/module/powerflow/autotest/test_IEEE_13_MLE.glm b/module/powerflow/autotest/test_IEEE_13_MLE.glm index 5e139b413..48ec54699 100644 --- a/module/powerflow/autotest/test_IEEE_13_MLE.glm +++ b/module/powerflow/autotest/test_IEEE_13_MLE.glm @@ -1,7 +1,7 @@ // $Id: IEEE13-Feb27.glm // Copyright (C) 2011 Battelle Memorial Institute -#set iteration_limit=100000; +#set iteration_limit=100 clock { timezone EST+5EDT; @@ -12,9 +12,10 @@ clock { module powerflow { solver_method NR; line_capacitance true; -#ifdef powerflow::solver_ml_config - solver_ml_config "../solver_mle.conf"; +#ifexist "../solver_py.conf" +#define DIR=.. #endif + solver_py_config "${DIR:-.}/solver_mle.conf"; } module assert; From 2e863acd3d6394fd1ad30c744cb984f80ca0e3a2 Mon Sep 17 00:00:00 2001 From: "David P. Chassin" Date: Fri, 24 Sep 2021 13:55:43 -0700 Subject: [PATCH 08/28] Update setup-Linux-amzn-2.sh --- build-aux/setup-Linux-amzn-2.sh | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/build-aux/setup-Linux-amzn-2.sh b/build-aux/setup-Linux-amzn-2.sh index a9c737451..6bea8b315 100755 --- a/build-aux/setup-Linux-amzn-2.sh +++ b/build-aux/setup-Linux-amzn-2.sh @@ -15,15 +15,22 @@ 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.0/Python-3.9.0.tgz | tar xz + cd Python-3.9.0 + ./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 + /usr/local/bin/python3 pip -m install mysql-connector matplotlib numpy pandas Pillow +fi # mono if [ ! -f /usr/bin/mono ]; then From 297cf0a9202e20e5c6880a2725d3f1b18858e0c5 Mon Sep 17 00:00:00 2001 From: "David P. Chassin" Date: Fri, 24 Sep 2021 16:47:14 -0700 Subject: [PATCH 09/28] Create setup-Linux-ubuntu-20.sh --- build-aux/setup-Linux-ubuntu-20.sh | 73 ++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 build-aux/setup-Linux-ubuntu-20.sh diff --git a/build-aux/setup-Linux-ubuntu-20.sh b/build-aux/setup-Linux-ubuntu-20.sh new file mode 100644 index 000000000..52828f766 --- /dev/null +++ b/build-aux/setup-Linux-ubuntu-20.sh @@ -0,0 +1,73 @@ +#!/bin/bash + +# Install needed system tools +# update first +apt-get -q update +apt-get -q install tzdata -y + +# install python 3.9 +apt-get -q install python3.9 -y +update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.9 1 +apt-get -q install python3.9-dev -y +apt-get -q install python3-pip -y +echo '#/bin/bash +/usr/bin/python3-config $*' > /usr/local/bin/python3-config +chmod +x /usr/local/bin/python3-config + +# install python libraries by validation +pip3 -q install --upgrade pip +pip -q install pandas matplotlib mysql-client Pillow + +# 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 + +# doxgygen +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 +pip3 install networkx +apt-get install mdbtools -y From 67723533c9b5066ddb5dabd2470d67be882f1c72 Mon Sep 17 00:00:00 2001 From: "David P. Chassin" Date: Mon, 27 Sep 2021 13:48:49 -0700 Subject: [PATCH 10/28] Update setup-Linux-ubuntu-20.sh --- build-aux/setup-Linux-ubuntu-20.sh | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/build-aux/setup-Linux-ubuntu-20.sh b/build-aux/setup-Linux-ubuntu-20.sh index 52828f766..39b91aabc 100644 --- a/build-aux/setup-Linux-ubuntu-20.sh +++ b/build-aux/setup-Linux-ubuntu-20.sh @@ -6,13 +6,21 @@ apt-get -q update apt-get -q install tzdata -y # install python 3.9 -apt-get -q install python3.9 -y -update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.9 1 -apt-get -q install python3.9-dev -y -apt-get -q install python3-pip -y -echo '#/bin/bash -/usr/bin/python3-config $*' > /usr/local/bin/python3-config -chmod +x /usr/local/bin/python3-config +if [ ! -x /usr/local/bin/python3 -o $(/usr/local/bin/python3 --version | cut -f-2 -d.) != "Python 3.9" ]; then + apt-get install libssl-dev bzip2-dev libffi-dev lzma-dev -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 + /usr/local/bin/python3 pip -m install mysql-connector matplotlib numpy pandas Pillow +fi # install python libraries by validation pip3 -q install --upgrade pip From 12a56eeb918d10768389519cc95c8501279630b3 Mon Sep 17 00:00:00 2001 From: "David P. Chassin" Date: Mon, 27 Sep 2021 14:34:40 -0700 Subject: [PATCH 11/28] Update setup-Linux-ubuntu-20.sh --- build-aux/setup-Linux-ubuntu-20.sh | 43 +++++++++++++++--------------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/build-aux/setup-Linux-ubuntu-20.sh b/build-aux/setup-Linux-ubuntu-20.sh index 39b91aabc..6657997a7 100644 --- a/build-aux/setup-Linux-ubuntu-20.sh +++ b/build-aux/setup-Linux-ubuntu-20.sh @@ -5,9 +5,25 @@ 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 - apt-get install libssl-dev bzip2-dev libffi-dev lzma-dev -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 @@ -18,28 +34,13 @@ if [ ! -x /usr/local/bin/python3 -o $(/usr/local/bin/python3 --version | cut -f- 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 - /usr/local/bin/python3 pip -m install mysql-connector matplotlib numpy pandas Pillow fi # install python libraries by validation -pip3 -q install --upgrade pip -pip -q install pandas matplotlib mysql-client Pillow - -# 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 +/usr/local/bin/python3 pip -m install --upgrade pip +/usr/local/bin/python3 pip -m install mysql-connector mysql-client matplotlib numpy pandas Pillow -# doxgygen +# doxggen apt-get -q install gawk -y if [ ! -x /usr/bin/doxygen ]; then if [ ! -d /usr/local/src/doxygen ]; then @@ -77,5 +78,5 @@ mono /usr/local/natural_docs/NaturalDocs.exe \$*' > /usr/local/bin/natural_docs fi # converter support -pip3 install networkx -apt-get install mdbtools -y +/usr/local/bin/python3 pip -m install networkx +apt-get -q install mdbtools -y From 526d21595bab574ad154e6b4f36e39c45d8d289e Mon Sep 17 00:00:00 2001 From: "David P. Chassin" Date: Mon, 27 Sep 2021 15:32:35 -0700 Subject: [PATCH 12/28] Update setup-Darwin-20.sh --- build-aux/setup-Darwin-20.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 build-aux/setup-Darwin-20.sh diff --git a/build-aux/setup-Darwin-20.sh b/build-aux/setup-Darwin-20.sh old mode 100644 new mode 100755 From a4f4db912b17e5b6e642f6fc903c717bc13b4d92 Mon Sep 17 00:00:00 2001 From: "David P. Chassin" Date: Mon, 27 Sep 2021 15:32:37 -0700 Subject: [PATCH 13/28] Update setup-Linux-ubuntu-20.sh --- build-aux/setup-Linux-ubuntu-20.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 build-aux/setup-Linux-ubuntu-20.sh diff --git a/build-aux/setup-Linux-ubuntu-20.sh b/build-aux/setup-Linux-ubuntu-20.sh old mode 100644 new mode 100755 From 6cb980a453eabeead7048b0e9f9d71fe1c6895a2 Mon Sep 17 00:00:00 2001 From: "David P. Chassin" Date: Mon, 27 Sep 2021 15:39:15 -0700 Subject: [PATCH 14/28] Update version.sh --- build-aux/version.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build-aux/version.sh b/build-aux/version.sh index f6663a992..b90d1355d 100755 --- a/build-aux/version.sh +++ b/build-aux/version.sh @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash # This file is used by autoconf to generate the version string. # It is assumed that this script is run from the top-level srcdir. EXE=$0 From b2eca6eb3a0d2a43ac3291a0a0b81cfb2d7b6934 Mon Sep 17 00:00:00 2001 From: "David P. Chassin" Date: Mon, 27 Sep 2021 16:24:12 -0700 Subject: [PATCH 15/28] Update setup-Linux-amzn-2.sh --- build-aux/setup-Linux-amzn-2.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/build-aux/setup-Linux-amzn-2.sh b/build-aux/setup-Linux-amzn-2.sh index 6bea8b315..b70b4b1ac 100755 --- a/build-aux/setup-Linux-amzn-2.sh +++ b/build-aux/setup-Linux-amzn-2.sh @@ -19,8 +19,8 @@ yum -q install libcurl-devel -y 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.0/Python-3.9.0.tgz | tar xz - cd Python-3.9.0 + 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 @@ -29,7 +29,8 @@ if [ ! -x /usr/local/bin/python3 -o $(/usr/local/bin/python3 --version | cut -f- 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 - /usr/local/bin/python3 pip -m install mysql-connector matplotlib numpy pandas Pillow + 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 @@ -52,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 From 3828c48ee288b72c436262f3d019d3acb1b8739a Mon Sep 17 00:00:00 2001 From: "David P. Chassin" Date: Mon, 27 Sep 2021 16:24:14 -0700 Subject: [PATCH 16/28] Update setup-Linux-ubuntu-20.sh --- build-aux/setup-Linux-ubuntu-20.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/build-aux/setup-Linux-ubuntu-20.sh b/build-aux/setup-Linux-ubuntu-20.sh index 6657997a7..bc22c8aeb 100755 --- a/build-aux/setup-Linux-ubuntu-20.sh +++ b/build-aux/setup-Linux-ubuntu-20.sh @@ -34,6 +34,7 @@ if [ ! -x /usr/local/bin/python3 -o $(/usr/local/bin/python3 --version | cut -f- 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 From 583922a414b9dfae4ff620a06263026bed9674a7 Mon Sep 17 00:00:00 2001 From: "David P. Chassin" Date: Wed, 3 Nov 2021 16:45:33 -0700 Subject: [PATCH 17/28] Update solver_py.cpp --- module/powerflow/solver_py.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/module/powerflow/solver_py.cpp b/module/powerflow/solver_py.cpp index e6e921ac1..2a8a2a1d6 100644 --- a/module/powerflow/solver_py.cpp +++ b/module/powerflow/solver_py.cpp @@ -960,6 +960,13 @@ void sync_busdata_raw(PyObject *pModel,unsigned int &bus_count,BUSDATA *&bus,e_d 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 ) From 3f11c5484a7ddb3c6e913c1119d61440a937f5c5 Mon Sep 17 00:00:00 2001 From: "David P. Chassin" Date: Fri, 5 Nov 2021 09:01:50 -0700 Subject: [PATCH 18/28] Update test_IEEE_13_MLE.glm --- .../powerflow/autotest/test_IEEE_13_MLE.glm | 55 ++++++++++--------- 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/module/powerflow/autotest/test_IEEE_13_MLE.glm b/module/powerflow/autotest/test_IEEE_13_MLE.glm index 48ec54699..be13e2708 100644 --- a/module/powerflow/autotest/test_IEEE_13_MLE.glm +++ b/module/powerflow/autotest/test_IEEE_13_MLE.glm @@ -2,6 +2,7 @@ // Copyright (C) 2011 Battelle Memorial Institute #set iteration_limit=100 +#define MAX_VERR=6 clock { timezone EST+5EDT; @@ -317,15 +318,15 @@ object node { //633 { object complex_assert { target voltage_A; value 2445.01-2.56d; - within 5; + within ${MAX_VERR:-5}; }; object complex_assert { target voltage_B; value 2498.09-121.77d; - within 5; + within ${MAX_VERR:-5}; }; object complex_assert { target voltage_C; value 2437.32+117.82d; - within 5; + within ${MAX_VERR:-5}; }; } @@ -348,15 +349,15 @@ object node { //632 { object complex_assert { target voltage_A; value 2452.21-2.49d; - within 5; + within ${MAX_VERR:-5}; }; object complex_assert { target voltage_B; value 2502.56-121.72d; - within 5; + within ${MAX_VERR:-5}; }; object complex_assert { target voltage_C; value 2443.56+117.83d; - within 5; + within ${MAX_VERR:-5}; }; } @@ -371,15 +372,15 @@ object node { //650 { object complex_assert { target voltage_A; value 2401.7771; - within 5; + within ${MAX_VERR:-5}; }; object complex_assert { target voltage_B; value 2401.7771-120.0d; - within 5; + within ${MAX_VERR:-5}; }; object complex_assert { target voltage_C; value 2401.7771+120.0d; - within 5; + within ${MAX_VERR:-5}; }; object recorder { property "voltage_A,voltage_B,voltage_C"; @@ -398,12 +399,12 @@ object node { //680 { object complex_assert { target voltage_A; value 2377.75-5.3d; - within 5; + within ${MAX_VERR:-5}; }; object complex_assert { target voltage_B; value 2528.82-122.34dd; - within 5; + within ${MAX_VERR:-5}; }; object complex_assert { target voltage_C; @@ -423,12 +424,12 @@ object node { //684 { object complex_assert { target voltage_A; value 2373.65-5.32d; - within 5; + within ${MAX_VERR:-5}; }; object complex_assert { target voltage_C; value 2343.65+115.78d; - within 5; + within ${MAX_VERR:-5}; }; } @@ -448,17 +449,17 @@ object load { //634 { nominal_voltage 480.000; object complex_assert { target voltage_A; - within 5; + within ${MAX_VERR:-5}; value 275-3.23d; }; object complex_assert { target voltage_B; - within 5; + within ${MAX_VERR:-5}; value 283.16-122.22d; }; object complex_assert { target voltage_C; - within 5; + within ${MAX_VERR:-5}; value 276.02+117.34d; }; } @@ -473,12 +474,12 @@ object load { //645 { nominal_voltage 2401.7771; object complex_assert { target voltage_B; - within 5; + within ${MAX_VERR:-5}; value 2480.798-121.90d; }; object complex_assert { target voltage_C; - within 5; + within ${MAX_VERR:-5}; value 2439.00+117.86d; }; } @@ -492,12 +493,12 @@ object load { //646 { nominal_voltage 2401.7771; object complex_assert { target voltage_B; - within 5; + within ${MAX_VERR:-5}; value 2476.47-121.98d; }; object complex_assert { target voltage_C; - within 5; + within ${MAX_VERR:-5}; value 2433.96+117.90d; }; } @@ -513,7 +514,7 @@ object load { //652 { nominal_voltage 2401.7771; object complex_assert { target voltage_A; - within 5; + within ${MAX_VERR:-5}; value 2359.74-5.25d; }; } @@ -530,12 +531,12 @@ object load { //671 { nominal_voltage 2401.7771; object complex_assert { target voltage_A; - within 5; + within ${MAX_VERR:-5}; value 2377.76-5.3d; }; object complex_assert { target voltage_B; - within 5; + within ${MAX_VERR:-5}; value 2526.67-122.34d; }; object complex_assert { @@ -560,12 +561,12 @@ object load { //675 { nominal_voltage 2401.7771; object complex_assert { target voltage_A; - within 5; + within ${MAX_VERR:-5}; value 2362.15-5.56d; }; object complex_assert { target voltage_B; - within 5; + within ${MAX_VERR:-5}; value 2534.59-122.52d; }; object complex_assert { @@ -587,12 +588,12 @@ object load { //692 { nominal_voltage 2401.7771; object complex_assert { target voltage_A; - within 5; + within ${MAX_VERR:-5}; value 2377.76-5.31d; }; object complex_assert { target voltage_B; - within 5; + within ${MAX_VERR:-5}; value 2526.67-122.34d; }; object complex_assert { From ebe5f38f0484797eabfa8850904e5492e4d759f7 Mon Sep 17 00:00:00 2001 From: "David P. Chassin" Date: Wed, 24 Nov 2021 10:52:14 -0800 Subject: [PATCH 19/28] Update solver_py.cpp --- module/powerflow/solver_py.cpp | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/module/powerflow/solver_py.cpp b/module/powerflow/solver_py.cpp index fa5ff1805..a2bcff152 100644 --- a/module/powerflow/solver_py.cpp +++ b/module/powerflow/solver_py.cpp @@ -919,7 +919,7 @@ void sync_busdata_raw(PyObject *pModel,unsigned int &bus_count,BUSDATA *&bus,e_d "SAr","SAi","SBr","SBi","SCr","SCi", "YAr","YAi","YBr","YBi","YCr","YCi", "IAr","IAi","IBr","IBi","ICr","ICi", - "VAr","VAi","VBr","VBi","VCr","VCi", + "VAm","VAa","VBm","VBa","VCm","VCa", }; size_t ntags = sizeof(tags)/sizeof(tags[0]); PyObject *taglist = PyList_New(ntags); @@ -961,24 +961,28 @@ void sync_busdata_raw(PyObject *pModel,unsigned int &bus_count,BUSDATA *&bus,e_d 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); + SET_BUS(n,18,bus[n].V[0].Mag()); + SET_BUS(n,19,bus[n].V[0].Ang()); + SET_BUS(n,20,bus[n].V[1].Mag()); + SET_BUS(n,21,bus[n].V[1].Ang()); + SET_BUS(n,22,bus[n].V[2].Mag()); + SET_BUS(n,23,bus[n].V[2].Ang()); } } 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); + double mag, ang; + GET_BUS(n,18,mag); + GET_BUS(n,19,ang); + bus[n].V[0].SetPolar(mag,ang); + GET_BUS(n,20,mag); + GET_BUS(n,21,ang); + bus[n].V[1].SetPolar(mag,ang); + GET_BUS(n,22,mag); + GET_BUS(n,23,ang); + bus[n].V[2].SetPolar(mag,ang); } } } @@ -1483,7 +1487,6 @@ PyObject *sync_solution( } } - void solver_python_learn ( unsigned int bus_count, BUSDATA *bus, From ca22f9cbab232211a8f0861e42a038d484832762 Mon Sep 17 00:00:00 2001 From: "David P. Chassin" Date: Wed, 24 Nov 2021 11:47:00 -0800 Subject: [PATCH 20/28] Update solver_py.cpp --- module/powerflow/solver_py.cpp | 33 ++++++++++----------------------- 1 file changed, 10 insertions(+), 23 deletions(-) diff --git a/module/powerflow/solver_py.cpp b/module/powerflow/solver_py.cpp index a2bcff152..bdf7bc8a4 100644 --- a/module/powerflow/solver_py.cpp +++ b/module/powerflow/solver_py.cpp @@ -487,6 +487,10 @@ int solver_python_init(void) pKwargs = PyDict_New(); } PyDict_SetItemString(pModel,"options",pKwargs); + if ( pSolution == NULL ) + { + pSolution = PyDict_Copy(pModel); + } } if ( ! python_mle_data_only ) { @@ -502,10 +506,6 @@ int solver_python_init(void) { init_learndata(); } - if ( pSolution == NULL ) - { - pSolution = PyDict_Copy(pModel); - } } return 0; } @@ -1466,25 +1466,12 @@ PyObject *sync_solution( bool *bad_computations, int64 iterations) { - 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; - } + 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; } void solver_python_learn ( From d67d609a13a3e05ba9c8c0910da53ad4c5e1cdb2 Mon Sep 17 00:00:00 2001 From: "David P. Chassin" Date: Wed, 24 Nov 2021 12:10:00 -0800 Subject: [PATCH 21/28] Update solver_nr.cpp --- module/powerflow/solver_nr.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/module/powerflow/solver_nr.cpp b/module/powerflow/solver_nr.cpp index 7e7f6465a..da3657007 100644 --- a/module/powerflow/solver_nr.cpp +++ b/module/powerflow/solver_nr.cpp @@ -5034,6 +5034,7 @@ int64 solver_nr(unsigned int bus_count, } //Default else - it was a failure, just keep going } + Iteration = return_value_for_solver_NR; //Deflag the "island locker" NR_solver_working = false; From 5beb96b57e76d84bbe8b0313680c8219c8bd5afa Mon Sep 17 00:00:00 2001 From: "David P. Chassin" Date: Thu, 20 Jan 2022 11:41:19 -0800 Subject: [PATCH 22/28] Update solver_py.cpp --- module/powerflow/solver_py.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/module/powerflow/solver_py.cpp b/module/powerflow/solver_py.cpp index bdf7bc8a4..dd98971df 100644 --- a/module/powerflow/solver_py.cpp +++ b/module/powerflow/solver_py.cpp @@ -962,11 +962,11 @@ void sync_busdata_raw(PyObject *pModel,unsigned int &bus_count,BUSDATA *&bus,e_d SET_BUS(n,17,bus[n].I[2].i); SET_BUS(n,18,bus[n].V[0].Mag()); - SET_BUS(n,19,bus[n].V[0].Ang()); + SET_BUS(n,19,bus[n].V[0].Arg()); SET_BUS(n,20,bus[n].V[1].Mag()); - SET_BUS(n,21,bus[n].V[1].Ang()); + SET_BUS(n,21,bus[n].V[1].Arg()); SET_BUS(n,22,bus[n].V[2].Mag()); - SET_BUS(n,23,bus[n].V[2].Ang()); + SET_BUS(n,23,bus[n].V[2].Arg()); } } else if ( dir == ED_IN ) From 83d8f7ad44be38788fb966fa0558f8c381611249 Mon Sep 17 00:00:00 2001 From: "David P. Chassin" Date: Mon, 24 Jan 2022 14:16:19 -0800 Subject: [PATCH 23/28] Fix python solver copyback NR initialization error --- module/powerflow/solver_nr.cpp | 3 ++- module/powerflow/solver_py.cpp | 9 ++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/module/powerflow/solver_nr.cpp b/module/powerflow/solver_nr.cpp index da3657007..2bf651ca7 100644 --- a/module/powerflow/solver_nr.cpp +++ b/module/powerflow/solver_nr.cpp @@ -342,10 +342,11 @@ int64 solver_nr(unsigned int bus_count, if ( solver_python_init() == 0 ) { Iteration = solver_python_solve(bus_count,bus,branch_count,branch,powerflow_values,powerflow_type,mesh_imped_vals,bad_computations,Iteration); - if ( Iteration >= 0 ) + if ( Iteration == 0 ) { return Iteration; } + // else <0 proceed with NR solver } } catch (const char *msg) diff --git a/module/powerflow/solver_py.cpp b/module/powerflow/solver_py.cpp index dd98971df..b128cc6e2 100644 --- a/module/powerflow/solver_py.cpp +++ b/module/powerflow/solver_py.cpp @@ -1165,6 +1165,13 @@ unsigned long long get_linkhash(unsigned int branch_count, BRANCHDATA *&branch, return hashcode; } +// Run python solver +// +// Returns: +// -1 call NR and initialize with guess +// 0 use guess and proceed without running NR +// <-1 error encountered, run NR and don't use the guess +// int solver_python_solve ( unsigned int &bus_count, BUSDATA *&bus, @@ -1192,7 +1199,7 @@ int solver_python_solve ( else if ( pResult && PyLong_Check(pResult) ) { result = PyLong_AsLong(pResult); - if ( result >= 0 ) + if ( result == -1 || result == 0 ) // -1 means no solution but guess is ok, 0 means solution is ok { sync_model(bus_count,bus,branch_count,branch,ED_IN); } From e3e56078c532d59dd63d6d2e0b5eeed21f4f808a Mon Sep 17 00:00:00 2001 From: "David P. Chassin" Date: Thu, 3 Feb 2022 09:55:58 -0800 Subject: [PATCH 24/28] Update solver_nr.cpp --- module/powerflow/solver_nr.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/powerflow/solver_nr.cpp b/module/powerflow/solver_nr.cpp index b8685d84e..5e00f961b 100644 --- a/module/powerflow/solver_nr.cpp +++ b/module/powerflow/solver_nr.cpp @@ -5028,7 +5028,7 @@ int64 solver_nr(unsigned int bus_count, } //Default else - it was a failure, just keep going } - Iteration = return_value_for_solver_NR; + Iteration = return_value_for_solver_NR+1; //Deflag the "island locker" NR_solver_working = false; From 8ab6b59cbb397863fd49a278764f52f3a71d6a22 Mon Sep 17 00:00:00 2001 From: "David P. Chassin" Date: Thu, 3 Feb 2022 11:11:33 -0800 Subject: [PATCH 25/28] Update solver_nr.cpp --- module/powerflow/solver_nr.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/powerflow/solver_nr.cpp b/module/powerflow/solver_nr.cpp index 5e00f961b..b67562ec1 100644 --- a/module/powerflow/solver_nr.cpp +++ b/module/powerflow/solver_nr.cpp @@ -5065,7 +5065,7 @@ int64 solver_nr(unsigned int bus_count, double t = clock() - t_start; char buffer[64]; if ( gl_printtime(gl_globalclock,buffer,sizeof(buffer)-1) > 0 ) - fprintf(nr_profile, "%s,%.1f,%.1lld,%d,%d,%s\n", buffer, t, return_value_for_solver_NR == 0 ? 1 : return_value_for_solver_NR,bus_count,branch_count,bad_computations ? "false" : "true"); + fprintf(nr_profile, "%s,%.1f,%.1lld,%d,%d,%s\n", buffer, t, Iteration,bus_count,branch_count,bad_computations ? "false" : "true"); } //Return the maximum iteration count From db236047cebdf25ed345e4dc6dde23fc83729c23 Mon Sep 17 00:00:00 2001 From: "David P. Chassin" Date: Thu, 3 Feb 2022 14:38:35 -0800 Subject: [PATCH 26/28] Fix NR profiler formatting --- gldcore/cmdarg.cpp | 12 ++++++++---- module/powerflow/init.cpp | 2 ++ module/powerflow/solver_nr.cpp | 31 +++++++++++++++++++++++++------ 3 files changed, 35 insertions(+), 10 deletions(-) diff --git a/gldcore/cmdarg.cpp b/gldcore/cmdarg.cpp index 15de71615..6c0828c77 100644 --- a/gldcore/cmdarg.cpp +++ b/gldcore/cmdarg.cpp @@ -378,15 +378,15 @@ int GldCmdarg::profile(int argc, const char *argv[]) const char *opt = strchr(argv[0],'='); if ( opt++ != NULL ) { - if ( strcmp(opt,"text") == 0 ) + if ( stricmp(opt,"text") == 0 || stricmp(opt,"txt") == 0 ) { global_profile_output_format = POF_TEXT; } - else if ( strcmp(opt,"csv") == 0 ) + else if ( stricmp(opt,"csv") == 0 ) { global_profile_output_format = POF_CSV; } - else if ( strcmp(opt,"json") == 0 ) + else if ( stricmp(opt,"json") == 0 ) { global_profile_output_format = POF_JSON; } @@ -395,8 +395,12 @@ int GldCmdarg::profile(int argc, const char *argv[]) output_error("profiler option '%s' is not valid",opt); return CMDERR; } + global_profiler = TRUE; + } + else + { + global_profiler = !global_profiler; } - global_profiler = !global_profiler; return 0; } diff --git a/module/powerflow/init.cpp b/module/powerflow/init.cpp index a4206ac20..106305ac6 100644 --- a/module/powerflow/init.cpp +++ b/module/powerflow/init.cpp @@ -74,6 +74,8 @@ EXPORT CLASS *init(CALLBACKS *fntable, MODULE *module, int argc, char *argv[]) gl_global_create("powerflow::solver_profile_headers_included", PT_bool, &solver_profile_headers_included,PT_DESCRIPTION, "Flag to include headers in NR solver profile file",NULL); extern char1024 solver_headers; gl_global_create("powerflow::solver_headers", PT_char1024, &solver_headers,PT_DESCRIPTION, "Headers in NR solver profile file",NULL); + extern bool solver_profile_csv; + gl_global_create("powerflow::solver_profile_csv", PT_bool, &solver_profile_csv,PT_DESCRIPTION, "Flag output solver profile in CSV format",NULL); extern char1024 solver_py_config; gl_global_create("powerflow::solver_py_config", PT_char1024, &solver_py_config, PT_DESCRIPTION, "PY solver configuration file location",NULL); diff --git a/module/powerflow/solver_nr.cpp b/module/powerflow/solver_nr.cpp index b67562ec1..2cfa6f363 100644 --- a/module/powerflow/solver_nr.cpp +++ b/module/powerflow/solver_nr.cpp @@ -52,12 +52,13 @@ using namespace std; #include #include -char1024 solver_profile_filename = "solver_nr_profile.csv"; -char1024 solver_headers = "timestamp,duration[microsec],iteration,bus_count,branch_count,error"; +char1024 solver_profile_filename = "solver_nr_profile.txt"; static FILE * nr_profile = NULL; +const char *solver_headers = "timestamp,duration[microsec],iteration,bus_count,branch_count,error"; bool solver_profile_headers_included = true; bool solver_profile_enable = false; bool solver_dump_enable = false; +bool solver_profile_csv = false; //SuperLU variable structure //These are the working variables, but structured for island implementation @@ -71,8 +72,8 @@ typedef struct { //Initialize the sparse notation void sparse_init(SPARSE* sm, int nels, int ncols) { - if (solver_profile_enable) - { + if ( solver_profile_enable ) + { nr_profile = fopen(solver_profile_filename,"w"); if ( nr_profile == NULL ) { @@ -83,7 +84,16 @@ void sparse_init(SPARSE* sm, int nels, int ncols) } else if ( solver_profile_headers_included ) { - fprintf(nr_profile,"%s\n",(const char*)solver_headers); + if ( solver_profile_csv ) + { + + fprintf(nr_profile,"%s\n",solver_headers); + } + else + { + fprintf(nr_profile,"timestamp duration[microsec] iteration bus_count branch_count error\n"); + fprintf(nr_profile,"----------------------- ------------------ --------- --------- ------------ -----\n"); + } } } int indexval; @@ -5065,7 +5075,16 @@ int64 solver_nr(unsigned int bus_count, double t = clock() - t_start; char buffer[64]; if ( gl_printtime(gl_globalclock,buffer,sizeof(buffer)-1) > 0 ) - fprintf(nr_profile, "%s,%.1f,%.1lld,%d,%d,%s\n", buffer, t, Iteration,bus_count,branch_count,bad_computations ? "false" : "true"); + { + if ( solver_profile_csv ) + { + fprintf(nr_profile, "%s,%.1f,%.1lld,%d,%d,%d\n", buffer, t, Iteration,bus_count,branch_count,bad_computations ? 0 : 1); + } + else + { + fprintf(nr_profile, "%s %18.1f %9lld %9d %12d %s\n", buffer, t, Iteration,bus_count,branch_count,bad_computations ? "no" : "yes"); + } + } } //Return the maximum iteration count From 8445afe54e11b9e4ce84e13e913929ab570ee363 Mon Sep 17 00:00:00 2001 From: "David P. Chassin" Date: Fri, 6 May 2022 12:58:25 -0700 Subject: [PATCH 27/28] Create Solver_profile_csv.md --- .../Powerflow/Global/Solver_profile_csv.md | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 docs/Module/Powerflow/Global/Solver_profile_csv.md diff --git a/docs/Module/Powerflow/Global/Solver_profile_csv.md b/docs/Module/Powerflow/Global/Solver_profile_csv.md new file mode 100644 index 000000000..7808fe2a9 --- /dev/null +++ b/docs/Module/Powerflow/Global/Solver_profile_csv.md @@ -0,0 +1,23 @@ +[[/Module/Powerflow/Global/Solver_profile_csv]] -- Enable CSV formatting of solver profile data + +# Synopsis + +Shell: + +~~~ +bash$ gridlabd -D|--define solver_profile_csv={TRUE,FALSE} +~~~ + +GLM: + +~~~ + #set solver_profile_csv={TRUE,FALSE} +~~~ + +# Description + +This global enables formatting of solver output as CSV. + +# See also + +* [[/Module/Powerflow]] From 7d1f680fd5371645ff2436f255bbe58e7b6d5f65 Mon Sep 17 00:00:00 2001 From: "David P. Chassin" Date: Tue, 10 May 2022 17:20:34 -0700 Subject: [PATCH 28/28] Update solver_nr.cpp --- module/powerflow/solver_nr.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/module/powerflow/solver_nr.cpp b/module/powerflow/solver_nr.cpp index 2cfa6f363..003e8f18d 100644 --- a/module/powerflow/solver_nr.cpp +++ b/module/powerflow/solver_nr.cpp @@ -54,7 +54,7 @@ using namespace std; char1024 solver_profile_filename = "solver_nr_profile.txt"; static FILE * nr_profile = NULL; -const char *solver_headers = "timestamp,duration[microsec],iteration,bus_count,branch_count,error"; +char1024 solver_headers = "timestamp,duration[microsec],iteration,bus_count,branch_count,error"; bool solver_profile_headers_included = true; bool solver_profile_enable = false; bool solver_dump_enable = false; @@ -87,7 +87,7 @@ void sparse_init(SPARSE* sm, int nels, int ncols) if ( solver_profile_csv ) { - fprintf(nr_profile,"%s\n",solver_headers); + fprintf(nr_profile,"%s\n",(const char*)solver_headers); } else {