00001
00050 #include <stdlib.h>
00051 #include <stdio.h>
00052 #include <errno.h>
00053 #include <math.h>
00054
00055 #include "solver_nr.h"
00056 #include "restoration.h"
00057 #include "node.h"
00058 #include "transformer.h"
00059
00060 CLASS *node::oclass = NULL;
00061 CLASS *node::pclass = NULL;
00062
00063 unsigned int node::n = 0;
00064
00065 node::node(MODULE *mod) : powerflow_object(mod)
00066 {
00067 if(oclass == NULL)
00068 {
00069 pclass = powerflow_object::oclass;
00070 oclass = gl_register_class(mod,"node",sizeof(node),PC_PRETOPDOWN|PC_BOTTOMUP|PC_POSTTOPDOWN|PC_UNSAFE_OVERRIDE_OMIT);
00071 if(oclass == NULL)
00072 GL_THROW("unable to register object class implemented by %s",__FILE__);
00073
00074 if(gl_publish_variable(oclass,
00075 PT_INHERIT, "powerflow_object",
00076 PT_enumeration, "bustype", PADDR(bustype),
00077 PT_KEYWORD, "PQ", PQ,
00078 PT_KEYWORD, "PV", PV,
00079 PT_KEYWORD, "SWING", SWING,
00080 PT_set, "busflags", PADDR(busflags),
00081 PT_KEYWORD, "HASSOURCE", (set)NF_HASSOURCE,
00082 PT_object, "reference_bus", PADDR(reference_bus),
00083 PT_double,"maximum_voltage_error[V]",PADDR(maximum_voltage_error),
00084
00085 PT_complex, "voltage_A[V]", PADDR(voltageA),
00086 PT_complex, "voltage_B[V]", PADDR(voltageB),
00087 PT_complex, "voltage_C[V]", PADDR(voltageC),
00088 PT_complex, "voltage_AB[V]", PADDR(voltageAB),
00089 PT_complex, "voltage_BC[V]", PADDR(voltageBC),
00090 PT_complex, "voltage_CA[V]", PADDR(voltageCA),
00091 PT_complex, "current_A[A]", PADDR(currentA),
00092 PT_complex, "current_B[A]", PADDR(currentB),
00093 PT_complex, "current_C[A]", PADDR(currentC),
00094 PT_complex, "power_A[VA]", PADDR(powerA),
00095 PT_complex, "power_B[VA]", PADDR(powerB),
00096 PT_complex, "power_C[VA]", PADDR(powerC),
00097 PT_complex, "shunt_A[S]", PADDR(shuntA),
00098 PT_complex, "shunt_B[S]", PADDR(shuntB),
00099 PT_complex, "shunt_C[S]", PADDR(shuntC),
00100
00101 NULL) < 1) GL_THROW("unable to publish properties in %s",__FILE__);
00102
00103
00104 nodelinks.next=NULL;
00105 }
00106 }
00107
00108 int node::isa(char *classname)
00109 {
00110 return strcmp(classname,"node")==0 || powerflow_object::isa(classname);
00111 }
00112
00113 int node::create(void)
00114 {
00115 int result = powerflow_object::create();
00116
00117 #ifdef SUPPORT_OUTAGES
00118 condition=OC_NORMAL;
00119 #endif
00120
00121 n++;
00122
00123 bustype = PQ;
00124 busflags = NF_HASSOURCE;
00125 busphasesIn = 0;
00126 busphasesOut = 0;
00127 reference_bus = NULL;
00128 nominal_voltage = 0.0;
00129 maximum_voltage_error = 0.0;
00130 frequency = nominal_frequency;
00131 fault_Z = 1e-6;
00132 prev_NTime = 0;
00133 SubNode = NONE;
00134 SubNodeParent = NULL;
00135 NR_subnode_reference = NULL;
00136 Extra_Data=NULL;
00137 NR_link_table = NULL;
00138 NR_connected_links[0] = NR_connected_links[1] = 0;
00139 YVs[0] = YVs[1] = YVs[2] = 0.0;
00140
00141 GS_converged=false;
00142
00143 NR_node_reference = -1;
00144 house_present = false;
00145 nom_res_curr[0] = nom_res_curr[1] = nom_res_curr[2] = 0.0;
00146
00147 memset(voltage,0,sizeof(voltage));
00148 memset(voltaged,0,sizeof(voltaged));
00149 memset(current,0,sizeof(current));
00150 memset(power,0,sizeof(power));
00151 memset(shunt,0,sizeof(shunt));
00152
00153 return result;
00154 }
00155
00156 int node::init(OBJECT *parent)
00157 {
00158
00159
00160
00161
00162
00163
00164
00165
00166 if (solver_method==SM_NR)
00167 {
00168 OBJECT *obj = OBJECTHDR(this);
00169
00170
00171 if (NR_swing_bus == NULL)
00172 {
00173 OBJECT *temp_obj = NULL;
00174 node *list_node;
00175 unsigned int swing_count = 0;
00176 FINDLIST *bus_list = gl_find_objects(FL_NEW,FT_CLASS,SAME,"node",FT_END);
00177
00178
00179 while(temp_obj=gl_find_next(bus_list,temp_obj))
00180 {
00181 list_node = OBJECTDATA(temp_obj,node);
00182
00183 if (list_node->bustype==SWING)
00184 {
00185 NR_swing_bus=temp_obj;
00186 swing_count++;
00187 }
00188 }
00189
00190
00191 gl_free(bus_list);
00192 bus_list = gl_find_objects(FL_NEW,FT_CLASS,SAME,"meter",FT_END);
00193
00194
00195 temp_obj = NULL;
00196
00197
00198 while(temp_obj=gl_find_next(bus_list,temp_obj))
00199 {
00200 list_node = OBJECTDATA(temp_obj,node);
00201
00202 if (list_node->bustype==SWING)
00203 {
00204 NR_swing_bus=temp_obj;
00205 swing_count++;
00206 }
00207 }
00208
00209
00210 gl_free(bus_list);
00211 bus_list = gl_find_objects(FL_NEW,FT_CLASS,SAME,"load",FT_END);
00212
00213
00214 temp_obj = NULL;
00215
00216
00217 while(temp_obj=gl_find_next(bus_list,temp_obj))
00218 {
00219 list_node = OBJECTDATA(temp_obj,node);
00220
00221 if (list_node->bustype==SWING)
00222 {
00223 NR_swing_bus=temp_obj;
00224 swing_count++;
00225 }
00226 }
00227
00228
00229 gl_free(bus_list);
00230 bus_list = gl_find_objects(FL_NEW,FT_CLASS,SAME,"triplex_node",FT_END);
00231
00232
00233 temp_obj = NULL;
00234
00235
00236 while(temp_obj=gl_find_next(bus_list,temp_obj))
00237 {
00238 list_node = OBJECTDATA(temp_obj,node);
00239
00240 if (list_node->bustype==SWING)
00241 {
00242 NR_swing_bus=temp_obj;
00243 swing_count++;
00244 }
00245 }
00246
00247
00248 gl_free(bus_list);
00249
00250 if (swing_count==0)
00251 {
00252 GL_THROW("NR: no swing bus found");
00253
00254
00255
00256
00257 }
00258
00259 if (swing_count>1)
00260 {
00261 GL_THROW("NR: more than one swing bus found!");
00262
00263
00264
00265
00266
00267 }
00268 }
00269
00270
00271 if ((obj->parent!=NULL) && (OBJECTDATA(obj->parent,node)->bustype!=SWING))
00272 {
00273
00274 if (!(gl_object_isa(obj->parent,"load","powerflow") | gl_object_isa(obj->parent,"node","powerflow") | gl_object_isa(obj->parent,"meter","powerflow")))
00275 GL_THROW("NR: Parent is not a node, load or meter!");
00276
00277
00278
00279
00280
00281 node *parNode = OBJECTDATA(obj->parent,node);
00282
00283
00284 set p_phase_to_check, c_phase_to_check;
00285
00286
00287 p_phase_to_check = (parNode->phases & (~(PHASE_N)));
00288 c_phase_to_check = (phases & (~(PHASE_N)));
00289
00290
00291 if ((parNode->phases!=phases) && (p_phase_to_check != c_phase_to_check))
00292 {
00293
00294 p_phase_to_check = (parNode->phases & (~(PHASE_D | PHASE_N)));
00295 c_phase_to_check = (phases & (~(PHASE_D | PHASE_N)));
00296
00297
00298 if ((phases & PHASE_D) && ((parNode->phases & (PHASE_A|PHASE_B|PHASE_C)) != (PHASE_A|PHASE_B|PHASE_C)))
00299 {
00300 GL_THROW("NR: Parent and child node phases for nodes %s and %s do not match!",obj->parent->name,obj->name);
00301
00302
00303
00304
00305
00306 }
00307 else if ((p_phase_to_check & c_phase_to_check) != c_phase_to_check)
00308 {
00309 GL_THROW("NR: Parent and child node phases for nodes %s and %s do not match!",obj->parent->name,obj->name);
00310
00311 }
00312 else
00313 {
00314 if ((parNode->SubNode==CHILD) | (parNode->SubNode==DIFF_CHILD) | ((obj->parent->parent!=NR_swing_bus) && (obj->parent->parent!=NULL)))
00315 {
00316 GL_THROW("NR: Grandchildren are not supported at this time!");
00317
00318
00319
00320
00321
00322
00323 }
00324 else
00325 {
00326
00327 SubNode = DIFF_CHILD;
00328 SubNodeParent = obj->parent;
00329
00330 parNode->SubNode = DIFF_PARENT;
00331 parNode->SubNodeParent = obj;
00332
00333
00334 NR_subnode_reference = &(parNode->NR_node_reference);
00335
00336
00337 if (parNode->Extra_Data == NULL)
00338 {
00339 parNode->Extra_Data = (complex *)gl_malloc(9*sizeof(complex));
00340 if (parNode->Extra_Data == NULL)
00341 {
00342 GL_THROW("NR: Memory allocation failure for differently connected load.");
00343
00344
00345
00346
00347
00348 }
00349 }
00350 }
00351
00352
00353 obj->parent=NULL;
00354
00355
00356 NR_node_reference = -99;
00357
00358
00359
00360 gl_set_rank(obj,3);
00361
00362
00363 }
00364 }
00365 else
00366 {
00367 if ((parNode->SubNode==CHILD) | (parNode->SubNode==DIFF_CHILD) | ((obj->parent->parent!=NR_swing_bus) && (obj->parent->parent!=NULL)))
00368 {
00369 GL_THROW("NR: Grandchildren are not supported at this time!");
00370
00371 }
00372 else
00373 {
00374
00375 SubNode = CHILD;
00376 SubNodeParent = obj->parent;
00377
00378 parNode->SubNode = PARENT;
00379 parNode->SubNodeParent = obj;
00380
00381
00382 NR_subnode_reference = &(parNode->NR_node_reference);
00383 }
00384
00385
00386 obj->parent=NULL;
00387
00388
00389 NR_node_reference = -99;
00390
00391
00392
00393 gl_set_rank(obj,3);
00394
00395
00396
00397 last_child_power[0][0] = last_child_power[0][1] = last_child_power[0][2] = complex(0,0);
00398 last_child_power[1][0] = last_child_power[1][1] = last_child_power[1][2] = complex(0,0);
00399 last_child_power[2][0] = last_child_power[2][1] = last_child_power[2][2] = complex(0,0);
00400 last_child_current12 = 0.0;
00401 }
00402 }
00403 else
00404 {
00405 NR_bus_count++;
00406
00407
00408
00409 if (bustype==SWING)
00410 {
00411 gl_set_rank(obj,6);
00412 }
00413 else
00414 {
00415 gl_set_rank(obj,4);
00416 }
00417 }
00418
00419 if ((obj->parent==NULL) && (bustype!=SWING))
00420 {
00421 gl_set_parent(obj,NR_swing_bus);
00422 }
00423
00424
00425 if (this->bustype!=SWING)
00426 {
00427
00428 if (obj->parent==NULL)
00429 throw "NR: no swing bus found or specified";
00430
00431
00432
00433
00434
00435 }
00436 }
00437 else if (solver_method==SM_GS)
00438 {
00439 OBJECT *obj = OBJECTHDR(this);
00440
00441 FINDLIST *buslist = gl_find_objects(FL_NEW,FT_CLASS,SAME,"node",AND,FT_PROPERTY,"bustype",SAME,"SWING",FT_END);
00442 if (buslist==NULL)
00443 throw "GS: no swing bus found";
00444
00445
00446
00447
00448 if (buslist->hit_count>1)
00449 gl_warning("GS: more than one swing bus found, you must specify which is this node's parent");
00450
00451
00452
00453
00454
00455 OBJECT *SwingBusObj = gl_find_next(buslist,NULL);
00456
00457
00458 if ((obj->parent!=NULL) && (OBJECTDATA(obj->parent,node)->bustype!=SWING))
00459 {
00460 gl_warning("Parent/child implementation marginally tested, use at your own risk!");
00461
00462
00463
00464
00465
00466
00467 if (!(gl_object_isa(obj->parent,"load","powerflow") | gl_object_isa(obj->parent,"node","powerflow") | gl_object_isa(obj->parent,"meter","powerflow")))
00468 throw("GS: Parent is not a load or node!");
00469
00470
00471
00472
00473
00474 node *parNode = OBJECTDATA(obj->parent,node);
00475
00476
00477 if (parNode->phases!=phases)
00478 throw("GS: Parent and child node phases do not match!");
00479
00480
00481
00482
00483
00484 if ((parNode->SubNode==CHILD_NOINIT) | ((obj->parent->parent!=SwingBusObj) && (obj->parent->parent!=NULL)))
00485 {
00486
00487 SubNode = CHILD_NOINIT;
00488 if (parNode->SubNode==CHILD_NOINIT)
00489 SubNodeParent = parNode->SubNodeParent;
00490 else
00491 SubNodeParent = obj->parent->parent;
00492 }
00493 else
00494 {
00495
00496 SubNode = CHILD_NOINIT;
00497 SubNodeParent = obj->parent;
00498
00499 parNode->SubNode = PARENT;
00500 parNode->SubNodeParent = obj;
00501 }
00502
00503
00504 obj->parent=NULL;
00505
00506
00507 last_child_power[0][0] = last_child_power[0][1] = last_child_power[0][2] = complex(0,0);
00508 last_child_power[1][0] = last_child_power[1][1] = last_child_power[1][2] = complex(0,0);
00509 last_child_power[2][0] = last_child_power[2][1] = last_child_power[2][2] = complex(0,0);
00510 last_child_current12 = 0.0;
00511
00512 }
00513
00514 if ((obj->parent==NULL) && (bustype!=SWING))
00515 {
00516 gl_set_parent(obj,SwingBusObj);
00517 }
00518
00519
00520 if (this->bustype!=SWING)
00521 {
00522
00523 if (obj->parent==NULL)
00524 throw "GS: no swing bus found or specified";
00525
00526
00527
00528
00529
00530
00531
00532 if (!gl_object_isa(obj->parent,"node"))
00533 throw "GS: node parent is not a node itself";
00534
00535
00536
00537
00538
00539
00540 else
00541 {
00542 node *pNode = OBJECTDATA(obj->parent,node);
00543
00544 if (pNode->bustype!=SWING)
00545 throw "GS: node parent is not a swing bus";
00546
00547
00548
00549
00550 }
00551 }
00552
00553
00554 Ys[0][0] = Ys[0][1] = Ys[0][2] = complex(0,0);
00555 Ys[1][0] = Ys[1][1] = Ys[1][2] = complex(0,0);
00556 Ys[2][0] = Ys[2][1] = Ys[2][2] = complex(0,0);
00557
00558
00559 YVs[0] = complex(0,0);
00560 YVs[1] = complex(0,0);
00561 YVs[2] = complex(0,0);
00562 }
00563 else if (solver_method == SM_FBS)
00564 {
00565 OBJECT *obj = OBJECTHDR(this);
00566
00567 if (obj->parent != NULL)
00568 {
00569 if((gl_object_isa(obj->parent,"load","powerflow") | gl_object_isa(obj->parent,"node","powerflow") | gl_object_isa(obj->parent,"meter","powerflow")))
00570 {
00571 node *parNode = OBJECTDATA(obj->parent,node);
00572
00573
00574 set p_phase_to_check, c_phase_to_check;
00575
00576
00577 p_phase_to_check = (parNode->phases & (~(PHASE_D | PHASE_N)));
00578 c_phase_to_check = (phases & (~(PHASE_D | PHASE_N)));
00579
00580
00581 if ((p_phase_to_check & c_phase_to_check) != c_phase_to_check)
00582 {
00583 GL_THROW("Parent and child node phases are incompatible for nodes %s and %s.",obj->parent->name,obj->name);
00584
00585
00586
00587
00588 }
00589 }
00590 }
00591 }
00592 else
00593 GL_THROW("unsupported solver method");
00594
00595
00596
00597
00598 int result = powerflow_object::init(parent);
00599
00600
00601 if (solver_method==SM_GS)
00602 {
00603 OBJECT *obje = OBJECTHDR(this);
00604
00605 if (bustype==SWING)
00606 {
00607 gl_set_rank(obje,5);
00608 }
00609 else if (SubNode!=CHILD_NOINIT)
00610 {
00611 gl_set_rank(obje,1);
00612 }
00613 else
00614 {
00615 gl_set_rank(obje,1);
00616 }
00617 }
00618
00619
00620 if (nominal_voltage==0 && parent)
00621 {
00622 powerflow_object *pParent = OBJECTDATA(parent,powerflow_object);
00623 if (gl_object_isa(parent,"transformer"))
00624 {
00625 transformer *pTransformer = OBJECTDATA(parent,transformer);
00626 transformer_configuration *pConfiguration = OBJECTDATA(pTransformer->configuration,transformer_configuration);
00627 nominal_voltage = pConfiguration->V_secondary;
00628 }
00629 else
00630 nominal_voltage = pParent->nominal_voltage;
00631 }
00632
00633
00634 if (maximum_voltage_error<0)
00635 throw "negative maximum_voltage_error is invalid";
00636
00637
00638
00639
00640
00641
00642
00643 if (maximum_voltage_error==0.0)
00644 maximum_voltage_error = nominal_voltage * default_maximum_voltage_error;
00645
00646
00647 if (fault_Z<=0)
00648 throw "negative fault impedance is invalid";
00649
00650
00651
00652
00653
00654
00655 if (nominal_voltage<=0)
00656 throw "nominal_voltage is not set";
00657
00658
00659
00660
00661
00662
00663 if (k>1)
00664 {
00665 if (geographic_degree>0)
00666 geographic_degree = n/(1/(geographic_degree/n) + log((double)k));
00667 else
00668 geographic_degree = n/log((double)k);
00669 }
00670
00671
00672 if (bustype==SWING || bustype==PV)
00673 busflags |= NF_HASSOURCE;
00674
00675
00676 if (has_phase(PHASE_S))
00677 {
00678 if (has_phase(PHASE_A))
00679 {
00680 if (voltage[0] == 0)
00681 {
00682 voltage[0].SetPolar(nominal_voltage,0.0);
00683 }
00684 if (voltage[1] == 0)
00685 {
00686 voltage[1].SetPolar(nominal_voltage,0.0);
00687 }
00688 }
00689 else if (has_phase(PHASE_B))
00690 {
00691 if (voltage[0] == 0)
00692 {
00693 voltage[0].SetPolar(nominal_voltage,-PI*2/3);
00694 }
00695 if (voltage[1] == 0)
00696 {
00697 voltage[1].SetPolar(nominal_voltage,-PI*2/3);
00698 }
00699 }
00700 else if (has_phase(PHASE_C))
00701 {
00702 if (voltage[0] == 0)
00703 {
00704 voltage[0].SetPolar(nominal_voltage,PI*2/3);
00705 }
00706 if (voltage[1] == 0)
00707 {
00708 voltage[1].SetPolar(nominal_voltage,PI*2/3);
00709 }
00710 }
00711 else
00712 throw("Please specify which phase (A,B,or C) the triplex node is attached to.");
00713
00714 voltage[2] = complex(0,0);
00715 }
00716 else if ((has_phase(PHASE_A|PHASE_B|PHASE_C)) || (has_phase(PHASE_D)))
00717 {
00718 if (voltage[0] == 0)
00719 {
00720 voltage[0].SetPolar(nominal_voltage,0.0);
00721 }
00722 if (voltage[1] == 0)
00723 {
00724 voltage[1].SetPolar(nominal_voltage,-2*PI/3);
00725 }
00726 if (voltage[2] == 0)
00727 {
00728 voltage[2].SetPolar(nominal_voltage,2*PI/3);
00729 }
00730 }
00731 else
00732 {
00733 if (!has_phase(PHASE_A))
00734 voltage[0]=0.0;
00735 else
00736 voltage[0].SetPolar(nominal_voltage,0);
00737
00738 if (!has_phase(PHASE_B))
00739 voltage[1]=0.0;
00740 else
00741 voltage[2].SetPolar(nominal_voltage,-2*PI/3);
00742
00743 if (!has_phase(PHASE_C))
00744 voltage[2]=0.0;
00745 else
00746 voltage[2].SetPolar(nominal_voltage,2*PI/3);
00747 }
00748
00749 if (has_phase(PHASE_D) & voltageAB==0)
00750 {
00751 voltageAB = voltageA - voltageB;
00752 voltageBC = voltageB - voltageC;
00753 voltageCA = voltageC - voltageA;
00754 }
00755 else if (has_phase(PHASE_S))
00756 {
00757
00758 voltaged[0] = voltage[0] + voltage[1];
00759 voltaged[1] = voltage[0] - voltage[2];
00760 voltaged[2] = voltage[1] - voltage[2];
00761 }
00762
00763 return result;
00764 }
00765
00766 TIMESTAMP node::presync(TIMESTAMP t0)
00767 {
00768 OBJECT *obj = OBJECTHDR(this);
00769 TIMESTAMP t1 = powerflow_object::presync(t0);
00770
00771
00772 if (prev_NTime==0)
00773 {
00774 set phase_to_check;
00775 phase_to_check = (phases & (~(PHASE_D | PHASE_N)));
00776
00777
00778 if (((phase_to_check & busphasesIn) != phase_to_check) && (busphasesIn != 0))
00779 {
00780 GL_THROW("node:%d (%s) has more phases leaving than entering",obj->id,obj->name);
00781
00782
00783
00784
00785
00786
00787 }
00788 }
00789
00790 if (solver_method==SM_NR)
00791 {
00792
00793 current_inj[0] = current_inj[1] = current_inj[2] = 0.0;
00794
00795
00796 if (bustype==SWING)
00797 NR_cycle = !NR_cycle;
00798
00799 if (prev_NTime==0)
00800 {
00801 if (((SubNode == CHILD) || (SubNode == DIFF_CHILD)) && (NR_connected_links>0))
00802 {
00803 node *parNode = OBJECTDATA(SubNodeParent,node);
00804 parNode->NR_connected_links[0] += NR_connected_links[0];
00805
00806
00807 if (house_present==true)
00808 {
00809 parNode->house_present=true;
00810 }
00811 }
00812 }
00813
00814 if (NR_busdata==NULL || NR_branchdata==NULL)
00815 {
00816 NR_busdata = (BUSDATA *)gl_malloc(NR_bus_count * sizeof(BUSDATA));
00817 if (NR_busdata==NULL)
00818 {
00819 gl_error("NR: memory allocation failure for bus table");
00820
00821
00822
00823
00824 return 0;
00825 }
00826 NR_curr_bus = 0;
00827
00828 NR_branchdata = (BRANCHDATA *)gl_malloc(NR_branch_count * sizeof(BRANCHDATA));
00829 if (NR_branchdata==NULL)
00830 {
00831 gl_error("NR: memory allocation failure for branch table");
00832
00833
00834
00835
00836 return 0;
00837 }
00838 NR_curr_branch = 0;
00839
00840
00841 if (restoration_object != NULL)
00842 {
00843 restoration *Rest_Module = OBJECTDATA(restoration_object,restoration);
00844 Rest_Module->CreateConnectivity();
00845 }
00846
00847 if (bustype==SWING)
00848 {
00849 NR_populate();
00850 NR_admit_change = true;
00851 }
00852 else
00853 {
00854 GL_THROW("NR: An order requirement has been violated");
00855
00856
00857
00858
00859
00860
00861 }
00862 }
00863
00864 if ((SubNode==DIFF_PARENT) && (NR_cycle==false))
00865 {
00866
00867 Extra_Data[0] = Extra_Data[1] = Extra_Data[2] = 0.0;
00868
00869 Extra_Data[3] = Extra_Data[4] = Extra_Data[5] = 0.0;
00870
00871 Extra_Data[6] = Extra_Data[7] = Extra_Data[8] = 0.0;
00872 }
00873
00874
00875 if ((SubNode==PARENT) && (house_present==true))
00876 {
00877 nom_res_curr[0] = nom_res_curr[1] = nom_res_curr[2] = 0.0;
00878 }
00879 }
00880 else if (solver_method==SM_FBS)
00881 {
00882 #ifdef SUPPORT_OUTAGES
00883 if (condition!=OC_NORMAL)
00884 {
00885 voltage[0] = voltage[1] = voltage[2] = 0.0;
00886 condition = OC_NORMAL;
00887 }
00888 #endif
00889
00890 current_inj[0] = current_inj[1] = current_inj[2] = complex(0,0);
00891
00892
00893 last_voltage[0] = voltage[0];
00894 last_voltage[1] = voltage[1];
00895 last_voltage[2] = voltage[2];
00896
00897
00898 if (reference_bus!=NULL)
00899 {
00900 node *pRef = OBJECTDATA(reference_bus,node);
00901 frequency = pRef->frequency;
00902 }
00903 }
00904 else if ((solver_method==SM_GS) && (prev_NTime!=t0))
00905 {
00906
00907 YVs[0] = YVs[1] = YVs[2] = 0.0;
00908
00909 Ys[0][0] = Ys[0][1] = Ys[0][2] = 0.0;
00910 Ys[1][0] = Ys[1][1] = Ys[1][2] = 0.0;
00911 Ys[2][0] = Ys[2][1] = Ys[2][2] = 0.0;
00912 }
00913
00914 return t1;
00915 }
00916
00917 TIMESTAMP node::sync(TIMESTAMP t0)
00918 {
00919 TIMESTAMP t1 = powerflow_object::sync(t0);
00920 OBJECT *obj = OBJECTHDR(this);
00921
00922
00923 if ((t0!=prev_NTime) && (solver_method !=SM_GS))
00924 {
00925
00926 prev_NTime=t0;
00927 }
00928
00929 switch (solver_method)
00930 {
00931 case SM_FBS:
00932 {
00933 if (phases&PHASE_S)
00934 {
00935 complex temp_inj[2];
00936 complex adjusted_curr[3];
00937 complex temp_curr_val[3];
00938
00939 if (house_present)
00940 {
00941
00942 adjusted_curr[0].SetPolar(1.0,voltage[0].Arg());
00943 adjusted_curr[1].SetPolar(1.0,voltage[1].Arg());
00944 adjusted_curr[2].SetPolar(1.0,voltaged[0].Arg());
00945
00946
00947 temp_curr_val[0] = nom_res_curr[0]/(~adjusted_curr[0]);
00948 temp_curr_val[1] = nom_res_curr[1]/(~adjusted_curr[1]);
00949 temp_curr_val[2] = nom_res_curr[2]/(~adjusted_curr[2]);
00950 }
00951 else
00952 {
00953 temp_curr_val[0] = temp_curr_val[1] = temp_curr_val[2] = 0.0;
00954 }
00955
00956 #ifdef SUPPORT_OUTAGES
00957 if (voltage[0]!=0.0)
00958 {
00959 #endif
00960 current_inj[0] += (voltage1.IsZero() || (power1.IsZero() && shunt1.IsZero())) ? (current1 + temp_curr_val[0]) : (current1 + ~(power1/voltage1) + voltage1*shunt1 + temp_curr_val[0]);
00961 temp_inj[0] = current_inj[0];
00962 current_inj[0] += ((voltage1+voltage2).IsZero() || (power12.IsZero() && shunt12.IsZero())) ? (current12 + temp_curr_val[2]) : (current12 + ~(power12/(voltage1+voltage2)) + (voltage1+voltage2)*shunt12 + temp_curr_val[2]);
00963
00964 #ifdef SUPPORT_OUTAGES
00965 }
00966 else
00967 {
00968 temp_inj[0] = 0.0;
00969 current_inj[0]=0.0;
00970 }
00971
00972 if (voltage[1]!=0)
00973 {
00974 #endif
00975
00976 current_inj[1] += (voltage2.IsZero() || (power2.IsZero() && shunt2.IsZero())) ? (-current2 - temp_curr_val[1]) : (-current2 - ~(power2/voltage2) - voltage2*shunt2 - temp_curr_val[1]);
00977 temp_inj[1] = current_inj[1];
00978 current_inj[1] += ((voltage1+voltage2).IsZero() || (power12.IsZero() && shunt12.IsZero())) ? (-current12 - temp_curr_val[2]) : (-current12 - ~(power12/(voltage1+voltage2)) - (voltage1+voltage2)*shunt12 - temp_curr_val[2]);
00979
00980 #ifdef SUPPORT_OUTAGES
00981 }
00982 else
00983 {
00984 temp_inj[0] = 0.0;
00985 current_inj[1] = 0.0;
00986 }
00987 #endif
00988
00989 if (obj->parent!=NULL && gl_object_isa(obj->parent,"triplex_line","powerflow")) {
00990 link *plink = OBJECTDATA(obj->parent,link);
00991 current_inj[2] += plink->tn[0]*current_inj[0] + plink->tn[1]*current_inj[1];
00992 }
00993 else {
00994 current_inj[2] += ((voltage1.IsZero() || (power1.IsZero() && shunt1.IsZero())) ||
00995 (voltage2.IsZero() || (power2.IsZero() && shunt2.IsZero())))
00996 ? currentN : -(temp_inj[0] + temp_inj[1]);
00997 }
00998 }
00999 else if (has_phase(PHASE_D))
01000 {
01001
01002
01003 complex delta_current[3];
01004 complex power_current[3];
01005 complex delta_shunt[3];
01006 complex delta_shunt_curr[3];
01007
01008 delta_current[0]= (voltageAB.IsZero()) ? 0 : ~(powerA/voltageAB);
01009 delta_current[1]= (voltageBC.IsZero()) ? 0 : ~(powerB/voltageBC);
01010 delta_current[2]= (voltageCA.IsZero()) ? 0 : ~(powerC/voltageCA);
01011
01012 power_current[0]=delta_current[0]-delta_current[2];
01013 power_current[1]=delta_current[1]-delta_current[0];
01014 power_current[2]=delta_current[2]-delta_current[1];
01015
01016
01017 delta_shunt[0] = voltageAB*shuntA;
01018 delta_shunt[1] = voltageBC*shuntB;
01019 delta_shunt[2] = voltageCA*shuntC;
01020
01021 delta_shunt_curr[0] = delta_shunt[0]-delta_shunt[2];
01022 delta_shunt_curr[1] = delta_shunt[1]-delta_shunt[0];
01023 delta_shunt_curr[2] = delta_shunt[2]-delta_shunt[1];
01024
01025
01026 delta_current[0]=current[0]-current[2];
01027 delta_current[1]=current[1]-current[0];
01028 delta_current[2]=current[2]-current[1];
01029
01030 #ifdef SUPPORT_OUTAGES
01031 for (char kphase=0;kphase<3;kphase++)
01032 {
01033 if (voltaged[kphase]==0.0)
01034 {
01035 current_inj[kphase] = 0.0;
01036 }
01037 else
01038 {
01039 current_inj[kphase] += delta_current[kphase] + power_current[kphase] + delta_shunt_curr[kphase];
01040 }
01041 }
01042 #else
01043 current_inj[0] += delta_current[0] + power_current[0] + delta_shunt_curr[0];
01044 current_inj[1] += delta_current[1] + power_current[1] + delta_shunt_curr[1];
01045 current_inj[2] += delta_current[2] + power_current[2] + delta_shunt_curr[2];
01046 #endif
01047 }
01048 else
01049 {
01050
01051 #ifdef SUPPORT_OUTAGES
01052 for (char kphase=0;kphase<3;kphase++)
01053 {
01054 if (voltage[kphase]==0.0)
01055 {
01056 current_inj[kphase] = 0.0;
01057 }
01058 else
01059 {
01060 current_inj[kphase] += ((voltage[kphase]==0.0) || ((power[kphase] == 0) && shunt[kphase].IsZero())) ? current[kphase] : current[kphase] + ~(power[kphase]/voltage[kphase]) + voltage[kphase]*shunt[kphase];
01061 }
01062 }
01063 #else
01064 current_inj[0] += (voltageA.IsZero() || (powerA.IsZero() && shuntA.IsZero())) ? currentA : currentA + ~(powerA/voltageA) + voltageA*shuntA;
01065 current_inj[1] += (voltageB.IsZero() || (powerB.IsZero() && shuntB.IsZero())) ? currentB : currentB + ~(powerB/voltageB) + voltageB*shuntB;
01066 current_inj[2] += (voltageC.IsZero() || (powerC.IsZero() && shuntC.IsZero())) ? currentC : currentC + ~(powerC/voltageC) + voltageC*shuntC;
01067 #endif
01068 }
01069
01070 #ifdef SUPPORT_OUTAGES
01071 if (is_open_any())
01072 throw "unable to handle node open phase condition";
01073
01074 if (is_contact_any())
01075 {
01076
01077 if (is_contact(PHASE_A|PHASE_B|PHASE_C))
01078 voltageA = voltageB = voltageC = (voltageA + voltageB + voltageC)/3;
01079 else if (is_contact(PHASE_A|PHASE_B))
01080 voltageA = voltageB = (voltageA + voltageB)/2;
01081 else if (is_contact(PHASE_B|PHASE_C))
01082 voltageB = voltageC = (voltageB + voltageC)/2;
01083 else if (is_contact(PHASE_A|PHASE_C))
01084 voltageA = voltageC = (voltageA + voltageC)/2;
01085
01086
01087 if (is_contact(PHASE_A|PHASE_N) || is_contact(PHASE_A|GROUND))
01088 voltageA /= 2;
01089 if (is_contact(PHASE_B|PHASE_N) || is_contact(PHASE_B|GROUND))
01090 voltageB /= 2;
01091 if (is_contact(PHASE_C|PHASE_N) || is_contact(PHASE_C|GROUND))
01092 voltageC /= 2;
01093 }
01094 #endif
01095
01096
01097 if (obj->parent!=NULL && gl_object_isa(obj->parent,"node","powerflow"))
01098 {
01099 node *pNode = OBJECTDATA(obj->parent,node);
01100
01101
01102 if (((pNode->phases & phases) & (!(PHASE_D | PHASE_N))) == (phases & (!(PHASE_D | PHASE_N))))
01103 {
01104
01105 LOCKED(obj->parent, pNode->current_inj[0] += current_inj[0]);
01106 LOCKED(obj->parent, pNode->current_inj[1] += current_inj[1]);
01107 LOCKED(obj->parent, pNode->current_inj[2] += current_inj[2]);
01108 }
01109 else
01110 GL_THROW("Node:%d's parent does not have the proper phase connection to be a parent.",obj->id);
01111
01112
01113
01114
01115 }
01116
01117 break;
01118 }
01119 case SM_GS:
01120 {
01121
01122 complex Vtemp[3];
01123 complex YVsTemp[3];
01124 complex Vnew[3];
01125 complex dV[3];
01126 LINKCONNECTED *linktable=NULL;
01127 OBJECT *linkupdate;
01128 link *linkref;
01129
01130
01131 if ((SubNode==CHILD_NOINIT) || (SubNode==CHILD))
01132 {
01133 GS_P_C_NodeChecks(t0, t1, obj, linktable);
01134 }
01135
01136
01137 if (t0!=prev_NTime)
01138 {
01139
01140 prev_NTime=t0;
01141
01142
01143 GS_converged=false;
01144 }
01145
01146
01147 LOCK_OBJECT(obj);
01148 Vtemp[0]=voltage[0];
01149 Vtemp[1]=voltage[1];
01150 Vtemp[2]=voltage[2];
01151 YVsTemp[0] = YVs[0];
01152 YVsTemp[1] = YVs[1];
01153 YVsTemp[2] = YVs[2];
01154 UNLOCK_OBJECT(obj);
01155
01156
01157 dV[0] = dV[1] = dV[2] = complex(0,0);
01158
01159 if (SubNode!=CHILD)
01160 {
01161 switch (bustype) {
01162 case PV:
01163 {
01164
01165 if ((!has_phase(PHASE_A|PHASE_B|PHASE_C)) && (!has_phase(PHASE_D)))
01166 {
01167
01168 power[0].Im() = ((~Vtemp[0]*(Ys[0][0]*Vtemp[0]+Ys[0][1]*Vtemp[1]+Ys[0][2]*Vtemp[2]-YVsTemp[0]+current[0]+Vtemp[0]*shunt[0])).Im());
01169 Vnew[0] = (-(~power[0]/~Vtemp[0]+current[0]+Vtemp[0]*shunt[0])+YVsTemp[0]-Vtemp[1]*Ys[0][1]-Vtemp[2]*Ys[0][2])/Ys[0][0];
01170 Vnew[0] = (isnan(Vnew[0].Re())) ? complex(0,0) : Vnew[0];
01171
01172
01173 Vnew[0]=Vtemp[0]+(Vnew[0]-Vtemp[0])*acceleration_factor;
01174
01175 power[1].Im() = ((~Vtemp[1]*(Ys[1][0]*Vnew[0]+Ys[1][1]*Vtemp[1]+Ys[1][2]*Vtemp[2]-YVsTemp[1]+current[1]+Vtemp[1]*shunt[1])).Im());
01176 Vnew[1] = (-(~power[1]/~Vtemp[1]+current[1]+Vtemp[1]*shunt[1])+YVsTemp[1]-Vnew[0]*Ys[1][0]-Vtemp[2]*Ys[1][2])/Ys[1][1];
01177 Vnew[1] = (isnan(Vnew[1].Re())) ? complex(0,0) : Vnew[1];
01178
01179
01180 Vnew[1]=Vtemp[1]+(Vnew[1]-Vtemp[1])*acceleration_factor;
01181
01182 power[2].Im() = ((~Vtemp[2]*(Ys[2][0]*Vnew[0]+Ys[2][1]*Vnew[1]+Ys[2][2]*Vtemp[2]-YVsTemp[2]+current[2]+Vtemp[2]*shunt[2])).Im());
01183 Vnew[2] = (-(~power[2]/~Vtemp[2]+current[2]+Vtemp[2]*shunt[2])+YVsTemp[2]-Vnew[0]*Ys[2][0]-Vnew[1]*Ys[2][1])/Ys[2][2];
01184 Vnew[2] = (isnan(Vnew[2].Re())) ? complex(0,0) : Vnew[2];
01185
01186
01187 Vnew[2]=Vtemp[2]+(Vnew[2]-Vtemp[2])*acceleration_factor;
01188 }
01189 else
01190 {
01191
01192 power[0].Im() = ((~Vtemp[0]*(Ys[0][0]*Vtemp[0]+Ys[0][1]*Vtemp[1]+Ys[0][2]*Vtemp[2]-YVsTemp[0]+current[0]+Vtemp[0]*shunt[0])).Im());
01193 Vnew[0] = (-(~power[0]/~Vtemp[0]+current[0]+Vtemp[0]*shunt[0])+YVsTemp[0]-Vtemp[1]*Ys[0][1]-Vtemp[2]*Ys[0][2])/Ys[0][0];
01194
01195
01196 Vnew[0]=Vtemp[0]+(Vnew[0]-Vtemp[0])*acceleration_factor;
01197
01198 power[1].Im() = ((~Vtemp[1]*(Ys[1][0]*Vnew[0]+Ys[1][1]*Vtemp[1]+Ys[1][2]*Vtemp[2]-YVsTemp[1]+current[1]+Vtemp[1]*shunt[1])).Im());
01199 Vnew[1] = (-(~power[1]/~Vtemp[1]+current[1]+Vtemp[1]*shunt[1])+YVsTemp[1]-Vnew[0]*Ys[1][0]-Vtemp[2]*Ys[1][2])/Ys[1][1];
01200
01201
01202 Vnew[1]=Vtemp[1]+(Vnew[1]-Vtemp[1])*acceleration_factor;
01203
01204 power[2].Im() = ((~Vtemp[2]*(Ys[2][0]*Vnew[0]+Ys[2][1]*Vnew[1]+Ys[2][2]*Vtemp[2]-YVsTemp[2]+current[2]+Vtemp[2]*shunt[2])).Im());
01205 Vnew[2] = (-(~power[2]/~Vtemp[2]+current[2]+Vtemp[2]*shunt[2])+YVsTemp[2]-Vnew[0]*Ys[2][0]-Vnew[1]*Ys[2][1])/Ys[2][2];
01206
01207
01208 Vnew[2]=Vtemp[2]+(Vnew[2]-Vtemp[2])*acceleration_factor;
01209 }
01210
01211
01212 Vnew[0].SetPolar(Vtemp[0].Mag(),Vnew[0].Arg());
01213 Vnew[1].SetPolar(Vtemp[1].Mag(),Vnew[1].Arg());
01214 Vnew[2].SetPolar(Vtemp[2].Mag(),Vnew[2].Arg());
01215
01216
01217 dV[0]=Vnew[0]-Vtemp[0];
01218 dV[1]=Vnew[1]-Vtemp[1];
01219 dV[2]=Vnew[2]-Vtemp[2];
01220
01221
01222 Vtemp[0]=Vnew[0];
01223 Vtemp[1]=Vnew[1];
01224 Vtemp[2]=Vnew[2];
01225
01226 break;
01227 }
01228 case PQ:
01229 {
01230 if (has_phase(PHASE_S))
01231 {
01232
01233 Vnew[0] = (-(~power[0]/~Vtemp[0]+current[0]+Vtemp[0]*shunt[0])+YVsTemp[0]-Vtemp[1]*Ys[0][1]-Vtemp[2]*Ys[0][2])/Ys[0][0];
01234
01235
01236 Vnew[0]=Vtemp[0]+(Vnew[0]-Vtemp[0])*acceleration_factor;
01237
01238 Vnew[1] = (-(~power[1]/~Vtemp[1]+current[1]+Vtemp[1]*shunt[1])+YVsTemp[1]-Vnew[0]*Ys[1][0]-Vtemp[2]*Ys[1][2])/Ys[1][1];
01239
01240
01241 Vnew[1]=Vtemp[1]+(Vnew[1]-Vtemp[1])*acceleration_factor;
01242
01243
01244
01245
01246
01247 Vnew[2] = Vtemp[2];
01248 }
01249 else if ((!has_phase(PHASE_A|PHASE_B|PHASE_C)) && (!has_phase(PHASE_D)))
01250 {
01251
01252 Vnew[0] = (-(~power[0]/~Vtemp[0]+current[0]+Vtemp[0]*shunt[0])+YVsTemp[0]-Vtemp[1]*Ys[0][1]-Vtemp[2]*Ys[0][2])/Ys[0][0];
01253 Vnew[0] = (isnan(Vnew[0].Re())) ? complex(0,0) : Vnew[0];
01254
01255
01256 Vnew[0]=Vtemp[0]+(Vnew[0]-Vtemp[0])*acceleration_factor;
01257
01258 Vnew[1] = (-(~power[1]/~Vtemp[1]+current[1]+Vtemp[1]*shunt[1])+YVsTemp[1]-Vnew[0]*Ys[1][0]-Vtemp[2]*Ys[1][2])/Ys[1][1];
01259 Vnew[1] = (isnan(Vnew[1].Re())) ? complex(0,0) : Vnew[1];
01260
01261
01262 Vnew[1]=Vtemp[1]+(Vnew[1]-Vtemp[1])*acceleration_factor;
01263
01264 Vnew[2] = (-(~power[2]/~Vtemp[2]+current[1]+Vtemp[2]*shunt[2])+YVsTemp[2]-Vnew[0]*Ys[2][0]-Vnew[1]*Ys[2][1])/Ys[2][2];
01265 Vnew[2] = (isnan(Vnew[2].Re())) ? complex(0,0) : Vnew[2];
01266
01267
01268 Vnew[2]=Vtemp[2]+(Vnew[2]-Vtemp[2])*acceleration_factor;
01269 }
01270 else
01271 {
01272 if (has_phase(PHASE_D))
01273 {
01274 complex delta_current[3];
01275 complex power_current[3];
01276 complex delta_shunt[3];
01277 complex delta_shunt_curr[3];
01278
01279
01280 delta_current[0]= (voltageAB.IsZero()) ? 0 : ~(powerA/voltageAB);
01281 delta_current[1]= (voltageBC.IsZero()) ? 0 : ~(powerB/voltageBC);
01282 delta_current[2]= (voltageCA.IsZero()) ? 0 : ~(powerC/voltageCA);
01283
01284 power_current[0]=delta_current[0]-delta_current[2];
01285 power_current[1]=delta_current[1]-delta_current[0];
01286 power_current[2]=delta_current[2]-delta_current[1];
01287
01288
01289 delta_shunt[0] = voltageAB*shuntA;
01290 delta_shunt[1] = voltageBC*shuntB;
01291 delta_shunt[2] = voltageCA*shuntC;
01292
01293 delta_shunt_curr[0] = delta_shunt[0]-delta_shunt[2];
01294 delta_shunt_curr[1] = delta_shunt[1]-delta_shunt[0];
01295 delta_shunt_curr[2] = delta_shunt[2]-delta_shunt[1];
01296
01297
01298 delta_current[0]=current[0]-current[2];
01299 delta_current[1]=current[1]-current[0];
01300 delta_current[2]=current[2]-current[1];
01301
01302
01303 Vnew[0] = (-(power_current[0]+delta_current[0]+delta_shunt_curr[0])+YVsTemp[0]-Vtemp[1]*Ys[0][1]-Vtemp[2]*Ys[0][2])/Ys[0][0];
01304
01305
01306 Vnew[0]=Vtemp[0]+(Vnew[0]-Vtemp[0])*acceleration_factor;
01307
01308 Vnew[1] = (-(power_current[1]+delta_current[1]+delta_shunt_curr[1])+YVsTemp[1]-Vnew[0]*Ys[1][0]-Vtemp[2]*Ys[1][2])/Ys[1][1];
01309
01310
01311 Vnew[1]=Vtemp[1]+(Vnew[1]-Vtemp[1])*acceleration_factor;
01312
01313 Vnew[2] = (-(power_current[2]+delta_current[2]+delta_shunt_curr[2])+YVsTemp[2]-Vnew[0]*Ys[2][0]-Vnew[1]*Ys[2][1])/Ys[2][2];
01314
01315
01316 Vnew[2]=Vtemp[2]+(Vnew[2]-Vtemp[2])*acceleration_factor;
01317 }
01318 else
01319 {
01320
01321 Vnew[0] = (-(~power[0]/~Vtemp[0]+current[0]+Vtemp[0]*shunt[0])+YVsTemp[0]-Vtemp[1]*Ys[0][1]-Vtemp[2]*Ys[0][2])/Ys[0][0];
01322
01323
01324 Vnew[0]=Vtemp[0]+(Vnew[0]-Vtemp[0])*acceleration_factor;
01325
01326 Vnew[1] = (-(~power[1]/~Vtemp[1]+current[1]+Vtemp[1]*shunt[1])+YVsTemp[1]-Vnew[0]*Ys[1][0]-Vtemp[2]*Ys[1][2])/Ys[1][1];
01327
01328
01329 Vnew[1]=Vtemp[1]+(Vnew[1]-Vtemp[1])*acceleration_factor;
01330
01331 Vnew[2] = (-(~power[2]/~Vtemp[2]+current[2]+Vtemp[2]*shunt[2])+YVsTemp[2]-Vnew[0]*Ys[2][0]-Vnew[1]*Ys[2][1])/Ys[2][2];
01332
01333
01334 Vnew[2]=Vtemp[2]+(Vnew[2]-Vtemp[2])*acceleration_factor;
01335 }
01336 }
01337
01338
01339 dV[0]=Vnew[0]-Vtemp[0];
01340 dV[1]=Vnew[1]-Vtemp[1];
01341 dV[2]=Vnew[2]-Vtemp[2];
01342
01343
01344 Vtemp[0]=Vnew[0];
01345 Vtemp[1]=Vnew[1];
01346 Vtemp[2]=Vnew[2];
01347
01348 break;
01349 }
01350 case SWING:
01351 {
01352 break;
01353 }
01354 default:
01355 {
01356
01357 gl_error("invalid bus type");
01358
01359
01360
01361
01362
01363
01364 return TS_ZERO;
01365 }
01366 }
01367
01368
01369 if ((dV[0].Mag()!=0) | (dV[1].Mag()!=0) | (dV[2].Mag()!=0))
01370 {
01371 linktable = &nodelinks;
01372 OBJECT *datanode;
01373 char tempdir = 0;
01374
01375 while (linktable->next!=NULL)
01376 {
01377 linktable = linktable->next;
01378
01379 linkupdate = linktable->connectedlink;
01380 linkref = OBJECTDATA(linkupdate,link);
01381
01382 if (obj==linktable->fnodeconnected)
01383 {
01384 tempdir = 1;
01385 datanode = (linktable->tnodeconnected);
01386 linkref->UpdateYVs(datanode, tempdir, dV);
01387 }
01388 else if (obj==linktable->tnodeconnected)
01389 {
01390 tempdir = 2;
01391 datanode = (linktable->fnodeconnected);
01392 linkref->UpdateYVs(datanode, tempdir, dV);
01393 }
01394 }
01395 }
01396 }
01397
01398
01399 LOCK_OBJECT(obj);
01400 voltage[0] = Vtemp[0];
01401 voltage[1] = Vtemp[1];
01402 voltage[2] = Vtemp[2];
01403
01404
01405
01406 UNLOCK_OBJECT(obj);
01407
01408
01409 if ((dV[0].Mag()>maximum_voltage_error) | (dV[1].Mag()>maximum_voltage_error) | (dV[2].Mag()>maximum_voltage_error))
01410 {
01411 GS_all_converged=false;
01412 GS_converged=false;
01413 return t0;
01414 }
01415 else
01416 {
01417 GS_converged=true;
01418 GS_all_converged=true;
01419 return t1;
01420 }
01421 break;
01422 }
01423 case SM_NR:
01424 {
01425 if ((SubNode==CHILD) && (NR_cycle==false))
01426 {
01427
01428 node *ParToLoad = OBJECTDATA(SubNodeParent,node);
01429
01430 if (gl_object_isa(SubNodeParent,"load","powerflow"))
01431 {
01432
01433 ParToLoad->power[0]+=power[0];
01434 ParToLoad->power[1]+=power[1];
01435 ParToLoad->power[2]+=power[2];
01436
01437 ParToLoad->shunt[0]+=shunt[0];
01438 ParToLoad->shunt[1]+=shunt[1];
01439 ParToLoad->shunt[2]+=shunt[2];
01440
01441 ParToLoad->current[0]+=current[0];
01442 ParToLoad->current[1]+=current[1];
01443 ParToLoad->current[2]+=current[2];
01444 }
01445 else if (gl_object_isa(SubNodeParent,"node","powerflow"))
01446 {
01447
01448 ParToLoad->power[0]+=power[0]-last_child_power[0][0];
01449 ParToLoad->power[1]+=power[1]-last_child_power[0][1];
01450 ParToLoad->power[2]+=power[2]-last_child_power[0][2];
01451
01452 ParToLoad->shunt[0]+=shunt[0]-last_child_power[1][0];
01453 ParToLoad->shunt[1]+=shunt[1]-last_child_power[1][1];
01454 ParToLoad->shunt[2]+=shunt[2]-last_child_power[1][2];
01455
01456 ParToLoad->current[0]+=current[0]-last_child_power[2][0];
01457 ParToLoad->current[1]+=current[1]-last_child_power[2][1];
01458 ParToLoad->current[2]+=current[2]-last_child_power[2][2];
01459
01460 if (has_phase(PHASE_S))
01461 {
01462 ParToLoad->current12 +=current12-last_child_current12;
01463 }
01464
01465
01466 if (house_present==true)
01467 {
01468 ParToLoad->nom_res_curr[0] += nom_res_curr[0];
01469 ParToLoad->nom_res_curr[1] += nom_res_curr[1];
01470 ParToLoad->nom_res_curr[2] += nom_res_curr[2];
01471 }
01472 }
01473 else
01474 {
01475 GL_THROW("NR: Object %d is a child of something that it shouldn't be!",obj->id);
01476
01477
01478
01479
01480 }
01481
01482
01483 last_child_power[0][0] = power[0];
01484 last_child_power[0][1] = power[1];
01485 last_child_power[0][2] = power[2];
01486
01487 last_child_power[1][0] = shunt[0];
01488 last_child_power[1][1] = shunt[1];
01489 last_child_power[1][2] = shunt[2];
01490
01491 last_child_power[2][0] = current[0];
01492 last_child_power[2][1] = current[1];
01493 last_child_power[2][2] = current[2];
01494
01495 if (has_phase(PHASE_S))
01496 last_child_current12 = current12;
01497 }
01498
01499 if ((SubNode==DIFF_CHILD) && (NR_cycle==false))
01500 {
01501
01502 node *ParToLoad = OBJECTDATA(SubNodeParent,node);
01503
01504
01505 ParToLoad->Extra_Data[0] += power[0];
01506 ParToLoad->Extra_Data[1] += power[1];
01507 ParToLoad->Extra_Data[2] += power[2];
01508
01509 ParToLoad->Extra_Data[3] += shunt[0];
01510 ParToLoad->Extra_Data[4] += shunt[1];
01511 ParToLoad->Extra_Data[5] += shunt[2];
01512
01513 ParToLoad->Extra_Data[6] += current[0];
01514 ParToLoad->Extra_Data[7] += current[1];
01515 ParToLoad->Extra_Data[8] += current[2];
01516 }
01517
01518 if (NR_cycle==true)
01519 {
01520 if (has_phase(PHASE_D))
01521 {
01522 complex delta_shunt[3];
01523 complex delta_current[3];
01524
01525
01526 delta_shunt[0] = voltageAB*shunt[0];
01527 delta_shunt[1] = voltageBC*shunt[1];
01528 delta_shunt[2] = voltageCA*shunt[2];
01529
01530
01531 delta_current[0]= (voltaged[0]==0) ? complex(0,0) : ~(power[0]/voltageAB);
01532 delta_current[1]= (voltaged[1]==0) ? complex(0,0) : ~(power[1]/voltageBC);
01533 delta_current[2]= (voltaged[2]==0) ? complex(0,0) : ~(power[2]/voltageCA);
01534
01535 current_inj[0] += delta_shunt[0]-delta_shunt[2];
01536 current_inj[1] += delta_shunt[1]-delta_shunt[0];
01537 current_inj[2] += delta_shunt[2]-delta_shunt[1];
01538
01539 current_inj[0] +=delta_current[0]-delta_current[2];
01540 current_inj[1] +=delta_current[1]-delta_current[0];
01541 current_inj[2] +=delta_current[2]-delta_current[1];
01542
01543 current_inj[0] +=current[0]-current[2];
01544 current_inj[1] +=current[1]-current[0];
01545 current_inj[2] +=current[2]-current[1];
01546 }
01547 else if (has_phase(PHASE_S))
01548 {
01549 complex vdel;
01550 complex temp_current[3];
01551 complex temp_store[3];
01552 complex temp_val[3];
01553
01554
01555 vdel=voltage[0] + voltage[1];
01556
01557
01558
01559 temp_current[0] = current[0];
01560 temp_current[1] = current[1];
01561 temp_current[2] = current12;
01562
01563
01564 temp_current[0] += voltage[0] == 0.0 ? 0.0 : ~(power[0]/voltage[0]);
01565 temp_current[1] += voltage[1] == 0.0 ? 0.0 : ~(power[1]/voltage[1]);
01566 temp_current[2] += vdel == 0.0 ? 0.0 : ~(power[2]/vdel);
01567
01568 if (house_present)
01569 {
01570
01571 temp_store[0].SetPolar(1.0,voltage[0].Arg());
01572 temp_store[1].SetPolar(1.0,voltage[1].Arg());
01573 temp_store[2].SetPolar(1.0,vdel.Arg());
01574
01575
01576 temp_val[0] = nom_res_curr[0]/(~temp_store[0]);
01577 temp_val[1] = nom_res_curr[1]/(~temp_store[1]);
01578 temp_val[2] = nom_res_curr[2]/(~temp_store[2]);
01579
01580
01581 temp_current[0] += temp_val[0];
01582 temp_current[1] += temp_val[1];
01583 temp_current[2] += temp_val[2];
01584 }
01585
01586
01587 temp_current[0] += shunt[0]*voltage[0];
01588 temp_current[1] += shunt[1]*voltage[1];
01589 temp_current[2] += shunt[2]*vdel;
01590
01591
01592 current_inj[0] += (temp_current[0] + temp_current[2]);
01593 current_inj[1] += (-temp_current[1] - temp_current[2]);
01594
01595
01596 if ((Triplex_Data != NULL) && ((Triplex_Data[0] != 0.0) || (Triplex_Data[1] != 0.0)))
01597 {
01598 current_inj[2] += Triplex_Data[0]*current_inj[0] + Triplex_Data[1]*current_inj[1];
01599 }
01600 else
01601 {
01602 current_inj[2] += ((voltage1.IsZero() || (power1.IsZero() && shunt1.IsZero())) ||
01603 (voltage2.IsZero() || (power2.IsZero() && shunt2.IsZero())))
01604 ? currentN : -((current_inj[0]-temp_current[2])+(current_inj[1]-temp_current[2]));
01605 }
01606 }
01607 else
01608 {
01609 current_inj[0] += (voltage[0]==0) ? complex(0,0) : ~(power[0]/voltage[0]);
01610 current_inj[1] += (voltage[1]==0) ? complex(0,0) : ~(power[1]/voltage[1]);
01611 current_inj[2] += (voltage[2]==0) ? complex(0,0) : ~(power[2]/voltage[2]);
01612
01613 current_inj[0] +=voltage[0]*shunt[0];
01614 current_inj[1] +=voltage[1]*shunt[1];
01615 current_inj[2] +=voltage[2]*shunt[2];
01616
01617 current_inj[0] +=current[0];
01618 current_inj[1] +=current[1];
01619 current_inj[2] +=current[2];
01620 }
01621
01622
01623 if ((SubNode==CHILD) || (SubNode==DIFF_CHILD))
01624 {
01625 node *ParLoadObj=OBJECTDATA(SubNodeParent,node);
01626
01627 ParLoadObj->current_inj[0] += current_inj[0];
01628 ParLoadObj->current_inj[1] += current_inj[1];
01629 ParLoadObj->current_inj[2] += current_inj[2];
01630 }
01631 }
01632
01633 if ((NR_curr_bus==NR_bus_count) && (bustype==SWING))
01634 {
01635 if (NR_cycle==false)
01636 {
01637 bool bad_computation=false;
01638
01639 int64 result = solver_nr(NR_bus_count, NR_busdata, NR_branch_count, NR_branchdata, &bad_computation);
01640
01641
01642 NR_admit_change = false;
01643
01644 if (bad_computation==true)
01645 {
01646 GL_THROW("Newton-Raphson method is unable to converge to a solution at this operation point");
01647
01648
01649
01650
01651
01652 }
01653 else if (result<0)
01654 {
01655 gl_verbose("Newton-Raphson failed to converge, sticking at same iteration.");
01656
01657
01658
01659
01660 NR_retval=t0;
01661 }
01662 else
01663 NR_retval=t1;
01664
01665 return t0;
01666 }
01667 else
01668 return NR_retval;
01669 }
01670 else if (NR_curr_bus==NR_bus_count)
01671 return t1;
01672 else
01673 return t0;
01674 break;
01675 }
01676 default:
01677 GL_THROW("unsupported solver method");
01678
01679
01680
01681
01682 break;
01683 }
01684 return t1;
01685 }
01686
01687 TIMESTAMP node::postsync(TIMESTAMP t0)
01688 {
01689 TIMESTAMP t1 = powerflow_object::postsync(t0);
01690 TIMESTAMP RetValue=t1;
01691 OBJECT *obj = OBJECTHDR(this);
01692
01693 #ifdef SUPPORT_OUTAGES
01694 if (condition!=OC_NORMAL)
01695 {
01696 voltage[0] = voltage[1] = voltage[2] = 0.0;
01697 }
01698
01699 if (is_contact_any())
01700 {
01701 complex dVAB = voltageA - voltageB;
01702 complex dVBC = voltageB - voltageC;
01703 complex dVCA = voltageC - voltageA;
01704
01705
01706 if (is_contact(PHASE_A|PHASE_B|PHASE_C))
01708 throw "three-way contact not supported yet";
01709 else if (is_contact(PHASE_A|PHASE_B))
01710 current_inj[0] = - current_inj[1] = dVAB/fault_Z;
01711 else if (is_contact(PHASE_B|PHASE_C))
01712 current_inj[1] = - current_inj[2] = dVBC/fault_Z;
01713 else if (is_contact(PHASE_A|PHASE_C))
01714 current_inj[2] = - current_inj[0] = dVCA/fault_Z;
01715
01716
01717 if (is_contact(PHASE_A|PHASE_N) || is_contact(PHASE_A|GROUND))
01718 current_inj[0] = voltageA / fault_Z;
01719 if (is_contact(PHASE_B|PHASE_N) || is_contact(PHASE_B|GROUND))
01720 current_inj[1] = voltageB / fault_Z;
01721 if (is_contact(PHASE_C|PHASE_N) || is_contact(PHASE_C|GROUND))
01722 current_inj[2] = voltageC / fault_Z;
01723 }
01724
01725
01726
01727
01728 #endif
01729 if ((solver_method == SM_NR) && (SubNode==CHILD) && (NR_cycle==false))
01730 {
01731 node *ParToLoad = OBJECTDATA(SubNodeParent,node);
01732
01733
01734 ParToLoad->power[0]-=last_child_power[0][0];
01735 ParToLoad->power[1]-=last_child_power[0][1];
01736 ParToLoad->power[2]-=last_child_power[0][2];
01737
01738 ParToLoad->shunt[0]-=last_child_power[1][0];
01739 ParToLoad->shunt[1]-=last_child_power[1][1];
01740 ParToLoad->shunt[2]-=last_child_power[1][2];
01741
01742 ParToLoad->current[0]-=last_child_power[2][0];
01743 ParToLoad->current[1]-=last_child_power[2][1];
01744 ParToLoad->current[2]-=last_child_power[2][2];
01745
01746 if (has_phase(PHASE_S))
01747 ParToLoad->current12-=last_child_current12;
01748
01749
01750
01751 last_child_power[0][0] = last_child_power[0][1] = last_child_power[0][2] = 0.0;
01752
01753
01754 last_child_power[1][0] = last_child_power[1][1] = last_child_power[1][2] = 0.0;
01755
01756
01757 last_child_power[2][0] = last_child_power[2][1] = last_child_power[2][2] = 0.0;
01758
01759
01760 if (has_phase(PHASE_S))
01761 last_child_current12 = 0.0;
01762 }
01763
01764 if ((solver_method == SM_NR) && ((SubNode==CHILD) || (SubNode==DIFF_CHILD)) && (NR_cycle==false))
01765 {
01766 node *ParStealLoad = OBJECTDATA(SubNodeParent,node);
01767
01768
01769 voltage[0] = ParStealLoad->voltage[0];
01770 voltage[1] = ParStealLoad->voltage[1];
01771 voltage[2] = ParStealLoad->voltage[2];
01772 }
01773
01774
01775 if (require_voltage_control==TRUE)
01776 {
01777
01778 if ((busflags&NF_HASSOURCE)==0 && bustype==PQ)
01779 voltage[0] = voltage[1] = voltage[2] = complex(0,0);
01780 }
01781
01782
01783 if (phases&PHASE_S)
01784 {
01785 LOCKED(obj, voltage12 = voltage1 + voltage2);
01786 LOCKED(obj, voltage1N = voltage1 - voltageN);
01787 LOCKED(obj, voltage2N = voltage2 - voltageN);
01788 }
01789 else
01790 {
01791 LOCKED(obj, voltageAB = voltageA - voltageB);
01792 LOCKED(obj, voltageBC = voltageB - voltageC);
01793 LOCKED(obj, voltageCA = voltageC - voltageA);
01794 }
01795
01796 if (solver_method==SM_FBS)
01797 {
01798
01799 if (obj->parent!=NULL && (gl_object_isa(obj->parent,"node","powerflow")))
01800 {
01801
01802 node *pNode = OBJECTDATA(obj->parent,node);
01803 LOCKED(obj, voltage[0] = pNode->voltage[0]);
01804 LOCKED(obj, voltage[1] = pNode->voltage[1]);
01805 LOCKED(obj, voltage[2] = pNode->voltage[2]);
01806
01807
01808
01809 if (phases&PHASE_S)
01810 {
01811 LOCKED(obj, voltage12 = voltage1 + voltage2);
01812 LOCKED(obj, voltage1N = voltage1 - voltageN);
01813 LOCKED(obj, voltage2N = voltage2 - voltageN);
01814 }
01815 else
01816 {
01817 LOCKED(obj, voltageAB = voltageA - voltageB);
01818 LOCKED(obj, voltageBC = voltageB - voltageC);
01819 LOCKED(obj, voltageCA = voltageC - voltageA);
01820 }
01821 }
01822 }
01823 else if (solver_method==SM_GS)
01824 {
01825 if (GS_all_converged)
01826 {
01827 if (GS_converged)
01828 RetValue=t1;
01829 else
01830 {
01831 GS_all_converged=false;
01832 GS_converged=false;
01833
01834 RetValue=t0;
01835 }
01836 }
01837 else
01838 RetValue=t0;
01839
01840
01841 if (RetValue==t1)
01842 {
01843 LINKCONNECTED *linkscanner;
01844 OBJECT *currlinkobj;
01845 link *currlink;
01846
01847
01848 if (SubNode==CHILD)
01849 {
01850 node *parNode = OBJECTDATA(SubNodeParent,node);
01851
01852 voltage[0]=parNode->voltage[0];
01853 voltage[1]=parNode->voltage[1];
01854 voltage[2]=parNode->voltage[2];
01855
01856
01857 if (phases&PHASE_S)
01858 {
01859 LOCKED(obj, voltage12 = voltage1 + voltage2);
01860 LOCKED(obj, voltage1N = voltage1 - voltageN);
01861 LOCKED(obj, voltage2N = voltage2 - voltageN);
01862 }
01863 else
01864 {
01865 LOCKED(obj, voltageAB = voltageA - voltageB);
01866 LOCKED(obj, voltageBC = voltageB - voltageC);
01867 LOCKED(obj, voltageCA = voltageC - voltageA);
01868 }
01869 }
01870
01871
01872 current_inj[0] = current_inj[1] = current_inj[2] = complex(0,0);
01873
01874
01875 if ((bustype==PQ) | (bustype==PV))
01876 {
01877 if ((!has_phase(PHASE_A|PHASE_B|PHASE_C)) && (!has_phase(PHASE_D)))
01878 {
01879 current_inj[0] = (voltage[0]==0) ? complex(0,0) : ~(power[0]/voltage[0]);
01880 current_inj[1] = (voltage[1]==0) ? complex(0,0) : ~(power[1]/voltage[1]);
01881 current_inj[2] = (voltage[2]==0) ? complex(0,0) : ~(power[2]/voltage[2]);
01882 }
01883 else
01884 {
01885 if (has_phase(PHASE_D))
01886 {
01887 complex delta_shunt[3];
01888 complex delta_current[3];
01889
01890
01891 delta_shunt[0] = voltageAB*shunt[0];
01892 delta_shunt[1] = voltageBC*shunt[1];
01893 delta_shunt[2] = voltageCA*shunt[2];
01894
01895
01896 delta_current[0]= (voltaged[0]==0) ? complex(0,0) : ~(power[0]/voltageAB);
01897 delta_current[1]= (voltaged[1]==0) ? complex(0,0) : ~(power[1]/voltageBC);
01898 delta_current[2]= (voltaged[2]==0) ? complex(0,0) : ~(power[2]/voltageCA);
01899
01900 current_inj[0] += delta_shunt[0]-delta_shunt[2];
01901 current_inj[1] += delta_shunt[1]-delta_shunt[0];
01902 current_inj[2] += delta_shunt[2]-delta_shunt[1];
01903
01904 current_inj[0] +=delta_current[0]-delta_current[2];
01905 current_inj[1] +=delta_current[1]-delta_current[0];
01906 current_inj[2] +=delta_current[2]-delta_current[1];
01907
01908 current_inj[0] +=current[0]-current[2];
01909 current_inj[1] +=current[1]-current[0];
01910 current_inj[2] +=current[2]-current[1];
01911 }
01912 else
01913 {
01914 current_inj[0] += (voltage[0]==0) ? complex(0,0) : ~(power[0]/voltage[0]);
01915 current_inj[1] += (voltage[1]==0) ? complex(0,0) : ~(power[1]/voltage[1]);
01916 current_inj[2] += (voltage[2]==0) ? complex(0,0) : ~(power[2]/voltage[2]);
01917
01918 current_inj[0] +=voltage[0]*shunt[0];
01919 current_inj[1] +=voltage[1]*shunt[1];
01920 current_inj[2] +=voltage[2]*shunt[2];
01921
01922 current_inj[0] +=current[0];
01923 current_inj[1] +=current[1];
01924 current_inj[2] +=current[2];
01925 }
01926 }
01927 }
01928 else
01929 {
01930 current_inj[0] = current_inj[1] = current_inj[2] = complex(0,0);
01931 }
01932
01933
01934 linkscanner = &nodelinks;
01935
01936 while (linkscanner->next!=NULL)
01937 {
01938 linkscanner = linkscanner->next;
01939
01940 currlinkobj = linkscanner->connectedlink;
01941
01942 currlink = OBJECTDATA(currlinkobj,link);
01943
01944
01945 if (((currlink->from)->id) == (OBJECTHDR(this)->id))
01946 {
01947 if ((currlink->power_in.Mag()) > (currlink->power_out.Mag()))
01948 {
01949 current_inj[0] += currlink->current_in[0];
01950 current_inj[1] += currlink->current_in[1];
01951 current_inj[2] += currlink->current_in[2];
01952 }
01953 }
01954 else if (((currlink->to)->id) == (OBJECTHDR(this)->id))
01955 {
01956 if ((currlink->power_in.Mag()) < (currlink->power_out.Mag()))
01957 {
01958 current_inj[0] -= currlink->current_out[0];
01959 current_inj[1] -= currlink->current_out[1];
01960 current_inj[2] -= currlink->current_out[2];
01961 }
01962 }
01963 }
01964
01965 if (SubNode==CHILD)
01966 {
01967 node *ParToLoad = OBJECTDATA(SubNodeParent,node);
01968
01969
01970 ParToLoad->power[0]-=last_child_power[0][0];
01971 ParToLoad->power[1]-=last_child_power[0][1];
01972 ParToLoad->power[2]-=last_child_power[0][2];
01973
01974 ParToLoad->shunt[0]-=last_child_power[1][0];
01975 ParToLoad->shunt[1]-=last_child_power[1][1];
01976 ParToLoad->shunt[2]-=last_child_power[1][2];
01977
01978 ParToLoad->current[0]-=last_child_power[2][0];
01979 ParToLoad->current[1]-=last_child_power[2][1];
01980 ParToLoad->current[2]-=last_child_power[2][2];
01981
01982
01983
01984 last_child_power[0][0] = last_child_power[0][1] = last_child_power[0][2] = 0.0;
01985
01986
01987 last_child_power[1][0] = last_child_power[1][1] = last_child_power[1][2] = 0.0;
01988
01989
01990 last_child_power[2][0] = last_child_power[2][1] = last_child_power[2][2] = 0.0;
01991 }
01992 }
01993 }
01994
01995 #ifdef SUPPORT_OUTAGES
01996
01997 if (phases&PHASE_S)
01998 {
01999 double V1pu = voltage1.Mag()/nominal_voltage;
02000 double V2pu = voltage2.Mag()/nominal_voltage;
02001 if (V1pu<0.8 || V2pu<0.8)
02002 status=UNDERVOLT;
02003 else if (V1pu>1.2 || V2pu>1.2)
02004 status=OVERVOLT;
02005 else
02006 status=NOMINAL;
02007 }
02008 else
02009 {
02010 double VApu = voltageA.Mag()/nominal_voltage;
02011 double VBpu = voltageB.Mag()/nominal_voltage;
02012 double VCpu = voltageC.Mag()/nominal_voltage;
02013 if (VApu<0.8 || VBpu<0.8 || VCpu<0.8)
02014 status=UNDERVOLT;
02015 else if (VApu>1.2 || VBpu>1.2 || VCpu>1.2)
02016 status=OVERVOLT;
02017 else
02018 status=NOMINAL;
02019 }
02020 #endif
02021 if (solver_method==SM_FBS)
02022 {
02023
02024 double sync_V = (last_voltage[0]-voltage[0]).Mag() + (last_voltage[1]-voltage[1]).Mag() + (last_voltage[2]-voltage[2]).Mag();
02025
02026
02027 if (sync_V > maximum_voltage_error){
02028
02029
02030 RetValue=t0;
02031 }
02032 }
02033
02034
02035 return RetValue;
02036 }
02037
02038 int node::kmldump(FILE *fp)
02039 {
02040 OBJECT *obj = OBJECTHDR(this);
02041 if (isnan(obj->latitude) || isnan(obj->longitude))
02042 return 0;
02043 fprintf(fp,"<Placemark>\n");
02044 if (obj->name)
02045 fprintf(fp,"<name>%s</name>\n", obj->name, obj->oclass->name, obj->id);
02046 else
02047 fprintf(fp,"<name>%s %d</name>\n", obj->oclass->name, obj->id);
02048 fprintf(fp,"<description>\n");
02049 fprintf(fp,"<![CDATA[\n");
02050 fprintf(fp,"<TABLE>\n");
02051 fprintf(fp,"<TR><TD WIDTH=\"25%\">%s %d<HR></TD><TH WIDTH=\"25%\" ALIGN=CENTER>Phase A<HR></TH><TH WIDTH=\"25%\" ALIGN=CENTER>Phase B<HR></TH><TH WIDTH=\"25%\" ALIGN=CENTER>Phase C<HR></TH></TR>\n", obj->oclass->name, obj->id);
02052
02053
02054 fprintf(fp,"<TR><TH ALIGN=LEFT>Voltage</TH>");
02055 double vscale = primary_voltage_ratio*sqrt((double) 3.0)/(double) 1000.0;
02056 if (has_phase(PHASE_A))
02057 fprintf(fp,"<TD ALIGN=RIGHT STYLE=\"font-family:courier;\">%.3f kV <BR>%.3f deg </TD>",
02058 voltageA.Mag()*vscale,voltageA.Arg()*180/3.1416);
02059 else
02060 fprintf(fp,"<TD></TD>");
02061 if (has_phase(PHASE_B))
02062 fprintf(fp,"<TD ALIGN=RIGHT STYLE=\"font-family:courier;\">%.3f kV <BR>%.3f deg </TD>",
02063 voltageB.Mag()*vscale,voltageB.Arg()*180/3.1416);
02064 else
02065 fprintf(fp,"<TD></TD>");
02066 if (has_phase(PHASE_C))
02067 fprintf(fp,"<TD ALIGN=RIGHT STYLE=\"font-family:courier;\">%.3f kV <BR>%.3f deg </TD>",
02068 voltageC.Mag()*vscale,voltageC.Arg()*180/3.1416);
02069 else
02070 fprintf(fp,"<TD></TD>");
02071
02072
02074
02075
02076 if (gl_object_isa(obj,"load"))
02077 {
02078 load *pLoad = OBJECTDATA(obj,load);
02079 fprintf(fp,"<TR><TH ALIGN=LEFT>Load</TH>");
02080 if (has_phase(PHASE_A))
02081 {
02082 complex load_A = ~voltageA*pLoad->constant_current[0] + pLoad->powerA;
02083 fprintf(fp,"<TD ALIGN=RIGHT STYLE=\"font-family:courier;\">%.3f kW <BR>%.3f kVAR</TD>",
02084 load_A.Re(),load_A.Im());
02085 }
02086 else
02087 fprintf(fp,"<TD></TD>");
02088 if (has_phase(PHASE_B))
02089 {
02090 complex load_B = ~voltageB*pLoad->constant_current[1] + pLoad->powerB;
02091 fprintf(fp,"<TD ALIGN=RIGHT STYLE=\"font-family:courier;\">%.3f kW <BR>%.3f kVAR</TD>",
02092 load_B.Re(),load_B.Im());
02093 }
02094 else
02095 fprintf(fp,"<TD></TD>");
02096 if (has_phase(PHASE_C))
02097 {
02098 complex load_C = ~voltageC*pLoad->constant_current[2] + pLoad->powerC;
02099 fprintf(fp,"<TD ALIGN=RIGHT STYLE=\"font-family:courier;\">%.3f kW <BR>%.3f kVAR</TD>",
02100 load_C.Re(),load_C.Im());
02101 }
02102 else
02103 fprintf(fp,"<TD></TD>");
02104 }
02105 fprintf(fp,"</TR>\n");
02106 fprintf(fp,"</TABLE>\n");
02107 fprintf(fp,"]]>\n");
02108 fprintf(fp,"</description>\n");
02109 fprintf(fp,"<Point>\n");
02110 fprintf(fp,"<coordinates>%f,%f</coordinates>\n",obj->longitude,obj->latitude);
02111 fprintf(fp,"</Point>\n");
02112 fprintf(fp,"</Placemark>\n");
02113 return 0;
02114 }
02115
02117
02119
02127 EXPORT int create_node(OBJECT **obj, OBJECT *parent)
02128 {
02129 try
02130 {
02131 *obj = gl_create_object(node::oclass);
02132 if (*obj!=NULL)
02133 {
02134 node *my = OBJECTDATA(*obj,node);
02135 gl_set_parent(*obj,parent);
02136 return my->create();
02137 }
02138 }
02139 catch (const char *msg)
02140 {
02141 gl_error("create_node: %s", msg);
02142 }
02143 return 0;
02144 }
02145
02146
02147 EXPORT int commit_node(OBJECT *obj)
02148 {
02149 node *pNode = OBJECTDATA(obj,node);
02150 try {
02151
02152 if (solver_method==SM_FBS)
02153 {
02154 if (pNode->has_phase(PHASE_A)) {
02155
02156 }
02157 else
02158 pNode->voltage[0] = complex(0,0);
02159
02160 if (pNode->has_phase(PHASE_B)) {
02161
02162 }
02163 else
02164 pNode->voltage[1] = complex(0,0);
02165
02166 if (pNode->has_phase(PHASE_C)) {
02167
02168 }
02169 else
02170 pNode->voltage[2] = complex(0,0);
02171
02172 }
02173 return 1;
02174 }
02175 catch (char *msg)
02176 {
02177 GL_THROW("%s (node:%d): %s", pNode->get_name(), pNode->get_id(), msg);
02178 return 0;
02179 }
02180
02181 }
02182
02189 EXPORT int init_node(OBJECT *obj)
02190 {
02191 node *my = OBJECTDATA(obj,node);
02192 try {
02193 return my->init(obj->parent);
02194 }
02195 catch (const char *msg)
02196 {
02197 GL_THROW("%s (node:%d): %s", my->get_name(), my->get_id(), msg);
02198 return 0;
02199 }
02200 }
02201
02210 EXPORT TIMESTAMP sync_node(OBJECT *obj, TIMESTAMP t0, PASSCONFIG pass)
02211 {
02212 node *pObj = OBJECTDATA(obj,node);
02213 try {
02214 TIMESTAMP t1 = TS_NEVER;
02215 switch (pass) {
02216 case PC_PRETOPDOWN:
02217 return pObj->presync(t0);
02218 case PC_BOTTOMUP:
02219 return pObj->sync(t0);
02220 case PC_POSTTOPDOWN:
02221 t1 = pObj->postsync(t0);
02222 obj->clock = t0;
02223 return t1;
02224 default:
02225 throw "invalid pass request";
02226 }
02227 }
02228 catch (const char *msg)
02229 {
02230 gl_error("node %s (%s:%d): %s", obj->name, obj->oclass->name, obj->id, msg);
02231 }
02232 catch (...)
02233 {
02234 gl_error("node %s (%s:%d): unknown exception", obj->name, obj->oclass->name, obj->id);
02235 }
02236 return TS_INVALID;
02237 }
02238
02243 void *node::GS_P_C_NodeChecks(TIMESTAMP t0, TIMESTAMP t1, OBJECT *obj, LINKCONNECTED *linktable)
02244 {
02245 if (SubNode==CHILD_NOINIT)
02246 {
02247
02248 node *ParOfChildNode = OBJECTDATA(SubNodeParent,node);
02249 LINKCONNECTED *parlink = &ParOfChildNode->nodelinks;
02250
02251 linktable = &nodelinks;
02252
02253 if (linktable->next!=NULL)
02254 {
02255
02256 LINKCONNECTED *ltemp;
02257 node *tempnode;
02258
02259 while (linktable->next!=NULL)
02260 {
02261 linktable = linktable->next;
02262
02263 LINKCONNECTED *lnewconnected = (LINKCONNECTED *)gl_malloc(sizeof(LINKCONNECTED));
02264 if (lnewconnected==NULL)
02265 {
02266 gl_error("GS: memory allocation failure");
02267
02268
02269
02270
02271 return 0;
02272 }
02273
02274 lnewconnected->next = parlink->next;
02275
02276
02277 parlink->next = lnewconnected;
02278
02279
02280 lnewconnected->connectedlink = linktable->connectedlink;
02281
02282
02283 if (linktable->fnodeconnected==obj)
02284 {
02285 lnewconnected->fnodeconnected = SubNodeParent;
02286 lnewconnected->tnodeconnected = linktable->tnodeconnected;
02287
02288
02289 tempnode = OBJECTDATA(linktable->tnodeconnected,node);
02290 ltemp = &tempnode->nodelinks;
02291
02292 while (ltemp->next!=NULL)
02293 {
02294 ltemp = ltemp->next;
02295
02296 if (ltemp->fnodeconnected==obj)
02297 ltemp->fnodeconnected=SubNodeParent;
02298 else if (ltemp->tnodeconnected==obj)
02299 ltemp->tnodeconnected=SubNodeParent;
02300 }
02301 }
02302 else
02303 {
02304 lnewconnected->fnodeconnected = linktable->fnodeconnected;
02305 lnewconnected->tnodeconnected = SubNodeParent;
02306
02307
02308 tempnode = OBJECTDATA(linktable->fnodeconnected,node);
02309 ltemp = &tempnode->nodelinks;
02310
02311 while (ltemp->next!=NULL)
02312 {
02313 ltemp = ltemp->next;
02314
02315 if (ltemp->fnodeconnected==obj)
02316 ltemp->fnodeconnected=SubNodeParent;
02317 else if (ltemp->tnodeconnected==obj)
02318 ltemp->tnodeconnected=SubNodeParent;
02319 }
02320 }
02321 }
02322
02323
02324 nodelinks.next=NULL;
02325 }
02326
02327 SubNode=CHILD;
02328 }
02329
02330 if ((SubNode==CHILD) && (prev_NTime!=t0))
02331 {
02332 node *ParNodeAdmit = OBJECTDATA(SubNodeParent,node);
02333
02334
02335 ParNodeAdmit->Ys[0][0]+=Ys[0][0];
02336 ParNodeAdmit->Ys[0][1]+=Ys[0][1];
02337 ParNodeAdmit->Ys[0][2]+=Ys[0][2];
02338 ParNodeAdmit->Ys[1][0]+=Ys[1][0];
02339 ParNodeAdmit->Ys[1][1]+=Ys[1][1];
02340 ParNodeAdmit->Ys[1][2]+=Ys[1][2];
02341 ParNodeAdmit->Ys[2][0]+=Ys[2][0];
02342 ParNodeAdmit->Ys[2][1]+=Ys[2][1];
02343 ParNodeAdmit->Ys[2][2]+=Ys[2][2];
02344
02345 ParNodeAdmit->YVs[0]+=YVs[0];
02346 ParNodeAdmit->YVs[1]+=YVs[1];
02347 ParNodeAdmit->YVs[2]+=YVs[2];
02348 }
02349
02350 if (SubNode==CHILD)
02351 {
02352 node *ParToLoad = OBJECTDATA(SubNodeParent,node);
02353
02354 if (gl_object_isa(SubNodeParent,"load"))
02355 {
02356
02357 ParToLoad->power[0]+=power[0];
02358 ParToLoad->power[1]+=power[1];
02359 ParToLoad->power[2]+=power[2];
02360
02361 ParToLoad->shunt[0]+=shunt[0];
02362 ParToLoad->shunt[1]+=shunt[1];
02363 ParToLoad->shunt[2]+=shunt[2];
02364
02365 ParToLoad->current[0]+=current[0];
02366 ParToLoad->current[1]+=current[1];
02367 ParToLoad->current[2]+=current[2];
02368 }
02369 else if (gl_object_isa(SubNodeParent,"node"))
02370 {
02371
02372 ParToLoad->power[0]+=power[0]-last_child_power[0][0];
02373 ParToLoad->power[1]+=power[1]-last_child_power[0][1];
02374 ParToLoad->power[2]+=power[2]-last_child_power[0][2];
02375
02376 ParToLoad->shunt[0]+=shunt[0]-last_child_power[1][0];
02377 ParToLoad->shunt[1]+=shunt[1]-last_child_power[1][1];
02378 ParToLoad->shunt[2]+=shunt[2]-last_child_power[1][2];
02379
02380 ParToLoad->current[0]+=current[0]-last_child_power[2][0];
02381 ParToLoad->current[1]+=current[1]-last_child_power[2][1];
02382 ParToLoad->current[2]+=current[2]-last_child_power[2][2];
02383 }
02384 else
02385 throw("GS: Object %d is a child of something that it shouldn't be!",obj->id);
02386
02387
02388
02389
02390
02391
02392 last_child_power[0][0] = power[0];
02393 last_child_power[0][1] = power[1];
02394 last_child_power[0][2] = power[2];
02395
02396 last_child_power[1][0] = shunt[0];
02397 last_child_power[1][1] = shunt[1];
02398 last_child_power[1][2] = shunt[2];
02399
02400 last_child_power[2][0] = current[0];
02401 last_child_power[2][1] = current[1];
02402 last_child_power[2][2] = current[2];
02403 }
02404 return 0;
02405 }
02412 LINKCONNECTED *node::attachlink(OBJECT *obj)
02413 {
02414
02415 link *templink = OBJECTDATA(obj,link);
02416
02417
02418 LINKCONNECTED *lconnected = (LINKCONNECTED *)gl_malloc(sizeof(LINKCONNECTED));
02419 if (lconnected==NULL)
02420 {
02421 gl_error("GS: memory allocation failure for link table");
02422 return 0;
02423
02424
02425 }
02426
02427 lconnected->next = nodelinks.next;
02428
02429
02430 nodelinks.next = lconnected;
02431
02432
02433 lconnected->connectedlink = obj;
02434
02435
02436 lconnected->fnodeconnected = templink->from;
02437 lconnected->tnodeconnected = templink->to;
02438
02439 return 0;
02440 }
02447 int *node::NR_populate(void)
02448 {
02449
02450 OBJECT *me = OBJECTHDR(this);
02451
02452
02453 NR_busdata[NR_curr_bus].type = (int)bustype;
02454
02455
02456 NR_busdata[NR_curr_bus].phases = 128*has_phase(PHASE_S) + 8*has_phase(PHASE_D) + 4*has_phase(PHASE_A) + 2*has_phase(PHASE_B) + has_phase(PHASE_C);
02457
02458
02459 NR_busdata[NR_curr_bus].name = me->name;
02460
02461
02462 NR_busdata[NR_curr_bus].max_volt_error = maximum_voltage_error;
02463
02464
02465 NR_busdata[NR_curr_bus].V = &voltage[0];
02466
02467
02468 NR_busdata[NR_curr_bus].S = &power[0];
02469
02470
02471 NR_busdata[NR_curr_bus].Y = &shunt[0];
02472
02473
02474 NR_busdata[NR_curr_bus].I = ¤t[0];
02475
02476
02477 NR_busdata[NR_curr_bus].Link_Table = (int *)gl_malloc(NR_connected_links[0]*sizeof(int));
02478
02479 if (NR_busdata[NR_curr_bus].Link_Table == NULL)
02480 {
02481 GL_THROW("NR: Failed to allocate link table for node:%d",OBJECTHDR(this)->id);
02482
02483
02484
02485
02486
02487 }
02488
02489
02490 if (restoration_object != NULL)
02491 {
02492 if (NR_connected_links[0] != 1)
02493 {
02494 NR_busdata[NR_curr_bus].Child_Nodes = (int *)gl_malloc((NR_connected_links[0]-1)*sizeof(int));
02495
02496 if (NR_busdata[NR_curr_bus].Child_Nodes == NULL)
02497 {
02498 GL_THROW("NR: Failed to allocate child node table for node:%d - %s",OBJECTHDR(this)->id,OBJECTHDR(this)->name);
02499
02500
02501
02502
02503
02504 }
02505
02506
02507 NR_busdata[NR_curr_bus].Parent_Node = -1;
02508
02509 for (unsigned int index=0; index<(NR_connected_links[0]-1); index++)
02510 NR_busdata[NR_curr_bus].Child_Nodes[index] = -1;
02511
02512 NR_busdata[NR_curr_bus].Child_Node_idx = 0;
02513 }
02514 else
02515 {
02516 if (bustype == SWING)
02517 {
02518 NR_busdata[NR_curr_bus].Child_Nodes = (int *)gl_malloc(sizeof(int));
02519
02520 if (NR_busdata[NR_curr_bus].Child_Nodes == NULL)
02521 {
02522 GL_THROW("NR: Failed to allocate child node table for node:%d - %s",OBJECTHDR(this)->id,OBJECTHDR(this)->name);
02523
02524 }
02525
02526 NR_busdata[NR_curr_bus].Child_Nodes[0] = -1;
02527
02528 NR_busdata[NR_curr_bus].Parent_Node = 0;
02529 }
02530 else
02531 {
02532 NR_busdata[NR_curr_bus].Child_Nodes = 0;
02533 }
02534 }
02535 }
02536
02537
02538 NR_busdata[NR_curr_bus].Link_Table_Size = NR_connected_links[0];
02539
02540
02541 if (has_phase(PHASE_S))
02542 {
02543 if (house_present)
02544 {
02545 NR_busdata[NR_curr_bus].house_var = &nom_res_curr[0];
02546 NR_busdata[NR_curr_bus].phases |= 0x40;
02547 }
02548
02549 NR_busdata[NR_curr_bus].extra_var = ¤t12;
02550 }
02551 else if (SubNode==DIFF_PARENT)
02552 {
02553 NR_busdata[NR_curr_bus].extra_var = Extra_Data;
02554 NR_busdata[NR_curr_bus].phases |= 0x10;
02555 }
02556
02557
02558 NR_busdata[NR_curr_bus].kv_base = -1.0;
02559 NR_busdata[NR_curr_bus].mva_base = -1.0;
02560
02561
02562 NR_busdata[NR_curr_bus].Matrix_Loc = -1;
02563
02564
02565 NR_node_reference = NR_curr_bus;
02566
02567
02568 NR_busdata[NR_curr_bus].origphases = NR_busdata[NR_curr_bus].phases;
02569
02570
02571 NR_curr_bus++;
02572
02573 return 0;
02574 }
02575
02576 EXPORT int isa_node(OBJECT *obj, char *classname)
02577 {
02578 return OBJECTDATA(obj,node)->isa(classname);
02579 }
02580