00001
00011 #include "pw_load.h"
00012
00013 #ifdef HAVE_POWERWORLD
00014 #ifndef PWX64
00015
00023 int check_COM_output_load(_variant_t output){
00024 BSTR bHolder;
00025 _variant_t element;
00026 LONG indices[1] = {0};
00027 char *ptr = 0;
00028 HRESULT hr;
00029 SAFEARRAY *output_array;
00030
00031 if(output.vt != (VT_VARIANT | VT_ARRAY)){
00032 gl_error("check_COM_output_load: COM call did not return an array of variants");
00033
00034
00035
00036
00037 return 0;
00038 }
00039 output_array = output.parray;
00040 hr = SafeArrayGetElement(output_array, indices, &element);
00041 switch(hr){
00042 case S_OK:
00043 break;
00044 case DISP_E_BADINDEX:
00045 gl_error("check_COM_output_load: bad index in SafeArrayGetElement");
00046
00047
00048
00049
00050 return 0;
00051 break;
00052 case E_INVALIDARG:
00053 gl_error("check_COM_output_load: invalid arguement in SafeArrayGetElement");
00054
00055
00056
00057
00058 return 0;
00059 break;
00060 case E_OUTOFMEMORY:
00061 gl_error("check_COM_output_load: ran out of memory during SafeArrayGetElement");
00062
00063
00064
00065
00066
00067 return 0;
00068 break;
00069 }
00070 bHolder = element.bstrVal;
00071 ptr = _com_util::ConvertBSTRToString(bHolder);
00072 if(strlen(ptr) > 0){
00073 gl_error("check_COM_output_load: %s", ptr);
00074
00075
00076
00077
00078 return 0;
00079 }
00080 return 1;
00081 }
00082
00083
00084 EXPORT_CREATE(pw_load);
00085 EXPORT_INIT(pw_load);
00086 EXPORT_SYNC(pw_load);
00087 EXPORT_ISA(pw_load);
00088
00089 CLASS *pw_load::oclass = NULL;
00090 pw_load *pw_load::defaults = NULL;
00091
00092 pw_load::pw_load(MODULE *module)
00093 {
00094 if (oclass==NULL)
00095 {
00096
00097 oclass = gld_class::create(module,"pw_load",sizeof(pw_load),PC_PRETOPDOWN|PC_BOTTOMUP|PC_POSTTOPDOWN|PC_AUTOLOCK);
00098 if (oclass==NULL){
00099 throw "unable to register class pw_load";
00100
00101 } else {
00102 oclass->trl = TRL_PROVEN;
00103 }
00104
00105 defaults = this;
00106 if (gl_publish_variable(oclass,
00107 PT_int32, "powerworld_bus_num", get_powerworld_bus_num_offset(),PT_DESCRIPTION, "bus_num key field of the load",
00108 PT_char1024, "powerworld_load_id", get_powerworld_load_id_offset(),PT_DESCRIPTION, "load_id key field of the load",
00109 PT_double, "power_threshold[MVA]", get_power_threshold_offset(),PT_DESCRIPTION, "power threshold for this object to trigger a model update",
00110 PT_double, "power_diff[MVA]", get_power_diff_offset(),PT_DESCRIPTION, "current power difference posted to this object",
00111 PT_complex, "load_power[MVA]", get_load_power_offset(),PT_DESCRIPTION, "constant power draw on the load",
00112 PT_complex, "load_impedance[MVA]", get_load_impedance_offset(),PT_DESCRIPTION, "constant impedance draw on the load",
00113 PT_complex, "load_current[MVA]", get_load_current_offset(),PT_DESCRIPTION, "constant current draw on the load",
00114 PT_complex, "last_load_power[MVA]", get_last_load_power_offset(),PT_DESCRIPTION, "constant power draw on the load",
00115 PT_complex, "last_load_impedance[MVA]", get_last_load_impedance_offset(),PT_DESCRIPTION, "constant impedance draw on the load",
00116 PT_complex, "last_load_current[MVA]", get_last_load_current_offset(),PT_DESCRIPTION, "constant current draw on the load",
00117 PT_complex, "load_voltage[V]", get_load_voltage_offset(),PT_DESCRIPTION, "transmission system voltage on this load",
00118 PT_double, "bus_nom_volt[V]", get_bus_nom_volt_offset(), PT_DESCRIPTION, "Nominal voltage of PowerWorld load",
00119 PT_double, "bus_volt_angle[deg]", get_bus_volt_angle_offset(),PT_DESCRIPTION,"Current voltage angle of the PowerWorld load",
00120
00121 PT_double, "pw_load_mw", get_pw_load_mw_offset(),PT_DESCRIPTION,"Real power portion of total power of the PowerWorld load",
00122 PT_complex, "pw_load_mva", get_pw_load_mva_offset(),PT_DESCRIPTION,"Complex value of total power of the PowerWorld load",
00123 NULL)<1){
00124 char msg[256];
00125 sprintf(msg, "unable to publish properties in %s",__FILE__);
00126 throw msg;
00127
00128 }
00129
00130 memset(this,0,sizeof(pw_load));
00131 powerworld_bus_num = -1;
00132 }
00133 }
00134
00135 int pw_load::create(){
00136 return 1;
00137 }
00138
00139 int pw_load::get_powerworld_busangle(){
00140
00141 _variant_t HUGEP *presults, *pvariant;
00142 HRESULT hr;
00143 SAFEARRAYBOUND bounds[1];
00144 _variant_t fields, values, results;
00145 char *tempstr = 0;
00146 BSTR tempbstr = 0;
00147
00148 double load_angle = 0.0;
00149
00150
00151
00152 try {
00153 ISimulatorAutoPtr SimAuto(cModel->A);
00154
00155 bounds[0].cElements = 2;
00156 bounds[0].lLbound = 0;
00157
00158 fields.vt = VT_ARRAY | VT_VARIANT;
00159 fields.parray = SafeArrayCreate(VT_VARIANT, 1, bounds);
00160 if (!fields.parray){
00161 throw _com_error(E_OUTOFMEMORY);
00162 }
00163 values.vt = VT_ARRAY | VT_VARIANT;
00164 values.parray = SafeArrayCreate(VT_VARIANT, 1, bounds);
00165 if (!values.parray){
00166 throw _com_error(E_OUTOFMEMORY);
00167 }
00168
00169 hr = SafeArrayAccessData(fields.parray, (void HUGEP **)&pvariant);
00170 if (FAILED(hr)){
00171 throw _com_error(hr);
00172 }
00173 pvariant[0] = "BusNum";
00174 pvariant[1] = "BusAngle";
00175 SafeArrayUnaccessData(fields.parray);
00176
00177 hr = SafeArrayAccessData(values.parray, (void HUGEP **)&pvariant);
00178 if (FAILED(hr)){
00179 throw _com_error(hr);
00180 }
00181 char pbn_str[32];
00182 sprintf(pbn_str, "%i", powerworld_bus_num);
00183
00184 pvariant[0] = _com_util::ConvertStringToBSTR(pbn_str);
00185 pvariant[1] = _variant_t();
00186
00187 SysFreeString(tempbstr);
00188 SafeArrayUnaccessData(values.parray);
00189
00190 results = SimAuto->GetParametersSingleElement(L"Bus", fields, values);
00191
00192 hr = SafeArrayAccessData(results.parray, (void HUGEP **)&presults);
00193 if (FAILED(hr)){
00194 throw _com_error(hr);
00195 }
00196 if (((_bstr_t)(_variant_t)presults[0]).length()){
00197 tempstr = _com_util::ConvertBSTRToString((_bstr_t)(_variant_t)presults[0]);
00198 gl_error("Error from GetParametersSingleElement(): %s", tempstr);
00199
00200
00201
00202
00203 delete [] tempstr;
00204 tempstr = 0;
00205 SafeArrayDestroy(fields.parray);
00206 SafeArrayDestroy(values.parray);
00207 return 1;
00208 } else {
00209
00210 hr = SafeArrayAccessData(presults[1].parray, (void HUGEP **)&pvariant);
00211 if (FAILED(hr)){
00212 throw _com_error(hr);
00213 }
00214 load_angle = wcstod(pvariant[1].bstrVal, 0);
00215
00216 SafeArrayUnaccessData(presults[1].parray);
00217
00218
00219 }
00220 SafeArrayUnaccessData(results.parray);
00221 bus_volt_angle = load_angle;
00222
00223
00224
00225 SafeArrayDestroy(fields.parray);
00226 SafeArrayDestroy(values.parray);
00227 }
00228 catch (_com_error err) {
00229
00230 std::cout << "!!! " << err.ErrorMessage() << "\n";
00231 return 1;
00232 }
00233 catch(...){
00234 gl_error("Unknown excetpion in get_powerworld_busangle!");
00235 return 1;
00236 }
00237 return 0;
00238 }
00239
00240 int pw_load::get_powerworld_nomvolt(){
00241
00242 _variant_t HUGEP *presults, *pvariant;
00243 HRESULT hr;
00244 SAFEARRAYBOUND bounds[1];
00245 _variant_t fields, values, results;
00246 char *tempstr = 0;
00247 BSTR tempbstr = 0;
00248
00249 double load_bnv = 0.0;
00250
00251
00252 try {
00253 ISimulatorAutoPtr SimAuto(cModel->A);
00254
00255 bounds[0].cElements = 2;
00256 bounds[0].lLbound = 0;
00257
00258 fields.vt = VT_ARRAY | VT_VARIANT;
00259 fields.parray = SafeArrayCreate(VT_VARIANT, 1, bounds);
00260 if (!fields.parray){
00261 throw _com_error(E_OUTOFMEMORY);
00262 }
00263 values.vt = VT_ARRAY | VT_VARIANT;
00264 values.parray = SafeArrayCreate(VT_VARIANT, 1, bounds);
00265 if (!values.parray){
00266 throw _com_error(E_OUTOFMEMORY);
00267 }
00268
00269 hr = SafeArrayAccessData(fields.parray, (void HUGEP **)&pvariant);
00270 if (FAILED(hr)){
00271 throw _com_error(hr);
00272 }
00273 pvariant[0] = "BusNum";
00274 pvariant[1] = "BusNomVolt";
00275 SafeArrayUnaccessData(fields.parray);
00276
00277 hr = SafeArrayAccessData(values.parray, (void HUGEP **)&pvariant);
00278 if (FAILED(hr)){
00279 throw _com_error(hr);
00280 }
00281 char pbn_str[32];
00282 sprintf(pbn_str, "%i", powerworld_bus_num);
00283
00284 pvariant[0] = _com_util::ConvertStringToBSTR(pbn_str);
00285 pvariant[1] = _variant_t();
00286
00287 SysFreeString(tempbstr);
00288 SafeArrayUnaccessData(values.parray);
00289
00290 results = SimAuto->GetParametersSingleElement(L"Bus", fields, values);
00291
00292 hr = SafeArrayAccessData(results.parray, (void HUGEP **)&presults);
00293 if (FAILED(hr)){
00294 throw _com_error(hr);
00295 }
00296 if (((_bstr_t)(_variant_t)presults[0]).length()){
00297 tempstr = _com_util::ConvertBSTRToString((_bstr_t)(_variant_t)presults[0]);
00298 gl_error("Error from GetParametersSingleElement(): %s", tempstr);
00299
00300
00301
00302
00303 delete [] tempstr;
00304 tempstr = 0;
00305 SafeArrayDestroy(fields.parray);
00306 SafeArrayDestroy(values.parray);
00307
00308 return 1;
00309 } else {
00310
00311 hr = SafeArrayAccessData(presults[1].parray, (void HUGEP **)&pvariant);
00312 if (FAILED(hr)){
00313 throw _com_error(hr);
00314 }
00315 load_bnv = wcstod(pvariant[1].bstrVal, 0);
00316
00317 SafeArrayUnaccessData(presults[1].parray);
00318
00319
00320 }
00321 SafeArrayUnaccessData(results.parray);
00322
00323 bus_nom_volt = load_bnv * 1000.0;
00324
00325
00326
00327 SafeArrayDestroy(fields.parray);
00328 SafeArrayDestroy(values.parray);
00329 }
00330 catch (_com_error err) {
00331
00332 std::cout << "!!! " << err.ErrorMessage() << "\n";
00333 return 1;
00334 }
00335
00336 catch(...){
00337 gl_error("Unknown excetpion in get_powerworld_nomvolt!");
00338 return 1;
00339 }
00340 return 0;
00341 }
00342
00343
00349 int pw_load::get_powerworld_voltage(){
00350
00351 _variant_t HUGEP *presults, *pvariant;
00352 HRESULT hr;
00353 SAFEARRAYBOUND bounds[1];
00354 _variant_t fields, values, results;
00355 char *tempstr = 0;
00356 BSTR tempbstr = 0;
00357
00358 double load_voltage_d = 0.0;
00359 double load_mva = 0.0, load_mvr = 0.0, load_mw = 0.0;
00360
00361
00362
00363 try {
00364 ISimulatorAutoPtr SimAuto(cModel->A);
00365
00366 bounds[0].cElements = 8;
00367 bounds[0].lLbound = 0;
00368
00369 fields.vt = VT_ARRAY | VT_VARIANT;
00370 fields.parray = SafeArrayCreate(VT_VARIANT, 1, bounds);
00371 if (!fields.parray){
00372 throw _com_error(E_OUTOFMEMORY);
00373 }
00374 values.vt = VT_ARRAY | VT_VARIANT;
00375 values.parray = SafeArrayCreate(VT_VARIANT, 1, bounds);
00376 if (!values.parray){
00377 throw _com_error(E_OUTOFMEMORY);
00378 }
00379
00380 hr = SafeArrayAccessData(fields.parray, (void HUGEP **)&pvariant);
00381 if (FAILED(hr)){
00382 throw _com_error(hr);
00383 }
00384 pvariant[0] = "BusNum";
00385 pvariant[1] = "LoadID";
00386 pvariant[2] = "BusKVVolt";
00387 pvariant[3] = "LoadMVA";
00388 pvariant[4] = "LoadMW";
00389 pvariant[5] = "LoadMVR";
00390 pvariant[6] = "LoadSMW";
00391 pvariant[7] = "LoadSMVR";
00392 SafeArrayUnaccessData(fields.parray);
00393
00394 hr = SafeArrayAccessData(values.parray, (void HUGEP **)&pvariant);
00395 if (FAILED(hr)){
00396 throw _com_error(hr);
00397 }
00398 char pbn_str[32];
00399 sprintf(pbn_str, "%i", powerworld_bus_num);
00400
00401 pvariant[0] = _com_util::ConvertStringToBSTR(pbn_str);
00402 pvariant[1] = tempbstr = _com_util::ConvertStringToBSTR(this->powerworld_load_id);
00403 pvariant[2] = _variant_t();
00404 pvariant[3] = _variant_t();
00405 pvariant[4] = _variant_t();
00406 pvariant[5] = _variant_t();
00407 pvariant[6] = _variant_t();
00408 pvariant[7] = _variant_t();
00409
00410 SysFreeString(tempbstr);
00411 SafeArrayUnaccessData(values.parray);
00412
00413 results = SimAuto->GetParametersSingleElement(L"Load", fields, values);
00414
00415 hr = SafeArrayAccessData(results.parray, (void HUGEP **)&presults);
00416 if (FAILED(hr)){
00417 throw _com_error(hr);
00418 }
00419 if (((_bstr_t)(_variant_t)presults[0]).length()){
00420 tempstr = _com_util::ConvertBSTRToString((_bstr_t)(_variant_t)presults[0]);
00421 gl_error("Error from GetParametersSingleElement(): %s", tempstr);
00422
00423
00424
00425
00426 delete [] tempstr;
00427 tempstr = 0;
00428 SafeArrayDestroy(fields.parray);
00429 SafeArrayDestroy(values.parray);
00430 return 1;
00431 } else {
00432 double load_pi, load_pr;
00433
00434 hr = SafeArrayAccessData(presults[1].parray, (void HUGEP **)&pvariant);
00435 if (FAILED(hr)){
00436 throw _com_error(hr);
00437 }
00438 load_voltage_d = wcstod(pvariant[2].bstrVal, 0);
00439 load_mva = wcstod(pvariant[3].bstrVal, 0);
00440 load_mw = wcstod(pvariant[4].bstrVal, 0);
00441 load_mvr = wcstod(pvariant[5].bstrVal, 0);
00442 load_pr = wcstod(pvariant[6].bstrVal, 0);
00443 load_pi = wcstod(pvariant[7].bstrVal, 0);
00444 SafeArrayUnaccessData(presults[1].parray);
00445
00446
00447 }
00448 SafeArrayUnaccessData(results.parray);
00449 load_voltage_mag = load_voltage_d * 1000.0;
00450 pw_load_mw = load_mw;
00451 pw_load_mva = complex(load_mw, load_mvr, I);
00452
00453
00454
00455 SafeArrayDestroy(fields.parray);
00456 SafeArrayDestroy(values.parray);
00457 }
00458 catch (_com_error err) {
00459
00460 std::cout << "!!! " << err.ErrorMessage() << "\n";
00461 return 1;
00462 }
00463 catch(...){
00464 gl_error("Unknown excetpion in get_pwd_voltage!");
00465 return 1;
00466 }
00467 return 0;
00468 }
00469
00475 int pw_load::post_powerworld_current(){
00476
00477 _variant_t HUGEP *presults, *pvariant;
00478 HRESULT hr;
00479 SAFEARRAYBOUND bounds[1];
00480 _variant_t fields, values, results;
00481 BSTR tempbstr;
00482
00483 try {
00484 ISimulatorAutoPtr SimAuto(cModel->A);
00485
00486 bounds[0].cElements = 8;
00487 bounds[0].lLbound = 0;
00488
00489 fields.vt = VT_ARRAY | VT_VARIANT;
00490 fields.parray = SafeArrayCreate(VT_VARIANT, 1, bounds);
00491 if (!fields.parray){
00492 throw _com_error(E_OUTOFMEMORY);
00493 }
00494 values.vt = VT_ARRAY | VT_VARIANT;
00495 values.parray = SafeArrayCreate(VT_VARIANT, 1, bounds);
00496 if (!values.parray){
00497 throw _com_error(E_OUTOFMEMORY);
00498 }
00499
00500 hr = SafeArrayAccessData(fields.parray, (void HUGEP **)&pvariant);
00501 if (FAILED(hr)){
00502 throw _com_error(hr);
00503 }
00504 pvariant[0] = "BusNum";
00505 pvariant[1] = "LoadID";
00506 pvariant[2] = "LoadSMW";
00507 pvariant[3] = "LoadSMVR";
00508 pvariant[4] = "LoadIMW";
00509 pvariant[5] = "LoadIMVR";
00510 pvariant[6] = "LoadZMW";
00511 pvariant[7] = "LoadZMVR";
00512 SafeArrayUnaccessData(fields.parray);
00513
00514 hr = SafeArrayAccessData(values.parray, (void HUGEP **)&pvariant);
00515 if (FAILED(hr)){
00516 throw _com_error(hr);
00517 }
00518 pvariant[0] = this->powerworld_bus_num;
00519 pvariant[1] = tempbstr = _com_util::ConvertStringToBSTR(this->powerworld_load_id);
00520 pvariant[2] = load_power.Re();
00521 pvariant[3] = load_power.Im();
00522 pvariant[4] = load_current.Re();
00523 pvariant[5] = load_current.Im();
00524 pvariant[6] = load_impedance.Re();
00525 pvariant[7] = load_impedance.Im();
00526 SysFreeString(tempbstr);
00527 SafeArrayUnaccessData(values.parray);
00528
00529
00530 results = SimAuto->ChangeParametersSingleElement(L"Load", fields, values);
00531
00532 hr = SafeArrayAccessData(results.parray, (void HUGEP **)&presults);
00533 if (FAILED(hr)){
00534 throw _com_error(hr);
00535 }
00536 if (((_bstr_t)(_variant_t)presults[0]).length()){
00537 char *tempstr = _com_util::ConvertBSTRToString((_bstr_t)(_variant_t)presults[0]);
00538 gl_error("Error from SetParametersSingleElement(): %s", tempstr);
00539
00540
00541
00542
00543 delete [] tempstr;
00544 } else {
00545
00546 }
00547 SafeArrayUnaccessData(results.parray);
00548 }
00549 catch (_com_error err) {
00550
00551 std::cout << "!!! " << err.ErrorMessage() << "\n";
00552 }
00553 return 0;
00554 }
00555
00561 int pw_load::init(OBJECT *parent){
00562 _bstr_t otype;
00563 _variant_t plist;
00564 _variant_t vlist;
00565 _variant_t output;
00566
00567
00568
00569
00570 int nomvolt_value = 0;
00571 int busangle_value = 0;
00572 int voltage_value = 0;
00573
00574 if(0 == parent){
00575 char objname[256];
00576 gl_error("pw_load::init(): object \'%s\' does not specify a parent model object", gl_name(parent, objname, 255));
00577
00578
00579
00580 return 0;
00581 }
00582 if(!gl_object_isa(parent, "pw_model")){
00583 char objname[256], modelname[256];
00584 gl_error("pw_load::init(): object \'%s\' specifies a parent object \'%s\' that is not a pw_model object", gl_name(parent, objname, 255), gl_name(parent, modelname, 255));
00585
00586
00587
00588 return 0;
00589 }
00590 if((parent->flags & OF_INIT) != OF_INIT){
00591 char objname[256];
00592 gl_verbose("pw_load::init(): deferring initialization on %s", gl_name(parent, objname, 255));
00593 return 2;
00594 }
00595
00596
00597 cModel = OBJECTDATA(parent, pw_model);
00598
00599
00600 if(powerworld_bus_num < 0){
00601 gl_error("powerworld_bus_num must be a non-negative integer");
00602
00603
00604
00605 return 0;
00606 }
00607 if(powerworld_load_id[0] == 0){
00608 gl_error("powerworld_load_id must be set");
00609
00610
00611
00612 return 0;
00613 }
00614 nomvolt_value = get_powerworld_nomvolt();
00615 busangle_value = get_powerworld_busangle();
00616 voltage_value = get_powerworld_voltage();
00617
00618 if(nomvolt_value != 0){
00619 char objname[256];
00620 gl_error("pw_load::init(): unable to get PowerWorld nominal voltage from Bus #%i, for the pw_load \'%s\'", powerworld_bus_num, gl_name(OBJECTHDR(this), objname, 255));
00621
00622
00623
00624
00625 return 0;
00626 }
00627
00628 if(busangle_value != 0){
00629 char objname[256];
00630 gl_error("pw_load::init(): unable to get PowerWorld bus voltage from Bus #%i, Load ID %s, for the pw_load \'%s\'", powerworld_bus_num, powerworld_load_id, gl_name(OBJECTHDR(this), objname, 255));
00631
00632
00633
00634
00635 return 0;
00636 }
00637 if(voltage_value != 0){
00638 char objname[256];
00639 gl_error("pw_load::init(): unable to get PowerWorld bus voltage from Bus #%i, Load ID %s, for the pw_load \'%s\'", powerworld_bus_num, powerworld_load_id, gl_name(OBJECTHDR(this), objname, 255));
00640
00641
00642
00643
00644 return 0;
00645 }
00646
00647 load_voltage.SetPolar(load_voltage_mag, (bus_volt_angle/180.0*PI),A);
00648
00649
00650 if(power_threshold < 0.0){
00651 gl_warning("pw_load::init(): power_threshold is negative, making positive");
00652
00653
00654
00655
00656 power_threshold = -power_threshold;
00657 }
00658
00659
00660 if (power_threshold == 0.0)
00661 {
00662
00663 power_threshold = 0.1*pw_load_mva.Mag();
00664
00665 if (power_threshold == 0.0)
00666 {
00667 gl_warning("pw_load::init(): power_threshold is zero, convergence may not occur!");
00668
00669
00670
00671
00672
00673 }
00674 else
00675 {
00676 gl_warning("pw_load::init(): power_threshold was zero, set to 0.1%% of load - %.0f MVA",power_threshold);
00677
00678
00679
00680
00681
00682 }
00683 }
00684
00685 return 1;
00686 }
00687
00692 TIMESTAMP pw_load::presync(TIMESTAMP t1){
00693 if(0 == cModel){
00694 gl_error("pw_load::presync(): cModel is null (is deferred initialization enabled?)");
00695
00696
00697
00698
00699 return TS_INVALID;
00700 }
00701 if(!cModel->get_valid_flag()){
00702 gl_verbose("not fetching voltage due to invalid model state");
00703 } else {
00704 if(0 != get_powerworld_busangle()){
00705 gl_error("pw_load::presync(): get_powerworld_busangle failed");
00706
00707
00708
00709
00710 return TS_INVALID;
00711 }
00712 if(0 != get_powerworld_voltage()){
00713 gl_error("pw_load::presync(): get_powerworld_voltage failed");
00714
00715
00716
00717
00718 return TS_INVALID;
00719 }
00720
00721 load_voltage.SetPolar(load_voltage_mag, (bus_volt_angle/180.0*PI),A);
00722 }
00723
00724
00725 return TS_NEVER;
00726 }
00727
00734 TIMESTAMP pw_load::sync(TIMESTAMP t1){
00735
00736
00737 double z_diff, i_diff, p_diff;
00738 z_diff = load_power.Mag() - last_load_power.Mag();
00739 i_diff = load_current.Mag() - last_load_current.Mag();
00740 p_diff = load_impedance.Mag() - last_load_impedance.Mag();
00741 power_diff = fabs(z_diff) + fabs(i_diff) + fabs(p_diff);
00742
00743 if(power_diff > power_threshold){
00744 OBJECT *obj = OBJECTHDR(this);
00745 cModel->set_update_flag(true, gld_wlock(obj->parent));
00746
00747 }
00748 return TS_NEVER;
00749 }
00750
00755 TIMESTAMP pw_load::postsync(TIMESTAMP t1){
00756
00757
00758
00759 if(cModel->get_update_flag()){
00760 if(0 != post_powerworld_current()){
00761 return TS_INVALID;
00762 }
00763
00764 last_load_power = load_power;
00765 last_load_current = load_current;
00766 last_load_impedance = load_impedance;
00767 }
00768 return TS_NEVER;
00769 }
00770
00771 int pw_load::isa(char *classname){
00772 return (0 == strcmp(classname, oclass->name));
00773 }
00774
00775 #endif //PWX64
00776 #endif //HAVE_POWERWORLD
00777