00001
00012 #include <stdlib.h>
00013 #include <stdio.h>
00014 #include <errno.h>
00015 #include <math.h>
00016
00017 #include "switch_object.h"
00018
00020
00022 CLASS* switch_object::oclass = NULL;
00023 CLASS* switch_object::pclass = NULL;
00024
00025 switch_object::switch_object(MODULE *mod) : link_object(mod)
00026 {
00027 if(oclass == NULL)
00028 {
00029 pclass = link_object::oclass;
00030
00031 oclass = gl_register_class(mod,"switch",sizeof(switch_object),PC_PRETOPDOWN|PC_BOTTOMUP|PC_POSTTOPDOWN|PC_UNSAFE_OVERRIDE_OMIT|PC_AUTOLOCK);
00032 if (oclass==NULL)
00033 throw "unable to register class switch_object";
00034 else
00035 oclass->trl = TRL_QUALIFIED;
00036
00037 if(gl_publish_variable(oclass,
00038 PT_INHERIT, "link",
00039 PT_enumeration, "phase_A_state", PADDR(phase_A_state),PT_DESCRIPTION,"Defines the current state of the phase A switch",
00040 PT_KEYWORD, "OPEN", (enumeration)OPEN,
00041 PT_KEYWORD, "CLOSED", (enumeration)CLOSED,
00042 PT_enumeration, "phase_B_state", PADDR(phase_B_state),PT_DESCRIPTION,"Defines the current state of the phase B switch",
00043 PT_KEYWORD, "OPEN", (enumeration)OPEN,
00044 PT_KEYWORD, "CLOSED", (enumeration)CLOSED,
00045 PT_enumeration, "phase_C_state", PADDR(phase_C_state),PT_DESCRIPTION,"Defines the current state of the phase C switch",
00046 PT_KEYWORD, "OPEN", (enumeration)OPEN,
00047 PT_KEYWORD, "CLOSED", (enumeration)CLOSED,
00048 PT_enumeration, "operating_mode", PADDR(switch_banked_mode),PT_DESCRIPTION,"Defines whether the switch operates in a banked or per-phase control mode",
00049 PT_KEYWORD, "INDIVIDUAL", (enumeration)INDIVIDUAL_SW,
00050 PT_KEYWORD, "BANKED", (enumeration)BANKED_SW,
00051 PT_double, "switch_resistance[Ohm]",PADDR(switch_resistance), PT_DESCRIPTION,"The resistance value of the switch when it is not blown.",
00052 NULL) < 1) GL_THROW("unable to publish properties in %s",__FILE__);
00053
00054 if (gl_publish_function(oclass,"change_switch_state",(FUNCTIONADDR)change_switch_state)==NULL)
00055 GL_THROW("Unable to publish switch state change function");
00056 if (gl_publish_function(oclass,"reliability_operation",(FUNCTIONADDR)reliability_operation)==NULL)
00057 GL_THROW("Unable to publish switch reliability operation function");
00058 if (gl_publish_function(oclass, "create_fault", (FUNCTIONADDR)create_fault_switch)==NULL)
00059 GL_THROW("Unable to publish fault creation function");
00060 if (gl_publish_function(oclass, "fix_fault", (FUNCTIONADDR)fix_fault_switch)==NULL)
00061 GL_THROW("Unable to publish fault restoration function");
00062 if (gl_publish_function(oclass, "change_switch_faults", (FUNCTIONADDR)switch_fault_updates)==NULL)
00063 GL_THROW("Unable to publish switch fault correction function");
00064 if (gl_publish_function(oclass, "change_switch_state_toggle", (FUNCTIONADDR)change_switch_state_toggle)==NULL)
00065 GL_THROW("Unable to publish switch toggle function");
00066
00067
00068 if (gl_publish_function(oclass, "interupdate_pwr_object", (FUNCTIONADDR)interupdate_switch)==NULL)
00069 GL_THROW("Unable to publish switch deltamode function");
00070
00071
00072 if (gl_publish_function(oclass, "update_power_pwr_object", (FUNCTIONADDR)updatepowercalc_link)==NULL)
00073 GL_THROW("Unable to publish switch external power calculation function");
00074 if (gl_publish_function(oclass, "check_limits_pwr_object", (FUNCTIONADDR)calculate_overlimit_link)==NULL)
00075 GL_THROW("Unable to publish switch external power limit calculation function");
00076 }
00077 }
00078
00079 int switch_object::isa(char *classname)
00080 {
00081 return strcmp(classname,"switch")==0 || link_object::isa(classname);
00082 }
00083
00084 int switch_object::create()
00085 {
00086 int result = link_object::create();
00087
00088 prev_full_status = 0x00;
00089 switch_banked_mode = BANKED_SW;
00090 phase_A_state = CLOSED;
00091 phase_B_state = CLOSED;
00092 phase_C_state = CLOSED;
00093
00094 prev_SW_time = 0;
00095
00096 phased_switch_status = 0x00;
00097 faulted_switch_phases = 0x00;
00098 prefault_banked = false;
00099
00100 event_schedule = NULL;
00101 eventgen_obj = NULL;
00102 fault_handle_call = NULL;
00103 event_schedule_map_attempt = false;
00104
00105 switch_resistance = -1.0;
00106
00107 return result;
00108 }
00109
00110 int switch_object::init(OBJECT *parent)
00111 {
00112 double phase_total, switch_total;
00113 char indexa, indexb;
00114
00115 OBJECT *obj = OBJECTHDR(this);
00116
00117
00118 SpecialLnk = SWITCH;
00119
00120 int result = link_object::init(parent);
00121
00122
00123
00124 if (solver_method==SM_FBS)
00125 {
00126 for (indexa=0; indexa<3; indexa++)
00127 {
00128 for (indexb=0; indexb<3; indexb++)
00129 {
00130
00131 b_mat[indexa][indexb] = 0.0;
00132 c_mat[indexa][indexb] = 0.0;
00133 B_mat[indexa][indexb] = 0.0;
00134
00135
00136 a_mat[indexa][indexb] = 0.0;
00137 A_mat[indexa][indexb] = 0.0;
00138 d_mat[indexa][indexb] = 0.0;
00139 }
00140 }
00141
00142
00143 gl_warning("switch objects may not behave properly under FBS!");
00144
00145
00146
00147
00148
00149
00150
00151 }
00152 else
00153 {
00154
00155
00156
00157
00158 for (indexa=0; indexa<3; indexa++)
00159 {
00160 for (indexb=0; indexb<3; indexb++)
00161 {
00162 From_Y[indexa][indexb] = 0.0;
00163 a_mat[indexa][indexb] = 0.0;
00164 }
00165 }
00166
00167 if(switch_resistance == 0.0){
00168 gl_warning("Switch:%s switch_resistance has been set to zero. This will result singular matrix. Setting to the global default.",obj->name);
00169
00170
00171
00172
00173 }
00174 if(switch_resistance < 0.0){
00175 switch_resistance = default_resistance;
00176 }
00177 }
00178
00179
00180 if (switch_banked_mode == BANKED_SW)
00181 {
00182
00183 prefault_banked = true;
00184
00185
00186 phase_total = (double)(has_phase(PHASE_A) + has_phase(PHASE_B) + has_phase(PHASE_C));
00187
00188 switch_total = 0.0;
00189 if (has_phase(PHASE_A) && (phase_A_state == CLOSED))
00190 switch_total += 1.0;
00191
00192 if (has_phase(PHASE_B) && (phase_B_state == CLOSED))
00193 switch_total += 1.0;
00194
00195 if (has_phase(PHASE_C) && (phase_C_state == CLOSED))
00196 switch_total += 1.0;
00197
00198 switch_total /= phase_total;
00199
00200 if (switch_total > 0.5)
00201 {
00202
00203 if (status == LS_OPEN)
00204 {
00205 phase_A_state = phase_B_state = phase_C_state = CLOSED;
00206 }
00207 else
00208 {
00209 phase_A_state = phase_B_state = phase_C_state = CLOSED;
00210 }
00211 }
00212 else
00213 {
00214 if (switch_total == 0.5)
00215 {
00216 if (status == LS_OPEN)
00217 {
00218 phase_A_state = phase_B_state = phase_C_state = OPEN;
00219 }
00220 else
00221 {
00222 phase_A_state = phase_B_state = phase_C_state = CLOSED;
00223 }
00224 }
00225 else
00226 {
00227 status = LS_OPEN;
00228 phase_A_state = phase_B_state = phase_C_state = OPEN;
00229 }
00230 }
00231
00232 if (status==LS_OPEN)
00233 {
00234 if (solver_method == SM_NR)
00235 {
00236 From_Y[0][0] = complex(0.0,0.0);
00237 From_Y[1][1] = complex(0.0,0.0);
00238 From_Y[2][2] = complex(0.0,0.0);
00239
00240
00241 a_mat[0][0] = complex(0.0,0.0);
00242 a_mat[1][1] = complex(0.0,0.0);
00243 a_mat[2][2] = complex(0.0,0.0);
00244
00245 d_mat[0][0] = complex(0.0,0.0);
00246 d_mat[1][1] = complex(0.0,0.0);
00247 d_mat[2][2] = complex(0.0,0.0);
00248 }
00249 else
00250 {
00251 A_mat[0][0] = complex(0.0,0.0);
00252 A_mat[1][1] = complex(0.0,0.0);
00253 A_mat[2][2] = complex(0.0,0.0);
00254
00255 d_mat[0][0] = complex(0.0,0.0);
00256 d_mat[1][1] = complex(0.0,0.0);
00257 d_mat[2][2] = complex(0.0,0.0);
00258 }
00259
00260 phase_A_state = phase_B_state = phase_C_state = OPEN;
00261 prev_full_status = 0x00;
00262 }
00263 else
00264 {
00265 if (has_phase(PHASE_A))
00266 {
00267 if (solver_method == SM_NR)
00268 {
00269 From_Y[0][0] = complex(1.0/switch_resistance,1.0/switch_resistance);
00270 b_mat[0][0] = complex(switch_resistance,switch_resistance);
00271 a_mat[0][0] = 1.0;
00272 d_mat[0][0] = 1.0;
00273 }
00274 else
00275 {
00276 A_mat[0][0] = 1.0;
00277 d_mat[0][0] = 1.0;
00278 }
00279
00280 phase_A_state = CLOSED;
00281 prev_full_status |= 0x04;
00282 }
00283
00284 if (has_phase(PHASE_B))
00285 {
00286 if (solver_method == SM_NR)
00287 {
00288 From_Y[1][1] = complex(1.0/switch_resistance,1.0/switch_resistance);
00289 b_mat[1][1] = complex(switch_resistance,switch_resistance);
00290 a_mat[1][1] = 1.0;
00291 d_mat[1][1] = 1.0;
00292 }
00293 else
00294 {
00295 A_mat[1][1] = 1.0;
00296 d_mat[1][1] = 1.0;
00297 }
00298
00299 phase_B_state = CLOSED;
00300 prev_full_status |= 0x02;
00301 }
00302
00303 if (has_phase(PHASE_C))
00304 {
00305 if (solver_method == SM_NR)
00306 {
00307 From_Y[2][2] = complex(1.0/switch_resistance,1.0/switch_resistance);
00308 b_mat[2][2] = complex(switch_resistance,switch_resistance);
00309 a_mat[2][2] = 1.0;
00310 d_mat[2][2] = 1.0;
00311 }
00312 else
00313 {
00314 A_mat[2][2] = 1.0;
00315 d_mat[2][2] = 1.0;
00316 }
00317
00318 phase_C_state = CLOSED;
00319 prev_full_status |= 0x01;
00320 }
00321 }
00322 }
00323 else
00324 {
00325 if (status==LS_OPEN)
00326 {
00327 if (solver_method == SM_NR)
00328 {
00329 From_Y[0][0] = complex(0.0,0.0);
00330 From_Y[1][1] = complex(0.0,0.0);
00331 From_Y[2][2] = complex(0.0,0.0);
00332
00333
00334 b_mat[0][0] = complex(0.0,0.0);
00335 b_mat[1][1] = complex(0.0,0.0);
00336 b_mat[2][2] = complex(0.0,0.0);
00337
00338
00339 a_mat[0][0] = 0.0;
00340 a_mat[1][1] = 0.0;
00341 a_mat[2][2] = 0.0;
00342
00343 d_mat[0][0] = 0.0;
00344 d_mat[1][1] = 0.0;
00345 d_mat[2][2] = 0.0;
00346 }
00347 else
00348 {
00349 A_mat[0][0] = complex(0.0,0.0);
00350 A_mat[1][1] = complex(0.0,0.0);
00351 A_mat[2][2] = complex(0.0,0.0);
00352
00353 d_mat[0][0] = complex(0.0,0.0);
00354 d_mat[1][1] = complex(0.0,0.0);
00355 d_mat[2][2] = complex(0.0,0.0);
00356 }
00357
00358 phase_A_state = phase_B_state = phase_C_state = OPEN;
00359 prev_full_status = 0x00;
00360 }
00361 else
00362 {
00363 if (has_phase(PHASE_A))
00364 {
00365 if (phase_A_state == CLOSED)
00366 {
00367 if (solver_method == SM_NR)
00368 {
00369 From_Y[0][0] = complex(1.0/switch_resistance,1.0/switch_resistance);
00370 b_mat[0][0] = complex(switch_resistance,switch_resistance);
00371 a_mat[0][0] = 1.0;
00372 d_mat[0][0] = 1.0;
00373 }
00374 else
00375 {
00376 A_mat[0][0] = 1.0;
00377 d_mat[0][0] = 1.0;
00378 }
00379 prev_full_status |= 0x04;
00380 }
00381 else
00382 {
00383 if (solver_method == SM_NR)
00384 {
00385 From_Y[0][0] = complex(0.0,0.0);
00386 b_mat[0][0] = complex(0.0,0.0);
00387 a_mat[0][0] = complex(0.0,0.0);
00388 d_mat[0][0] = complex(0.0,0.0);
00389 }
00390 else
00391 {
00392 A_mat[0][0] = complex(0.0,0.0);
00393 d_mat[0][0] = complex(0.0,0.0);
00394 }
00395 prev_full_status &=0xFB;
00396 }
00397 }
00398
00399 if (has_phase(PHASE_B))
00400 {
00401 if (phase_B_state == CLOSED)
00402 {
00403 if (solver_method == SM_NR)
00404 {
00405 From_Y[1][1] = complex(1.0/switch_resistance,1.0/switch_resistance);
00406 b_mat[1][1] = complex(switch_resistance,switch_resistance);
00407 a_mat[1][1] = 1.0;
00408 d_mat[1][1] = 1.0;
00409 }
00410 else
00411 {
00412 A_mat[1][1] = 1.0;
00413 d_mat[1][1] = 1.0;
00414 }
00415 prev_full_status |= 0x02;
00416 }
00417 else
00418 {
00419 if (solver_method == SM_NR)
00420 {
00421 From_Y[1][1] = complex(0.0,0.0);
00422 b_mat[1][1] = complex(0.0,0.0);
00423 a_mat[1][1] = complex(0.0,0.0);
00424 d_mat[1][1] = complex(0.0,0.0);
00425 }
00426 else
00427 {
00428 A_mat[1][1] = complex(0.0,0.0);
00429 d_mat[1][1] = complex(0.0,0.0);
00430 }
00431 prev_full_status &=0xFD;
00432 }
00433 }
00434
00435 if (has_phase(PHASE_C))
00436 {
00437 if (phase_C_state == CLOSED)
00438 {
00439 if (solver_method == SM_NR)
00440 {
00441 From_Y[2][2] = complex(1.0/switch_resistance,1.0/switch_resistance);
00442 b_mat[2][2] = complex(switch_resistance,switch_resistance);
00443 a_mat[2][2] = 1.0;
00444 d_mat[2][2] = 1.0;
00445 }
00446 else
00447 {
00448 A_mat[2][2] = 1.0;
00449 d_mat[2][2] = 1.0;
00450 }
00451 prev_full_status |= 0x01;
00452 }
00453 else
00454 {
00455 if (solver_method == SM_NR)
00456 {
00457 From_Y[2][2] = complex(0.0,0.0);
00458 b_mat[2][2] = complex(0.0,0.0);
00459 a_mat[2][2] = complex(0.0,0.0);
00460 d_mat[2][2] = complex(0.0,0.0);
00461 }
00462 else
00463 {
00464 A_mat[2][2] = complex(0.0,0.0);
00465 d_mat[2][2] = complex(0.0,0.0);
00466 }
00467 prev_full_status &=0xFE;
00468 }
00469 }
00470 }
00471 }
00472
00473
00474 phased_switch_status = prev_full_status;
00475
00476 return result;
00477 }
00478
00479
00480 void switch_object::BOTH_switch_sync_pre(unsigned char *work_phases_pre, unsigned char *work_phases_post)
00481 {
00482
00483
00484 if ((solver_method == SM_NR) && (event_schedule != NULL))
00485 {
00486 if (meshed_fault_checking_enabled == false)
00487 {
00488
00489 *work_phases_pre = NR_branchdata[NR_branch_reference].phases & 0x07;
00490
00491
00492 *work_phases_post = switch_expected_sync_function();
00493
00494
00495 *work_phases_post &= 0x07;
00496 }
00497 else
00498 {
00499
00500 switch_sync_function();
00501 }
00502 }
00503 else
00504 {
00505
00506 switch_sync_function();
00507
00508
00509 *work_phases_pre = 0x00;
00510 *work_phases_post = 0x00;
00511 }
00512 }
00513
00514
00515 void switch_object::NR_switch_sync_post(unsigned char *work_phases_pre, unsigned char *work_phases_post, OBJECT *obj, TIMESTAMP *t0, TIMESTAMP *t2)
00516 {
00517 unsigned char work_phases, work_phases_closed;
00518 char fault_val[9];
00519 int working_protect_phases[3];
00520 int result_val, impl_fault, indexval;
00521 bool fault_mode;
00522 TIMESTAMP temp_time;
00523
00524
00525 if (meshed_fault_checking_enabled == false)
00526 {
00527
00528 if (*work_phases_pre != *work_phases_post)
00529 {
00530
00531 working_protect_phases[0] = 0;
00532 working_protect_phases[1] = 0;
00533 working_protect_phases[2] = 0;
00534
00535
00536 work_phases = (*work_phases_pre ^ *work_phases_post) & 0x07;
00537
00538
00539 work_phases_closed = work_phases & *work_phases_post;
00540
00541
00542 if (work_phases_closed == work_phases)
00543 {
00544 fault_mode = true;
00545
00546 }
00547 else
00548 {
00549 fault_mode = false;
00550
00551 }
00552
00553
00554 fault_val[0] = 'S';
00555 fault_val[1] = 'W';
00556 fault_val[2] = '-';
00557
00558
00559 impl_fault = -1;
00560
00561
00562 switch (work_phases)
00563 {
00564 case 0x00:
00565 GL_THROW("switch:%s supposedly opened, but doesn't register the right phases",obj->name);
00566
00567
00568
00569
00570
00571 break;
00572 case 0x01:
00573 fault_val[3] = 'C';
00574 fault_val[4] = '\0';
00575 impl_fault = 20;
00576 working_protect_phases[2] = 1;
00577 break;
00578 case 0x02:
00579 fault_val[3] = 'B';
00580 fault_val[4] = '\0';
00581 impl_fault = 19;
00582 working_protect_phases[1] = 1;
00583 break;
00584 case 0x03:
00585 fault_val[3] = 'B';
00586 fault_val[4] = 'C';
00587 fault_val[5] = '\0';
00588 impl_fault = 22;
00589 working_protect_phases[1] = 1;
00590 working_protect_phases[2] = 1;
00591 break;
00592 case 0x04:
00593 fault_val[3] = 'A';
00594 fault_val[4] = '\0';
00595 impl_fault = 18;
00596 working_protect_phases[0] = 1;
00597 break;
00598 case 0x05:
00599 fault_val[3] = 'A';
00600 fault_val[4] = 'C';
00601 fault_val[5] = '\0';
00602 impl_fault = 23;
00603 working_protect_phases[0] = 1;
00604 working_protect_phases[2] = 1;
00605 break;
00606 case 0x06:
00607 fault_val[3] = 'A';
00608 fault_val[4] = 'B';
00609 fault_val[5] = '\0';
00610 impl_fault = 21;
00611 working_protect_phases[0] = 1;
00612 working_protect_phases[1] = 1;
00613 break;
00614 case 0x07:
00615 fault_val[3] = 'A';
00616 fault_val[4] = 'B';
00617 fault_val[5] = 'C';
00618 fault_val[6] = '\0';
00619 impl_fault = 24;
00620 working_protect_phases[0] = 1;
00621 working_protect_phases[1] = 1;
00622 working_protect_phases[2] = 1;
00623 break;
00624 default:
00625 GL_THROW("switch:%s supposedly opened, but doesn't register the right phases",obj->name);
00626
00627 }
00628
00629
00630 if (fault_mode == true)
00631 {
00632
00633 for (indexval=0; indexval<3; indexval++)
00634 {
00635
00636 if ((protect_locations[indexval] == -1) && (working_protect_phases[indexval] == 1))
00637 {
00638
00639 protect_locations[indexval] = NR_branch_reference;
00640 }
00641 }
00642 }
00643
00644 if (event_schedule != NULL)
00645 {
00646
00647 if (fault_mode == true)
00648 {
00649 if (mean_repair_time != 0)
00650 temp_time = 50 + (TIMESTAMP)(mean_repair_time);
00651 else
00652 temp_time = 50;
00653
00654
00655 result_val = ((int (*)(OBJECT *, OBJECT *, char *, TIMESTAMP, TIMESTAMP, int, bool))(*event_schedule))(*eventgen_obj,obj,fault_val,(*t0-50),temp_time,impl_fault,fault_mode);
00656 }
00657 else
00658 {
00659 result_val = ((int (*)(OBJECT *, OBJECT *, char *, TIMESTAMP, TIMESTAMP, int, bool))(*event_schedule))(*eventgen_obj,obj,fault_val,*t0,TS_NEVER,-1,fault_mode);
00660 }
00661
00662
00663 if (result_val != 1)
00664 {
00665 GL_THROW("Attempt to change switch:%s failed in a reliability manner",obj->name);
00666
00667
00668
00669
00670 }
00671
00672
00673 *t2 = *t0;
00674
00675 }
00676 else
00677 {
00678 gl_warning("No fault_check object present - Newton-Raphson solver may fail!");
00679
00680
00681
00682
00683
00684
00685 }
00686 }
00687 }
00688
00689 }
00690
00691 TIMESTAMP switch_object::sync(TIMESTAMP t0)
00692 {
00693 OBJECT *obj = OBJECTHDR(this);
00694 unsigned char work_phases_pre, work_phases_post;
00695
00696
00697 if (event_schedule_map_attempt == false)
00698 {
00699
00700 if (fault_check_object != NULL)
00701 {
00702
00703 eventgen_obj = get_object(fault_check_object, "eventgen_object");
00704
00705
00706 if (*eventgen_obj != NULL)
00707 {
00708
00709 event_schedule = (FUNCTIONADDR)(gl_get_function(*eventgen_obj,"add_event"));
00710
00711
00712 if (event_schedule == NULL)
00713 {
00714 gl_warning("Unable to map add_event function in eventgen:%s",*(*eventgen_obj)->name);
00715
00716
00717
00718
00719
00720 }
00721 }
00722
00723 }
00724
00725
00726
00727 event_schedule_map_attempt = true;
00728 }
00729
00730
00731 if (prev_SW_time != t0)
00732 prev_SW_time = t0;
00733
00734
00735 BOTH_switch_sync_pre(&work_phases_pre, &work_phases_post);
00736
00737
00738 TIMESTAMP t2=link_object::sync(t0);
00739
00740 if (solver_method == SM_NR)
00741 {
00742
00743 NR_switch_sync_post(&work_phases_pre, &work_phases_post, obj, &t0, &t2);
00744 }
00745
00746 if (t2==TS_NEVER)
00747 return(t2);
00748 else
00749 return(-t2);
00750 }
00751
00752
00753
00754 void switch_object::switch_sync_function(void)
00755 {
00756 unsigned char pres_status;
00757 double phase_total, switch_total;
00758 OBJECT *obj = OBJECTHDR(this);
00759 int result_val;
00760
00761 pres_status = 0x00;
00762
00763
00764 if (meshed_fault_checking_enabled == false)
00765 {
00766 if (switch_banked_mode == BANKED_SW)
00767 {
00768 if (status == prev_status)
00769 {
00770
00771 phase_total = (double)(has_phase(PHASE_A) + has_phase(PHASE_B) + has_phase(PHASE_C));
00772
00773 switch_total = 0.0;
00774 if (has_phase(PHASE_A) && (phase_A_state == CLOSED))
00775 switch_total += 1.0;
00776
00777 if (has_phase(PHASE_B) && (phase_B_state == CLOSED))
00778 switch_total += 1.0;
00779
00780 if (has_phase(PHASE_C) && (phase_C_state == CLOSED))
00781 switch_total += 1.0;
00782
00783 switch_total /= phase_total;
00784
00785 if (switch_total > 0.5)
00786 {
00787 status = LS_CLOSED;
00788 phase_A_state = phase_B_state = phase_C_state = CLOSED;
00789 }
00790 else
00791 {
00792 if (switch_total == 0.5)
00793 {
00794 if (status == LS_OPEN)
00795 {
00796 phase_A_state = phase_B_state = phase_C_state = OPEN;
00797 }
00798 else
00799 {
00800 phase_A_state = phase_B_state = phase_C_state = CLOSED;
00801 }
00802 }
00803 else
00804 {
00805 status = LS_OPEN;
00806 phase_A_state = phase_B_state = phase_C_state = OPEN;
00807 }
00808 }
00809 }
00810 else
00811 {
00812 if (status==LS_OPEN)
00813 phase_A_state = phase_B_state = phase_C_state = OPEN;
00814 else
00815 phase_A_state = phase_B_state = phase_C_state = CLOSED;
00816 }
00817
00818 if (status==LS_OPEN)
00819 {
00820 if (has_phase(PHASE_A))
00821 {
00822 if (solver_method == SM_NR)
00823 {
00824 From_Y[0][0] = complex(0.0,0.0);
00825 b_mat[0][0] = complex(0.0,0.0);
00826 a_mat[0][0] = 0.0;
00827 d_mat[0][0] = 0.0;
00828 NR_branchdata[NR_branch_reference].phases &= 0xFB;
00829 }
00830 else
00831 {
00832 A_mat[0][0] = 0.0;
00833 d_mat[0][0] = 0.0;
00834 }
00835 }
00836
00837 if (has_phase(PHASE_B))
00838 {
00839 if (solver_method == SM_NR)
00840 {
00841 From_Y[1][1] = complex(0.0,0.0);
00842 b_mat[1][1] = complex(0.0,0.0);
00843 a_mat[1][1] = 0.0;
00844 d_mat[1][1] = 0.0;
00845 NR_branchdata[NR_branch_reference].phases &= 0xFD;
00846 }
00847 else
00848 {
00849 A_mat[1][1] = 0.0;
00850 d_mat[1][1] = 0.0;
00851 }
00852 }
00853
00854 if (has_phase(PHASE_C))
00855 {
00856 if (solver_method == SM_NR)
00857 {
00858 From_Y[2][2] = complex(0.0,0.0);
00859 b_mat[2][2] = complex(0.0,0.0);
00860 a_mat[2][2] = 0.0;
00861 d_mat[2][2] = 0.0;
00862 NR_branchdata[NR_branch_reference].phases &= 0xFE;
00863 }
00864 else
00865 {
00866 A_mat[2][2] = 0.0;
00867 d_mat[2][2] = 0.0;
00868 }
00869 }
00870 }
00871 else
00872 {
00873 if (has_phase(PHASE_A))
00874 {
00875 pres_status |= 0x04;
00876
00877 if (solver_method == SM_NR)
00878 {
00879 From_Y[0][0] = complex(1.0/switch_resistance,1.0/switch_resistance);
00880 b_mat[0][0] = complex(switch_resistance,switch_resistance);
00881 a_mat[0][0] = 1.0;
00882 d_mat[0][0] = 1.0;
00883 NR_branchdata[NR_branch_reference].phases |= 0x04;
00884 }
00885 else
00886 {
00887 A_mat[0][0] = 1.0;
00888 d_mat[0][0] = 1.0;
00889 }
00890 }
00891
00892 if (has_phase(PHASE_B))
00893 {
00894 pres_status |= 0x02;
00895
00896 if (solver_method == SM_NR)
00897 {
00898 From_Y[1][1] = complex(1.0/switch_resistance,1.0/switch_resistance);
00899 b_mat[1][1] = complex(switch_resistance,switch_resistance);
00900 a_mat[1][1] = 1.0;
00901 d_mat[1][1] = 1.0;
00902 NR_branchdata[NR_branch_reference].phases |= 0x02;
00903 }
00904 else
00905 {
00906 A_mat[1][1] = 1.0;
00907 d_mat[1][1] = 1.0;
00908 }
00909 }
00910
00911 if (has_phase(PHASE_C))
00912 {
00913 pres_status |= 0x01;
00914
00915 if (solver_method == SM_NR)
00916 {
00917 From_Y[2][2] = complex(1.0/switch_resistance,1.0/switch_resistance);
00918 b_mat[2][2] = complex(switch_resistance,switch_resistance);
00919 a_mat[2][2] = 1.0;
00920 d_mat[2][2] = 1.0;
00921 NR_branchdata[NR_branch_reference].phases |= 0x01;
00922 }
00923 else
00924 {
00925 A_mat[2][2] = 1.0;
00926 d_mat[2][2] = 1.0;
00927 }
00928 }
00929 }
00930 }
00931 else
00932 {
00933 if (status == LS_OPEN)
00934 {
00935 phase_A_state = phase_B_state = phase_C_state = OPEN;
00936
00937 if (solver_method == SM_NR)
00938 {
00939 From_Y[0][0] = complex(0.0,0.0);
00940 From_Y[1][1] = complex(0.0,0.0);
00941 From_Y[2][2] = complex(0.0,0.0);
00942
00943 b_mat[0][0] = complex(0.0,0.0);
00944 b_mat[1][1] = complex(0.0,0.0);
00945 b_mat[2][2] = complex(0.0,0.0);
00946
00947 NR_branchdata[NR_branch_reference].phases &= 0xF0;
00948 }
00949 else
00950 {
00951 A_mat[0][0] = 0.0;
00952 A_mat[1][1] = 0.0;
00953 A_mat[2][2] = 0.0;
00954
00955 d_mat[0][0] = 0.0;
00956 d_mat[1][1] = 0.0;
00957 d_mat[2][2] = 0.0;
00958 }
00959 }
00960 else
00961 {
00962 if (has_phase(PHASE_A))
00963 {
00964 if (phase_A_state == CLOSED)
00965 {
00966 pres_status |= 0x04;
00967
00968 if (solver_method == SM_NR)
00969 {
00970 From_Y[0][0] = complex(1.0/switch_resistance,1.0/switch_resistance);
00971 b_mat[0][0] = complex(switch_resistance,switch_resistance);
00972 NR_branchdata[NR_branch_reference].phases |= 0x04;
00973 a_mat[0][0] = 1.0;
00974 d_mat[0][0] = 1.0;
00975 }
00976 else
00977 {
00978 A_mat[0][0] = 1.0;
00979 d_mat[0][0] = 1.0;
00980 }
00981 }
00982 else
00983 {
00984 if (solver_method == SM_NR)
00985 {
00986 From_Y[0][0] = complex(0.0,0.0);
00987 b_mat[0][0] = complex(0.0,0.0);
00988 NR_branchdata[NR_branch_reference].phases &= 0xFB;
00989 a_mat[0][0] = 0.0;
00990 d_mat[0][0] = 0.0;
00991 }
00992 else
00993 {
00994 A_mat[0][0] = 0.0;
00995 d_mat[0][0] = 0.0;
00996 }
00997 }
00998 }
00999
01000 if (has_phase(PHASE_B))
01001 {
01002 if (phase_B_state == CLOSED)
01003 {
01004 pres_status |= 0x02;
01005
01006 if (solver_method == SM_NR)
01007 {
01008 From_Y[1][1] = complex(1.0/switch_resistance,1.0/switch_resistance);
01009 b_mat[1][1] = complex(switch_resistance,switch_resistance);
01010 NR_branchdata[NR_branch_reference].phases |= 0x02;
01011 a_mat[1][1] = 1.0;
01012 d_mat[1][1] = 1.0;
01013 }
01014 else
01015 {
01016 A_mat[1][1] = 1.0;
01017 d_mat[1][1] = 1.0;
01018 }
01019 }
01020 else
01021 {
01022 if (solver_method == SM_NR)
01023 {
01024 From_Y[1][1] = complex(0.0,0.0);
01025 b_mat[1][1] = complex(0.0,0.0);
01026 NR_branchdata[NR_branch_reference].phases &= 0xFD;
01027 a_mat[1][1] = 0.0;
01028 d_mat[1][1] = 0.0;
01029 }
01030 else
01031 {
01032 A_mat[1][1] = 0.0;
01033 d_mat[1][1] = 0.0;
01034 }
01035 }
01036 }
01037
01038 if (has_phase(PHASE_C))
01039 {
01040 if (phase_C_state == CLOSED)
01041 {
01042 pres_status |= 0x01;
01043
01044 if (solver_method == SM_NR)
01045 {
01046 From_Y[2][2] = complex(1.0/switch_resistance,1.0/switch_resistance);
01047 b_mat[2][2] = complex(switch_resistance,switch_resistance);
01048 NR_branchdata[NR_branch_reference].phases |= 0x01;
01049 a_mat[2][2] = 1.0;
01050 d_mat[2][2] = 1.0;
01051 }
01052 else
01053 {
01054 A_mat[2][2] = 1.0;
01055 d_mat[2][2] = 1.0;
01056 }
01057 }
01058 else
01059 {
01060 if (solver_method == SM_NR)
01061 {
01062 From_Y[2][2] = complex(0.0,0.0);
01063 b_mat[2][2] = complex(0.0,0.0);
01064 NR_branchdata[NR_branch_reference].phases &= 0xFE;
01065 a_mat[2][2] = 0.0;
01066 d_mat[2][2] = 0.0;
01067 }
01068 else
01069 {
01070 A_mat[2][2] = 0.0;
01071 d_mat[2][2] = 0.0;
01072 }
01073 }
01074 }
01075 }
01076 }
01077
01078
01079
01080 if (solver_method == SM_NR)
01081 {
01082 if ((status != prev_status) || (pres_status != prev_full_status))
01083 {
01084 LOCK_OBJECT(NR_swing_bus);
01085 NR_admit_change = true;
01086 UNLOCK_OBJECT(NR_swing_bus);
01087 }
01088 }
01089
01090 prev_full_status = pres_status;
01091 }
01092 else
01093 {
01094 if (status != prev_status)
01095 {
01096
01097 if (fault_handle_call == NULL)
01098 {
01099
01100 if (fault_check_object != NULL)
01101 {
01102
01103 fault_handle_call = (FUNCTIONADDR)(gl_get_function(fault_check_object,"reliability_alterations"));
01104
01105
01106 if (fault_handle_call == NULL)
01107 {
01108 GL_THROW("switch:%d - %s - Failed to map the topology update function!",obj->id,(obj->name ? obj->name : "Unnamed"));
01109
01110
01111
01112
01113 }
01114 }
01115
01116 }
01117
01118
01119
01120 if (status == CLOSED)
01121 {
01122
01123 if (has_phase(PHASE_A))
01124 {
01125
01126 NR_branchdata[NR_branch_reference].phases |= 0x04;
01127 From_Y[0][0] = complex(1.0/switch_resistance,1.0/switch_resistance);
01128 b_mat[0][0] = complex(switch_resistance,switch_resistance);
01129 a_mat[0][0] = 1.0;
01130 d_mat[0][0] = 1.0;
01131 }
01132
01133 if (has_phase(PHASE_B))
01134 {
01135 NR_branchdata[NR_branch_reference].phases |= 0x02;
01136 From_Y[1][1] = complex(1.0/switch_resistance,1.0/switch_resistance);
01137 b_mat[1][1] = complex(switch_resistance,switch_resistance);
01138 a_mat[1][1] = 1.0;
01139 d_mat[1][1] = 1.0;
01140 }
01141
01142 if (has_phase(PHASE_C))
01143 {
01144 NR_branchdata[NR_branch_reference].phases |= 0x01;
01145 From_Y[2][2] = complex(1.0/switch_resistance,1.0/switch_resistance);
01146 b_mat[2][2] = complex(switch_resistance,switch_resistance);
01147 a_mat[2][2] = 1.0;
01148 d_mat[2][2] = 1.0;
01149 }
01150
01151
01152 if (fault_handle_call != NULL)
01153 {
01154
01155 result_val = ((int (*)(OBJECT *, int, bool))(*fault_handle_call))(fault_check_object,NR_branch_reference,true);
01156
01157
01158 if (result_val != 1)
01159 {
01160 GL_THROW("switch:%d - %s - Topology update fail!",obj->id,(obj->name ? obj->name : "Unnamed"));
01161
01162
01163
01164
01165 }
01166 }
01167
01168 }
01169 else
01170 {
01171
01172 NR_branchdata[NR_branch_reference].phases &= 0xF8;
01173
01174
01175 From_Y[0][0] = complex(0.0,0.0);
01176 From_Y[1][1] = complex(0.0,0.0);
01177 From_Y[2][2] = complex(0.0,0.0);
01178
01179 b_mat[0][0] = complex(0.0,0.0);
01180 b_mat[1][1] = complex(0.0,0.0);
01181 b_mat[2][2] = complex(0.0,0.0);
01182
01183 A_mat[0][0] = 0.0;
01184 A_mat[1][1] = 0.0;
01185 A_mat[2][2] = 0.0;
01186
01187 d_mat[0][0] = 0.0;
01188 d_mat[1][1] = 0.0;
01189 d_mat[2][2] = 0.0;
01190
01191
01192
01193 if (fault_handle_call != NULL)
01194 {
01195
01196 result_val = ((int (*)(OBJECT *, int, bool))(*fault_handle_call))(fault_check_object,NR_branch_reference,false);
01197
01198
01199 if (result_val != 1)
01200 {
01201 GL_THROW("switch:%d - %s - Topology update fail!",obj->id,(obj->name ? obj->name : "Unnamed"));
01202
01203 }
01204 }
01205
01206 }
01207
01208
01209 prev_status = status;
01210
01211
01212 LOCK_OBJECT(NR_swing_bus);
01213 NR_admit_change = true;
01214 UNLOCK_OBJECT(NR_swing_bus);
01215 }
01216
01217 }
01218 }
01219
01220
01221 unsigned char switch_object::switch_expected_sync_function(void)
01222 {
01223 unsigned char phases_out;
01224 double phase_total, switch_total;
01225 SWITCHSTATE temp_A_state, temp_B_state, temp_C_state;
01226 enumeration temp_status;
01227
01228 if (solver_method==SM_NR)
01229 {
01230
01231 phases_out = NR_branchdata[NR_branch_reference].phases;
01232 temp_A_state = (SWITCHSTATE)phase_A_state;
01233 temp_B_state = (SWITCHSTATE)phase_B_state;
01234 temp_C_state = (SWITCHSTATE)phase_C_state;
01235 temp_status = status;
01236
01237 if (switch_banked_mode == BANKED_SW)
01238 {
01239 if (temp_status == prev_status)
01240 {
01241
01242 phase_total = (double)(has_phase(PHASE_A) + has_phase(PHASE_B) + has_phase(PHASE_C));
01243
01244 switch_total = 0.0;
01245 if (has_phase(PHASE_A) && (temp_A_state == CLOSED))
01246 switch_total += 1.0;
01247
01248 if (has_phase(PHASE_B) && (temp_B_state == CLOSED))
01249 switch_total += 1.0;
01250
01251 if (has_phase(PHASE_C) && (temp_C_state == CLOSED))
01252 switch_total += 1.0;
01253
01254 switch_total /= phase_total;
01255
01256 if (switch_total > 0.5)
01257 {
01258 temp_status = LS_CLOSED;
01259 temp_A_state = temp_B_state = temp_C_state = CLOSED;
01260 }
01261 else
01262 {
01263 if (switch_total == 0.5)
01264 {
01265 if (temp_status == LS_OPEN)
01266 {
01267 temp_A_state = temp_B_state = temp_C_state = OPEN;
01268 }
01269 else
01270 {
01271 temp_A_state = temp_B_state = temp_C_state = CLOSED;
01272 }
01273 }
01274 else
01275 {
01276 temp_status = LS_OPEN;
01277 temp_A_state = temp_B_state = temp_C_state = OPEN;
01278 }
01279 }
01280 }
01281 else
01282 {
01283 if (temp_status==LS_OPEN)
01284 temp_A_state = temp_B_state = temp_C_state = OPEN;
01285 else
01286 temp_A_state = temp_B_state = temp_C_state = CLOSED;
01287 }
01288
01289 if (temp_status==LS_OPEN)
01290 {
01291 if (has_phase(PHASE_A))
01292 {
01293 phases_out &= 0xFB;
01294 }
01295
01296 if (has_phase(PHASE_B))
01297 {
01298 phases_out &= 0xFD;
01299 }
01300
01301 if (has_phase(PHASE_C))
01302 {
01303 phases_out &= 0xFE;
01304 }
01305 }
01306 else
01307 {
01308 if (has_phase(PHASE_A))
01309 {
01310 phases_out |= 0x04;
01311 }
01312
01313 if (has_phase(PHASE_B))
01314 {
01315 phases_out |= 0x02;
01316 }
01317
01318 if (has_phase(PHASE_C))
01319 {
01320 phases_out |= 0x01;
01321 }
01322 }
01323 }
01324 else
01325 {
01326 if (temp_status == LS_OPEN)
01327 {
01328 temp_A_state = temp_B_state = temp_C_state = OPEN;
01329 phases_out &= 0xF0;
01330 }
01331 else
01332 {
01333 if (has_phase(PHASE_A))
01334 {
01335 if (temp_A_state == CLOSED)
01336 {
01337 phases_out |= 0x04;
01338 }
01339 else
01340 {
01341 phases_out &= 0xFB;
01342 }
01343 }
01344
01345 if (has_phase(PHASE_B))
01346 {
01347 if (temp_B_state == CLOSED)
01348 {
01349 phases_out |= 0x02;
01350 }
01351 else
01352 {
01353 phases_out &= 0xFD;
01354 }
01355 }
01356
01357 if (has_phase(PHASE_C))
01358 {
01359 if (temp_C_state == CLOSED)
01360 {
01361 phases_out |= 0x01;
01362 }
01363 else
01364 {
01365 phases_out &= 0xFE;
01366 }
01367 }
01368 }
01369 }
01370 }
01371
01372
01373 return phases_out;
01374 }
01375
01376
01377
01378 void switch_object::set_switch(bool desired_status)
01379 {
01380 status = desired_status;
01381
01382 if (solver_method == SM_NR)
01383 {
01384 if (status != prev_status)
01385 {
01386
01387 if (status==LS_OPEN)
01388 {
01389 if (has_phase(PHASE_A))
01390 {
01391 From_Y[0][0] = complex(0.0,0.0);
01392 b_mat[0][0] = complex(0.0,0.0);
01393 a_mat[0][0] = 0.0;
01394 d_mat[0][0] = 0.0;
01395 NR_branchdata[NR_branch_reference].phases &= 0xFB;
01396 phase_A_state = OPEN;
01397 }
01398
01399 if (has_phase(PHASE_B))
01400 {
01401 From_Y[1][1] = complex(0.0,0.0);
01402 b_mat[1][1] = complex(0.0,0.0);
01403 a_mat[1][1] = 0.0;
01404 d_mat[1][1] = 0.0;
01405 NR_branchdata[NR_branch_reference].phases &= 0xFD;
01406 phase_B_state = OPEN;
01407 }
01408
01409 if (has_phase(PHASE_C))
01410 {
01411 From_Y[2][2] = complex(0.0,0.0);
01412 b_mat[2][2] = complex(0.0,0.0);
01413 a_mat[2][2] = 0.0;
01414 d_mat[2][2] = 0.0;
01415 NR_branchdata[NR_branch_reference].phases &= 0xFE;
01416 phase_C_state = OPEN;
01417 }
01418 }
01419 else
01420 {
01421 if (has_phase(PHASE_A))
01422 {
01423 From_Y[0][0] = complex(1.0/switch_resistance,1.0/switch_resistance);
01424 b_mat[0][0] = complex(switch_resistance,switch_resistance);
01425 a_mat[0][0] = 1.0;
01426 d_mat[0][0] = 1.0;
01427 NR_branchdata[NR_branch_reference].phases |= 0x04;
01428 phase_A_state = CLOSED;
01429 }
01430
01431 if (has_phase(PHASE_B))
01432 {
01433 From_Y[1][1] = complex(1.0/switch_resistance,1.0/switch_resistance);
01434 b_mat[1][1] = complex(switch_resistance,switch_resistance);
01435 a_mat[1][1] = 1.0;
01436 d_mat[1][1] = 1.0;
01437 NR_branchdata[NR_branch_reference].phases |= 0x02;
01438 phase_B_state = CLOSED;
01439 }
01440
01441 if (has_phase(PHASE_C))
01442 {
01443 From_Y[2][2] = complex(1.0/switch_resistance,1.0/switch_resistance);
01444 b_mat[2][2] = complex(switch_resistance,switch_resistance);
01445 a_mat[2][2] = 1.0;
01446 d_mat[2][2] = 1.0;
01447 NR_branchdata[NR_branch_reference].phases |= 0x01;
01448 phase_C_state = CLOSED;
01449 }
01450 }
01451
01452
01453 LOCK_OBJECT(NR_swing_bus);
01454
01455
01456 NR_admit_change = true;
01457
01458
01459 UNLOCK_OBJECT(NR_swing_bus);
01460
01461
01462 prev_status = status;
01463 }
01464
01465 }
01466 else
01467 {
01468 gl_warning("Switch status updated, but no other changes made.");
01469
01470
01471
01472
01473
01474 }
01475 }
01476
01477
01478
01479
01480 void switch_object::set_switch_full(char desired_status_A, char desired_status_B, char desired_status_C)
01481 {
01482 if (desired_status_A == 0)
01483 phase_A_state = OPEN;
01484 else if (desired_status_A == 1)
01485 phase_A_state = CLOSED;
01486
01487
01488 if (desired_status_B == 0)
01489 phase_B_state = OPEN;
01490 else if (desired_status_B == 1)
01491 phase_B_state = CLOSED;
01492
01493
01494 if (desired_status_C == 0)
01495 phase_C_state = OPEN;
01496 else if (desired_status_C == 1)
01497 phase_C_state = CLOSED;
01498
01499
01500
01501 switch_sync_function();
01502 }
01503
01504
01505
01506
01507
01508 void switch_object::set_switch_full_reliability(unsigned char desired_status)
01509 {
01510 unsigned char desA, desB, desC, phase_change;
01511
01512
01513 phase_change = desired_status ^ (~faulted_switch_phases);
01514
01515
01516 if ((phase_change & 0x04) == 0x04)
01517 {
01518
01519 if ((desired_status & 0x04) == 0x04)
01520 {
01521
01522 if ((phased_switch_status & 0x04) == 0x04)
01523 {
01524 desA=1;
01525 }
01526 else
01527 {
01528 desA=0;
01529 }
01530
01531 faulted_switch_phases &= 0xFB;
01532 }
01533 else
01534 {
01535 if (phase_A_state == CLOSED)
01536 {
01537 phased_switch_status |= 0x04;
01538 }
01539 else
01540 {
01541 phased_switch_status &= 0xFB;
01542 }
01543
01544 desA=0;
01545 faulted_switch_phases |= 0x04;
01546 }
01547 }
01548 else
01549 desA=2;
01550
01551 if ((phase_change & 0x02) == 0x02)
01552 {
01553
01554 if ((desired_status & 0x02) == 0x02)
01555 {
01556
01557 if ((phased_switch_status & 0x02) == 0x02)
01558 {
01559 desB=1;
01560 }
01561 else
01562 {
01563 desB=0;
01564 }
01565
01566 faulted_switch_phases &= 0xFD;
01567 }
01568 else
01569 {
01570 if (phase_B_state == CLOSED)
01571 {
01572 phased_switch_status |= 0x02;
01573 }
01574 else
01575 {
01576 phased_switch_status &= 0xFD;
01577 }
01578
01579 desB=0;
01580 faulted_switch_phases |= 0x02;
01581 }
01582 }
01583 else
01584 desB=2;
01585
01586 if ((phase_change & 0x01) == 0x01)
01587 {
01588
01589 if ((desired_status & 0x01) == 0x01)
01590 {
01591
01592 if ((phased_switch_status & 0x01) == 0x01)
01593 {
01594 desC=1;
01595 }
01596 else
01597 {
01598 desC=0;
01599 }
01600
01601 faulted_switch_phases &= 0xFE;
01602 }
01603 else
01604 {
01605 if (phase_C_state == CLOSED)
01606 {
01607 phased_switch_status |= 0x01;
01608 }
01609 else
01610 {
01611 phased_switch_status &= 0xFE;
01612 }
01613
01614 desC=0;
01615 faulted_switch_phases |= 0x01;
01616 }
01617 }
01618 else
01619 desC=2;
01620
01621
01622 if (meshed_fault_checking_enabled == false)
01623 {
01624
01625 if ((faulted_switch_phases != 0x00) && (prefault_banked == true) && (switch_banked_mode == BANKED_SW))
01626 {
01627
01628 switch_banked_mode = INDIVIDUAL_SW;
01629 }
01630 else if ((faulted_switch_phases == 0x00) && (prefault_banked == true) && (switch_banked_mode == INDIVIDUAL_SW))
01631 {
01632
01633 switch_banked_mode = BANKED_SW;
01634 }
01635
01636 }
01637
01638
01639
01640 set_switch_full(desA,desB,desC);
01641
01642 }
01643
01644
01645 OBJECT **switch_object::get_object(OBJECT *obj, char *name)
01646 {
01647 PROPERTY *p = gl_get_property(obj,name);
01648 if (p==NULL || p->ptype!=PT_object)
01649 return NULL;
01650 return (OBJECT**)GETADDR(obj,p);
01651 }
01652
01653
01654 void switch_object::set_switch_faulted_phases(unsigned char desired_status)
01655 {
01656
01657 phased_switch_status |= desired_status;
01658 }
01659
01660
01661 SIMULATIONMODE switch_object::inter_deltaupdate_switch(unsigned int64 delta_time, unsigned long dt, unsigned int iteration_count_val,bool interupdate_pos)
01662 {
01663 OBJECT *hdr = OBJECTHDR(this);
01664 TIMESTAMP t0_val, t2_val;
01665 unsigned char work_phases_pre, work_phases_post;
01666
01667
01668 t0_val = TS_NEVER;
01669 t2_val = TS_NEVER;
01670
01671 if (interupdate_pos == false)
01672 {
01673
01674 NR_link_presync_fxn();
01675
01676
01677 BOTH_switch_sync_pre(&work_phases_pre,&work_phases_post);
01678
01679
01680 NR_switch_sync_post(&work_phases_pre,&work_phases_post,hdr,&t0_val,&t2_val);
01681
01682 return SM_DELTA;
01683 }
01684 else
01685 {
01686
01687 BOTH_link_postsync_fxn();
01688
01689 return SM_EVENT;
01690 }
01691 }
01692
01694
01696
01704 EXPORT TIMESTAMP commit_switch_object(OBJECT *obj, TIMESTAMP t1, TIMESTAMP t2)
01705 {
01706 if (solver_method==SM_FBS)
01707 {
01708 switch_object *plink = OBJECTDATA(obj,switch_object);
01709 plink->calculate_power();
01710 }
01711 return TS_NEVER;
01712 }
01713 EXPORT int create_switch(OBJECT **obj, OBJECT *parent)
01714 {
01715 try
01716 {
01717 *obj = gl_create_object(switch_object::oclass);
01718 if (*obj!=NULL)
01719 {
01720 switch_object *my = OBJECTDATA(*obj,switch_object);
01721 gl_set_parent(*obj,parent);
01722 return my->create();
01723 }
01724 else
01725 return 0;
01726 }
01727 CREATE_CATCHALL(switch_object);
01728 }
01729
01736 EXPORT int init_switch(OBJECT *obj)
01737 {
01738 try {
01739 switch_object *my = OBJECTDATA(obj,switch_object);
01740 return my->init(obj->parent);
01741 }
01742 INIT_CATCHALL(switch_object);
01743 }
01744
01753 EXPORT TIMESTAMP sync_switch(OBJECT *obj, TIMESTAMP t0, PASSCONFIG pass)
01754 {
01755 try {
01756 switch_object *pObj = OBJECTDATA(obj,switch_object);
01757 TIMESTAMP t1 = TS_NEVER;
01758 switch (pass) {
01759 case PC_PRETOPDOWN:
01760 return pObj->presync(t0);
01761 case PC_BOTTOMUP:
01762 return pObj->sync(t0);
01763 case PC_POSTTOPDOWN:
01764 t1 = pObj->postsync(t0);
01765 obj->clock = t0;
01766 return t1;
01767 default:
01768 throw "invalid pass request";
01769 }
01770 }
01771 SYNC_CATCHALL(switch_object);
01772 }
01773
01774 EXPORT int isa_switch(OBJECT *obj, char *classname)
01775 {
01776 return OBJECTDATA(obj,switch_object)->isa(classname);
01777 }
01778
01779
01780 EXPORT int change_switch_state(OBJECT *thisobj, unsigned char phase_change, bool state)
01781 {
01782 char desA, desB, desC;
01783
01784
01785 switch_object *swtchobj = OBJECTDATA(thisobj,switch_object);
01786
01787 if ((swtchobj->switch_banked_mode == switch_object::BANKED_SW) || (meshed_fault_checking_enabled == true))
01788 {
01789 swtchobj->set_switch(state);
01790 }
01791 else
01792 {
01793
01794 if ((phase_change & 0x04) == 0x04)
01795 {
01796 if (state==true)
01797 desA=1;
01798 else
01799 desA=0;
01800 }
01801 else
01802 desA=2;
01803
01804
01805 if ((phase_change & 0x02) == 0x02)
01806 {
01807 if (state==true)
01808 desB=1;
01809 else
01810 desB=0;
01811 }
01812 else
01813 desB=2;
01814
01815
01816 if ((phase_change & 0x01) == 0x01)
01817 {
01818 if (state==true)
01819 desC=1;
01820 else
01821 desC=0;
01822 }
01823 else
01824 desC=2;
01825
01826
01827 swtchobj->set_switch_full(desA,desB,desC);
01828 }
01829
01830 return 1;
01831 }
01832
01833
01834 EXPORT int change_switch_state_toggle(OBJECT *thisobj)
01835 {
01836 FUNCTIONADDR funadd = NULL;
01837 int ext_result;
01838
01839
01840 switch_object *swtchobj = OBJECTDATA(thisobj,switch_object);
01841
01842
01843 if (swtchobj->status == switch_object::OPEN)
01844 {
01845 swtchobj->set_switch(true);
01846 }
01847 else
01848 {
01849 swtchobj->set_switch(false);
01850 }
01851
01852
01853
01854
01855 funadd = (FUNCTIONADDR)(gl_get_function(fault_check_object,"reliability_alterations"));
01856
01857
01858 if (funadd == NULL)
01859 {
01860 gl_error("Unable to update topology for switching action");
01861
01862
01863
01864
01865
01866
01867 return 0;
01868 }
01869
01870
01871 ext_result = ((int (*)(OBJECT *, int, bool))(*funadd))(fault_check_object,0,false);
01872
01873
01874 if (ext_result != 1)
01875 {
01876 gl_error("Unable to update topology for switching action");
01877
01878
01879 return 0;
01880 }
01881
01882 return 1;
01883 }
01884
01885
01886 EXPORT int reliability_operation(OBJECT *thisobj, unsigned char desired_phases)
01887 {
01888
01889 switch_object *swtchobj = OBJECTDATA(thisobj,switch_object);
01890
01891 swtchobj->set_switch_full_reliability(desired_phases);
01892
01893 return 1;
01894 }
01895
01896 EXPORT int create_fault_switch(OBJECT *thisobj, OBJECT **protect_obj, char *fault_type, int *implemented_fault, TIMESTAMP *repair_time)
01897 {
01898 int retval;
01899
01900
01901 switch_object *thisswitch = OBJECTDATA(thisobj,switch_object);
01902
01903
01904 retval = thisswitch->link_fault_on(protect_obj, fault_type, implemented_fault,repair_time);
01905
01906 return retval;
01907 }
01908 EXPORT int fix_fault_switch(OBJECT *thisobj, int *implemented_fault, char *imp_fault_name)
01909 {
01910 int retval;
01911
01912
01913 switch_object *thisswitch = OBJECTDATA(thisobj,switch_object);
01914
01915
01916 retval = thisswitch->link_fault_off(implemented_fault, imp_fault_name);
01917
01918
01919 *implemented_fault = -1;
01920
01921 return retval;
01922 }
01923
01924 EXPORT int switch_fault_updates(OBJECT *thisobj, unsigned char restoration_phases)
01925 {
01926
01927 switch_object *thisswitch = OBJECTDATA(thisobj,switch_object);
01928
01929
01930 thisswitch->set_switch_faulted_phases(restoration_phases);
01931
01932 return 1;
01933 }
01934
01935
01936 EXPORT SIMULATIONMODE interupdate_switch(OBJECT *obj, unsigned int64 delta_time, unsigned long dt, unsigned int iteration_count_val, bool interupdate_pos)
01937 {
01938 switch_object *my = OBJECTDATA(obj,switch_object);
01939 SIMULATIONMODE status = SM_ERROR;
01940 try
01941 {
01942 status = my->inter_deltaupdate_switch(delta_time,dt,iteration_count_val,interupdate_pos);
01943 return status;
01944 }
01945 catch (char *msg)
01946 {
01947 gl_error("interupdate_link(obj=%d;%s): %s", obj->id, obj->name?obj->name:"unnamed", msg);
01948 return status;
01949 }
01950 }
01951
01952 int switch_object::kmldata(int (*stream)(const char*,...))
01953 {
01954 int phase[3] = {has_phase(PHASE_A),has_phase(PHASE_B),has_phase(PHASE_C)};
01955 enumeration state[3] = {phase_A_state, phase_B_state, phase_C_state};
01956
01957
01958 stream("<TR><TH ALIGN=LEFT>Status</TH>");
01959 for ( int i = 0 ; i<sizeof(phase)/sizeof(phase[0]) ; i++ )
01960 {
01961 if ( phase[i] )
01962 stream("<TD ALIGN=CENTER COLSPAN=2 STYLE=\"font-family:courier;\"><NOBR>%s</NOBR></TD>", state[i]?"CLOSED":"OPEN");
01963 else
01964 stream("<TD ALIGN=CENTER COLSPAN=2 STYLE=\"font-family:courier;\">—</TD>");
01965 }
01966 stream("</TR>\n");
01967
01968
01969 gld_global run_realtime("run_realtime");
01970 gld_global server("hostname");
01971 gld_global port("server_portnum");
01972 if ( run_realtime.get_bool() )
01973 {
01974 stream("<TR><TH ALIGN=LEFT>Control</TH>");
01975 for ( int i = 0 ; i<sizeof(phase)/sizeof(phase[0]) ; i++ )
01976 {
01977 if ( phase[i] )
01978 stream("<TD ALIGN=CENTER COLSPAN=2 STYLE=\"font-family:courier;\"><FORM ACTION=\"http://%s:%d/kml/%s\" METHOD=GET><INPUT TYPE=SUBMIT NAME=\"switchA\" VALUE=\"%s\" /></FORM></TD>",
01979 (const char*)server.get_string(), port.get_int16(), (const char*)get_name(), state[i] ? "OPEN" : "CLOSE");
01980 else
01981 stream("<TD ALIGN=CENTER COLSPAN=2 STYLE=\"font-family:courier;\">—</TD>");
01982 }
01983 stream("</TR>\n");
01984 }
01985 return 2;
01986 }
01987