diff --git a/src/applications/components/vs_matrix/vs_components.cpp b/src/applications/components/vs_matrix/vs_components.cpp index 6eb3c1815..2f485fe55 100755 --- a/src/applications/components/vs_matrix/vs_components.cpp +++ b/src/applications/components/vs_matrix/vs_components.cpp @@ -6,15 +6,10 @@ // ------------------------------------------------------------- /** * @file vs_components.cpp - * @author Bruce Palmer - * @date 2024-06-07 07:45:40 d3g293 + * @author Kelvin Tan + * @date 2024-07-23 01:00:00 d3g293 * - * @updated Shri Abhyankar - * Conversion of constant current, constant admittance values from raw file - * to constant power - * @date 2022-12-23 - - * @brief Methods used in power flow application + * @brief Methods used in power flow and voltage stability application * * */ @@ -1750,6 +1745,68 @@ void gridpack::voltage_stability::VSBus::scaleLoadPower(std::string tag, double } } +/** + * Increment load power based off specified value. + * Increment loads in specified area. + * @param transfer value to increment load real power + * @param area index of area for incrementing load + * @param zone index of zone for incrementing load + * @param total active power demand of the area + */ +void gridpack::voltage_stability::VSBus::IncrementLoadPower(std::string tag, double value, double ltotal) +{ + int i; + double p_lratio; + for (i=0; i &tag, std::vector &pg, std::vector &status) +{ + tag.clear(); + pg.clear(); + status.clear(); + int i; + for (i=0; i(getBus1().get()); + *vs = bus1->getVoltage(); + gridpack::voltage_stability::VSBus *bus2 = + dynamic_cast(getBus2().get()); + *vr = bus2->getVoltage(); + *p_theta = bus1->getPhase() - bus2->getPhase(); +} + +/** + * Return impedance magnitude of the line element + * @param tag describing line element on branch + * @return impedance magnitude + */ +double gridpack::voltage_stability::VSBranch::getImpedanceMagnitude( + std::string tag) // KT +{ + gridpack::voltage_stability::VSBus *bus1 = + dynamic_cast(getBus1().get()); + double zmag, ybusr, ybusi; + ybusr = p_ybusr_frwd; + ybusi = p_ybusi_frwd; + zmag = 1/(ybusr * ybusr + ybusi * ybusi); + return zmag; +} +/** + * Return fast voltage stability index (FVSI) for the line element + * @param tag describing line element on branch + * @return voltage stability index + */ +double gridpack::voltage_stability::VSBranch::getVoltageStabilityIndex( + std::string tag) +{ + double vr, vs, x, r, ybusr, ybusi, FVSI; + gridpack::ComplexType z, i, s; + s = getComplexPower(tag); + double p = real(s); + double q = imag(s); + i = ComplexType(0.0,1.0); + z = ComplexType(0.0,0.0); + ybusr = p_ybusr_frwd; + ybusi = p_ybusi_frwd; + z = 1.0/(ybusr + ybusi*i); + r = real(z); + x = imag(z); + getBranchVoltages(&vs, &vr, &p_theta); + auto zmag = getImpedanceMagnitude(tag); + FVSI = 4 * (zmag * q/p_sbase * x) / (vs * vs * (r*sin(p_theta) + x*cos(p_theta)) * (r*sin(p_theta) + x*cos(p_theta))); + if (FVSI < 0.0) FVSI = -1.0 * FVSI; + return FVSI; +} /** * Return complex power for line element @@ -2279,8 +2394,10 @@ bool gridpack::voltage_stability::VSBranch::serialWrite(char *string, const int std::vector tags = getLineTags(); int i; int ilen = 0; + double FVSI = 0.0; for (i=0; i &tag, + std::vector &pg, std::vector &status); + + /** + * Increment generators real power based off specified value. + * Increment generators in specified area. + * @param transfer value to increment generators real power + * @param area index of area for incrementing generation + * @param zone index of zone for incrementing generation + * @param total power generation of an area + */ + void IncrementGeneratorPower(std::string tag, double value, double gtotal); + + /** + * Increment load power based off specified value. + * Increment loads in specified area. + * @param transfer value to increment load real power + * @param area index of area for incrementing load + * @param zone index of zone for incrementing load + * @param total active power demand of the area + */ + void IncrementLoadPower(std::string tag, double value, double ltotal); + /** * Get available margin for generator * @param tag character ID for generator @@ -605,6 +634,25 @@ class VSBranch */ void getPQ(VSBus *bus, double *p, double *q); + /** + * Return the sending and receiving voltage of a branch + * @param vs: Sending bus voltage + * @param vr: Receiving bus voltage + * @param p_theta: Phase angle difference + */ + void getBranchVoltages(double *vs, double *vr, double *p_theta); + /** + * Return impedance magnitude for line element + * @param bus describing sending bus of the branch + * @return impedance magnitude + */ + double getImpedanceMagnitude(std::string tag); + /** + * Return fast voltage stability index (FVSI) for the line element + * @param tag describing line element on branch + * @return voltage stability index + */ + double getVoltageStabilityIndex(std::string tag); /** * Set the mode to control what matrices and vectors are built when using * the mapper diff --git a/src/applications/contingency_analysis/CMakeLists.txt b/src/applications/contingency_analysis/CMakeLists.txt index 1b5089fd5..e9e6a69e2 100644 --- a/src/applications/contingency_analysis/CMakeLists.txt +++ b/src/applications/contingency_analysis/CMakeLists.txt @@ -14,6 +14,8 @@ # ------------------------------------------------------------- set(target_libraries + gridpack_vsmatrix_components + gridpack_voltage_stability_module gridpack_powerflow_module gridpack_pfmatrix_components gridpack_ymatrix_components diff --git a/src/applications/development/wind_dsa/CMakeLists.txt b/src/applications/development/wind_dsa/CMakeLists.txt index 315e8c2d9..4e63d4e0e 100644 --- a/src/applications/development/wind_dsa/CMakeLists.txt +++ b/src/applications/development/wind_dsa/CMakeLists.txt @@ -17,6 +17,8 @@ set(target_libraries gridpack_dynamic_simulation_full_y_module gridpack_powerflow_module gridpack_pfmatrix_components + gridpack_vsmatrix_components + gridpack_voltage_stability_module gridpack_dsmatrix_components gridpack_ymatrix_components gridpack_components diff --git a/src/applications/dynamic_simulation_dae/CMakeLists.txt b/src/applications/dynamic_simulation_dae/CMakeLists.txt index b9537047e..1aaddccd1 100644 --- a/src/applications/dynamic_simulation_dae/CMakeLists.txt +++ b/src/applications/dynamic_simulation_dae/CMakeLists.txt @@ -17,6 +17,8 @@ set(target_libraries gridpack_dynamic_simulation_dae_module gridpack_powerflow_module gridpack_pfmatrix_components + gridpack_vsmatrix_components + gridpack_voltage_stability_module gridpack_ymatrix_components gridpack_components gridpack_partition diff --git a/src/applications/dynamic_simulation_full_y/CMakeLists.txt b/src/applications/dynamic_simulation_full_y/CMakeLists.txt index 4ea60b49f..16032b3f0 100644 --- a/src/applications/dynamic_simulation_full_y/CMakeLists.txt +++ b/src/applications/dynamic_simulation_full_y/CMakeLists.txt @@ -21,6 +21,8 @@ set(target_libraries gridpack_dynamic_simulation_full_y_module gridpack_powerflow_module gridpack_pfmatrix_components + gridpack_voltage_stability_module + gridpack_vsmatrix_components gridpack_dsmatrix_components gridpack_ymatrix_components gridpack_components diff --git a/src/applications/examples/contingency_analysis/CMakeLists.txt b/src/applications/examples/contingency_analysis/CMakeLists.txt index 82768fa02..5f43cf983 100644 --- a/src/applications/examples/contingency_analysis/CMakeLists.txt +++ b/src/applications/examples/contingency_analysis/CMakeLists.txt @@ -16,6 +16,8 @@ set(target_libraries gridpack_powerflow_module gridpack_pfmatrix_components + gridpack_vsmatrix_components + gridpack_voltage_stability_module gridpack_ymatrix_components gridpack_components gridpack_stream diff --git a/src/applications/examples/powerflow/CMakeLists.txt b/src/applications/examples/powerflow/CMakeLists.txt index f57989fb3..9f27bfb4d 100644 --- a/src/applications/examples/powerflow/CMakeLists.txt +++ b/src/applications/examples/powerflow/CMakeLists.txt @@ -15,6 +15,8 @@ set(target_libraries gridpack_pfmatrix_components + gridpack_vsmatrix_components + gridpack_voltage_stability_module gridpack_ymatrix_components gridpack_components gridpack_stream diff --git a/src/applications/hadrec/CMakeLists.txt b/src/applications/hadrec/CMakeLists.txt index 26fe7732c..37be33ba8 100644 --- a/src/applications/hadrec/CMakeLists.txt +++ b/src/applications/hadrec/CMakeLists.txt @@ -14,10 +14,12 @@ # ------------------------------------------------------------- set(target_libraries - gridpack_hadrec_module gridpack_dynamic_simulation_full_y_module gridpack_powerflow_module gridpack_pfmatrix_components + gridpack_voltage_stability_module + gridpack_vsmatrix_components + gridpack_hadrec_module gridpack_ymatrix_components gridpack_components gridpack_stream diff --git a/src/applications/kalman_ds/CMakeLists.txt b/src/applications/kalman_ds/CMakeLists.txt index 19049794f..148a4068c 100644 --- a/src/applications/kalman_ds/CMakeLists.txt +++ b/src/applications/kalman_ds/CMakeLists.txt @@ -18,6 +18,8 @@ set(target_libraries gridpack_powerflow_module gridpack_kdsmatrix_components gridpack_pfmatrix_components + gridpack_vsmatrix_components + gridpack_voltage_stability_module gridpack_dsmatrix_components gridpack_ymatrix_components gridpack_components diff --git a/src/applications/modules/hadrec/CMakeLists.txt b/src/applications/modules/hadrec/CMakeLists.txt index 7fff5d8ef..e6439c470 100644 --- a/src/applications/modules/hadrec/CMakeLists.txt +++ b/src/applications/modules/hadrec/CMakeLists.txt @@ -23,6 +23,8 @@ set(target_libraries gridpack_configuration gridpack_timer gridpack_pfmatrix_components + gridpack_vsmatrix_components + gridpack_voltage_stability_module gridpack_ymatrix_components gridpack_dynamic_simulation_full_y_module gridpack_powerflow_module diff --git a/src/applications/modules/powerflow/CMakeLists.txt b/src/applications/modules/powerflow/CMakeLists.txt index 4b20e34ad..b8cbbf8d2 100644 --- a/src/applications/modules/powerflow/CMakeLists.txt +++ b/src/applications/modules/powerflow/CMakeLists.txt @@ -22,6 +22,8 @@ set(target_libraries gridpack_math gridpack_configuration gridpack_timer + gridpack_vsmatrix_components + gridpack_voltage_stability_module gridpack_pfmatrix_components gridpack_ymatrix_components ${PARMETIS_LIBRARY} ${METIS_LIBRARY} @@ -39,13 +41,13 @@ add_library(gridpack_powerflow_module pf_app_module.cpp pf_factory_module.cpp ) - gridpack_set_library_version(gridpack_powerflow_module) target_link_libraries(gridpack_powerflow_module gridpack_pfmatrix_components gridpack_partition gridpack_stream + ${target_libraries} ) diff --git a/src/applications/modules/powerflow/pf_app_module.cpp b/src/applications/modules/powerflow/pf_app_module.cpp index be03a6117..450134a54 100644 --- a/src/applications/modules/powerflow/pf_app_module.cpp +++ b/src/applications/modules/powerflow/pf_app_module.cpp @@ -15,6 +15,7 @@ */ // ------------------------------------------------------------- +#include "gridpack/applications/modules/voltage_stability/vs_app_module.hpp" #include "pf_app_module.hpp" #include "pf_factory_module.hpp" #include "gridpack/mapper/full_map.hpp" @@ -40,6 +41,10 @@ gridpack::powerflow::PFAppModule::PFAppModule(void) { p_no_print = false; + current_increment = 0.0; + p_bPVAnlyDone = true; + sink_area = 0; + src_area = 0; } /** @@ -135,6 +140,11 @@ void gridpack::powerflow::PFAppModule::readNetwork( p_qlim = cursor->get("qlim",0); p_max_iteration = cursor->get("maxIteration",50); ComplexType tol; + //KT + max_increment = cursor->get("maxIncrement",0.0); + increment = cursor->get("TransferIncrement",0.0); + src_area = cursor->get("SourceArea",0); + sink_area = cursor->get("SinkArea",0); // Phase shift sign double phaseShiftSign = cursor->get("phaseShiftSign",1.0); @@ -1419,3 +1429,28 @@ bool gridpack::powerflow::PFAppModule::getDataCollectionBranchParam( { return p_getDataCollectionBranchParam(bus1, bus2, ckt, branchParam, value); } + +/* KT +*/ + +bool gridpack::powerflow::PFAppModule::isPVAnlyDone() +{ + //gridpack::utility::Configuration::CursorPtr cursor; + printf("Increment = %f, Max Increment = %f\n", increment, max_increment); + gridpack::parallel::Communicator world; + /* + boost::shared_ptr + pf_network(new gridpack::voltage_stability::VSNetwork(world)); + gridpack::voltage_stability::VSAppModule vs_app; + */ + + boost::shared_ptr + pf_network(new gridpack::voltage_stability::VSNetwork(world)); + + gridpack::voltage_stability::VSAppModule vs_app; + + //gridpack::voltage_stability::VSAppModule vs_app; + + + return vs_app.isPVAnlyDone(increment,max_increment); +} diff --git a/src/applications/modules/powerflow/pf_app_module.hpp b/src/applications/modules/powerflow/pf_app_module.hpp index 16cdd663c..e2d8036d0 100644 --- a/src/applications/modules/powerflow/pf_app_module.hpp +++ b/src/applications/modules/powerflow/pf_app_module.hpp @@ -25,6 +25,11 @@ #include "gridpack/parser/dictionary.hpp" #include "gridpack/utilities/string_utils.hpp" + +#include "gridpack/applications/modules/voltage_stability/vs_factory_module.hpp" +#include "gridpack/applications/modules/voltage_stability/vs_app_module.hpp" + + namespace gridpack { namespace powerflow { @@ -352,6 +357,9 @@ class PFAppModule * @param flag if true, suppress printing */ void suppressOutput(bool flag); + // KT + bool isPVAnlyDone(); + bool p_bPVAnlyDone; #ifdef USE_GOSS /** @@ -873,7 +881,18 @@ class PFAppModule // qlim enforce flag int p_qlim; + + + double max_increment, increment, current_increment; + int sink_area, src_area; + + + //boost::shared_ptr + // pf_network(new gridpack::voltage_stability::VSNetwork(world)); + //gridpack::voltage_stability::VSAppModule pf_app; + + boost::shared_ptr v_stability; // KT // pointer to bus IO module boost::shared_ptr > p_busIO; diff --git a/src/applications/modules/voltage_stability/vs_app_module.cpp b/src/applications/modules/voltage_stability/vs_app_module.cpp index 9462d1f45..de4d5f506 100644 --- a/src/applications/modules/voltage_stability/vs_app_module.cpp +++ b/src/applications/modules/voltage_stability/vs_app_module.cpp @@ -15,8 +15,10 @@ */ // ------------------------------------------------------------- +#include "gridpack/applications/modules/powerflow/pf_app_module.hpp" +#include "gridpack/applications/modules/voltage_stability/vs_factory_module.hpp" #include "vs_app_module.hpp" -#include "vs_factory_module.hpp" +//#include "vs_factory_module.hpp" #include "gridpack/mapper/full_map.hpp" #include "gridpack/mapper/bus_vector_map.hpp" #include "gridpack/parser/PTI23_parser.hpp" @@ -31,6 +33,8 @@ #include "gridpack/math/math.hpp" #include "vs_helper.hpp" #include "gridpack/utilities/string_utils.hpp" +#include +#include #define USE_REAL_VALUES @@ -39,7 +43,14 @@ */ gridpack::voltage_stability::VSAppModule::VSAppModule(void) { - p_no_print = false; + current_increment = 0.0; + p_bPVAnlyDone = true; + zone = 0; + sink_area = 0; + src_area = 0; + gt = 0.0; + lt = 0.0; + PV_header = false; } /** @@ -49,1049 +60,32 @@ gridpack::voltage_stability::VSAppModule::~VSAppModule(void) { } -enum Parser{PTI23, PTI33, PTI34, PTI35, MAT_POWER, GOSS}; - -/** - * Read in and partition the powerflow network. The input file is read - * directly from the Powerflow block in the configuration file so no - * external file names or parameters need to be passed to this routine - * @param network pointer to a VSNetwork object. This should not have any - * buses or branches defined on it. - * @param config point to open configuration file - * @param idx index of configuration to use if set to a non-negative value - */ -void gridpack::voltage_stability::VSAppModule::readNetwork( - boost::shared_ptr &network, - gridpack::utility::Configuration *config, int idx) -{ - p_network = network; - p_comm = network->communicator(); - p_config = config; - - // load input file - gridpack::utility::CoarseTimer *timer = - gridpack::utility::CoarseTimer::instance(); - int t_total = timer->createCategory("Powerflow: Total Application"); - timer->start(t_total); - - // read configuration file - config->enableLogging(&std::cout); - - gridpack::utility::Configuration::CursorPtr cursor; - cursor = config->getCursor("Configuration.Powerflow"); - if (cursor == NULL) { - printf("No Powerflow block detected in input deck\n"); - } - std::string filename; - int filetype = PTI23; - if (idx == -1) { - if (!cursor->get("networkConfiguration",&filename)) { - if (cursor->get("networkConfiguration_v33",&filename)) { - filetype = PTI33; - } else if (cursor->get("networkConfiguration_v34",&filename)) { - filetype = PTI34; - } else if (cursor->get("networkConfiguration_v35",&filename)) { - filetype = PTI35; - } else if (cursor->get("networkConfiguration_mat",&filename)) { - filetype = MAT_POWER; - } else if (cursor->get("networkConfiguration_GOSS",&filename)) { - filetype = GOSS; - } else { - printf("No network configuration file specified\n"); - return; - } - } - } else if (idx >= 0) { - gridpack::utility::Configuration::CursorPtr network_cursor; - network_cursor = config->getCursor( - "Configuration.Powerflow.networkFiles"); - gridpack::utility::Configuration::ChildCursors files; - if (network_cursor) network_cursor->children(files); - if (idx < files.size()) { - if (!files[idx]->get("networkConfiguration",&filename)) { - if (files[idx]->get("networkConfiguration_v33",&filename)) { - filetype = PTI33; - } else if (files[idx]->get("networkConfiguration_v34",&filename)) { - filetype = PTI34; - } else if (files[idx]->get("networkConfiguration_v35",&filename)) { - filetype = PTI35; - } else if (cursor->get("networkConfiguration_mat",&filename)) { - filetype = MAT_POWER; - } else { - printf("Unknown network configuration file specified\n"); - return; - } - } - } else { - printf("Unknown file index\n"); - return; - } - } else { - printf("No network configuration file specified\n"); - return; - } - // Convergence and iteration parameters - p_tolerance = cursor->get("tolerance",1.0e-6); - p_qlim = cursor->get("qlim",0); - p_max_iteration = cursor->get("maxIteration",50); - ComplexType tol; - // Phase shift sign - double phaseShiftSign = cursor->get("phaseShiftSign",1.0); - - int t_pti = timer->createCategory("Powerflow: Network Parser"); - timer->start(t_pti); - if (filetype == PTI23) { - gridpack::parser::PTI23_parser parser(network); -#ifdef USE_GOSS - char sbuf[256], sbuf2[256]; - sprintf(sbuf,"{ \"simulation_id\": \"%s\"}",simID.c_str()); - sprintf(sbuf2,"reply.%s.%s\n",filename.c_str(),p_simID.c_str()); - p_goss_client.publish(networkFile,sbuf,sbuf2); - std::vector fileVec = p_goss_client.subscribeFileAsVector(std::string(sbuf2)); - parser.parse(fileVec); -#else - try { - parser.parse(filename.c_str()); - } catch (const gridpack::Exception e) { - std::string w(e.what()); - if (!p_no_print) { - char ebuf[512]; - sprintf(ebuf,"p[%d] unable to open network file: %s with error: %s\n", - filename.c_str(),w.c_str()); - if (p_comm.rank() == 0) { - printf("%s",ebuf); - } - } - timer->stop(t_total); - } -#endif - if (phaseShiftSign == -1.0) { - parser.changePhaseShiftSign(); - } - } else if (filetype == PTI33) { - gridpack::parser::PTI33_parser parser(network); -#ifdef USE_GOSS - char sbuf[256], sbuf2[256]; - sprintf(sbuf,"{ \"simulation_id\": \"%s\"}",simID.c_str()); - sprintf(sbuf2,"reply.%s.%s\n",filename.c_str(),p_simID.c_str()); - p_goss_client.publish(networkFile,sbuf,sbuf2); - std::vector fileVec = p_goss_client.subscribeFileAsVector(std::string(sbuf2)); - parser.parse(fileVec); -#else - parser.parse(filename.c_str()); -#endif - if (phaseShiftSign == -1.0) { - parser.changePhaseShiftSign(); - } - } else if (filetype == PTI34) { - gridpack::parser::PTI34_parser parser(network); -#ifdef USE_GOSS - char sbuf[256], sbuf2[256]; - sprintf(sbuf,"{ \"simulation_id\": \"%s\"}",simID.c_str()); - sprintf(sbuf2,"reply.%s.%s\n",filename.c_str(),p_simID.c_str()); - p_goss_client.publish(networkFile,sbuf,sbuf2); - std::vector fileVec = p_goss_client.subscribeFileAsVector(std::string(sbuf2)); - parser.parse(fileVec); -#else - parser.parse(filename.c_str()); -#endif - if (phaseShiftSign == -1.0) { - parser.changePhaseShiftSign(); - } - } else if (filetype == PTI35) { - gridpack::parser::PTI35_parser parser(network); -#ifdef USE_GOSS - char sbuf[256], sbuf2[256]; - sprintf(sbuf,"{ \"simulation_id\": \"%s\"}",simID.c_str()); - sprintf(sbuf2,"reply.%s.%s\n",filename.c_str(),p_simID.c_str()); - p_goss_client.publish(networkFile,sbuf,sbuf2); - std::vector fileVec = p_goss_client.subscribeFileAsVector(std::string(sbuf2)); - parser.parse(fileVec); -#else - parser.parse(filename.c_str()); -#endif - if (phaseShiftSign == -1.0) { - parser.changePhaseShiftSign(); - } - } else if (filetype == MAT_POWER) { - gridpack::parser::MAT_parser parser(network); -#ifdef USE_GOSS - char sbuf[256], sbuf2[256]; - sprintf(sbuf,"{ \"simulation_id\": \"%s\"}",simID.c_str()); - sprintf(sbuf2,"reply.%s.%s\n",filename.c_str(),p_simID.c_str()); - p_goss_client.publish(networkFile,sbuf,sbuf2); - std::vector fileVec = p_goss_client.subscribeFileAsVector(std::string(sbuf2)); - parser.parse(fileVec); -#else - parser.parse(filename.c_str()); -#endif - } else if (filetype == GOSS) { - gridpack::parser::GOSS_parser parser(network); - parser.parse(filename.c_str()); - } - timer->stop(t_pti); - - // Create serial IO object to export data from buses - p_busIO.reset(new gridpack::serial_io::SerialBusIO(512,network)); - - // Create serial IO object to export data from branches - p_branchIO.reset(new gridpack::serial_io::SerialBranchIO(512,network)); - char ioBuf[128]; - - if (!p_no_print) { - sprintf(ioBuf,"\nMaximum number of iterations: %d\n",p_max_iteration); - p_busIO->header(ioBuf); - sprintf(ioBuf,"\nConvergence tolerance: %f\n",p_tolerance); - p_busIO->header(ioBuf); - } - - // partition network - int t_part = timer->createCategory("Powerflow: Partition"); - timer->start(t_part); - network->partition(); - timer->stop(t_part); - timer->stop(t_total); -} - -/** - * Set up exchange buffers and other internal parameters and initialize - * network components using data from data collection - */ -void gridpack::voltage_stability::VSAppModule::initialize() -{ - gridpack::utility::CoarseTimer *timer = - gridpack::utility::CoarseTimer::instance(); - int t_total = timer->createCategory("Powerflow: Total Application"); - timer->start(t_total); - - // create factory - p_factory.reset(new gridpack::voltage_stability::VSFactoryModule(p_network)); - int t_load = timer->createCategory("Powerflow: Factory Load"); - timer->start(t_load); - p_factory->load(); - // p_factory->dumpData(); - timer->stop(t_load); - - // set network components using factory - int t_setc = timer->createCategory("Powerflow: Factory Set Components"); - timer->start(t_setc); - p_factory->setComponents(); - timer->stop(t_setc); - - // Set up bus data exchange buffers. Need to decide what data needs to be - // exchanged - int t_setx = timer->createCategory("Powerflow: Factory Set Exchange"); - timer->start(t_setx); - p_factory->setExchange(); - timer->stop(t_setx); - - // Create bus data exchange - int t_updt = timer->createCategory("Powerflow: Bus Update"); - timer->start(t_updt); - p_network->initBusUpdate(); - timer->stop(t_updt); - timer->stop(t_total); -} - -/** - * Reinitialize calculation from data collections - */ -void gridpack::voltage_stability::VSAppModule::reload() -{ - gridpack::utility::CoarseTimer *timer = - gridpack::utility::CoarseTimer::instance(); - int t_load = timer->createCategory("Powerflow: Factory Load"); - timer->start(t_load); - p_factory->load(); - timer->stop(t_load); -} - -/** - * Execute the iterative solve portion of the application using a - * hand-coded Newton-Raphson solver - * @return false if an error was encountered in the solution - */ -bool gridpack::voltage_stability::VSAppModule::solve() -{ - bool ret = true; - gridpack::utility::CoarseTimer *timer = - gridpack::utility::CoarseTimer::instance(); - int t_total = timer->createCategory("Powerflow: Total Application"); - timer->start(t_total); - p_factory->clearViolations(); - gridpack::ComplexType tol = 2.0*p_tolerance; - int iter = 0; - bool repeat = true; - int int_repeat = 0; - while (repeat) { - iter = 0; - tol = 2.0*p_tolerance; - int_repeat ++; - char ioBuf[128]; - if (!p_no_print) { - sprintf (ioBuf," repeat time = %d \n", int_repeat); - p_busIO->header(ioBuf); - } - - // set YBus components so that you can create Y matrix - int t_fact = timer->createCategory("Powerflow: Factory Operations"); - timer->start(t_fact); - p_factory->setYBus(); - timer->stop(t_fact); - - int t_cmap = timer->createCategory("Powerflow: Create Mappers"); - timer->start(t_cmap); - p_factory->setMode(VS_YBus); - -#if 0 - gridpack::mapper::FullMatrixMap mMap(p_network); -#endif - timer->stop(t_cmap); - int t_mmap = timer->createCategory("Powerflow: Map to Matrix"); - timer->start(t_mmap); -#if 0 - gridpack::mapper::FullMatrixMap mMap(p_network); - boost::shared_ptr Y = mMap.mapToMatrix(); - p_busIO->header("\nY-matrix values\n"); - // Y->print(); - Y->save("Ybus.m"); -#endif - timer->stop(t_mmap); - - // make Sbus components to create S vector - timer->start(t_fact); - p_factory->setSBus(); - timer->stop(t_fact); - // p_busIO->header("\nIteration 0\n"); - - // Set PQ - timer->start(t_cmap); - p_factory->setMode(VS_RHS); - gridpack::mapper::BusVectorMap vMap(p_network); - timer->stop(t_cmap); - int t_vmap = timer->createCategory("Powerflow: Map to Vector"); - timer->start(t_vmap); - -#ifdef USE_REAL_VALUES - boost::shared_ptr PQ = vMap.mapToRealVector(); -#else - boost::shared_ptr PQ = vMap.mapToVector(); -#endif - timer->stop(t_vmap); - gridpack::ComplexType tol_org = PQ->normInfinity(); - if (!p_no_print) { - sprintf (ioBuf,"\n----------test Iteration 0, before VS solve, Tol: %12.6e \n", real(tol_org)); - p_busIO->header(ioBuf); - } - // PQ->print(); - timer->start(t_cmap); - p_factory->setMode(VS_Jacobian); - gridpack::mapper::FullMatrixMap jMap(p_network); - timer->stop(t_cmap); - timer->start(t_mmap); - -#ifdef USE_REAL_VALUES - boost::shared_ptr J = jMap.mapToRealMatrix(); -#else - boost::shared_ptr J = jMap.mapToMatrix(); -#endif - timer->stop(t_mmap); - // p_busIO->header("\nJacobian values\n"); - // J->print(); - - // Create X vector by cloning PQ -#ifdef USE_REAL_VALUES - boost::shared_ptr X(PQ->clone()); -#else - boost::shared_ptr X(PQ->clone()); -#endif - - gridpack::utility::Configuration::CursorPtr cursor; - cursor = p_config->getCursor("Configuration.Powerflow"); - // Create linear solver - int t_csolv = timer->createCategory("Powerflow: Create Linear Solver"); - timer->start(t_csolv); -#ifdef USE_REAL_VALUES - gridpack::math::RealLinearSolver solver(*J); -#else - gridpack::math::LinearSolver solver(*J); -#endif - solver.configure(cursor); - timer->stop(t_csolv); - - // First iteration - X->zero(); //might not need to do this - //p_busIO->header("\nCalling solver\n"); - int t_lsolv = timer->createCategory("Powerflow: Solve Linear Equation"); - timer->start(t_lsolv); - // char dbgfile[32]; - // sprintf(dbgfile,"j0.bin"); - // J->saveBinary(dbgfile); - // sprintf(dbgfile,"pq0.bin"); - // PQ->saveBinary(dbgfile); - try { - solver.solve(*PQ, *X); - } catch (const gridpack::Exception e) { - std::string w(e.what()); - if (!p_no_print) { - sprintf(ioBuf,"p[%d] hit exception: %s\n", - p_network->communicator().rank(), - w.c_str()); - p_busIO->header(ioBuf); - p_busIO->header("Solver failure\n\n"); - } - timer->stop(t_lsolv); - timer->stop(t_total); - - return false; - } - timer->stop(t_lsolv); - tol = PQ->normInfinity(); - // Create timer for map to bus - int t_bmap = timer->createCategory("Powerflow: Map to Bus"); - int t_updt = timer->createCategory("Powerflow: Bus Update"); - if (!p_no_print) { - sprintf(ioBuf,"\nIteration %d Tol: %12.6e\n",iter+1,real(tol)); - p_busIO->header(ioBuf); - } - - while (real(tol) > p_tolerance && iter < p_max_iteration) { - // Push current values in X vector back into network components - // Need to implement setValues method in VSBus class in order for this to - // work - timer->start(t_bmap); - p_factory->setMode(VS_RHS); - vMap.mapToBus(X); - timer->stop(t_bmap); - - // Exchange data between ghost buses (I don't think we need to exchange data - // between branches) - timer->start(t_updt); - // p_factory->checkQlimViolations(); - p_network->updateBuses(); - timer->stop(t_updt); - - // Create new versions of Jacobian and PQ vector - timer->start(t_vmap); -#ifdef USE_REAL_VALUES - vMap.mapToRealVector(PQ); -#else - vMap.mapToVector(PQ); -#endif - // p_busIO->header("\nnew PQ vector at iter %d\n",iter); - // PQ->print(); - timer->stop(t_vmap); - timer->start(t_mmap); - p_factory->setMode(VS_Jacobian); -#ifdef USE_REAL_VALUES - jMap.mapToRealMatrix(J); -#else - jMap.mapToMatrix(J); -#endif - timer->stop(t_mmap); - - // Create linear solver - timer->start(t_lsolv); - X->zero(); //might not need to do this - // sprintf(dbgfile,"j%d.bin",iter+1); - // J->saveBinary(dbgfile); - // sprintf(dbgfile,"pq%d.bin",iter+1); - // PQ->saveBinary(dbgfile); - try { - solver.solve(*PQ, *X); - } catch (const gridpack::Exception e) { - std::string w(e.what()); - if (!p_no_print) { - sprintf(ioBuf,"p[%d] hit exception: %s\n", - p_network->communicator().rank(), - w.c_str()); - p_busIO->header(ioBuf); - p_busIO->header("Solver failure\n\n"); - } - timer->stop(t_lsolv); - timer->stop(t_total); - return false; - } - timer->stop(t_lsolv); - - tol = PQ->normInfinity(); - if (!p_no_print) { - sprintf(ioBuf,"\nIteration %d Tol: %12.6e\n",iter+1,real(tol)); - p_busIO->header(ioBuf); - } - iter++; - if (real(tol)> 100.0*real(tol_org)){ - ret = false; - if (!p_no_print) { - sprintf (ioBuf,"\n-------------current iteration tol bigger than 100 times of original tol, power flow diverge\n"); - p_busIO->header(ioBuf); - } - break; - } - } - - if (iter >= p_max_iteration) ret = false; - if (p_qlim == 0) { - repeat = false; - } else { - if (p_factory->checkQlimViolations()) { - repeat =false; - } else { - if (!p_no_print) { - sprintf (ioBuf,"There are Qlim violations at iter =%d\n", iter); - p_busIO->header(ioBuf); - } - } - } - // Push final result back onto buses - timer->start(t_bmap); - p_factory->setMode(VS_RHS); - vMap.mapToBus(X); - timer->stop(t_bmap); - - // Make sure that ghost buses have up-to-date values before printing out - // results - timer->start(t_updt); - p_network->updateBuses(); - timer->stop(t_updt); - } - timer->stop(t_total); - return ret; - -} -/** - * Execute the iterative solve portion of the application using a library - * non-linear solver - * @return false if an error was caught in the solution algorithm - */ -bool gridpack::voltage_stability::VSAppModule::nl_solve() -{ - gridpack::utility::CoarseTimer *timer = - gridpack::utility::CoarseTimer::instance(); - int t_total = timer->createCategory("Powerflow: Total Application"); - timer->start(t_total); - p_factory->clearViolations(); - - int t_fact = timer->createCategory("Powerflow: Factory Operations"); - timer->start(t_fact); - p_factory->setYBus(); - p_factory->setSBus(); - timer->stop(t_fact); - - // Solve the problem - bool useNewton(false); - gridpack::utility::Configuration::CursorPtr cursor; - cursor = p_config->getCursor("Configuration.Powerflow"); - useNewton = cursor->get("UseNewton", useNewton); - - - int t_lsolv = timer->createCategory("Powerflow: Non-Linear Solver"); - timer->start(t_lsolv); - - VSSolverHelper helper(p_factory, p_network); - math::RealNonlinearSolver::JacobianBuilder jbuildf = boost::ref(helper); - math::RealNonlinearSolver::FunctionBuilder fbuildf = boost::ref(helper); - - boost::scoped_ptr solver; - if (useNewton) { - math::RealNewtonRaphsonSolver *tmpsolver = - new math::RealNewtonRaphsonSolver(*(helper.J), jbuildf, fbuildf); - tmpsolver->tolerance(p_tolerance); - tmpsolver->maximumIterations(p_max_iteration); - solver.reset(tmpsolver); - } else { - solver.reset(new math::RealNonlinearSolver(*(helper.J), - jbuildf, fbuildf)); - } - - bool ret = true; - try { - solver->configure(cursor); - solver->solve(*helper.X); - helper.update(*helper.X); - } catch (const Exception& e) { - std::cerr << e.what() << std::endl; - timer->stop(t_lsolv); - timer->stop(t_total); - ret = false; - } - - timer->stop(t_lsolv); - timer->stop(t_total); - return ret; -} - - -/** - * Write out results of powerflow calculation to standard output or a file - */ -void gridpack::voltage_stability::VSAppModule::write() -{ - if (p_no_print) return; - gridpack::utility::CoarseTimer *timer = - gridpack::utility::CoarseTimer::instance(); - int t_total = timer->createCategory("Powerflow: Total Application"); - timer->start(t_total); - int t_write = timer->createCategory("Powerflow: Write Results"); - timer->start(t_write); - p_branchIO->header("\n Branch Power Flow\n"); - p_branchIO->header("\n Bus 1 Bus 2 CKT P" - " Q\n"); - p_branchIO->write(); - //p_branchIO->write("record"); - - - p_busIO->header("\n Generator Power\n"); - p_busIO->header("\n Bus Number GenID Pgen Qgen\n"); - p_busIO->write("power"); - p_busIO->header("\n Bus Voltages and Phase Angles\n"); - p_busIO->header("\n Bus Number Phase Angle Voltage Magnitude\n"); - p_busIO->write(); - //p_busIO->write("record"); - timer->stop(t_write); - timer->stop(t_total); -} - -void gridpack::voltage_stability::VSAppModule::writeBus(const char *signal) -{ - if (p_no_print) return; - gridpack::utility::CoarseTimer *timer = - gridpack::utility::CoarseTimer::instance(); - int t_total = timer->createCategory("Powerflow: Total Application"); - timer->start(t_total); - int t_write = timer->createCategory("Powerflow: Write Results"); - timer->start(t_write); - timer->start(t_total); - p_busIO->write(signal); - timer->stop(t_write); - timer->stop(t_total); -} - -void gridpack::voltage_stability::VSAppModule::writeCABus() -{ - if (p_no_print) return; - gridpack::utility::CoarseTimer *timer = - gridpack::utility::CoarseTimer::instance(); - int t_total = timer->createCategory("Contingency: Total Application"); - timer->start(t_total); - int t_write = timer->createCategory("Contingency: Write Results"); - timer->start(t_write); - p_busIO->write("ca"); -// p_busIO->write(signal); - timer->stop(t_write); - timer->stop(t_total); -} - -void gridpack::voltage_stability::VSAppModule::writeBranch(const char *signal) -{ - if (p_no_print) return; - gridpack::utility::CoarseTimer *timer = - gridpack::utility::CoarseTimer::instance(); - int t_total = timer->createCategory("Powerflow: Total Application"); - timer->start(t_total); - int t_write = timer->createCategory("Powerflow: Write Results"); - timer->start(t_write); - timer->start(t_total); - p_branchIO->write(signal); - timer->stop(t_write); - timer->stop(t_total); -} - -void gridpack::voltage_stability::VSAppModule::writeCABranch() -{ - if (p_no_print) return; - gridpack::utility::CoarseTimer *timer = - gridpack::utility::CoarseTimer::instance(); - int t_total = timer->createCategory("Contingency: Total Application"); - timer->start(t_total); - int t_write = timer->createCategory("Contingency: Write Results"); - timer->start(t_write); - p_branchIO->write("flow"); - timer->stop(t_write); - timer->stop(t_total); -} - -std::vector gridpack::voltage_stability::VSAppModule::writeBusString( - const char *signal) -{ - std::vector ret; - gridpack::utility::CoarseTimer *timer = - gridpack::utility::CoarseTimer::instance(); - int t_total = timer->createCategory("Contingency: Total Application"); - timer->start(t_total); - int t_write = timer->createCategory("Contingency: Write Results"); - timer->start(t_write); - ret = p_busIO->writeStrings(signal); - timer->stop(t_write); - timer->stop(t_total); - return ret; -} - -std::vector gridpack::voltage_stability::VSAppModule::writeBranchString( - const char *signal) -{ - std::vector ret; - gridpack::utility::CoarseTimer *timer = - gridpack::utility::CoarseTimer::instance(); - int t_total = timer->createCategory("Contingency: Total Application"); - timer->start(t_total); - int t_write = timer->createCategory("Contingency: Write Results"); - timer->start(t_write); - ret = p_branchIO->writeStrings(signal); - timer->stop(t_write); - timer->stop(t_total); - return ret; -} - -void gridpack::voltage_stability::VSAppModule::writeHeader(const char *msg) -{ - if (p_no_print) return; - p_busIO->header(msg); -} - -/** - * Redirect output from standard out - * @param filename name of file to write results to - */ -void gridpack::voltage_stability::VSAppModule::open(const char *filename) -{ - if (p_no_print) return; - p_busIO->open(filename); - p_branchIO->setStream(p_busIO->getStream()); -} - -void gridpack::voltage_stability::VSAppModule::close() -{ - if (p_no_print) return; - p_busIO->close(); - p_branchIO->setStream(p_busIO->getStream()); -} - -/** - * Print string. This can be used to direct output to the file opened using - * the open command - * @param buf string to be printed - */ -void gridpack::voltage_stability::VSAppModule::print(const char *buf) -{ - if (p_no_print) return; - p_busIO->header(buf); -} - -/** - * Export final configuration to PSS/E v34 formatted file - * @param filename name of file to store network configuration - */ -void gridpack::voltage_stability::VSAppModule::exportPSSE34(std::string &filename) -{ - if (p_no_print) return; - gridpack::expnet::PSSE34Export exprt(p_network); - exprt.writeFile(filename); -} - -/** - * Export final configuration to PSS/E v33 formatted file - * @param filename name of file to store network configuration - */ -void gridpack::voltage_stability::VSAppModule::exportPSSE33(std::string &filename) -{ - if (p_no_print) return; - gridpack::expnet::PSSE33Export exprt(p_network); - exprt.writeFile(filename); -} - -/** - * Export final configuration to PSS/E v23 formatted file - * @param filename name of file to store network configuration - */ -void gridpack::voltage_stability::VSAppModule::exportPSSE23(std::string &filename) -{ - //if (p_no_print) return; - gridpack::expnet::PSSE23Export exprt(p_network); - exprt.writeFile(filename); -} - -/** - * Save results of powerflow calculation to data collection objects - */ -void gridpack::voltage_stability::VSAppModule::saveData() -{ - p_factory->saveData(); -} - -/** - * Save results of voltage_stability calculation to data collection objects - * added by Renke, also modify the original bus mag, ang, - * and the original generator PG QG in the datacollection - */ -void gridpack::voltage_stability::VSAppModule::saveDataAlsotoOrg() -{ - p_factory->saveDataAlsotoOrg(); -} - -/** - * get the power flow solution for the specific bus, vmag and v angle - * @param bus original number, bus solution vmag and v angle - * @return false if location of bus is not found in - * network - */ - -bool gridpack::voltage_stability::VSAppModule::getVSSolutionSingleBus( - int bus_number, double &bus_mag, double &bus_angle) -{ - bool ret = true; - std::vector vec_busintidx; - int ibus, nbus; - gridpack::voltage_stability::VSBus *bus; - - vec_busintidx = p_network->getLocalBusIndices(bus_number); - nbus = vec_busintidx.size(); - if (nbus == 0) ret = false; - for(ibus=0; ibus - (p_network->getBus(vec_busintidx[ibus]).get()); //->getOriginalIndex() - //printf("----renke debug VSAppModule::getVSSolutionSingleBus, \n"); - bus_mag=bus->getVoltage(); - double anglerads = bus->getPhase(); - double pi = 4.0*atan(1.0); - bus_angle = 180.0*anglerads/pi; - } - - return ret; -} - -/** - * Set a contingency - * @param event data describing location and type of contingency - * @return false if location of contingency is not found in - * network - */ -bool gridpack::voltage_stability::VSAppModule::setContingency( - gridpack::voltage_stability::VSContingency &event) -{ - bool ret = true; - if (event.p_type == VS_Generator) { - int ngen = event.p_busid.size(); - int i, j, idx, jdx; - for (i=0; i lids = p_network->getLocalBusIndices(idx); - if (lids.size() == 0) ret = false; - gridpack::voltage_stability::VSBus *bus; - for (j=0; j( - p_network->getBus(jdx).get()); - event.p_saveGenStatus[i] = bus->getGenStatus(tag); - bus->setGenStatus(tag, false); - } - } - } else if (event.p_type == VS_Branch) { - int to, from; - int nline = event.p_to.size(); - int i, j, idx, jdx; - for (i=0; i lids = p_network->getLocalBranchIndices(from,to); - if (lids.size() == 0) ret = false; - gridpack::voltage_stability::VSBranch *branch; - for (j=0; j( - p_network->getBranch(jdx).get()); - event.p_saveLineStatus[i] = branch->getBranchStatus(tag); - branch->setBranchStatus(tag, false); - } - } - } else { - ret = false; - } - if (ret) { - p_contingency_name = event.p_name; - } else { - p_contingency_name.clear(); - } - p_factory->checkLoneBus(); - return ret; -} - /** - * Return system to the state before the contingency - * @param event data describing location and type of contingency - * @return false if location of contingency is not found in network + * Increment generators real power based off specified value. + * Increment generators in specified area. + * @param transfer value to increment generators real power + * @param area index of area for incrementing generation + * @param zone index of zone for incrementing generation + * @param total power generation of an area */ -bool gridpack::voltage_stability::VSAppModule::unSetContingency( - gridpack::voltage_stability::VSContingency &event) +void gridpack::voltage_stability::VSAppModule::IncrementGeneratorRealPower( + double inc, int area, int zone, double gt) { - p_factory->clearLoneBus(); - bool ret = true; - if (event.p_type == VS_Generator) { - int ngen = event.p_busid.size(); - int i, j, idx, jdx; - for (i=0; i lids = p_network->getLocalBusIndices(idx); - if (lids.size() == 0) ret = false; - gridpack::voltage_stability::VSBus *bus; - for (j=0; j( - p_network->getBus(jdx).get()); - bus->setGenStatus(tag, event.p_saveGenStatus[i]); - } - } - } else if (event.p_type == VS_Branch) { - int to, from; - int nline = event.p_to.size(); - int i, j, idx, jdx; - for (i=0; i lids = p_network->getLocalBranchIndices(from,to); - if (lids.size() == 0) ret = false; - gridpack::voltage_stability::VSBranch *branch; - for (j=0; j( - p_network->getBranch(jdx).get()); - branch->setBranchStatus(tag,event.p_saveLineStatus[i]); - } - } - } else { - ret = false; - } - return ret; + v_factory->IncrementGeneratorRealPower(inc,area,zone,gt); } /** - * Set voltage limits on all buses - * @param Vmin lower bound on voltages - * @param Vmax upper bound on voltages + * Increment load power based off specified value. + * Increment loads in specified area. + * @param transfer value to increment load real power + * @param area index of area for incrementing load + * @param zone index of zone for incrementing load + * @param total active power demand of the area */ -void gridpack::voltage_stability::VSAppModule::setVoltageLimits(double Vmin, double Vmax) +void gridpack::voltage_stability::VSAppModule::IncrementLoadPower( + double inc, int area, int zone, double lt) { - p_factory->setVoltageLimits(Vmin, Vmax); -} - -/** - * Check to see if there are any voltage violations in the network - * @param area area number. If this parameter is included, only check for - * violations in this area - * @return true if no violations found - */ -bool gridpack::voltage_stability::VSAppModule::checkVoltageViolations() -{ - return p_factory->checkVoltageViolations(); -} -bool gridpack::voltage_stability::VSAppModule::checkVoltageViolations( - int area) -{ - return p_factory->checkVoltageViolations(area); -} - -/** - * Set "ignore" parameter on all buses with violations so that subsequent - * checks are not counted as violations - */ -void gridpack::voltage_stability::VSAppModule::ignoreVoltageViolations() -{ - p_factory->ignoreVoltageViolations(); -} - -/** - * Clear "ignore" parameter on all buses - */ -void gridpack::voltage_stability::VSAppModule::clearVoltageViolations() -{ - p_factory->clearVoltageViolations(); -} - -/** - * Check to see if there are any line overload violations in the - * network The last call checks for overloads on specific lines. - * @param area area number. If this parameter is included, only check for - * violations in this area - * @param bus1 original index of "from" bus for branch - * @param bus2 original index of "to" bus for branch - * @param tags line IDs for individual lines - * @param violations true if violation detected on branch, false otherwise - * @return true if no violations found - */ -bool gridpack::voltage_stability::VSAppModule::checkLineOverloadViolations() -{ - return p_factory->checkLineOverloadViolations(); -} -bool gridpack::voltage_stability::VSAppModule::checkLineOverloadViolations(int area) -{ - return p_factory->checkLineOverloadViolations(area); -} -bool gridpack::voltage_stability::VSAppModule::checkLineOverloadViolations( - std::vector &bus1, std::vector &bus2, - std::vector &tags, std::vector &violations) -{ - return p_factory->checkLineOverloadViolations(bus1,bus2,tags,violations); -} - -/** - * Check to see if there are any Q limit violations in the network - * @param area only check for violations in specified area - * @return true if no violations found - */ -bool gridpack::voltage_stability::VSAppModule::checkQlimViolations() -{ - return p_factory->checkQlimViolations(); -} -bool gridpack::voltage_stability::VSAppModule::checkQlimViolations(int area) -{ - return p_factory->checkQlimViolations(area); -} - -/** - * Clear changes that were made for Q limit violations and reset - * system to its original state - */ -void gridpack::voltage_stability::VSAppModule::clearQlimViolations() -{ - p_factory->clearQlimViolations(); -} - -/** - * Reset voltages to values in network configuration file - */ -void gridpack::voltage_stability::VSAppModule::resetVoltages() -{ - p_factory->resetVoltages(); -} - -/** - * Scale generator real power. If zone less than 1 then scale all - * generators in the area. - * @param scale factor to scale real power generation - * @param area index of area for scaling generation - * @param zone index of zone for scaling generation - */ -void gridpack::voltage_stability::VSAppModule::scaleGeneratorRealPower( - double scale, int area, int zone) -{ - p_factory->scaleGeneratorRealPower(scale,area,zone); -} - -/** - * Scale load power. If zone less than 1 then scale all - * loads in the area. - * @param scale factor to scale load real power - * @param area index of area for scaling load - * @param zone index of zone for scaling load - */ -void gridpack::voltage_stability::VSAppModule::scaleLoadPower( - double scale, int area, int zone) -{ - p_factory->scaleLoadPower(scale,area,zone); + v_factory->IncrementLoadPower(inc,area,zone,lt); } /** @@ -1107,315 +101,94 @@ double gridpack::voltage_stability::VSAppModule::getTotalLoadRealPower(int area, } /** - * Return the current real power generation and the maximum and minimum total - * power generation for all generators in the zone. If zone is less than 1 - * then return values for all generators in the area - * @param area index of area - * @param zone index of zone - * @param total total real power generation - * @param pmin minimum allowable real power generation - * @param pmax maximum available real power generation - */ -void gridpack::voltage_stability::VSAppModule::getGeneratorMargins(int area, - int zone, double *total, double *pmin, double *pmax) -{ - p_factory->getGeneratorMargins(area,zone,total,pmin,pmax); -} - -/** - * Reset power of loads and generators to original values - */ -void gridpack::voltage_stability::VSAppModule::resetPower() -{ - p_factory->resetPower(); -} - -/** - * Write real time path rating diagnostics - * @param src_area generation area - * @param src_zone generation zone - * @param load_area load area - * @param load_zone load zone - * @param gen_scale scale factor for generation - * @param load_scale scale factor for loads - * @param file name of file containing diagnostics + * Check to see if PV Analysis is complete + * @return return true if parameter is not found */ -void gridpack::voltage_stability::VSAppModule::writeRTPRDiagnostics( - int src_area, int src_zone, int load_area, - int load_zone, double gen_scale, double load_scale, const char *file) +bool gridpack::voltage_stability::VSAppModule::isPVAnlyDone(double increment, double max_increment) { - if (p_no_print) return; - p_factory->setRTPRParams(src_area,src_zone,load_area,load_zone, - gen_scale,load_scale); - p_busIO->open(file); - double gtotal, ltotal, pmin, pmax, scaled; - p_factory->getGeneratorMargins(src_area, src_zone,>otal,&pmin,&pmax); - ltotal = p_factory->getTotalLoadRealPower(load_area,load_zone); - if (gen_scale > 0.0) { - scaled = gtotal + gen_scale*(pmax-gtotal); - } else { - scaled = gtotal + gen_scale*(gtotal-pmin); + if (current_increment >= (max_increment)){ + p_bPVAnlyDone = true; } - char sbuf[128]; - sprintf(sbuf,"Total Generation: %16.4f\n",gtotal); - p_busIO->header(sbuf); - sprintf(sbuf," Minimum Generation: %16.4f\n",pmin); - p_busIO->header(sbuf); - sprintf(sbuf," Maximum Generation: %16.4f\n",pmax); - p_busIO->header(sbuf); - sprintf(sbuf," Generator Scale Factor: %16.4f\n",gen_scale); - p_busIO->header(sbuf); - sprintf(sbuf," Scaled Generation: %16.4f\n",scaled); - p_busIO->header(sbuf); - p_busIO->header("\nIndividual Scaled Generators\n"); - sprintf(sbuf,"\n Bus ID Status Area Zone Real Power Scaled Power" - " Pmin Pmax\n\n"); - p_busIO->header(sbuf); - p_busIO->write("src_gen"); - sprintf(sbuf,"\nTotal Load: %16.4f\n",ltotal); - p_busIO->header(sbuf); - sprintf(sbuf," Load Scale Factor: %16.4f\n",load_scale); - p_busIO->header(sbuf); - sprintf(sbuf," Scaled Load: %16.4f\n",load_scale*ltotal); - p_busIO->header(sbuf); - p_busIO->header("\nIndividual Scaled Loads\n"); - sprintf(sbuf,"\n Bus ID Status Area Zone Real Power Scaled Power" - " Reactive Power Scaled Power\n\n"); - p_busIO->header(sbuf); - p_busIO->write("sink_load"); - p_busIO->close(); + return p_bPVAnlyDone; } /** - * Get strings documenting contingency failures. Strings are *not* terminated - * with a carriage return + * Set up PV Curve internal parameters and initialize */ -std::vector gridpack::voltage_stability::VSAppModule::getContingencyFailures() -{ - std::vector ret; - std::vector violations; - violations = p_factory->getViolations(); - int nsize = violations.size(); +void gridpack::voltage_stability::VSAppModule::InitializePVCurve(std::string filename) +{ + std::cout<<"1 Done "<getCursor("Configuration.Powerflow"); + */ + std::cout<<"2 Done "<getTotalGenRealPower(src_area,zone); + lt = getTotalLoadRealPower(sink_area, zone); + p_bPVAnlyDone = false; + std::cout<<"1 Done "<get("PVAnalysisData",&filename)) { + printf("No PV Analysis output data file specified\n"); + } + else{}*/ + std::cout<<"3 Done "<numBuses(); int i; - char sbuf[128]; - for (i=0; igetActiveBus(i)) { + gridpack::voltage_stability::VSBus *bus = + dynamic_cast + (p_network->getBus(i).get()); + file << "Bus " << bus->getOriginalIndex() << ","; + } + } + file << "\n"; + PV_header = true; + file.close(); + } - return ret; -} - -/** - * User rate B parameter for line overload violations - * @param flag if true, use RATEB parameter - */ -void gridpack::voltage_stability::VSAppModule::useRateB(bool flag) -{ - p_factory->useRateB(flag); -} - -/** - * Suppress all output from power flow module - * @param flag if true, suppress printing - */ -void gridpack::voltage_stability::VSAppModule::suppressOutput(bool flag) -{ - p_no_print = flag; } -#ifdef USE_GOSS /** - * Set GOSS client if one already exists - * @param client pointer to existing GOSS client + * Execute one transfer increment */ -void gridpack::voltage_stability::VSAppModule::setGOSSClient( - gridpack::goss::GOSSClient &client, std:;string simID) +void gridpack::voltage_stability::VSAppModule::IncrementPVCurveStep() { - p_goss_client = client; - p_simID = simID; -} -#endif -/** - * Modify generator parameters in data collection for specified bus - * @param bus_id bus ID - * @param gen_id two character token specifying generator on bus - * @param genParam string representing dictionary name of data element - * to be modified - * @param value new value of parameter - * @return return false if parameter is not found - */ -bool gridpack::voltage_stability::VSAppModule::modifyDataCollectionGenParam( - int bus_id, std::string gen_id, std::string genParam, double value) -{ - gridpack::utility::StringUtils util; - std::string clean_gen_id = util.clean2Char(gen_id); - return p_modifyDataCollectionGenParam(bus_id,clean_gen_id,genParam,value); -} -bool gridpack::voltage_stability::VSAppModule::modifyDataCollectionGenParam( - int bus_id, std::string gen_id, std::string genParam, int value) -{ - gridpack::utility::StringUtils util; - std::string clean_gen_id = util.clean2Char(gen_id); - return p_modifyDataCollectionGenParam(bus_id,clean_gen_id,genParam,value); -} - -/** - * Modify load parameters in data collection for specified bus - * @param bus_id bus ID - * @param load_id two character token specifying load on bus - * @param loadParam string representing dictionary name of data element - * to be modified - * @param value new value of parameter - * @return return false if parameter is not found - */ -bool gridpack::voltage_stability::VSAppModule::modifyDataCollectionLoadParam( - int bus_id, std::string load_id, std::string loadParam, double value) -{ - gridpack::utility::StringUtils util; - std::string clean_load_id = util.clean2Char(load_id); - return p_modifyDataCollectionLoadParam(bus_id,clean_load_id,loadParam,value); -} -bool gridpack::voltage_stability::VSAppModule::modifyDataCollectionLoadParam( - int bus_id, std::string load_id, std::string loadParam, int value) -{ - gridpack::utility::StringUtils util; - std::string clean_load_id = util.clean2Char(load_id); - return p_modifyDataCollectionLoadParam(bus_id,clean_load_id,loadParam,value); -} - -/** - * Modify parameters in data collection for specified bus - * @param bus_id bus ID - * @param busParam string representing dictionary name of data element - * to be modified - * @param value new value of parameter - * @return return false if parameter is not found - */ -bool gridpack::voltage_stability::VSAppModule::modifyDataCollectionBusParam( - int bus_id, std::string busParam, double value) -{ - return p_modifyDataCollectionBusParam(bus_id,busParam,value); -} -bool gridpack::voltage_stability::VSAppModule::modifyDataCollectionBusParam( - int bus_id, std::string busParam, int value) -{ - return p_modifyDataCollectionBusParam(bus_id,busParam,value); -} - -/** - * Modify parameters in data collection for specified branch - * @param bus1, bus2 bus IDs for from and to bus - * @param ckt two character token specifying branch - * @param branchParam string representing dictionary name of data element - * to be modified - * @param value new value of parameter - * @return return false if parameter is not found - */ -bool gridpack::voltage_stability::VSAppModule::modifyDataCollectionBranchParam( - int bus1, int bus2, std::string ckt, - std::string branchParam, double value) -{ - return p_modifyDataCollectionBranchParam(bus1,bus2,ckt,branchParam,value); -} -bool gridpack::voltage_stability::VSAppModule::modifyDataCollectionBranchParam( - int bus1, int bus2, std::string ckt, - std::string branchParam, int value) -{ - return p_modifyDataCollectionBranchParam(bus1,bus2,ckt,branchParam,value); -} - -/** - * Get generator parameters in data collection for specified bus - * @param bus_id bus ID - * @param gen_id two character token specifying generator on bus - * @param genParam string representing dictionary name of data element - * to be modified - * @param value value of parameter - * @return return false if parameter is not found - */ -bool gridpack::voltage_stability::VSAppModule::getDataCollectionGenParam( - int bus_id, std::string gen_id, - std::string genParam, double *value) -{ - return p_getDataCollectionGenParam(bus_id, gen_id, genParam, value); -} -bool gridpack::voltage_stability::VSAppModule::getDataCollectionGenParam( - int bus_id, std::string gen_id, - std::string genParam, int *value) -{ - return p_getDataCollectionGenParam(bus_id, gen_id, genParam, value); -} - -/** - * Get load parameters in data collection for specified bus - * @param bus_id bus ID - * @param load_id two character token specifying load on bus - * @param loadParam string representing dictionary name of data element - * to be modified - * @param value value of parameter - * @return return false if parameter is not found - */ -bool gridpack::voltage_stability::VSAppModule::getDataCollectionLoadParam( - int bus_id, std::string load_id, - std::string loadParam, double *value) -{ - return p_getDataCollectionLoadParam(bus_id, load_id, loadParam, value); -} -bool gridpack::voltage_stability::VSAppModule::getDataCollectionLoadParam( - int bus_id, std::string load_id, - std::string loadParam, int *value) -{ - return p_getDataCollectionLoadParam(bus_id, load_id, loadParam, value); -} - -/** - * Get parameters in data collection for specified bus - * @param bus_id bus ID - * @param busParam string representing dictionary name of data element - * to be modified - * @param value value of parameter - * @return return false if parameter is not found - */ -bool gridpack::voltage_stability::VSAppModule::getDataCollectionBusParam( - int bus_id, std::string busParam, double *value) -{ - return p_getDataCollectionBusParam(bus_id, busParam, value); -} -bool gridpack::voltage_stability::VSAppModule::getDataCollectionBusParam( - int bus_id, std::string busParam, int *value) -{ - return p_getDataCollectionBusParam(bus_id, busParam, value); -} - -/** - * Get parameters in data collection for specified branch - * @param bus1, bus2 bus IDs for from and to bus - * @param ckt two character token specifying branch - * @param branchParam string representing dictionary name of data element - * to be modified - * @param value value of parameter - * @return return false if parameter is not found - */ -bool gridpack::voltage_stability::VSAppModule::getDataCollectionBranchParam( - int bus1, int bus2, std::string ckt, - std::string branchParam, double *value) -{ - return p_getDataCollectionBranchParam(bus1, bus2, ckt, branchParam, value); -} -bool gridpack::voltage_stability::VSAppModule::getDataCollectionBranchParam( - int bus1, int bus2, std::string ckt, - std::string branchParam, int *value) -{ - return p_getDataCollectionBranchParam(bus1, bus2, ckt, branchParam, value); + IncrementGeneratorRealPower(increment, src_area, zone, gt); + IncrementLoadPower(increment, sink_area, zone, lt); + gridpack::utility::Configuration::CursorPtr cursor; + cursor = p_config->getCursor("Configuration.Powerflow"); + std::string filename; + if (!cursor->get("PVAnalysisData",&filename)) { + printf("No PV Analysis output data file specified\n"); + } + else{ + static int numBus = p_network->numBuses(); + int i; + double bus_varray[numBus] = {}; + std::ofstream file; + file.open(filename.c_str(), std::ios_base::app); + file.is_open(); + file << current_increment << ","; + for (i=0; igetActiveBus(i)) { + gridpack::voltage_stability::VSBus *bus = + dynamic_cast + (p_network->getBus(i).get()); + file << bus->getVoltage() << ","; + } + } + file << "\n"; + file.close(); + + } + gt = gt + increment; + lt = lt + increment; + current_increment = current_increment + increment; } diff --git a/src/applications/modules/voltage_stability/vs_app_module.hpp b/src/applications/modules/voltage_stability/vs_app_module.hpp index 3a06b6b02..6b95febce 100644 --- a/src/applications/modules/voltage_stability/vs_app_module.hpp +++ b/src/applications/modules/voltage_stability/vs_app_module.hpp @@ -22,6 +22,8 @@ #include "gridpack/serial_io/serial_io.hpp" #include "gridpack/configuration/configuration.hpp" #include "vs_factory_module.hpp" +#include "gridpack/applications/modules/voltage_stability/vs_app_module.hpp" +#include "gridpack/applications/modules/powerflow/pf_app_module.hpp" #include "gridpack/parser/dictionary.hpp" #include "gridpack/utilities/string_utils.hpp" @@ -76,6 +78,7 @@ struct VSContingency class VSAppModule { public: + /** * Basic constructor */ @@ -86,215 +89,18 @@ class VSAppModule */ ~VSAppModule(void); - /** - * Read in and partition the powerflow network. The input file is read - * directly from the Powerflow block in the configuration file so no - * external file names or parameters need to be passed to this routine - * @param network pointer to a VSNetwork object. This should not have any - * buses or branches defined on it. - * @param config point to open configuration file - * @param idx index of configuration to use if set to a non-negative value - */ - void readNetwork(boost::shared_ptr &network, - gridpack::utility::Configuration *config, - int idx = -1); - - /** - * Set up exchange buffers and other internal parameters and initialize - * network components using data from data collection - */ - void initialize(); - - /** - * Reinitialize calculation from data collections - */ - void reload(); - - /** - * Execute the iterative solve portion of the application using a hand-coded - * Newton-Raphson solver - * @return false if an error was caught in the solution algorithm - */ - bool solve(); - - /** - * Execute the iterative solve portion of the application using a library - * non-linear solver - * @return false if an error was caught in the solution algorithm - */ - bool nl_solve(); - - /** - * Write out results of powerflow calculation to standard output - * Separate calls for writing only data from buses or branches - * @param signal tell underlying write what records to print - */ - void write(); - void writeBus(const char* signal); - void writeBranch(const char* signal); - void writeCABus(); - void writeCABranch(); - void writeHeader(const char *msg); - std::vector writeBusString(const char *signal = NULL); - std::vector writeBranchString(const char *signal = NULL); - - /** - * Redirect output from standard out - * @param filename name of file to write results to - */ - void open(const char *filename); - void close(); - - /** - * Print string. This can be used to direct output to the file opened using - * the open command - * @param buf string to be printed - */ - void print(const char *buf); - - /** - * Save results of powerflow calculation to data collection objects - */ - void saveData(); - - /** - * Save results of powerflow calculation to data collection objects - * added by Renke, also modify the original bus mag, ang, - * and the original generator PG QG in the datacollection - */ - void saveDataAlsotoOrg(); - - /** - * get the power flow solution for the specific bus, vmag and v angle - * @param bus original number, bus solution vmag and v angle - * @return false if location of bus is not found in - * network - */ - - bool getVSSolutionSingleBus(int bus_number, double &bus_mag, double &bus_angle); - - /** - * Export final configuration to PSS/E v34 formatted file - * @param filename name of file to store network configuration - */ - void exportPSSE34(std::string &filename); - - /** - * Export final configuration to PSS/E v33 formatted file - * @param filename name of file to store network configuration - */ - void exportPSSE33(std::string &filename); - - /** - * Export final configuration to PSS/E v23 formatted file - * @param filename name of file to store network configuration - */ - void exportPSSE23(std::string &filename); + void IncrementGeneratorRealPower(double inc, int area, int zone, double gtotal); /** - * Set a contingency - * @param event data describing location and type of contingency - * @return false if location of contingency is not found in network - */ - bool setContingency(VSContingency &event); - - /** - * Return system to the state before the contingency - * @param event data describing location and type of contingency - * @return false if location of contingency is not found in network + * Increment load power based off specified value. + * Increment loads in specified area. + * @param transfer value to increment load real power + * @param area index of area for incrementing load + * @param zone index of zone for incrementing load + * @param total active power demand of the area */ - bool unSetContingency(VSContingency &event); - - /** - * Set voltage limits on all buses - * @param Vmin lower bound on voltages - * @param Vmax upper bound on voltages - */ - void setVoltageLimits(double Vmin, double Vmax); - - /** - * Check to see if there are any voltage violations in the network. - * @param area only check for violations in specified area - * @return true if no violations found - */ - bool checkVoltageViolations(); - bool checkVoltageViolations(int area); - - /** - * Set "ignore" parameter on all buses with violations so that subsequent - * checks are not counted as violations - */ - void ignoreVoltageViolations(); - - /** - * Clear "ignore" parameter on all buses - */ - void clearVoltageViolations(); - - /** - * Check to see if there are any line overload violations in - * the network. The last call checks for overloads on specific lines. - * @param area only check for violations in specified area - * @param bus1 original index of "from" bus for branch - * @param bus2 original index of "to" bus for branch - * @param tags line IDs for individual lines - * @param violations true if violation detected on branch, false otherwise - * @return true if no violations found - */ - bool checkLineOverloadViolations(); - bool checkLineOverloadViolations(int area); - bool checkLineOverloadViolations(std::vector &bus1, - std::vector &bus2, std::vector &tags, - std::vector &violations); - - /** - * Set "ignore" paramter on all lines with violations so that subsequent - * checks are not counted as violations - */ - void ignoreLineOverloadViolations(); - - /** - * Clear "ignore" parameter on all lines - */ - void clearLineOverloadViolations(); - - /** - * Check to see if there are any Q limit violations in the network - * @param area only check for violations in specified area - * @return true if no violations found - */ - bool checkQlimViolations(); - bool checkQlimViolations(int area); - - /** - * Clear changes that were made for Q limit violations and reset - * system to its original state - */ - void clearQlimViolations(); - - /** - * Reset voltages to values in network configuration file - */ - void resetVoltages(); - - /** - * Scale generator real power. If zone less than 1 then scale all - * generators in the area. - * @param scale factor to scale real power generation - * @param area index of area for scaling generation - * @param zone index of zone for scaling generation - */ - void scaleGeneratorRealPower(double scale, int area, int zone); - - /** - * Scale load power. If zone less than 1 then scale all - * loads in the area. - * @param scale factor to scale load real power - * @param area index of area for scaling load - * @param zone index of zone for scaling load - */ - void scaleLoadPower(double scale, int area, int zone); - + void IncrementLoadPower(double inc, int area, int zone, double ltotal); + /** * Return the total real power load for all loads in the zone. If zone * less than 1, then return the total load real power for the area @@ -303,591 +109,51 @@ class VSAppModule * @return total load */ double getTotalLoadRealPower(int area, int zone); - - /** - * Return the current real power generation and the maximum and minimum total - * power generation for all generators in the zone. If zone is less than 1 - * then return values for all generators in the area - * @param area index of area - * @param zone index of zone - * @param total total real power generation - * @param pmin minimum allowable real power generation - * @param pmax maximum available real power generation - */ - void getGeneratorMargins(int area, int zone, double *total, double *pmin, - double *pmax); - - /** - * Reset power of loads and generators to original values - */ - void resetPower(); - - /** - * Write real time path rating diagnostics - * @param src_area generation area - * @param src_zone generation zone - * @param load_area load area - * @param load_zone load zone - * @param gen_scale scale factor for generation - * @param load_scale scale factor for loads - * @param file name of file containing diagnostics - */ - void writeRTPRDiagnostics(int src_area, int src_zone, int load_area, - int load_zone, double gen_scale, double load_scale, const char *file); - - /** - * Get strings documenting contingency failures. Strings are *not* - * terminated with a carriage return - */ - std::vector getContingencyFailures(); - - /** - * User rate B parameter for line overload violations - * @param flag if true, use RATEB parameter - */ - void useRateB(bool flag); - + /** - * Suppress all output from power flow module - * @param flag if true, suppress printing + * Check to see if PV Analysis is complete + * @return return true if parameter is not found */ - void suppressOutput(bool flag); - -#ifdef USE_GOSS - /** - * Set GOSS client if one already exists - * @param client pointer to existing GOSS client - * @param simID simulation ID - */ - void setGOSSClient(gridpack::goss::GOSSClient &client, std::string simID); -#endif - - /** - * Modify generator parameters in data collection for specified bus - * @param bus_id bus ID - * @param gen_id two character token specifying generator on bus - * @param genParam string representing dictionary name of data element - * to be modified - * @param value new value of parameter - * @return return false if parameter is not found - */ - bool modifyDataCollectionGenParam(int bus_id, std::string gen_id, - std::string genParam, double value); - bool modifyDataCollectionGenParam(int bus_id, std::string gen_id, - std::string genParam, int value); - - /** - * Modify load parameters in data collection for specified bus - * @param bus_id bus ID - * @param load_id two character token specifying load on bus - * @param loadParam string representing dictionary name of data element - * to be modified - * @param value new value of parameter - * @return return false if parameter is not found - */ - bool modifyDataCollectionLoadParam(int bus_id, std::string load_id, - std::string loadParam, double value); - bool modifyDataCollectionLoadParam(int bus_id, std::string load_id, - std::string loadParam, int value); - - /** - * Modify parameters in data collection for specified bus - * @param bus_id bus ID - * @param busParam string representing dictionary name of data element - * to be modified - * @param value new value of parameter - * @return return false if parameter is not found - */ - bool modifyDataCollectionBusParam(int bus_id, - std::string busParam, double value); - bool modifyDataCollectionBusParam(int bus_id, - std::string busParam, int value); - - /** - * Modify parameters in data collection for specified branch - * @param bus1, bus2 bus IDs for from and to bus - * @param ckt two character token specifying branch - * @param branchParam string representing dictionary name of data element - * to be modified - * @param value new value of parameter - * @return return false if parameter is not found - */ - bool modifyDataCollectionBranchParam(int bus1, int bus2, std::string ckt, - std::string branchParam, double value); - bool modifyDataCollectionBranchParam(int bus1, int bus2, std::string ckt, - std::string branchParam, int value); - - /** - * Get generator parameters in data collection for specified bus - * @param bus_id bus ID - * @param gen_id two character token specifying generator on bus - * @param genParam string representing dictionary name of data element - * to be modified - * @param value value of parameter - * @return return false if parameter is not found - */ - bool getDataCollectionGenParam(int bus_id, std::string gen_id, - std::string genParam, double *value); - bool getDataCollectionGenParam(int bus_id, std::string gen_id, - std::string genParam, int *value); - - /** - * Get load parameters in data collection for specified bus - * @param bus_id bus ID - * @param load_id two character token specifying load on bus - * @param loadParam string representing dictionary name of data element - * to be modified - * @param value value of parameter - * @return return false if parameter is not found - */ - bool getDataCollectionLoadParam(int bus_id, std::string load_id, - std::string loadParam, double *value); - bool getDataCollectionLoadParam(int bus_id, std::string load_id, - std::string loadParam, int *value); - + bool isPVAnlyDone(double increment, double max_increment); + /** - * Get parameters in data collection for specified bus - * @param bus_id bus ID - * @param busParam string representing dictionary name of data element - * to be modified - * @param value value of parameter - * @return return false if parameter is not found + * Set up PV Curve internal parameters and initialize */ - bool getDataCollectionBusParam(int bus_id, - std::string busParam, double *value); - bool getDataCollectionBusParam(int bus_id, - std::string busParam, int *value); - + void InitializePVCurve(std::string filename); + /** - * Get parameters in data collection for specified branch - * @param bus1, bus2 bus IDs for from and to bus - * @param ckt two character token specifying branch - * @param branchParam string representing dictionary name of data element - * to be modified - * @param value value of parameter - * @return return false if parameter is not found + * Execute one transfer increment */ - bool getDataCollectionBranchParam(int bus1, int bus2, std::string ckt, - std::string branchParam, double *value); - bool getDataCollectionBranchParam(int bus1, int bus2, std::string ckt, - std::string branchParam, int *value); + void IncrementPVCurveStep(); private: - - /** - * Template function for modifying generator parameters in data collection - * for specified bus - * @param bus_id bus ID - * @param gen_id two character token specifying generator on bus - * @param gen_par string representing dictionary name of data element - * to be modified - * @param value new value of parameter - * @return return false if parameter is not found - */ - template - bool p_modifyDataCollectionGenParam( - int bus_id, std::string gen_id, std::string genParam, T value) - { - std::vector indices = p_network->getLocalBusIndices(bus_id); - - gridpack::utility::StringUtils util; - std::string clean_id; - clean_id = util.clean2Char(gen_id); - - if (indices.size() > 0) { - int i; - bool ret = false; - for (i=0; i data = - p_network->getBusData(indices[i]); - int ngen; - if (data->getValue(GENERATOR_NUMBER, &ngen)) { - int igen = -1; - T tval; - int j; - std::string gID; - for (j = 0; jgetValue(GENERATOR_ID,&gID,j)) { - if (gID == clean_id) { - igen = j; - break; - } - } - } - if (igen >= 0) { - if (data->setValue(genParam.c_str(),value,igen)) { - ret = true; - } - } - } - } - return ret; - } - return false; - } - - /** - * Template function for modifying load parameters in data collection for - * specified bus - * @param bus_id bus ID - * @param load_id two character token specifying load on bus - * @param load_par string representing dictionary name of data element - * to be modified - * @param value new value of parameter - * @return return false if parameter is not found - */ - template - bool p_modifyDataCollectionLoadParam(int bus_id, std::string load_id, - std::string loadParam, T value) - { - std::vector indices = p_network->getLocalBusIndices(bus_id); - - gridpack::utility::StringUtils util; - std::string clean_id; - clean_id = util.clean2Char(load_id); - - if (indices.size() > 0) { - int i; - bool ret = false; - for (i=0; i data = - p_network->getBusData(indices[i]); - int nload; - if (data->getValue(LOAD_NUMBER, &nload)) { - int iload = -1; - T tval; - int j; - std::string lID; - for (j = 0; jgetValue(LOAD_ID,&lID,j)) { - if (lID == clean_id) { - iload = j; - break; - } - } - } - if (iload >= 0) { - if (data->setValue(loadParam.c_str(),value,iload)) { - ret = true; - } - } - } - } - return ret; - } - return false; - } - - /** - * Template function for modifying parameters in data collection for - * specified bus - * @param bus_id bus ID - * @param bus_par string representing dictionary name of data element - * to be modified - * @param value new value of parameter - * @return return false if parameter is not found - */ - template - bool p_modifyDataCollectionBusParam(int bus_id, std::string busParam, - T value) - { - std::vector indices = p_network->getLocalBusIndices(bus_id); - if (indices.size() > 0) { - int i; - bool ret = false; - for (i=0; i data = - p_network->getBusData(indices[i]); - T tval; - if (data->setValue(busParam.c_str(),value)) { - ret = true; - } - } - return ret; - } - return false; - } - - /** - * Template function for modifying parameters in data collection for - * specified branch - * @param bus1, bus2 bus IDs for from and to bus defining branch - * @param ckt two-character branch identifier - * @param branch_par string representing dictionary name of data element - * to be modified - * @param value new value of parameter - * @return return false if parameter is not found - */ - template - bool p_modifyDataCollectionBranchParam(int bus1, int bus2, std::string ckt, - std::string branchParam, T value) - { - std::vector indices = p_network->getLocalBranchIndices(bus1, bus2); - - gridpack::utility::StringUtils util; - std::string clean_id; - clean_id = util.clean2Char(ckt); - - if (indices.size() > 0) { - int i; - bool ret = false; - for (i=0; i data = - p_network->getBranchData(indices[i]); - int nbranch; - if (data->getValue(BRANCH_NUM_ELEMENTS, &nbranch)) { - int ibr = -1; - T tval; - int j; - std::string brID; - for (j=0; jgetValue(BRANCH_CKT,&brID,j)) { - if (clean_id == brID) { - ibr = j; - break; - } - } - } - if (ibr >= 0) { - if (data->setValue(branchParam.c_str(),value,ibr)) { - ret = true; - } - } - } - } - return ret; - } - return false; - } - - /** - * Template function get generator parameters in data collection - * for specified bus - * @param bus_id bus ID - * @param gen_id two character token specifying generator on bus - * @param gen_par string representing dictionary name of data element - * to be modified - * @param value value of parameter - * @return return false if parameter is not found - */ - template - bool p_getDataCollectionGenParam( - int bus_id, std::string gen_id, std::string genParam, T *value) - { - std::vector indices = p_network->getLocalBusIndices(bus_id); - - gridpack::utility::StringUtils util; - std::string clean_id; - clean_id = util.clean2Char(gen_id); - - if (indices.size() > 0) { - int i; - bool ret = false; - for (i=0; igetActiveBus(indices[i])) { - boost::shared_ptr data = - p_network->getBusData(indices[i]); - int ngen; - if (data->getValue(GENERATOR_NUMBER, &ngen)) { - int igen = -1; - T tval; - int j; - std::string gID; - for (j = 0; jgetValue(GENERATOR_ID,&gID,j)) { - if (gID == clean_id) { - igen = j; - break; - } - } - } - if (igen >= 0) { - if (data->getValue(genParam.c_str(),value,igen)) { - ret = true; - } - } - } - } - } - return ret; - } - return false; - } - - /** - * Template function to get load parameters in data collection for - * specified bus - * @param bus_id bus ID - * @param load_id two character token specifying load on bus - * @param load_par string representing dictionary name of data element - * to be modified - * @param value value of parameter - * @return return false if parameter is not found - */ - template - bool p_getDataCollectionLoadParam(int bus_id, std::string load_id, - std::string loadParam, T *value) - { - std::vector indices = p_network->getLocalBusIndices(bus_id); - - gridpack::utility::StringUtils util; - std::string clean_id; - clean_id = util.clean2Char(load_id); - - if (indices.size() > 0) { - int i; - bool ret = false; - for (i=0; igetActiveBus(indices[i])) { - boost::shared_ptr data = - p_network->getBusData(indices[i]); - int nload; - if (data->getValue(LOAD_NUMBER, &nload)) { - int iload = -1; - T tval; - int j; - std::string lID; - for (j = 0; jgetValue(LOAD_ID,&lID,j)) { - if (lID == clean_id) { - iload = j; - break; - } - } - } - if (iload >= 0) { - if (data->getValue(loadParam.c_str(),value,iload)) { - ret = true; - } - } - } - } - } - return ret; - } - return false; - } - - /** - * Template function to get parameters in data collection for - * specified bus - * @param bus_id bus ID - * @param bus_par string representing dictionary name of data element - * to be modified - * @param value value of parameter - * @return return false if parameter is not found - */ - template - bool p_getDataCollectionBusParam(int bus_id, std::string busParam, - T *value) - { - std::vector indices = p_network->getLocalBusIndices(bus_id); - if (indices.size() > 0) { - int i; - bool ret = false; - for (i=0; igetActiveBus(indices[i])) { - boost::shared_ptr data = - p_network->getBusData(indices[i]); - T tval; - if (data->getValue(busParam.c_str(),value)) { - ret = true; - } - } - } - return ret; - } - return false; - } - - /** - * Template function to get parameters in data collection for - * specified branch - * @param bus1, bus2 bus IDs for from and to bus defining branch - * @param ckt two-character branch identifier - * @param branch_par string representing dictionary name of data element - * to be modified - * @param value new value of parameter - * @return return false if parameter is not found - */ - template - bool p_getDataCollectionBranchParam(int bus1, int bus2, std::string ckt, - std::string branchParam, T *value) - { - std::vector indices = p_network->getLocalBranchIndices(bus1, bus2); - - gridpack::utility::StringUtils util; - std::string clean_id; - clean_id = util.clean2Char(ckt); - - if (indices.size() > 0) { - int i; - bool ret = false; - for (i=0; igetActiveBranch(indices[i])) { - boost::shared_ptr data = - p_network->getBranchData(indices[i]); - int nbranch; - if (data->getValue(BRANCH_NUM_ELEMENTS, &nbranch)) { - int ibr = -1; - T tval; - int j; - std::string brID; - for (j=0; jgetValue(BRANCH_CKT,&brID,j)) { - if (clean_id == brID) { - ibr = j; - break; - } - } - } - if (ibr >= 0) { - if (data->getValue(branchParam.c_str(),value,ibr)) { - ret = true; - } - } - } - } - } - return ret; - } - return false; - } + // pointer to network - boost::shared_ptr p_network; + boost::shared_ptr p_network; // communicator for network gridpack::parallel::Communicator p_comm; // pointer to factory - boost::shared_ptr p_factory; - - // maximum number of iterations - int p_max_iteration; - - // convergence tolerance - double p_tolerance; - - // qlim enforce flag - int p_qlim; + boost::shared_ptr p_factory; + // pointer to factory + boost::shared_ptr v_factory; + // pointer to bus IO module - boost::shared_ptr > p_busIO; + boost::shared_ptr > p_busIO; // pointer to branch IO module - boost::shared_ptr > p_branchIO; + boost::shared_ptr > p_branchIO; // pointer to configuration module gridpack::utility::Configuration *p_config; - - // string containing current contingency name - std::string p_contingency_name; - - // Flag to suppress all printing to standard out - bool p_no_print; + // Variables for PV Analysis + bool p_bPVAnlyDone,PV_header; + double max_increment, increment, gen_scale, load_scale, zone, lt, gt; + double current_increment; + int sink_area, src_area; #ifdef USE_GOSS gridpack::goss::GOSSClient p_goss_client; diff --git a/src/applications/modules/voltage_stability/vs_factory_module.cpp b/src/applications/modules/voltage_stability/vs_factory_module.cpp index 51fe9313d..732a95963 100644 --- a/src/applications/modules/voltage_stability/vs_factory_module.cpp +++ b/src/applications/modules/voltage_stability/vs_factory_module.cpp @@ -757,6 +757,102 @@ void gridpack::voltage_stability::VSFactoryModule::scaleLoadPower( } } +/** + * Increment generators real power based off specified value. + * Increment generators in specified area. + * @param transfer value to increment generators real power + * @param area index of area for incrementing generation + * @param zone index of zone for incrementing generation + * @param total power generation of an area + */ +void gridpack::voltage_stability::VSFactoryModule::IncrementGeneratorRealPower( + double inc, int area, int zone, double gtotal) +{ + int nbus = p_network->numBuses(); + int i, izone; + for (i=0; igetBus(i).get(); + if (zone > 0) { + izone = bus->getZone(); + } else { + izone = zone; + } + if (bus->getArea() == area && zone == izone) { + std::vector tags = bus->getGenerators(); + int j; + for (j=0; jIncrementGeneratorPower(tags[j],inc,gtotal); + } + } + } +} + +/** + * Increment load power based off specified value. + * Increment loads in specified area. + * @param transfer value to increment load real power + * @param area index of area for incrementing load + * @param zone index of zone for incrementing load + * @param total active power demand of the area + */ +void gridpack::voltage_stability::VSFactoryModule::IncrementLoadPower( + double inc, int area, int zone, double ltotal) +{ + int nbus = p_network->numBuses(); + int i, izone; + for (i=0; igetBus(i).get(); + if (zone > 0) { + izone = bus->getZone(); + } else { + izone = zone; + } + if (bus->getArea() == area && zone == izone) { + std::vector tags = bus->getLoads(); + int j; + for (j=0; jIncrementLoadPower(tags[j],inc,ltotal); + } + } + } +} + +/** + * Return the total power generation for all generators in the area. + * @param area index of area + * @param zone index of zone + * @return total power generation + */ +double gridpack::voltage_stability::VSFactoryModule::getTotalGenRealPower(int area, int zone) +{ + double ret = 0.0; + std::cout<<"3 Done "<numBuses(); + std::cout<<"4 Done "<getBus(i).get(); + if (zone > 0) { + izone = bus->getZone(); + } else { + izone = zone; + } + if (bus->getArea() == area && zone == izone) { + std::vector tags; + std::vector pg; + std::vector status; + bus->getGeneratorPower(tags,pg,status); + for (j=0; j(status[j])) { + ret += pg[j]; + } + } + } + } + p_network->communicator().sum(&ret,1); + return ret; +} + /** * Return the total real power load for all loads in the zone. If zone * less than 1, then return the total load for the area diff --git a/src/applications/modules/voltage_stability/vs_factory_module.hpp b/src/applications/modules/voltage_stability/vs_factory_module.hpp index e6c08e506..5edf38314 100644 --- a/src/applications/modules/voltage_stability/vs_factory_module.hpp +++ b/src/applications/modules/voltage_stability/vs_factory_module.hpp @@ -187,6 +187,34 @@ class VSFactoryModule */ void scaleLoadPower(double scale, int area, int zone); + /** + * Increment generators real power based off specified value. + * Increment generators in specified area. + * @param transfer value to increment generators real power + * @param area index of area for incrementing generation + * @param zone index of zone for incrementing generation + * @param total power generation of an area + */ + void IncrementGeneratorRealPower(double inc, int area, int zone, double gtotal); + + /** + * Increment load power based off specified value. + * Increment loads in specified area. + * @param transfer value to increment load real power + * @param area index of area for incrementing load + * @param zone index of zone for incrementing load + * @param total active power demand of the area + */ + void IncrementLoadPower(double inc, int area, int zone, double ltotal); + + /** + * Return the total power generation for all generators in the area. + * @param area index of area + * @param zone index of zone + * @return total power generation + */ + double getTotalGenRealPower(int area, int zone); + /** * Return the total real power load for all loads in the zone. If zone * less than 1, then return the total load for the area diff --git a/src/applications/modules/voltage_stability/vs_helper.hpp b/src/applications/modules/voltage_stability/vs_helper.hpp index 2dc72fb0c..f6d287d4a 100644 --- a/src/applications/modules/voltage_stability/vs_helper.hpp +++ b/src/applications/modules/voltage_stability/vs_helper.hpp @@ -35,157 +35,23 @@ namespace voltage_stability { struct VSSolverHelper : private utility::Uncopyable { + + // pointer to factory + boost::shared_ptr p_factory; + // pointer to factory + boost::shared_ptr v_factory; // The powerflow factory - boost::shared_ptr p_factory; - + //boost::shared_ptr p_factory; + + // pointer to network + boost::shared_ptr p_network; // The powerflow network controlled by ::p_factory - boost::shared_ptr p_network; + //boost::shared_ptr p_network; // A place to build/store the Jacobian boost::shared_ptr J; - // The network state estimate from previous solver iteration - /** - * See ::update() for why this is necessary. - * - */ - boost::shared_ptr Xold; - - /** - * The current network state estimate. - * This vector provides a space for the nonlinear solve to store the - * current solution estimate. It should be filled with the initial - * condition, handed to the nonlinear solver, and not changed - * afterward. - * - */ - boost::shared_ptr X; - - /** - * The difference between the current and previous estimate. - * See ::update() for why this is necessary. - * - */ - boost::shared_ptr Xdelta; - /** - * Constructor - * The current network state is gathered from the network. - * @param factory powerflow factory - * @param network network controlled by @c factory - * @return - */ - VSSolverHelper(boost::shared_ptr factory, - boost::shared_ptr network) - : p_factory(factory), p_network(network), Xold(), Xdelta() - { - p_factory->setMode(VS_State); - mapper::BusVectorMap vMap(p_network); - Xold = vMap.mapToRealVector(); - // Xold->print(); - X.reset(Xold->clone()); - Xdelta.reset(Xold->clone()); - Xdelta->zero(); - p_factory->setMode(VS_Jacobian); - mapper::FullMatrixMap jMap(p_network); - J = jMap.mapToRealMatrix(); - } - - /** - * Push the current estimated state back onto the network. - * The network state (voltage, phase) is updated with the current - * estimate from the nonlinear solver. - * - * FIXME: The problem here is that ...::mapToBus expects the - * @e CHANGE (old - current)? in state variables. IMHO, there should - * be a way to set the state variables directly. The solver should - * be responsible for making the @e entire estimate. - * - * @param Xcur current state estimate from the solver - */ - void - update(const math::RealVector& Xcur) - { - - Xdelta->equate(Xcur); - Xdelta->scale(-1.0); - Xdelta->add(*Xold); - double snorm(Xdelta->norm2()); - if (Xdelta->processor_rank() == 0) { - std::cout << "VSSolverHelper::update(): solution residual: " << snorm << std::endl; - } - - // Xdelta->print(); - p_factory->setMode(VS_RHS); - mapper::BusVectorMap vMap(p_network); - vMap.mapToBus(Xdelta); - Xold->equate(Xcur); - - // Exchange data between ghost buses (I don't think we need to exchange data - // between branches) - p_network->updateBuses(); - - } - - /** - * Build the Jacobian Matrix. - * This is called by the nonlinear solver each iteration to build - * the Jacobian from the current network state. - * - * @param Xcur current state estimate - * @param J Jacobian - */ - void - operator() (const math::RealVector& Xcur, math::RealMatrix& theJ) - { - // In both the Netwon-Raphson and PETSc nonlinear solver (some - // methods) implementations, the RHS function builder is called - // before this, so we may be able to count on the current solution - // being on the netork when here. - - // X.print(); - // update(Xcur); - - // Set to build Jacobian - p_factory->setMode(VS_Jacobian); - mapper::FullMatrixMap jMap(p_network); - - // build the Jacobian - jMap.mapToRealMatrix(theJ); - } - - /** - * Build the RHS function vector. - * This is called by the nonlinear solver each iteration to build - * the RHS vector from the current network state. This is also - * responsible for updating the network state with the current - * solution estimate, which assumes that it is called only once per - * solver iteration. This may not be true if certain methods are - * used or if a finite difference Jacobian is computed by the - * solver. - * - * @param Xcur current state estimate - * @param PQ computed RHS vector - */ - void - operator() (const math::RealVector& Xcur, math::RealVector& PQ) - { - // In both the Netwon-Raphson and PETSc nonlinear solver - // implementations, this is called before the Jacobian builder, so - // we may only need to map the solution back on to the network here. - - // X.print(); - update(Xcur); - - // set to build RHS vector - p_factory->setMode(VS_RHS); - mapper::BusVectorMap vMap(p_network); - - // build the RHS vector - vMap.mapToRealVector(PQ); - printf("norm of PQ: %f\n",PQ.norm2()); - } -}; -} -} + }; +}} \ No newline at end of file diff --git a/src/applications/powerflow/CMakeLists.txt b/src/applications/powerflow/CMakeLists.txt index dd2ff41f0..0c8d829c0 100644 --- a/src/applications/powerflow/CMakeLists.txt +++ b/src/applications/powerflow/CMakeLists.txt @@ -16,6 +16,8 @@ set(target_libraries gridpack_powerflow_module gridpack_pfmatrix_components + gridpack_voltage_stability_module + gridpack_vsmatrix_components gridpack_ymatrix_components gridpack_components gridpack_stream diff --git a/src/applications/powerflow/pf_main.cpp b/src/applications/powerflow/pf_main.cpp index 3e12376ef..954277475 100644 --- a/src/applications/powerflow/pf_main.cpp +++ b/src/applications/powerflow/pf_main.cpp @@ -19,6 +19,7 @@ #include #include "gridpack/include/gridpack.hpp" #include "gridpack/applications/modules/powerflow/pf_app_module.hpp" +#include "gridpack/applications/modules/voltage_stability/vs_app_module.hpp" const char* help = "GridPACK power flow application"; @@ -101,6 +102,16 @@ int main(int argc, char **argv) if (!noPrint) { timer ->dump(); } + bool start = pf_app.isPVAnlyDone(); + std::cout<<"Finished Power Flow. Initializing PV analysis: "< #include @@ -24,6 +24,7 @@ const char* help = "GridPACK power flow application"; int main(int argc, char **argv) { + // Initialize libraries (parallel and math) gridpack::Environment env(argc,argv,help); @@ -101,8 +102,15 @@ int main(int argc, char **argv) if (!noPrint) { timer ->dump(); } + bool start = pf_app.isPVAnlyDone(); + pf_app.InitializePVCurve(); + while(!pf_app.isPVAnlyDone()){ + pf_app.IncrementPVCurveStep(); + pf_app.solve(); + pf_app.saveData(); + } } return 0; } - +*/