00001
00005 #include <stdlib.h>
00006 #include <stdio.h>
00007 #include <errno.h>
00008 #include <math.h>
00009 #include <iostream>
00010
00011 using namespace std;
00012
00013 #include "restoration.h"
00014
00016
00018 CLASS* restoration::oclass = NULL;
00019
00020 CLASS* restoration::pclass = NULL;
00021
00022 restoration::restoration(MODULE *mod) : powerflow_library(mod)
00023 {
00024 if(oclass == NULL)
00025 {
00026 oclass = gl_register_class(mod,"restoration",sizeof(restoration),0x00);
00027 if (oclass==NULL)
00028 throw "unable to register class restoration";
00029 else
00030 oclass->trl = TRL_PROTOTYPE;
00031
00032 if(gl_publish_variable(oclass,
00033 PT_int32,"reconfig_attempts",PADDR(reconfig_attempts),PT_DESCRIPTION,"Number of reconfigurations/timestep to try before giving up",
00034 PT_int32,"reconfig_iteration_limit",PADDR(reconfig_iter_limit),PT_DESCRIPTION,"Number of iterations to let PF go before flagging this as a bad reconfiguration",
00035 PT_object,"source_vertex",PADDR(sourceVerObj),PT_DESCRIPTION,"Source vertex object for reconfiguration",
00036 PT_object,"faulted_section",PADDR(faultSecObj),PT_DESCRIPTION,"Faulted section for reconfiguration",
00037 PT_char1024,"feeder_power_limit",PADDR(feeder_power_limit_Pub),PT_DESCRIPTION,"Comma-separated power limit (VA) for feeders during reconfiguration",
00038 PT_char1024,"feeder_power_links",PADDR(feeder_power_link_Pub),PT_DESCRIPTION,"Comma-separated list of link-based objects for monitoring power through",
00039 PT_char1024,"feeder_vertex_list",PADDR(fVerPub),PT_DESCRIPTION,"Comma-separated object list that defines the feeder vertices",
00040 PT_char1024,"microgrid_power_limit",PADDR(microgrid_limit_Pub),PT_DESCRIPTION,"Comma-separated power limit (complex VA) for microgrids during reconfiguration",
00041 PT_char1024,"microgrid_power_links",PADDR(microgrid_power_link_Pub),PT_DESCRIPTION,"Comma-separated list of link-based objects for monitoring power through",
00042 PT_char1024,"microgrid_vertex_list",PADDR(mVerPub),PT_DESCRIPTION,"Comma-separated object list that defines the microgrid vertices",
00043 PT_double,"lower_voltage_limit[pu]",PADDR(voltage_limit[0]),PT_DESCRIPTION,"Lower voltage limit for the reconfiguration validity checks - per unit",
00044 PT_double,"upper_voltage_limit[pu]",PADDR(voltage_limit[1]),PT_DESCRIPTION,"Upper voltage limit for the reconfiguration validity checks - per unit",
00045 PT_char1024,"output_filename",PADDR(logfile_name),PT_DESCRIPTION,"Output text file name to describe final or attempted switching operations",
00046 PT_bool,"generate_all_scenarios",PADDR(stop_and_generate),PT_DESCRIPTION,"Flag to determine if restoration reconfiguration and continues, or explores the full space",
00047 NULL) < 1) GL_THROW("unable to publish properties in %s",__FILE__);
00048
00049 if (gl_publish_function(oclass, "perform_restoration", (FUNCTIONADDR)perform_restoration)==NULL)
00050 GL_THROW("Unable to publish restoration function");
00051 }
00052 }
00053
00054 int restoration::isa(char *classname)
00055 {
00056 return strcmp(classname,"restoration")==0;
00057 }
00058
00059 int restoration::create(void)
00060 {
00061 reconfig_attempts = 20;
00062 reconfig_iter_limit = 50;
00063 file_output_desired = false;
00064
00065 stop_and_generate = false;
00066
00067 feeder_power_limit = NULL;
00068 microgrid_limit = NULL;
00069 mVerObjList = NULL;
00070 fVerObjList = NULL;
00071 fLinkObjList = NULL;
00072 fLinkPowerFunc = NULL;
00073 mLinkObjList = NULL;
00074 mLinkPowerFunc = NULL;
00075 feeder_power_link_value = NULL;
00076 microgrid_power_link_value = NULL;
00077
00078 sourceVerObj = NULL;
00079 faultSecObj = NULL;
00080 numfVer = 0;
00081 numMG = 0;
00082
00083 MGIdx.currSize = 0;
00084 MGIdx.maxSize = 0;
00085 MGIdx.data = NULL;
00086
00087 MGIdx_1.currSize = 0;
00088 MGIdx_1.maxSize = 0;
00089 MGIdx_1.data = NULL;
00090
00091 MGIdx_2.currSize = 0;
00092 MGIdx_2.maxSize = 0;
00093 MGIdx_2.data = NULL;
00094
00095 feederVertices.currSize = 0;
00096 feederVertices.maxSize = 0;
00097 feederVertices.data = NULL;
00098
00099 feederVertices_1.currSize = 0;
00100 feederVertices_1.maxSize = 0;
00101 feederVertices_1.data = NULL;
00102
00103 feederVertices_2.currSize = 0;
00104 feederVertices_2.maxSize = 0;
00105 feederVertices_2.data = NULL;
00106
00107 top_ori = NULL;
00108 top_sim_1 = NULL;
00109 top_sim_2 = NULL;
00110 top_res = NULL;
00111 top_tmp = NULL;
00112
00113 tie_swi.currSize = 0;
00114 tie_swi.maxSize = 0;
00115 tie_swi.data_1 = NULL;
00116 tie_swi.data_2 = NULL;
00117
00118 tie_swi_1.currSize = 0;
00119 tie_swi_1.maxSize = 0;
00120 tie_swi_1.data_1 = NULL;
00121 tie_swi_1.data_2 = NULL;
00122
00123 tie_swi_2.currSize = 0;
00124 tie_swi_2.maxSize = 0;
00125 tie_swi_2.data_1 = NULL;
00126 tie_swi_2.data_2 = NULL;
00127
00128 sec_swi.currSize = 0;
00129 sec_swi.maxSize = 0;
00130 sec_swi.data_1 = NULL;
00131 sec_swi.data_2 = NULL;
00132
00133 sec_swi_1.currSize = 0;
00134 sec_swi_1.maxSize = 0;
00135 sec_swi_1.data_1 = NULL;
00136 sec_swi_1.data_2 = NULL;
00137
00138 sec_swi_2.currSize = 0;
00139 sec_swi_2.maxSize = 0;
00140 sec_swi_2.data_1 = NULL;
00141 sec_swi_2.data_2 = NULL;
00142
00143 sec_swi_map.currSize = 0;
00144 sec_swi_map.maxSize = 0;
00145 sec_swi_map.data_1 = NULL;
00146 sec_swi_map.data_2 = NULL;
00147
00148 sec_swi_map_1.currSize = 0;
00149 sec_swi_map_1.maxSize = 0;
00150 sec_swi_map_1.data_1 = NULL;
00151 sec_swi_map_1.data_2 = NULL;
00152
00153 voltage_limit[0] = 0.95;
00154 voltage_limit[1] = 1.05;
00155
00156 tie_swi_loc.currSize = 0;
00157 tie_swi_loc.maxSize = 0;
00158 tie_swi_loc.data_1 = NULL;
00159 tie_swi_loc.data_2 = NULL;
00160 tie_swi_loc.data_3 = NULL;
00161 tie_swi_loc.data_4 = NULL;
00162
00163 sec_swi_loc.currSize = 0;
00164 sec_swi_loc.maxSize = 0;
00165 sec_swi_loc.data_1 = NULL;
00166 sec_swi_loc.data_2 = NULL;
00167 sec_swi_loc.data_3 = NULL;
00168 sec_swi_loc.data_4 = NULL;
00169
00170 f_sec.from_vert = -1;
00171 f_sec.to_vert = -1;
00172 f_sec_1.from_vert = -1;
00173 f_sec_1.to_vert = -1;
00174 f_sec_2.from_vert = -1;
00175 f_sec_2.to_vert = -1;
00176
00177 s_ver = -1;
00178 s_ver_1 = -1;
00179 s_ver_2 = -1;
00180
00181 ver_map_1.currSize = 0;
00182 ver_map_1.maxSize = 0;
00183 ver_map_1.data = NULL;
00184
00185 ver_map_2.currSize = 0;
00186 ver_map_2.maxSize = 0;
00187 ver_map_2.data = NULL;
00188
00189 candidateSwOpe.currSize = 0;
00190 candidateSwOpe.maxSize = 0;
00191 candidateSwOpe.data_1 = NULL;
00192 candidateSwOpe.data_2 = NULL;
00193 candidateSwOpe.data_3 = NULL;
00194 candidateSwOpe.data_4 = NULL;
00195 candidateSwOpe.data_5 = NULL;
00196 candidateSwOpe.data_6 = NULL;
00197 candidateSwOpe.data_7 = NULL;
00198
00199 candidateSwOpe_1.currSize = 0;
00200 candidateSwOpe_1.maxSize = 0;
00201 candidateSwOpe_1.data_1 = NULL;
00202 candidateSwOpe_1.data_2 = NULL;
00203 candidateSwOpe_1.data_3 = NULL;
00204 candidateSwOpe_1.data_4 = NULL;
00205 candidateSwOpe_1.data_5 = NULL;
00206 candidateSwOpe_1.data_6 = NULL;
00207 candidateSwOpe_1.data_7 = NULL;
00208
00209 candidateSwOpe_2.currSize = 0;
00210 candidateSwOpe_2.maxSize = 0;
00211 candidateSwOpe_2.data_1 = NULL;
00212 candidateSwOpe_2.data_2 = NULL;
00213 candidateSwOpe_2.data_3 = NULL;
00214 candidateSwOpe_2.data_4 = NULL;
00215 candidateSwOpe_2.data_5 = NULL;
00216 candidateSwOpe_2.data_6 = NULL;
00217 candidateSwOpe_2.data_7 = NULL;
00218
00219 voltage_storage = NULL;
00220
00221 fault_check_fxn = NULL;
00222
00223 return 1;
00224 }
00225
00226 int restoration::init(OBJECT *parent)
00227 {
00228 OBJECT *obj = OBJECTHDR(this);
00229 int working_int_val, indexval;
00230
00231 if (solver_method == SM_NR)
00232 {
00233 if (restoration_object == NULL)
00234 {
00235 restoration_object = obj;
00236
00237
00238 if (reconfig_attempts==0)
00239 {
00240 GL_THROW("Infinite reconfigurations set.");
00241
00242
00243
00244
00245
00246 }
00247
00248 if (reconfig_iter_limit==0)
00249 {
00250 gl_warning("Infinite reconfiguration iterations set.");
00251
00252
00253
00254
00255
00256
00257 }
00258 }
00259 else
00260 {
00261 GL_THROW("Only one restoration object is permitted per model file");
00262
00263
00264
00265
00266
00267 }
00268
00269
00270
00271
00272 feeder_power_limit = ParseDoubleString(&feeder_power_limit_Pub[0],&numfVer);
00273
00274
00275 fVerObjList = ParseObjectString(&fVerPub[0],&working_int_val);
00276
00277
00278 if (numfVer != working_int_val)
00279 {
00280 GL_THROW("restoration: The number of feeder limits and feeder vertices must be the same!");
00281
00282
00283
00284 }
00285
00286
00287 fLinkObjList = ParseObjectString(&feeder_power_link_Pub[0],&working_int_val);
00288
00289
00290 if (numfVer != working_int_val)
00291 {
00292 GL_THROW("restoration: The number of feeder links and feeder vertices must be the same!");
00293
00294
00295
00296 }
00297
00298
00299 fLinkPowerFunc = (FUNCTIONADDR *)gl_malloc(numfVer*sizeof(FUNCTIONADDR));
00300
00301
00302 if (fLinkPowerFunc == NULL)
00303 {
00304 GL_THROW("Restoration: failed to allocate memory for link functions");
00305
00306
00307
00308
00309
00310 }
00311
00312
00313 feeder_power_link_value = (complex **)gl_malloc(numfVer*sizeof(complex *));
00314
00315
00316 if (feeder_power_link_value == NULL)
00317 {
00318 GL_THROW("Restoration: failed to allocate memory for calculated power values");
00319
00320
00321
00322
00323
00324 }
00325
00326
00327 for (indexval=0; indexval<numfVer; indexval++)
00328 {
00329
00330 fLinkPowerFunc[indexval] = (FUNCTIONADDR)(gl_get_function(fLinkObjList[indexval],"update_power_pwr_object"));
00331
00332
00333 if (fLinkPowerFunc[indexval] == NULL)
00334 {
00335 GL_THROW("Restoration: failed to find power calculation function for link:%s",fLinkObjList[indexval]->name ? fLinkObjList[indexval]->name : "Unnamed");
00336
00337
00338
00339
00340
00341 }
00342
00343
00344 feeder_power_link_value[indexval] = gl_get_complex_by_name(fLinkObjList[indexval],"power_out");
00345
00346
00347 if (feeder_power_link_value[indexval] == NULL)
00348 {
00349 GL_THROW("Restoration: failed to find calculated power value for link:s",fLinkObjList[indexval]->name ? fLinkObjList[indexval]->name : "Unnamed");
00350
00351
00352
00353
00354 }
00355 }
00356
00357
00358 microgrid_limit = ParseComplexString(µgrid_limit_Pub[0],&numMG);
00359
00360
00361 mVerObjList = ParseObjectString(&mVerPub[0],&working_int_val);
00362
00363
00364 if (numMG != working_int_val)
00365 {
00366 GL_THROW("restoration: The number of microgrid limits and microgrid vertices must be the same!");
00367
00368
00369
00370
00371 }
00372
00373
00374 mLinkObjList = ParseObjectString(µgrid_power_link_Pub[0],&working_int_val);
00375
00376
00377 if (numMG != working_int_val)
00378 {
00379 GL_THROW("restoration: The number of microgrid links and microgrid vertices must be the same!");
00380
00381
00382
00383 }
00384
00385
00386 mLinkPowerFunc = (FUNCTIONADDR *)gl_malloc(numMG*sizeof(FUNCTIONADDR));
00387
00388
00389 if (mLinkPowerFunc == NULL)
00390 {
00391 GL_THROW("Restoration: failed to allocate memory for link functions");
00392
00393 }
00394
00395
00396 microgrid_power_link_value = (complex **)gl_malloc(numMG*sizeof(complex *));
00397
00398
00399 if (microgrid_power_link_value == NULL)
00400 {
00401 GL_THROW("Restoration: failed to allocate memory for calculated power values");
00402
00403 }
00404
00405
00406 for (indexval=0; indexval<numMG; indexval++)
00407 {
00408
00409 mLinkPowerFunc[indexval] = (FUNCTIONADDR)(gl_get_function(mLinkObjList[indexval],"update_power_pwr_object"));
00410
00411
00412 if (mLinkPowerFunc[indexval] == NULL)
00413 {
00414 GL_THROW("Restoration: failed to find power calculation function for link:%s",mLinkObjList[indexval]->name ? mLinkObjList[indexval]->name : "Unnamed");
00415
00416 }
00417
00418
00419 microgrid_power_link_value[indexval] = gl_get_complex_by_name(mLinkObjList[indexval],"power_out");
00420
00421
00422 if (microgrid_power_link_value[indexval] == NULL)
00423 {
00424 GL_THROW("Restoration: failed to find calculated power value for link:s",mLinkObjList[indexval]->name ? mLinkObjList[indexval]->name : "Unnamed");
00425
00426 }
00427 }
00428
00429
00430 if (voltage_limit[1] <= voltage_limit[0])
00431 {
00432 GL_THROW("restoration: the upper and lower voltage limits are either equal, or backwards");
00433
00434
00435
00436 }
00437
00438
00439 if (logfile_name[0] != '\0')
00440 {
00441
00442 FILE *FPOutput = fopen(logfile_name,"wt");
00443
00444
00445 fclose(FPOutput);
00446
00447
00448 file_output_desired = true;
00449 }
00450 }
00451 else
00452 {
00453 GL_THROW("Restoration control is only valid for the Newton-Raphson solver at this time.");
00454
00455
00456
00457
00458 }
00459
00460 return 1;
00461 }
00462
00463
00464 int restoration::PerformRestoration(int faulting_link)
00465 {
00466 unsigned int indexval;
00467 int num_swi_open, num_swi_closed, secindexval, IdxSW;
00468 BRANCHVERTICES fsec;
00469
00470
00471 restoration_checks_active = true;
00472
00473 if (fault_check_object != NULL)
00474 {
00475
00476 if (fault_check_fxn == NULL)
00477 {
00478
00479 fault_check_fxn = (FUNCTIONADDR)(gl_get_function(fault_check_object,"reliability_alterations"));
00480
00481
00482 if (fault_check_fxn == NULL)
00483 {
00484 GL_THROW("Unable to update objects for reliability effects");
00485
00486 }
00487 }
00488
00489 }
00490 else
00491 {
00492 GL_THROW("Restoration: fault_check object not found.");
00493
00494
00495
00496
00497
00498 }
00499
00500
00501 if (sourceVerObj == NULL)
00502 {
00503 gl_warning("restoration: The source vertex for the reconfiguration is not defined, defaulting to a swing bus");
00504
00505
00506
00507
00508
00509
00510 sourceVerObj = NR_swing_bus;
00511 }
00512
00513
00514
00515 top_ori = (LinkedUndigraph *)gl_malloc(sizeof(LinkedUndigraph));
00516
00517
00518 if (top_ori == NULL)
00519 {
00520 GL_THROW("Restoration: failed to allocte graph theory object");
00521
00522
00523
00524
00525
00526 }
00527
00528
00529 new (top_ori) LinkedUndigraph(NR_bus_count);
00530
00531
00532
00533 INTVECTalloc(&MGIdx,numMG);
00534 INTVECTalloc(&MGIdx_1,numMG);
00535 INTVECTalloc(&MGIdx_2,numMG);
00536
00537
00538 for (secindexval=0; secindexval<numMG; secindexval++)
00539 {
00540
00541 for (indexval=0; indexval<NR_bus_count; indexval++)
00542 {
00543 if (mVerObjList[secindexval] == NR_busdata[indexval].obj)
00544 {
00545 MGIdx.data[MGIdx.currSize] = indexval;
00546 MGIdx.currSize++;
00547 break;
00548 }
00549 }
00550 }
00551
00552
00553
00554
00555
00556
00557
00558 for (indexval=0; indexval<NR_bus_count; indexval++)
00559 {
00560 if (sourceVerObj == NR_busdata[indexval].obj)
00561 {
00562 s_ver = indexval;
00563 break;
00564 }
00565 }
00566
00567
00568 if (s_ver == -1)
00569 {
00570 GL_THROW("Restoration: failed to find the source vertex!");
00571
00572
00573
00574
00575
00576 }
00577
00578
00579 num_swi_open = 0;
00580 num_swi_closed = 0;
00581
00582 for (indexval=0; indexval<NR_branch_count; indexval++)
00583 {
00584
00585 if ((NR_branchdata[indexval].lnk_type == 3) || (NR_branchdata[indexval].lnk_type == 2) || (NR_branchdata[indexval].lnk_type == 5))
00586 {
00587
00588 if (*NR_branchdata[indexval].status == LS_CLOSED)
00589 {
00590 top_ori->addEdge(NR_branchdata[indexval].from,NR_branchdata[indexval].to);
00591 }
00592
00593
00594
00595 if (NR_branchdata[indexval].lnk_type != 3)
00596 {
00597 if (*NR_branchdata[indexval].status == LS_CLOSED)
00598 {
00599
00600
00601 {
00602 num_swi_closed++;
00603 }
00604
00605 }
00606 else
00607 {
00608 num_swi_open++;
00609 }
00610 }
00611
00612 }
00613 else
00614 {
00615 top_ori->addEdge(NR_branchdata[indexval].from,NR_branchdata[indexval].to);
00616
00617
00618 if (NR_branchdata[indexval].lnk_type == 6)
00619 {
00620 num_swi_closed++;
00621 }
00622
00623 }
00624 }
00625
00626
00627 CHORDSETalloc(&tie_swi,num_swi_open);
00628 CHORDSETalloc(&tie_swi_1,num_swi_open);
00629 CHORDSETalloc(&tie_swi_2,num_swi_open);
00630 LOCSETalloc(&tie_swi_loc,num_swi_open);
00631
00632 CHORDSETalloc(&sec_swi,num_swi_closed);
00633 CHORDSETalloc(&sec_swi_1,num_swi_closed);
00634
00635 LOCSETalloc(&sec_swi_loc,num_swi_closed);
00636
00637
00638 for (indexval=0; indexval<NR_branch_count; indexval++)
00639 {
00640
00641 if ((NR_branchdata[indexval].lnk_type == 2) || (NR_branchdata[indexval].lnk_type == 5))
00642 {
00643
00644 if (*NR_branchdata[indexval].status == LS_CLOSED)
00645 {
00646
00647
00648 {
00649
00650 sec_swi.data_1[sec_swi.currSize] = NR_branchdata[indexval].from;
00651 sec_swi.data_2[sec_swi.currSize] = NR_branchdata[indexval].to;
00652 sec_swi.currSize++;
00653
00654
00655 sec_swi_loc.data_1[sec_swi_loc.currSize] = indexval;
00656 sec_swi_loc.data_2[sec_swi_loc.currSize] = 0;
00657 sec_swi_loc.data_3[sec_swi_loc.currSize] = 0;
00658 sec_swi_loc.data_4[sec_swi_loc.currSize] = 0;
00659 sec_swi_loc.currSize++;
00660 }
00661
00662 }
00663 else
00664 {
00665
00666 tie_swi.data_1[tie_swi.currSize] = NR_branchdata[indexval].from;
00667 tie_swi.data_2[tie_swi.currSize] = NR_branchdata[indexval].to;
00668 tie_swi.currSize++;
00669
00670
00671 tie_swi_loc.data_1[tie_swi_loc.currSize] = indexval;
00672 tie_swi_loc.data_2[tie_swi_loc.currSize] = 0;
00673 tie_swi_loc.data_3[tie_swi_loc.currSize] = 0;
00674 tie_swi_loc.data_4[tie_swi_loc.currSize] = 0;
00675 tie_swi_loc.currSize++;
00676
00677 }
00678 }
00679 else if (NR_branchdata[indexval].lnk_type == 6)
00680 {
00681
00682 sec_swi.data_1[sec_swi.currSize] = NR_branchdata[indexval].from;
00683 sec_swi.data_2[sec_swi.currSize] = NR_branchdata[indexval].to;
00684 sec_swi.currSize++;
00685
00686
00687 sec_swi_loc.data_1[sec_swi_loc.currSize] = indexval;
00688 sec_swi_loc.data_2[sec_swi_loc.currSize] = 0;
00689 sec_swi_loc.data_3[sec_swi_loc.currSize] = 0;
00690 sec_swi_loc.data_4[sec_swi_loc.currSize] = 0;
00691 sec_swi_loc.currSize++;
00692 }
00693
00694 }
00695
00696
00697
00698
00699
00700
00701 if (faulting_link == -99)
00702 {
00703
00704 if (faultSecObj == NULL)
00705 {
00706
00707 f_sec.from_vert = 0;
00708 f_sec.to_vert = 0;
00709 }
00710 else
00711 {
00712
00713
00714 for (indexval=0; indexval<NR_branch_count; indexval++)
00715 {
00716 if (faultSecObj == NR_branchdata[indexval].obj)
00717 {
00718 f_sec.from_vert = NR_branchdata[indexval].from;
00719 f_sec.to_vert = NR_branchdata[indexval].to;
00720 break;
00721 }
00722 }
00723 }
00724 }
00725 else
00726 {
00727 f_sec.from_vert = NR_branchdata[faulting_link].from;
00728 f_sec.to_vert = NR_branchdata[faulting_link].to;
00729 }
00730
00731
00732 if ((f_sec.from_vert == -1) || (f_sec.to_vert == -1))
00733 {
00734 GL_THROW("Restoration: failed to find the fault vertex");
00735
00736
00737
00738
00739
00740 }
00741
00742
00743
00744
00745 INTVECTalloc(&feederVertices,numfVer);
00746
00747
00748 for (secindexval=0; secindexval<numfVer; secindexval++)
00749 {
00750
00751 for (indexval=0; indexval<NR_bus_count; indexval++)
00752 {
00753 if (fVerObjList[secindexval] == NR_busdata[indexval].obj)
00754 {
00755 feederVertices.data[feederVertices.currSize] = indexval;
00756 feederVertices.currSize++;
00757 break;
00758 }
00759 }
00760 }
00761
00762
00763 simplifyTop_1();
00764
00765
00766 INTVECTalloc(&feederVertices_1,ver_map_1.currSize);
00767
00768
00769 for (secindexval=0; secindexval<feederVertices.currSize; secindexval++)
00770 {
00771 feederVertices_1.data[secindexval] = ver_map_1.data[feederVertices.data[secindexval]];
00772 feederVertices_1.currSize++;
00773 }
00774
00775
00776
00777
00778
00779 simplifyTop_2();
00780
00781
00782 setFeederVertices_2();
00783
00784
00785 setMicrogridVertices();
00786
00787
00788 modifySecSwiList();
00789
00790
00791 formSecSwiMap();
00792
00793
00794 top_res = (LinkedUndigraph *)gl_malloc(sizeof(LinkedUndigraph));
00795 top_tmp = (LinkedUndigraph *)gl_malloc(sizeof(LinkedUndigraph));
00796
00797
00798 if ((top_res == NULL) || (top_tmp == NULL))
00799 {
00800 GL_THROW("Restoration: failed to allocte graph theory object");
00801
00802 }
00803
00804
00805 new (top_res) LinkedUndigraph(0);
00806 new (top_tmp) LinkedUndigraph(0);
00807
00808 top_tmp->copy(top_sim_1);
00809
00810
00811 PowerflowSave();
00812
00813
00814 CHORDSETalloc(&sec_list,sec_swi.maxSize);
00815
00816
00817 memcpy(sec_list.data_1,sec_swi.data_1,sec_swi.maxSize*sizeof(int));
00818 memcpy(sec_list.data_2,sec_swi.data_2,sec_swi.maxSize*sizeof(int));
00819 sec_list.currSize = sec_swi.currSize;
00820
00821
00822 for (secindexval=0; secindexval<sec_list.currSize; secindexval++)
00823 {
00824
00825 fsec.from_vert = sec_list.data_1[secindexval];
00826 fsec.to_vert = sec_list.data_2[secindexval];
00827
00828
00829 renewFaultLocation(&fsec);
00830
00831
00832 IdxSW = spanningTreeSearch();
00833
00834
00835 if (file_output_desired == true)
00836 {
00837 printResult(IdxSW);
00838 }
00839
00840
00841 if (stop_and_generate == false)
00842 {
00843 break;
00844 }
00845
00846 }
00847
00848
00849 restoration_checks_active = false;
00850
00851 return 1;
00852 }
00853
00854
00855
00856
00857
00858 double *restoration::ParseDoubleString(char *input_string,int *num_items_found)
00859 {
00860 int index, num_items, item_count;
00861 char *working_token, *parsing_token;
00862 double *output_array;
00863
00864
00865 output_array = NULL;
00866
00867
00868 parsing_token = input_string;
00869 working_token = input_string;
00870
00871
00872 index = 0;
00873 num_items = 0;
00874
00875
00876 while ((*working_token != '\0') && (index < 1024))
00877 {
00878 if (*working_token == ',')
00879 num_items++;
00880
00881 index++;
00882 working_token++;
00883 }
00884
00885
00886 if ((num_items>=0) && (index != 0))
00887 {
00888 num_items++;
00889 }
00890
00891
00892
00893 if (num_items != 0)
00894 {
00895
00896 output_array = (double *)gl_malloc(num_items*sizeof(double));
00897
00898
00899 if (output_array == NULL)
00900 {
00901 gl_error("restoration: Failed to allocate space for double array!");
00902
00903
00904
00905
00906
00907
00908
00909 *num_items_found = -1;
00910 return NULL;
00911 }
00912
00913
00914 for (index=0; index<num_items; index++)
00915 {
00916 output_array[index] = 0.0;
00917 }
00918
00919
00920 item_count = 0;
00921 working_token = input_string;
00922
00923
00924 if (num_items > 1)
00925 {
00926
00927 while (item_count < (num_items - 1))
00928 {
00929
00930 parsing_token = strchr(working_token,',');
00931
00932
00933 if (parsing_token == NULL)
00934 {
00935 gl_error("restoration: Attempting to parse a character token failed");
00936
00937
00938
00939
00940
00941
00942 *num_items_found = -1;
00943 return NULL;
00944 }
00945 else
00946 {
00947
00948 *parsing_token = '\0';
00949
00950
00951 output_array[item_count] = strtod(working_token,NULL);
00952
00953
00954 item_count++;
00955 working_token = ++parsing_token;
00956 }
00957 }
00958 }
00959
00960
00961
00962 output_array[item_count] = strtod(working_token,NULL);
00963 }
00964 else
00965 {
00966 gl_warning("restoration: Attempt to parse double CSV array resulted in an empty array - check your inputs");
00967
00968
00969
00970
00971 }
00972
00973
00974 *num_items_found = num_items;
00975
00976
00977 return output_array;
00978 }
00979
00980
00981
00982
00983
00984 complex *restoration::ParseComplexString(char *input_string,int *num_items_found)
00985 {
00986 int index, num_items, item_count;
00987 char *working_token, *parsing_token, *complex_token, *offset_token;
00988 complex *output_array;
00989 double temp_value;
00990
00991
00992 output_array = NULL;
00993
00994
00995 parsing_token = input_string;
00996 working_token = input_string;
00997
00998
00999 index = 0;
01000 num_items = 0;
01001
01002
01003 while ((*working_token != '\0') && (index < 1024))
01004 {
01005 if (*working_token == ',')
01006 num_items++;
01007
01008 index++;
01009 working_token++;
01010 }
01011
01012
01013 if ((num_items>=0) && (index != 0))
01014 {
01015 num_items++;
01016 }
01017
01018
01019
01020 if (num_items != 0)
01021 {
01022
01023 output_array = (complex *)gl_malloc(num_items*sizeof(complex));
01024
01025
01026 if (output_array == NULL)
01027 {
01028 gl_error("restoration: Failed to allocate space for complex array!");
01029
01030
01031
01032
01033
01034
01035
01036 *num_items_found = -1;
01037 return NULL;
01038 }
01039
01040
01041 for (index=0; index<num_items; index++)
01042 {
01043 output_array[index] = complex(0.0,0.0);
01044 }
01045
01046
01047 item_count = 0;
01048 working_token = input_string;
01049
01050
01051 if (num_items > 1)
01052 {
01053
01054 while (item_count < (num_items - 1))
01055 {
01056
01057 parsing_token = strchr(working_token,',');
01058
01059
01060 if (parsing_token == NULL)
01061 {
01062 gl_error("restoration: Attempting to parse a character token failed");
01063
01064
01065
01066
01067
01068
01069 *num_items_found = -1;
01070 return NULL;
01071 }
01072 else
01073 {
01074
01075 *parsing_token = '\0';
01076
01077
01078 offset_token = working_token;
01079 offset_token++;
01080
01081
01082 complex_token = strpbrk(offset_token,"+-");
01083
01084
01085 if (complex_token == NULL)
01086 {
01087 gl_error("restoration: Attempting to parse a complex character token failed");
01088
01089
01090
01091
01092
01093
01094 *num_items_found = -1;
01095 return NULL;
01096 }
01097 else
01098 {
01099
01100
01101
01102 offset_token = parsing_token;
01103 *--offset_token = '\0';
01104 offset_token = complex_token;
01105
01106
01107 temp_value = strtod(complex_token,NULL);
01108
01109
01110 output_array[item_count].SetImag(temp_value);
01111
01112
01113 *offset_token = '\0';
01114
01115
01116 temp_value = strtod(working_token,NULL);
01117
01118
01119 output_array[item_count].SetReal(temp_value);
01120 }
01121
01122
01123 item_count++;
01124 working_token = ++parsing_token;
01125 }
01126 }
01127 }
01128
01129
01130
01131
01132 offset_token = working_token;
01133 offset_token++;
01134
01135
01136 complex_token = strpbrk(offset_token,"+-");
01137
01138
01139 if (complex_token == NULL)
01140 {
01141 gl_error("restoration: Attempting to parse a complex character token failed");
01142
01143
01144
01145 *num_items_found = -1;
01146 return NULL;
01147 }
01148 else
01149 {
01150
01151
01152
01153
01154
01155 offset_token = complex_token;
01156
01157
01158 temp_value = strtod(complex_token,NULL);
01159
01160
01161 output_array[item_count].SetImag(temp_value);
01162
01163
01164 *offset_token = '\0';
01165
01166
01167 temp_value = strtod(working_token,NULL);
01168
01169
01170 output_array[item_count].SetReal(temp_value);
01171 }
01172 }
01173 else
01174 {
01175 gl_warning("restoration: Attempt to parse complex CSV array resulted in an empty array - check your inputs");
01176
01177
01178
01179
01180 }
01181
01182
01183 *num_items_found = num_items;
01184
01185
01186 return output_array;
01187 }
01188
01189
01190
01191
01192 OBJECT **restoration::ParseObjectString(char *input_string,int *num_items_found)
01193 {
01194 int index, num_items, item_count;
01195 char *working_token, *parsing_token;
01196 OBJECT **output_array;
01197
01198
01199 output_array = NULL;
01200
01201
01202 parsing_token = input_string;
01203 working_token = input_string;
01204
01205
01206 index = 0;
01207 num_items = 0;
01208
01209
01210 while ((*working_token != '\0') && (index < 1024))
01211 {
01212 if (*working_token == ',')
01213 num_items++;
01214
01215 index++;
01216 working_token++;
01217 }
01218
01219
01220 if ((num_items>=0) && (index != 0))
01221 {
01222 num_items++;
01223 }
01224
01225
01226
01227 if (num_items != 0)
01228 {
01229
01230 output_array = (OBJECT **)gl_malloc(num_items*sizeof(OBJECT *));
01231
01232
01233 if (output_array == NULL)
01234 {
01235 gl_error("restoration: Failed to allocate space for object array!");
01236
01237
01238
01239
01240
01241
01242
01243 *num_items_found = -1;
01244 return NULL;
01245 }
01246
01247
01248 for (index=0; index<num_items; index++)
01249 {
01250 output_array[index] = NULL;
01251 }
01252
01253
01254 item_count = 0;
01255 working_token = input_string;
01256
01257
01258 if (num_items > 1)
01259 {
01260
01261 while (item_count < (num_items - 1))
01262 {
01263
01264 parsing_token = strchr(working_token,',');
01265
01266
01267 if (parsing_token == NULL)
01268 {
01269 gl_error("restoration: Attempting to parse a character token failed");
01270
01271
01272
01273
01274
01275
01276 *num_items_found = -1;
01277 return NULL;
01278 }
01279 else
01280 {
01281
01282 *parsing_token = '\0';
01283
01284
01285 output_array[item_count] = gl_get_object(working_token);
01286
01287
01288 item_count++;
01289 working_token = ++parsing_token;
01290 }
01291 }
01292 }
01293
01294
01295
01296 output_array[item_count] = gl_get_object(working_token);
01297 }
01298 else
01299 {
01300 gl_warning("restoration: Attempt to parse object CSV array resulted in an empty array - check your inputs");
01301
01302
01303
01304
01305 }
01306
01307
01308 *num_items_found = num_items;
01309
01310
01311 return output_array;
01312 }
01313
01314
01315
01316 void restoration::INTVECTalloc(INTVECT *inititem, int allocsizeval)
01317 {
01318 int indexval;
01319
01320
01321
01322
01323 if (inititem->data != NULL)
01324 {
01325 gl_free(inititem->data);
01326
01327
01328 inititem->data = NULL;
01329 }
01330
01331 inititem->currSize = 0;
01332 inititem->maxSize = allocsizeval;
01333
01334
01335 inititem->data = (int *)gl_malloc(allocsizeval*sizeof(int));
01336
01337
01338 if (inititem->data == NULL)
01339 {
01340 GL_THROW("Restoration: failed to allocte graph theory object");
01341
01342 }
01343
01344
01345 for (indexval=0; indexval<allocsizeval; indexval++)
01346 {
01347 inititem->data[indexval] = -1;
01348 }
01349 }
01350
01351
01352 void restoration::INTVECTfree(INTVECT *inititem)
01353 {
01354
01355 if (inititem->data != NULL)
01356 {
01357 gl_free(inititem->data);
01358
01359
01360 inititem->data = NULL;
01361 }
01362
01363
01364 inititem->currSize = 0;
01365 inititem->maxSize = 0;
01366 }
01367
01368
01369
01370
01371 void restoration::CHORDSETalloc(CHORDSET *inititem, int allocsizeval)
01372 {
01373 int indexval;
01374
01375
01376
01377
01378 if (inititem->data_1 != NULL)
01379 {
01380 gl_free(inititem->data_1);
01381
01382
01383 inititem->data_1 = NULL;
01384 }
01385
01386 if (inititem->data_2 != NULL)
01387 {
01388 gl_free(inititem->data_2);
01389
01390
01391 inititem->data_2 = NULL;
01392 }
01393
01394 inititem->currSize = 0;
01395 inititem->maxSize = allocsizeval;
01396
01397
01398 inititem->data_1 = (int *)gl_malloc(allocsizeval*sizeof(int));
01399 inititem->data_2 = (int *)gl_malloc(allocsizeval*sizeof(int));
01400
01401
01402 if ((inititem->data_1 == NULL) || (inititem->data_2 == NULL))
01403 {
01404 GL_THROW("Restoration: failed to allocte graph theory object");
01405
01406 }
01407
01408
01409 for (indexval=0; indexval<allocsizeval; indexval++)
01410 {
01411 inititem->data_1[indexval] = -1;
01412 inititem->data_2[indexval] = -1;
01413 }
01414 }
01415
01416
01417 void restoration::CHORDSETfree(CHORDSET *inititem)
01418 {
01419
01420 if (inititem->data_1 != NULL)
01421 {
01422 gl_free(inititem->data_1);
01423
01424
01425 inititem->data_1 = NULL;
01426 }
01427
01428 if (inititem->data_2 != NULL)
01429 {
01430 gl_free(inititem->data_2);
01431
01432
01433 inititem->data_2 = NULL;
01434 }
01435
01436
01437 inititem->currSize = 0;
01438 inititem->maxSize = 0;
01439 }
01440
01441
01442 void restoration::LOCSETalloc(LOCSET *inititem, int allocsizeval)
01443 {
01444 int indexval;
01445
01446
01447
01448
01449 if (inititem->data_1 != NULL)
01450 {
01451 gl_free(inititem->data_1);
01452
01453
01454 inititem->data_1 = NULL;
01455 }
01456
01457 if (inititem->data_2 != NULL)
01458 {
01459 gl_free(inititem->data_2);
01460
01461
01462 inititem->data_2 = NULL;
01463 }
01464
01465 if (inititem->data_3 != NULL)
01466 {
01467 gl_free(inititem->data_3);
01468
01469
01470 inititem->data_3 = NULL;
01471 }
01472
01473 if (inititem->data_4 != NULL)
01474 {
01475 gl_free(inititem->data_4);
01476
01477
01478 inititem->data_4 = NULL;
01479 }
01480
01481 inititem->currSize = 0;
01482 inititem->maxSize = allocsizeval;
01483
01484
01485 inititem->data_1 = (int *)gl_malloc(allocsizeval*sizeof(int));
01486 inititem->data_2 = (int *)gl_malloc(allocsizeval*sizeof(int));
01487 inititem->data_3 = (int *)gl_malloc(allocsizeval*sizeof(int));
01488 inititem->data_4 = (int *)gl_malloc(allocsizeval*sizeof(int));
01489
01490
01491 if ((inititem->data_1 == NULL) || (inititem->data_2 == NULL) || (inititem->data_3 == NULL) || (inititem->data_4 == NULL))
01492 {
01493 GL_THROW("Restoration: failed to allocte graph theory object");
01494
01495 }
01496
01497
01498 for (indexval=0; indexval<allocsizeval; indexval++)
01499 {
01500 inititem->data_1[indexval] = -1;
01501 inititem->data_2[indexval] = -1;
01502 inititem->data_3[indexval] = -1;
01503 inititem->data_4[indexval] = -1;
01504 }
01505 }
01506
01507
01508 void restoration::LOCSETfree(LOCSET *inititem)
01509 {
01510
01511 if (inititem->data_1 != NULL)
01512 {
01513 gl_free(inititem->data_1);
01514
01515
01516 inititem->data_1 = NULL;
01517 }
01518
01519 if (inititem->data_2 != NULL)
01520 {
01521 gl_free(inititem->data_2);
01522
01523
01524 inititem->data_2 = NULL;
01525 }
01526
01527 if (inititem->data_3 != NULL)
01528 {
01529 gl_free(inititem->data_3);
01530
01531
01532 inititem->data_3 = NULL;
01533 }
01534
01535 if (inititem->data_4 != NULL)
01536 {
01537 gl_free(inititem->data_4);
01538
01539
01540 inititem->data_4 = NULL;
01541 }
01542
01543
01544 inititem->currSize = 0;
01545 inititem->maxSize = 0;
01546 }
01547
01548
01549 void restoration::CANDSWOPalloc(CANDSWOP *inititem, int allocsizeval)
01550 {
01551 int indexval;
01552
01553
01554
01555
01556 if (inititem->data_1 != NULL)
01557 {
01558 gl_free(inititem->data_1);
01559
01560
01561 inititem->data_1 = NULL;
01562 }
01563
01564 if (inititem->data_2 != NULL)
01565 {
01566 gl_free(inititem->data_2);
01567
01568
01569 inititem->data_2 = NULL;
01570 }
01571
01572 if (inititem->data_3 != NULL)
01573 {
01574 gl_free(inititem->data_3);
01575
01576
01577 inititem->data_3 = NULL;
01578 }
01579
01580 if (inititem->data_4 != NULL)
01581 {
01582 gl_free(inititem->data_4);
01583
01584
01585 inititem->data_4 = NULL;
01586 }
01587
01588 if (inititem->data_5 != NULL)
01589 {
01590 gl_free(inititem->data_5);
01591
01592
01593 inititem->data_5 = NULL;
01594 }
01595
01596 if (inititem->data_6 != NULL)
01597 {
01598 gl_free(inititem->data_6);
01599
01600
01601 inititem->data_6 = NULL;
01602 }
01603
01604 if (inititem->data_7 != NULL)
01605 {
01606 gl_free(inititem->data_7);
01607
01608
01609 inititem->data_7 = NULL;
01610 }
01611
01612 inititem->currSize = 0;
01613 inititem->maxSize = allocsizeval;
01614
01615
01616 inititem->data_1 = (int *)gl_malloc(allocsizeval*sizeof(int));
01617 inititem->data_2 = (int *)gl_malloc(allocsizeval*sizeof(int));
01618 inititem->data_3 = (int *)gl_malloc(allocsizeval*sizeof(int));
01619 inititem->data_4 = (int *)gl_malloc(allocsizeval*sizeof(int));
01620 inititem->data_5 = (int *)gl_malloc(allocsizeval*sizeof(int));
01621 inititem->data_7 = (int *)gl_malloc(allocsizeval*sizeof(int));
01622
01623
01624 if ((inititem->data_1 == NULL) || (inititem->data_2 == NULL) || (inititem->data_3 == NULL))
01625 {
01626 GL_THROW("Restoration: failed to allocte graph theory object");
01627
01628 }
01629
01630
01631 if ((inititem->data_4 == NULL) || (inititem->data_5 == NULL) || (inititem->data_7 == NULL))
01632 {
01633 GL_THROW("Restoration: failed to allocte graph theory object");
01634
01635 }
01636
01637
01638 inititem->data_6 = (double *)gl_malloc(allocsizeval*sizeof(double));
01639
01640
01641 if (inititem->data_6 == NULL)
01642 {
01643 GL_THROW("Restoration: failed to allocte graph theory object");
01644
01645 }
01646
01647
01648 for (indexval=0; indexval<allocsizeval; indexval++)
01649 {
01650 inititem->data_1[indexval] = -1;
01651 inititem->data_2[indexval] = -1;
01652 inititem->data_3[indexval] = -1;
01653 inititem->data_4[indexval] = -1;
01654 inititem->data_5[indexval] = -1;
01655 inititem->data_7[indexval] = -1;
01656
01657
01658 inititem->data_6[indexval] = 0.0;
01659 }
01660 }
01661
01662
01663 void restoration::CANDSWOPfree(CANDSWOP *inititem)
01664 {
01665
01666 if (inititem->data_1 != NULL)
01667 {
01668 gl_free(inititem->data_1);
01669
01670
01671 inititem->data_1 = NULL;
01672 }
01673
01674 if (inititem->data_2 != NULL)
01675 {
01676 gl_free(inititem->data_2);
01677
01678
01679 inititem->data_2 = NULL;
01680 }
01681
01682 if (inititem->data_3 != NULL)
01683 {
01684 gl_free(inititem->data_3);
01685
01686
01687 inititem->data_3 = NULL;
01688 }
01689
01690 if (inititem->data_4 != NULL)
01691 {
01692 gl_free(inititem->data_4);
01693
01694
01695 inititem->data_4 = NULL;
01696 }
01697
01698 if (inititem->data_5 != NULL)
01699 {
01700 gl_free(inititem->data_5);
01701
01702
01703 inititem->data_5 = NULL;
01704 }
01705
01706 if (inititem->data_6 != NULL)
01707 {
01708 gl_free(inititem->data_6);
01709
01710
01711 inititem->data_6 = NULL;
01712 }
01713
01714 if (inititem->data_7 != NULL)
01715 {
01716 gl_free(inititem->data_7);
01717
01718
01719 inititem->data_7 = NULL;
01720 }
01721
01722
01723 inititem->currSize = 0;
01724 inititem->maxSize = 0;
01725 }
01726
01727
01728
01729 void restoration::simplifyTop_1(void)
01730 {
01731 int idx, v, s, jIndex, iIndex;
01732 int top_ori_VerNum, top_ori_VerNum_2;
01733
01734
01735 top_ori_VerNum = top_ori->getVerNum();
01736 INTVECTalloc(&ver_map_1,top_ori_VerNum);
01737
01738
01739 for (idx=0; idx<ver_map_1.maxSize; idx++)
01740 {
01741 ver_map_1.data[idx] = idx;
01742 }
01743
01744
01745 ver_map_1.currSize = ver_map_1.maxSize;
01746
01747
01748 top_sim_1 = (LinkedUndigraph *)gl_malloc(sizeof(LinkedUndigraph));
01749
01750
01751 if (top_sim_1 == NULL)
01752 {
01753 GL_THROW("Restoration: failed to allocte graph theory object");
01754
01755 }
01756
01757
01758 new (top_sim_1) LinkedUndigraph(0);
01759
01760
01761 top_sim_1->copy(top_ori);
01762
01763
01764
01765 top_ori->initializePos();
01766
01767
01768 top_ori_VerNum = top_ori->getVerNum();
01769 for (idx=0; idx<top_ori_VerNum; idx++)
01770 {
01771 v = top_ori->beginVertex(idx);
01772
01773 while (v != -1)
01774 {
01775 if ((v>idx) && (isSwitch(idx,v) == false) && ((v!=f_sec.from_vert) || (idx!=f_sec.to_vert)) && ((v!=f_sec.to_vert) || (idx!=f_sec.from_vert)))
01776 {
01777
01778
01779 if (ver_map_1.data[idx] < ver_map_1.data[v])
01780 {
01781 iIndex = ver_map_1.data[idx];
01782 jIndex = ver_map_1.data[v];
01783 }
01784 else
01785 {
01786 iIndex = ver_map_1.data[v];
01787 jIndex = ver_map_1.data[idx];
01788 }
01789
01790 top_ori_VerNum_2 = top_ori->getVerNum();
01791 for (s=0; s<top_ori_VerNum_2; s++)
01792 {
01793 if (ver_map_1.data[s] == jIndex)
01794 {
01795 ver_map_1.data[s] = iIndex;
01796 }
01797 else if (ver_map_1.data[s] > jIndex)
01798 {
01799 ver_map_1.data[s] = ver_map_1.data[s] - 1;
01800 }
01801 }
01802 }
01803 v = top_ori->nextVertex(idx);
01804 }
01805 }
01806
01807
01808 top_ori->deactivatePos();
01809
01810
01811 top_sim_1->mergeVer_2(&ver_map_1);
01812
01813
01814
01815
01816 for (idx=0; idx<sec_swi.currSize; idx++)
01817 {
01818 sec_swi_1.data_1[idx] = ver_map_1.data[sec_swi.data_1[idx]];
01819 sec_swi_1.data_2[idx] = ver_map_1.data[sec_swi.data_2[idx]];
01820 }
01821
01822
01823 sec_swi_1.currSize = sec_swi.currSize;
01824
01825
01826 for (idx=0; idx<tie_swi.currSize; idx++)
01827 {
01828 tie_swi_1.data_1[idx] = ver_map_1.data[tie_swi.data_1[idx]];
01829 tie_swi_1.data_2[idx] = ver_map_1.data[tie_swi.data_2[idx]];
01830 }
01831
01832
01833 tie_swi_1.currSize = tie_swi.currSize;
01834
01835
01836 f_sec_1.from_vert = ver_map_1.data[f_sec.from_vert];
01837 f_sec_1.to_vert = ver_map_1.data[f_sec.to_vert];
01838
01839
01840 s_ver_1 = ver_map_1.data[s_ver];
01841 }
01842
01843
01844
01845
01846 void restoration::simplifyTop_2(void)
01847 {
01848 int idx, uIdx, vIdx;
01849 int top_sim_2_getVerNum;
01850 int allocsizeval;
01851 CHAINNODE *v;
01852
01853
01854 top_sim_2 = (LinkedUndigraph *)gl_malloc(sizeof(LinkedUndigraph));
01855
01856
01857 if (top_sim_2 == NULL)
01858 {
01859 GL_THROW("Restoration: failed to allocte graph theory object");
01860
01861 }
01862
01863
01864 new (top_sim_2) LinkedUndigraph(0);
01865
01866
01867 top_sim_2->copy(top_sim_1);
01868
01869
01870
01871 INTVECTalloc(&ver_map_2,ver_map_1.maxSize);
01872
01873
01874 top_sim_2->simplify(&tie_swi_1, &f_sec_1, s_ver_1, &feederVertices_1, &ver_map_2);
01875
01876
01877
01878 for (idx=0; idx<tie_swi_1.currSize; idx++)
01879 {
01880 tie_swi_2.data_1[idx] = ver_map_2.data[tie_swi_1.data_1[idx]];
01881 tie_swi_2.data_2[idx] = ver_map_2.data[tie_swi_1.data_2[idx]];
01882 }
01883
01884
01885 tie_swi_2.currSize = tie_swi_1.currSize;
01886
01887
01888 f_sec_2.from_vert = ver_map_2.data[f_sec_1.from_vert];
01889 f_sec_2.to_vert = ver_map_2.data[f_sec_1.to_vert];
01890
01891
01892 s_ver_2 = ver_map_2.data[s_ver_1];
01893
01894
01895 allocsizeval = top_sim_2->getVerNum();
01896 CHORDSETalloc(&sec_swi_2,allocsizeval);
01897
01898 top_sim_2_getVerNum = top_sim_2->getVerNum();
01899 for (uIdx=0; uIdx<top_sim_2_getVerNum; uIdx++)
01900 {
01901 v = top_sim_2->adjList[uIdx]->first;
01902
01903 while (v != NULL)
01904 {
01905 vIdx = v->data;
01906 if ((vIdx > uIdx) && ((((uIdx==f_sec_2.from_vert) && (vIdx==f_sec_2.to_vert)) || ((uIdx==f_sec_2.to_vert) && (vIdx==f_sec_2.from_vert)))) == false)
01907 {
01908 sec_swi_2.data_1[sec_swi_2.currSize] = uIdx;
01909 sec_swi_2.data_2[sec_swi_2.currSize] = vIdx;
01910 sec_swi_2.currSize++;
01911
01912 if (sec_swi_2.currSize >= sec_swi_2.maxSize)
01913 {
01914
01915 if (sec_swi_2.currSize == sec_swi_2.maxSize)
01916 {
01917 gl_verbose("sec_swi_2 just hit maximum length");
01918 }
01919 else
01920 {
01921 GL_THROW("restoration: allocated array size exceeded!");
01922
01923
01924
01925
01926 }
01927 }
01928 }
01929 v = v->link;
01930 }
01931 }
01932 }
01933
01934
01935 void restoration::setFeederVertices_2(void)
01936 {
01937 int idx, curNode, nodeSetIdx;
01938 CHAINNODE *tNode;
01939 INTVECT nodeSet;
01940
01941
01942 nodeSet.data = NULL;
01943
01944
01945 INTVECTalloc(&nodeSet,feederVertices_1.maxSize);
01946
01947
01948 INTVECTalloc(&feederVertices_2,feederVertices_1.maxSize);
01949
01950
01951 feederVertices_2.currSize = feederVertices_2.maxSize;
01952
01953 for (idx=0; idx<feederVertices.currSize; idx++)
01954 {
01955
01956 nodeSetIdx = 0;
01957 nodeSet.data[nodeSetIdx] = feederVertices_1.data[idx];
01958 nodeSet.currSize = 1;
01959
01960 while ((nodeSet.data[nodeSetIdx] != -1) && (nodeSetIdx < nodeSet.currSize))
01961 {
01962 curNode = nodeSet.data[nodeSetIdx];
01963 nodeSetIdx++;
01964
01965 if (ver_map_2.data[curNode] != -1)
01966 {
01967 feederVertices_2.data[idx] = ver_map_2.data[curNode];
01968 break;
01969 }
01970 else
01971 {
01972 if (top_sim_1->adjList[curNode] != NULL)
01973 {
01974 tNode = top_sim_1->adjList[curNode]->first;
01975 }
01976 else
01977 {
01978 tNode = NULL;
01979 }
01980
01981 while (tNode != NULL)
01982 {
01983 if (tNode->data != s_ver_1)
01984 {
01985 nodeSet.data[nodeSet.currSize] = tNode->data;
01986 nodeSet.currSize++;
01987 }
01988 tNode = tNode->link;
01989 }
01990 }
01991 }
01992 }
01993
01994
01995 gl_free(nodeSet.data);
01996 }
01997
01998
01999 void restoration::setMicrogridVertices(void)
02000 {
02001 int idxval;
02002
02003
02004 for (idxval=0; idxval<MGIdx.currSize; idxval++)
02005 {
02006 MGIdx_1.data[idxval] = ver_map_1.data[MGIdx.data[idxval]];
02007 }
02008 MGIdx_1.currSize = MGIdx.currSize;
02009
02010
02011 for (idxval=0; idxval<MGIdx_1.currSize; idxval++)
02012 {
02013 MGIdx_2.data[idxval] = ver_map_2.data[MGIdx_1.data[idxval]];
02014 }
02015 MGIdx_2.currSize = MGIdx_1.currSize;
02016 }
02017
02018
02019
02020
02021
02022
02023
02024
02025 void restoration::modifySecSwiList(void)
02026 {
02027 CHORDSET sec_swi_temp, sec_swi_1_temp, sec_swi_2_temp;
02028 LOCSET sec_swi_loc_temp;
02029 int indexval;
02030
02031
02032 sec_swi_temp.data_1 = NULL;
02033 sec_swi_temp.data_2 = NULL;
02034 sec_swi_1_temp.data_1 = NULL;
02035 sec_swi_1_temp.data_2 = NULL;
02036 sec_swi_2_temp.data_1 = NULL;
02037 sec_swi_2_temp.data_2 = NULL;
02038 sec_swi_loc_temp.data_1 = NULL;
02039 sec_swi_loc_temp.data_2 = NULL;
02040 sec_swi_loc_temp.data_3 = NULL;
02041 sec_swi_loc_temp.data_4 = NULL;
02042
02043
02044 CHORDSETalloc(&sec_swi_temp,sec_swi.maxSize);
02045 CHORDSETalloc(&sec_swi_1_temp,sec_swi_1.maxSize);
02046 CHORDSETalloc(&sec_swi_2_temp,sec_swi_2.maxSize);
02047 LOCSETalloc(&sec_swi_loc_temp,sec_swi_loc.maxSize);
02048
02049
02050 memcpy(sec_swi_temp.data_1,sec_swi.data_1,sec_swi.maxSize*sizeof(int));
02051 memcpy(sec_swi_temp.data_2,sec_swi.data_2,sec_swi.maxSize*sizeof(int));
02052 memcpy(sec_swi_1_temp.data_1,sec_swi_1.data_1,sec_swi_1.maxSize*sizeof(int));
02053 memcpy(sec_swi_1_temp.data_2,sec_swi_1.data_2,sec_swi_1.maxSize*sizeof(int));
02054 memcpy(sec_swi_2_temp.data_1,sec_swi_2.data_1,sec_swi_2.maxSize*sizeof(int));
02055 memcpy(sec_swi_2_temp.data_2,sec_swi_2.data_2,sec_swi_2.maxSize*sizeof(int));
02056
02057
02058 memcpy(sec_swi_loc_temp.data_1,sec_swi_loc.data_1,sec_swi_loc.maxSize*sizeof(int));
02059 memcpy(sec_swi_loc_temp.data_2,sec_swi_loc.data_2,sec_swi_loc.maxSize*sizeof(int));
02060 memcpy(sec_swi_loc_temp.data_3,sec_swi_loc.data_3,sec_swi_loc.maxSize*sizeof(int));
02061 memcpy(sec_swi_loc_temp.data_4,sec_swi_loc.data_4,sec_swi_loc.maxSize*sizeof(int));
02062
02063
02064 sec_swi_temp.currSize = sec_swi.currSize;
02065 sec_swi_1_temp.currSize = sec_swi_1.currSize;
02066 sec_swi_2_temp.currSize = sec_swi_2.currSize;
02067 sec_swi_loc_temp.currSize = sec_swi_loc.currSize;
02068
02069
02070
02071
02072 for (indexval=0; indexval<sec_swi.maxSize; indexval++)
02073 {
02074 sec_swi.data_1[indexval] = -1;
02075 sec_swi.data_2[indexval] = -1;
02076
02077 sec_swi_loc.data_1[indexval] = -1;
02078 sec_swi_loc.data_2[indexval] = -1;
02079 sec_swi_loc.data_3[indexval] = -1;
02080 sec_swi_loc.data_4[indexval] = -1;
02081 }
02082
02083
02084 sec_swi.currSize = 0;
02085 sec_swi_loc.currSize = 0;
02086
02087
02088 for (indexval=0; indexval<sec_swi_temp.currSize; indexval++)
02089 {
02090 if ((sec_swi_temp.data_1[indexval] != s_ver) && (sec_swi_temp.data_2[indexval] != s_ver))
02091 {
02092
02093 sec_swi.data_1[sec_swi.currSize] = sec_swi_temp.data_1[indexval];
02094 sec_swi.data_2[sec_swi.currSize] = sec_swi_temp.data_2[indexval];
02095
02096
02097 sec_swi_loc.data_1[sec_swi_loc.currSize] = sec_swi_loc_temp.data_1[indexval];
02098 sec_swi_loc.data_2[sec_swi_loc.currSize] = sec_swi_loc_temp.data_2[indexval];
02099 sec_swi_loc.data_3[sec_swi_loc.currSize] = sec_swi_loc_temp.data_3[indexval];
02100 sec_swi_loc.data_4[sec_swi_loc.currSize] = sec_swi_loc_temp.data_4[indexval];
02101
02102
02103 sec_swi.currSize++;
02104 sec_swi_loc.currSize++;
02105 }
02106
02107 }
02108
02109
02110 for (indexval=0; indexval<sec_swi_1.maxSize; indexval++)
02111 {
02112 sec_swi_1.data_1[indexval] = -1;
02113 sec_swi_1.data_2[indexval] = -1;
02114 }
02115
02116
02117 sec_swi_1.currSize = 0;
02118
02119
02120 for (indexval=0; indexval<sec_swi_1_temp.currSize; indexval++)
02121 {
02122 if ((sec_swi_1_temp.data_1[indexval] != s_ver_1) && (sec_swi_1_temp.data_2[indexval] != s_ver_1))
02123 {
02124
02125 sec_swi_1.data_1[sec_swi_1.currSize] = sec_swi_1_temp.data_1[indexval];
02126 sec_swi_1.data_2[sec_swi_1.currSize] = sec_swi_1_temp.data_2[indexval];
02127
02128
02129 sec_swi_1.currSize++;
02130 }
02131
02132 }
02133
02134
02135 for (indexval=0; indexval<sec_swi_2.maxSize; indexval++)
02136 {
02137 sec_swi_2.data_1[indexval] = -1;
02138 sec_swi_2.data_2[indexval] = -1;
02139 }
02140
02141
02142 sec_swi_2.currSize = 0;
02143
02144
02145 for (indexval=0; indexval<sec_swi_2_temp.currSize; indexval++)
02146 {
02147 if ((sec_swi_2_temp.data_1[indexval] != s_ver_2) && (sec_swi_2_temp.data_2[indexval] != s_ver_2))
02148 {
02149
02150 sec_swi_2.data_1[sec_swi_2.currSize] = sec_swi_2_temp.data_1[indexval];
02151 sec_swi_2.data_2[sec_swi_2.currSize] = sec_swi_2_temp.data_2[indexval];
02152
02153
02154 sec_swi_2.currSize++;
02155 }
02156
02157 }
02158
02159
02160 CHORDSETfree(&sec_swi_temp);
02161 CHORDSETfree(&sec_swi_1_temp);
02162 CHORDSETfree(&sec_swi_2_temp);
02163 LOCSETfree(&sec_swi_loc_temp);
02164 }
02165
02166
02167 void restoration::formSecSwiMap(void)
02168 {
02169 int idx;
02170 BRANCHVERTICES sSW, sSW_1, inputBranch;
02171
02172
02173 CHORDSETalloc(&sec_swi_map,sec_swi_2.currSize);
02174 CHORDSETalloc(&sec_swi_map_1,sec_swi_2.currSize);
02175
02176 for (idx=0; idx<sec_swi_2.currSize; idx++)
02177 {
02178 inputBranch.from_vert = sec_swi_2.data_1[idx];
02179 inputBranch.to_vert = sec_swi_2.data_2[idx];
02180 mapSecSwi(&inputBranch,&sSW,&sSW_1);
02181
02182 sec_swi_map.data_1[idx] = sSW.from_vert;
02183 sec_swi_map.data_2[idx] = sSW.to_vert;
02184 sec_swi_map_1.data_1[idx] = sSW_1.from_vert;
02185 sec_swi_map_1.data_2[idx] = sSW_1.to_vert;
02186 }
02187
02188
02189 sec_swi_map.currSize = sec_swi_2.currSize;
02190 sec_swi_map_1.currSize = sec_swi_2.currSize;
02191 }
02192
02193
02194 void restoration::mapSecSwi(BRANCHVERTICES *sSW_2, BRANCHVERTICES *sSW, BRANCHVERTICES *sSW_1)
02195 {
02196 int idx, uIdx, vIdx, temp, detDistInt;
02197 double detDist;
02198
02199
02200
02201
02202 top_sim_1->BFS(s_ver_1);
02203
02204
02205
02206 uIdx = -1;
02207 vIdx = -1;
02208
02209
02210 for (idx=0; idx<ver_map_2.currSize; idx++)
02211 {
02212 if (ver_map_2.data[idx] == sSW_2->from_vert)
02213 {
02214 uIdx = idx;
02215 break;
02216 }
02217 }
02218
02219
02220 if (uIdx == -1)
02221 {
02222 GL_THROW("Restoration: failed to find desired vertex in mapping list");
02223
02224
02225
02226
02227
02228 }
02229
02230
02231 for (idx=0; idx<ver_map_2.currSize; idx++)
02232 {
02233 if (ver_map_2.data[idx] == sSW_2->to_vert)
02234 {
02235 vIdx = idx;
02236 break;
02237 }
02238 }
02239
02240
02241 if (vIdx == -1)
02242 {
02243 GL_THROW("Restoration: failed to find desired vertex in mapping list");
02244
02245 }
02246
02247 if (top_sim_1->dist[uIdx] > top_sim_1->dist[vIdx])
02248 {
02249 temp = uIdx;
02250 uIdx = vIdx;
02251 vIdx = temp;
02252 }
02253
02254 detDist = (top_sim_1->dist[vIdx] - top_sim_1->dist[uIdx])/2.0;
02255 detDistInt = (int)detDist;
02256
02257 for (idx=0; idx<detDistInt; idx++)
02258 {
02259 vIdx = top_sim_1->parent_value[vIdx];
02260 }
02261 sSW_1->to_vert = vIdx;
02262 sSW_1->from_vert = top_sim_1->parent_value[vIdx];
02263
02264
02265 idx = 0;
02266
02267
02268 while (idx<sec_swi_1.currSize)
02269 {
02270 if ((sec_swi_1.data_1[idx] == sSW_1->from_vert) && (sec_swi_1.data_2[idx] == sSW_1->to_vert))
02271 {
02272 sSW->from_vert = sec_swi.data_1[idx];
02273 sSW->to_vert = sec_swi.data_2[idx];
02274 break;
02275 }
02276 if ((sec_swi_1.data_1[idx] == sSW_1->to_vert) && (sec_swi_1.data_2[idx] == sSW_1->from_vert))
02277 {
02278 sSW->from_vert = sec_swi.data_2[idx];
02279 sSW->to_vert = sec_swi.data_1[idx];
02280 break;
02281 }
02282 idx++;
02283 }
02284 }
02285
02286
02287 void restoration::mapTieSwi(BRANCHVERTICES *tSW_2, BRANCHVERTICES *tSW, BRANCHVERTICES *tSW_1)
02288 {
02289 int idx;
02290
02291 idx = 0;
02292
02293
02294 tSW->from_vert = -1;
02295 tSW->to_vert = -1;
02296 tSW_1->from_vert = -1;
02297 tSW_1->to_vert = -1;
02298
02299
02300 while (idx<tie_swi_2.currSize)
02301 {
02302 if ((tie_swi_2.data_1[idx]==tSW_2->from_vert) && (tie_swi_2.data_2[idx]==tSW_2->to_vert))
02303 {
02304 tSW->from_vert = tie_swi.data_1[idx];
02305 tSW->to_vert = tie_swi.data_2[idx];
02306 tSW_1->from_vert = tie_swi_1.data_1[idx];
02307 tSW_1->to_vert = tie_swi_1.data_2[idx];
02308 break;
02309 }
02310
02311 if ((tie_swi_2.data_2[idx]==tSW_2->from_vert) && (tie_swi_2.data_1[idx]==tSW_2->to_vert))
02312 {
02313 tSW->from_vert = tie_swi.data_2[idx];
02314 tSW->to_vert = tie_swi.data_1[idx];
02315 tSW_1->from_vert = tie_swi_1.data_2[idx];
02316 tSW_1->to_vert = tie_swi_1.data_1[idx];
02317 break;
02318 }
02319
02320 idx++;
02321 }
02322 }
02323
02324
02325 void restoration::renewFaultLocation(BRANCHVERTICES *faultsection)
02326 {
02327
02328 f_sec.from_vert = faultsection->from_vert;
02329 f_sec.to_vert = faultsection->to_vert;
02330
02331
02332 f_sec_1.from_vert = ver_map_1.data[f_sec.from_vert];
02333 f_sec_1.to_vert = ver_map_1.data[f_sec.to_vert];
02334
02335
02336 simplifyTop_2();
02337
02338
02339 setFeederVertices_2();
02340
02341
02342 setMicrogridVertices();
02343
02344
02345
02346 modifySecSwiList();
02347
02348
02349 formSecSwiMap();
02350
02351
02352
02353 if (top_res != NULL)
02354 {
02355 top_res->delAllVer();
02356 }
02357
02358 if (top_tmp != NULL)
02359 {
02360 top_tmp->delAllVer();
02361 }
02362
02363
02364
02365
02366 new (top_res) LinkedUndigraph(0);
02367 new (top_tmp) LinkedUndigraph(0);
02368
02369
02370 top_tmp->copy(top_sim_1);
02371 }
02372
02373
02374
02375
02376
02377
02378 int restoration::spanningTreeSearch(void)
02379 {
02380 int idx, counter, preCounter, feederID, feeder_overloaded, k, tvi, startIdx, allocsize;
02381 int powerflow_result;
02382 CHORDSET FCutSet, FCutSet_1, FCutSet_2, FCutSet_2_1, FCutSet_2_2, new_tie_swi;
02383 BRANCHVERTICES FCutSetentry, FCutSet_1entry, FCutSet_2entry;
02384 BRANCHVERTICES SW_to_Open, SW_to_Open_1, SW_to_Open_2;
02385 BRANCHVERTICES sec_swi_2entry;
02386 bool feasible, swiInFeederBool;
02387 double overLoad;
02388
02389
02390 FCutSet.data_1 = NULL;
02391 FCutSet.data_2 = NULL;
02392 FCutSet_1.data_1 = NULL;
02393 FCutSet_1.data_2 = NULL;
02394 FCutSet_2.data_1 = NULL;
02395 FCutSet_2.data_2 = NULL;
02396 FCutSet_2_1.data_1 = NULL;
02397 FCutSet_2_1.data_2 = NULL;
02398 FCutSet_2_2.data_1 = NULL;
02399 FCutSet_2_2.data_2 = NULL;
02400 new_tie_swi.data_1 = NULL;
02401 new_tie_swi.data_2 = NULL;
02402
02403
02404 feasible = false;
02405
02406
02407 CHORDSETalloc(&FCutSet_2_2,tie_swi_2.maxSize);
02408 CHORDSETalloc(&FCutSet_2_1,tie_swi_2.maxSize);
02409 CHORDSETalloc(&FCutSet_2,tie_swi_2.maxSize);
02410 CHORDSETalloc(&FCutSet_1,tie_swi_2.maxSize);
02411 CHORDSETalloc(&FCutSet,tie_swi_2.maxSize);
02412
02413
02414 top_sim_2->BFS(s_ver_2);
02415
02416 top_sim_2->findFunCutSet(&tie_swi_2,&f_sec_2,&FCutSet_2);
02417
02418 for (idx=0; idx<FCutSet_2.currSize; idx++)
02419 {
02420 FCutSet_2entry.from_vert = FCutSet_2.data_1[idx];
02421 FCutSet_2entry.to_vert = FCutSet_2.data_2[idx];
02422
02423 mapTieSwi(&FCutSet_2entry,&FCutSetentry, &FCutSet_1entry);
02424
02425
02426 FCutSet.data_1[idx] = FCutSetentry.from_vert;
02427 FCutSet.data_2[idx] = FCutSetentry.to_vert;
02428 FCutSet_1.data_1[idx] = FCutSet_1entry.from_vert;
02429 FCutSet_1.data_2[idx] = FCutSet_1entry.to_vert;
02430 }
02431
02432
02433 FCutSet.currSize = FCutSet_2.currSize;
02434 FCutSet_1.currSize = FCutSet_2.currSize;
02435
02436
02437
02438
02439
02440
02441
02442 if (numMG > 0)
02443 {
02444 allocsize = 2*numMG*numfVer*(tie_swi.currSize + sec_swi.currSize);
02445 }
02446 else
02447 {
02448 allocsize = 2*numfVer*(tie_swi.currSize + sec_swi.currSize);
02449 }
02450
02451 CANDSWOPalloc(&candidateSwOpe,allocsize);
02452 CANDSWOPalloc(&candidateSwOpe_1,allocsize);
02453 CANDSWOPalloc(&candidateSwOpe_2,allocsize);
02454
02455 for (idx=0; idx<FCutSet_2.currSize; idx++)
02456 {
02457 candidateSwOpe_2.data_1[idx] = f_sec_2.from_vert;
02458 candidateSwOpe_2.data_2[idx] = f_sec_2.to_vert;
02459 candidateSwOpe_2.data_3[idx] = FCutSet_2.data_1[idx];
02460 candidateSwOpe_2.data_4[idx] = FCutSet_2.data_2[idx];
02461 candidateSwOpe_2.data_5[idx] = 0;
02462 candidateSwOpe_2.data_6[idx] = 0.0;
02463 candidateSwOpe_2.data_7[idx] = 0;
02464
02465 candidateSwOpe_1.data_1[idx] = f_sec_1.from_vert;
02466 candidateSwOpe_1.data_2[idx] = f_sec_1.to_vert;
02467 candidateSwOpe_1.data_3[idx] = FCutSet_1.data_1[idx];
02468 candidateSwOpe_1.data_4[idx] = FCutSet_1.data_2[idx];
02469 candidateSwOpe_1.data_5[idx] = 0;
02470 candidateSwOpe_1.data_6[idx] = 0.0;
02471 candidateSwOpe_1.data_7[idx] = 0;
02472
02473 candidateSwOpe.data_1[idx] = f_sec.from_vert;
02474 candidateSwOpe.data_2[idx] = f_sec.to_vert;
02475 candidateSwOpe.data_3[idx] = FCutSet.data_1[idx];
02476 candidateSwOpe.data_4[idx] = FCutSet.data_2[idx];
02477 candidateSwOpe.data_5[idx] = 0;
02478 candidateSwOpe.data_6[idx] = 0.0;
02479 candidateSwOpe.data_7[idx] = 0;
02480 }
02481
02482
02483 candidateSwOpe.currSize = FCutSet_2.currSize;
02484 candidateSwOpe_1.currSize = FCutSet_2.currSize;
02485 candidateSwOpe_2.currSize = FCutSet_2.currSize;
02486
02487
02488 counter = 0;
02489
02490 while (counter < candidateSwOpe.currSize)
02491 {
02492 if (candidateSwOpe.data_5[counter] == 0)
02493 {
02494
02495
02496
02497
02498 overLoad = 0.0;
02499 feederID = 0;
02500
02501
02502 modifyModel(counter);
02503
02504
02505 powerflow_result = runPowerFlow();
02506
02507
02508 if (powerflow_result == -1)
02509 {
02510 return -2;
02511
02512 }
02513 else if (powerflow_result == 0)
02514 {
02515
02516 modifyModel(counter);
02517
02518
02519 feasible=false;
02520
02521
02522 PowerflowRestore();
02523 }
02524 else
02525 {
02526
02527 checkPF2(&feasible, &overLoad, &feederID);
02528
02529
02530 if (feasible==false)
02531 {
02532 modifyModel(counter);
02533
02534
02535 PowerflowRestore();
02536 }
02537 }
02538
02539
02540 if (feasible == true)
02541 {
02542
02543 if (stop_and_generate == true)
02544 {
02545
02546 modifyModel(counter);
02547
02548
02549 PowerflowRestore();
02550 }
02551
02552
02553
02554
02555 CHORDSETfree(&FCutSet);
02556 CHORDSETfree(&FCutSet_1);
02557 CHORDSETfree(&FCutSet_2);
02558 CHORDSETfree(&FCutSet_2_1);
02559 CHORDSETfree(&FCutSet_2_2);
02560
02561 return counter;
02562 }
02563
02564
02565
02566 candidateSwOpe_2.data_6[counter] = overLoad;
02567 candidateSwOpe_1.data_6[counter] = overLoad;
02568 candidateSwOpe.data_6[counter] = overLoad;
02569
02570 candidateSwOpe_2.data_7[counter] = feederID;
02571 candidateSwOpe_1.data_7[counter] = feederID;
02572 candidateSwOpe.data_7[counter] = feederID;
02573
02574
02575 top_res->copy(top_sim_2);
02576 top_res->deleteEdge(candidateSwOpe_2.data_1[counter],candidateSwOpe_2.data_2[counter]);
02577 top_res->addEdge(candidateSwOpe_2.data_3[counter],candidateSwOpe_2.data_4[counter]);
02578 top_res->BFS(s_ver_2);
02579
02580
02581
02582 CHORDSETalloc(&new_tie_swi,tie_swi_2.currSize);
02583
02584
02585 memcpy(new_tie_swi.data_1,tie_swi_2.data_1,tie_swi_2.currSize*sizeof(int));
02586 memcpy(new_tie_swi.data_2,tie_swi_2.data_2,tie_swi_2.currSize*sizeof(int));
02587 new_tie_swi.currSize = tie_swi_2.currSize;
02588
02589 for (idx=0; idx<new_tie_swi.currSize; idx++)
02590 {
02591 if (((new_tie_swi.data_1[idx]==candidateSwOpe_2.data_3[counter]) && (new_tie_swi.data_2[idx]==candidateSwOpe_2.data_4[counter])) || ((new_tie_swi.data_1[idx]==candidateSwOpe_2.data_4[counter]) && (new_tie_swi.data_2[idx]==candidateSwOpe_2.data_3[counter])))
02592 {
02593 new_tie_swi.data_1[idx] = candidateSwOpe_2.data_1[counter];
02594 new_tie_swi.data_2[idx] = candidateSwOpe_2.data_2[counter];
02595 }
02596 }
02597
02598 for (idx=0; idx<sec_swi_2.currSize; idx++)
02599 {
02600
02601 SW_to_Open_2.from_vert = sec_swi_2.data_1[idx];
02602 SW_to_Open_2.to_vert = sec_swi_2.data_2[idx];
02603
02604 SW_to_Open.from_vert = sec_swi_map.data_1[idx];
02605 SW_to_Open.to_vert = sec_swi_map.data_2[idx];
02606
02607 SW_to_Open_1.from_vert = sec_swi_map_1.data_1[idx];
02608 SW_to_Open_1.to_vert = sec_swi_map_1.data_2[idx];
02609
02610
02611
02612 feeder_overloaded = candidateSwOpe_2.data_7[counter];
02613 swiInFeederBool = isSwiInFeeder(&SW_to_Open_2,feeder_overloaded);
02614 if ((feeder_overloaded != 01) && (swiInFeederBool == false))
02615 {
02616 continue;
02617 }
02618
02619
02620 sec_swi_2entry.from_vert = sec_swi_2.data_1[idx];
02621 sec_swi_2entry.to_vert = sec_swi_2.data_2[idx];
02622 top_sim_2->findFunCutSet(&tie_swi_2,&sec_swi_2entry,&FCutSet_2_1);
02623 top_res->findFunCutSet(&new_tie_swi,&sec_swi_2entry,&FCutSet_2_2);
02624
02625 CHORDSETintersect(&FCutSet_2_1, &FCutSet_2_2, &FCutSet_2);
02626
02627 for (k=0; k<FCutSet_2.currSize; k++)
02628 {
02629
02630 FCutSet_2entry.from_vert = FCutSet_2.data_1[k];
02631 FCutSet_2entry.to_vert = FCutSet_2.data_2[k];
02632
02633 mapTieSwi(&FCutSet_2entry,&FCutSetentry,&FCutSet_1entry);
02634
02635
02636 FCutSet.data_1[k] = FCutSetentry.from_vert;
02637 FCutSet.data_2[k] = FCutSetentry.to_vert;
02638 FCutSet_1.data_1[k] = FCutSet_1entry.from_vert;
02639 FCutSet_1.data_2[k] = FCutSet_1entry.to_vert;
02640 }
02641
02642
02643
02644 tvi=candidateSwOpe_2.currSize;
02645
02646
02647 for (k=0; k<FCutSet_2.currSize; k++)
02648 {
02649
02650 if ((tvi+k) >= candidateSwOpe.maxSize)
02651 {
02652 GL_THROW("Maximum size exceeded!");
02653
02654 }
02655
02656 candidateSwOpe_2.data_1[tvi+k]=SW_to_Open_2.from_vert;
02657 candidateSwOpe_2.data_2[tvi+k]=SW_to_Open_2.to_vert;
02658 candidateSwOpe_2.data_3[tvi+k]=FCutSet_2.data_1[k];
02659 candidateSwOpe_2.data_4[tvi+k]=FCutSet_2.data_2[k];
02660 candidateSwOpe_2.data_5[tvi+k]=counter;
02661 candidateSwOpe_2.data_6[tvi+k]=0.0;
02662 candidateSwOpe_2.data_7[tvi+k]=0;
02663
02664 candidateSwOpe_1.data_1[tvi+k]=SW_to_Open_1.from_vert;
02665 candidateSwOpe_1.data_2[tvi+k]=SW_to_Open_1.to_vert;
02666 candidateSwOpe_1.data_3[tvi+k]=FCutSet_1.data_1[k];
02667 candidateSwOpe_1.data_4[tvi+k]=FCutSet_1.data_2[k];
02668 candidateSwOpe_1.data_5[tvi+k]=counter;
02669 candidateSwOpe_1.data_6[tvi+k]=0.0;
02670 candidateSwOpe_1.data_7[tvi+k]=0;
02671
02672 candidateSwOpe.data_1[tvi+k]=SW_to_Open.from_vert;
02673 candidateSwOpe.data_2[tvi+k]=SW_to_Open.to_vert;
02674 candidateSwOpe.data_3[tvi+k]=FCutSet.data_1[k];
02675 candidateSwOpe.data_4[tvi+k]=FCutSet.data_2[k];
02676 candidateSwOpe.data_5[tvi+k]=counter;
02677 candidateSwOpe.data_6[tvi+k]=0.0;
02678 candidateSwOpe.data_7[tvi+k]=0;
02679 }
02680
02681
02682 tvi += FCutSet_2.currSize;
02683 candidateSwOpe_2.currSize = tvi;
02684 candidateSwOpe_1.currSize = tvi;
02685 candidateSwOpe.currSize = tvi;
02686 }
02687 }
02688 else
02689 {
02690
02691
02692
02693 modifyModel(counter);
02694
02695
02696 powerflow_result = runPowerFlow();
02697
02698
02699 if (powerflow_result == -1)
02700 {
02701 return -2;
02702
02703 }
02704 else if (powerflow_result == 0)
02705 {
02706
02707 modifyModel(counter);
02708
02709
02710 feasible=false;
02711
02712
02713 PowerflowRestore();
02714 }
02715 else
02716 {
02717
02718 checkPF2(&feasible, &overLoad, &feederID);
02719
02720
02721 if (feasible==false)
02722 {
02723 modifyModel(counter);
02724
02725
02726 PowerflowRestore();
02727 }
02728 }
02729
02730
02731 if (feasible == true)
02732 {
02733
02734 if (stop_and_generate == true)
02735 {
02736
02737 modifyModel(counter);
02738
02739
02740 PowerflowRestore();
02741 }
02742
02743
02744
02745
02746 CHORDSETfree(&FCutSet);
02747 CHORDSETfree(&FCutSet_1);
02748 CHORDSETfree(&FCutSet_2);
02749 CHORDSETfree(&FCutSet_2_1);
02750 CHORDSETfree(&FCutSet_2_2);
02751
02752 return counter;
02753 }
02754
02755
02756 candidateSwOpe_2.data_6[counter] = overLoad;
02757 candidateSwOpe_1.data_6[counter] = overLoad;
02758 candidateSwOpe.data_6[counter] = overLoad;
02759
02760 candidateSwOpe_2.data_7[counter] = feederID;
02761 candidateSwOpe_1.data_7[counter] = feederID;
02762 candidateSwOpe.data_7[counter] = feederID;
02763
02764
02765
02766
02767
02768 if (counter >= (allocsize-1))
02769 {
02770
02771
02772
02773
02774
02775
02776 CHORDSETfree(&FCutSet);
02777 CHORDSETfree(&FCutSet_1);
02778 CHORDSETfree(&FCutSet_2);
02779 CHORDSETfree(&FCutSet_2_1);
02780 CHORDSETfree(&FCutSet_2_2);
02781
02782
02783 return -1;
02784 }
02785
02786
02787
02788
02789
02790 if (feederID == -1)
02791 {
02792 counter++;
02793 continue;
02794 }
02795
02796
02797 top_res->copy(top_sim_2);
02798 top_res->deleteEdge(candidateSwOpe_2.data_1[counter],candidateSwOpe_2.data_2[counter]);
02799 top_res->addEdge(candidateSwOpe_2.data_3[counter],candidateSwOpe_2.data_4[counter]);
02800
02801 preCounter = candidateSwOpe_2.data_5[counter];
02802 while (preCounter != 0)
02803 {
02804 top_res->deleteEdge(candidateSwOpe_2.data_1[preCounter],candidateSwOpe_2.data_2[preCounter]);
02805 top_res->addEdge(candidateSwOpe_2.data_3[preCounter],candidateSwOpe_2.data_4[preCounter]);
02806 preCounter=candidateSwOpe_2.data_5[preCounter];
02807 }
02808 top_res->BFS(s_ver_2);
02809
02810
02811
02812 CHORDSETalloc(&new_tie_swi,tie_swi_2.currSize);
02813
02814
02815 memcpy(new_tie_swi.data_1,tie_swi_2.data_1,tie_swi_2.currSize*sizeof(int));
02816 memcpy(new_tie_swi.data_2,tie_swi_2.data_2,tie_swi_2.currSize*sizeof(int));
02817 new_tie_swi.currSize = tie_swi_2.currSize;
02818
02819 for (idx=0; idx<new_tie_swi.currSize; idx++)
02820 {
02821 if (((new_tie_swi.data_1[idx]==candidateSwOpe_2.data_3[counter]) && (new_tie_swi.data_2[idx]==candidateSwOpe_2.data_4[counter])) || ((new_tie_swi.data_1[idx]==candidateSwOpe_2.data_4[counter]) && (new_tie_swi.data_2[idx]==candidateSwOpe_2.data_3[counter])))
02822 {
02823 new_tie_swi.data_1[idx] = candidateSwOpe_2.data_1[counter];
02824 new_tie_swi.data_2[idx] = candidateSwOpe_2.data_2[counter];
02825 }
02826 }
02827
02828 preCounter = candidateSwOpe_2.data_5[counter];
02829 while (preCounter != 0)
02830 {
02831 for (idx=0; idx<new_tie_swi.currSize; idx++)
02832 {
02833 if (((new_tie_swi.data_1[idx]==candidateSwOpe_2.data_3[preCounter]) && (new_tie_swi.data_2[idx]==candidateSwOpe_2.data_4[preCounter])) || ((new_tie_swi.data_1[idx]==candidateSwOpe_2.data_4[preCounter]) && (new_tie_swi.data_2[idx]==candidateSwOpe_2.data_3[preCounter])))
02834 {
02835 new_tie_swi.data_1[idx] = candidateSwOpe_2.data_1[preCounter];
02836 new_tie_swi.data_2[idx] = candidateSwOpe_2.data_2[preCounter];
02837 }
02838 }
02839 preCounter = candidateSwOpe_2.data_5[preCounter];
02840 }
02841
02842 for (idx=0; idx<sec_swi_2.currSize; idx++)
02843 {
02844 if (((sec_swi_2.data_1[idx]==candidateSwOpe_2.data_1[counter]) && (sec_swi_2.data_2[idx]==candidateSwOpe_2.data_2[counter])) || ((sec_swi_2.data_1[idx]==candidateSwOpe_2.data_2[counter]) && (sec_swi_2.data_2[idx]==candidateSwOpe_2.data_1[counter])))
02845 {
02846 startIdx = idx + 1;
02847 break;
02848 }
02849 }
02850
02851 for (idx=startIdx; idx<sec_swi_2.currSize; idx++)
02852 {
02853
02854 SW_to_Open_2.from_vert = sec_swi_2.data_1[idx];
02855 SW_to_Open_2.to_vert = sec_swi_2.data_2[idx];
02856 SW_to_Open.from_vert = sec_swi_map.data_1[idx];
02857 SW_to_Open.to_vert = sec_swi_map.data_2[idx];
02858 SW_to_Open_1.from_vert = sec_swi_map_1.data_1[idx];
02859 SW_to_Open_1.to_vert = sec_swi_map_1.data_2[idx];
02860
02861
02862
02863 feeder_overloaded = candidateSwOpe_2.data_7[counter];
02864
02865 swiInFeederBool = isSwiInFeeder(&SW_to_Open_2,feeder_overloaded);
02866 if ((feeder_overloaded != 0) && (swiInFeederBool == false))
02867 {
02868 continue;
02869 }
02870
02871
02872 sec_swi_2entry.from_vert = sec_swi_2.data_1[idx];
02873 sec_swi_2entry.to_vert = sec_swi_2.data_2[idx];
02874 top_sim_2->findFunCutSet(&tie_swi_2,&sec_swi_2entry,&FCutSet_2_1);
02875 top_res->findFunCutSet(&new_tie_swi,&sec_swi_2entry,&FCutSet_2_2);
02876
02877 CHORDSETintersect(&FCutSet_2_1, &FCutSet_2_2, &FCutSet_2);
02878
02879 for (k=0; k<FCutSet_2.currSize; k++)
02880 {
02881
02882 FCutSet_2entry.from_vert = FCutSet_2.data_1[k];
02883 FCutSet_2entry.to_vert = FCutSet_2.data_2[k];
02884
02885 mapTieSwi(&FCutSet_2entry,&FCutSetentry,&FCutSet_1entry);
02886
02887
02888 FCutSet.data_1[k] = FCutSetentry.from_vert;
02889 FCutSet.data_2[k] = FCutSetentry.to_vert;
02890 FCutSet_1.data_1[k] = FCutSet_1entry.from_vert;
02891 FCutSet_1.data_2[k] = FCutSet_1entry.to_vert;
02892 }
02893
02894
02895
02896 tvi=candidateSwOpe_2.currSize;
02897
02898
02899 for (k=0; k<FCutSet_2.currSize; k++)
02900 {
02901
02902 if ((tvi+k) >= candidateSwOpe.maxSize)
02903 {
02904 GL_THROW("Maximum size exceeded!");
02905
02906 }
02907
02908 candidateSwOpe_2.data_1[tvi+k]=SW_to_Open_2.from_vert;
02909 candidateSwOpe_2.data_2[tvi+k]=SW_to_Open_2.to_vert;
02910 candidateSwOpe_2.data_3[tvi+k]=FCutSet_2.data_1[k];
02911 candidateSwOpe_2.data_4[tvi+k]=FCutSet_2.data_2[k];
02912 candidateSwOpe_2.data_5[tvi+k]=counter;
02913 candidateSwOpe_2.data_6[tvi+k]=0.0;
02914 candidateSwOpe_2.data_7[tvi+k]=0;
02915
02916 candidateSwOpe_1.data_1[tvi+k]=SW_to_Open_1.from_vert;
02917 candidateSwOpe_1.data_2[tvi+k]=SW_to_Open_1.to_vert;
02918 candidateSwOpe_1.data_3[tvi+k]=FCutSet_1.data_1[k];
02919 candidateSwOpe_1.data_4[tvi+k]=FCutSet_1.data_2[k];
02920 candidateSwOpe_1.data_5[tvi+k]=counter;
02921 candidateSwOpe_1.data_6[tvi+k]=0.0;
02922 candidateSwOpe_1.data_7[tvi+k]=0;
02923
02924 candidateSwOpe.data_1[tvi+k]=SW_to_Open.from_vert;
02925 candidateSwOpe.data_2[tvi+k]=SW_to_Open.to_vert;
02926 candidateSwOpe.data_3[tvi+k]=FCutSet.data_1[k];
02927 candidateSwOpe.data_4[tvi+k]=FCutSet.data_2[k];
02928 candidateSwOpe.data_5[tvi+k]=counter;
02929 candidateSwOpe.data_6[tvi+k]=0.0;
02930 candidateSwOpe.data_7[tvi+k]=0;
02931 }
02932
02933
02934 tvi += FCutSet_2.currSize;
02935 candidateSwOpe_2.currSize = tvi;
02936 candidateSwOpe_1.currSize = tvi;
02937 candidateSwOpe.currSize = tvi;
02938 }
02939 }
02940 counter = counter + 1;
02941 }
02942
02943
02944 CHORDSETfree(&FCutSet);
02945 CHORDSETfree(&FCutSet_1);
02946 CHORDSETfree(&FCutSet_2);
02947 CHORDSETfree(&FCutSet_2_1);
02948 CHORDSETfree(&FCutSet_2_2);
02949
02950 return -1;
02951 }
02952
02953
02954
02955
02956
02957 void restoration::CHORDSETintersect(CHORDSET *set_1, CHORDSET *set_2, CHORDSET *intersect)
02958 {
02959 int indexa, indexb, idx;
02960 CHORDSET *leftside, *rightside;
02961
02962
02963 for (idx=0; idx<intersect->maxSize; idx++)
02964 {
02965 intersect->data_1[idx] = -1;
02966 intersect->data_2[idx] = -1;
02967 }
02968
02969
02970 intersect->currSize = 0;
02971
02972
02973 if (set_1->currSize < set_2->currSize)
02974 {
02975
02976 leftside=set_1;
02977 rightside=set_2;
02978 }
02979 else
02980 {
02981
02982 leftside=set_2;
02983 rightside=set_1;
02984 }
02985
02986
02987 for (indexa=0; indexa<leftside->currSize; indexa++)
02988 {
02989
02990 for (indexb=0; indexb<rightside->currSize; indexb++)
02991 {
02992
02993 if ((leftside->data_1[indexa] == rightside->data_1[indexb]) && (leftside->data_2[indexa] == rightside->data_2[indexb]))
02994 {
02995
02996 intersect->data_1[intersect->currSize] = leftside->data_1[indexa];
02997 intersect->data_2[intersect->currSize] = leftside->data_2[indexa];
02998
02999
03000 intersect->currSize++;
03001
03002
03003
03004 break;
03005 }
03006
03007 }
03008 }
03009 }
03010
03011
03012
03013 void restoration::modifyModel(int counter)
03014 {
03015 CHORDSET swi_to_open, swi_to_close;
03016 int preCounter, idx, k, newsizeval, idxstart;
03017 LOCSET loc_sec, loc_tie;
03018 INTVECT locations_temp, locations;
03019 FUNCTIONADDR switching_fxn;
03020 int return_val;
03021 double return_val_double;
03022 OBJECT *thisobj = OBJECTHDR(this);
03023 OBJECT *swobj;
03024 bool switch_occurred, return_is_int_val;
03025
03026
03027 swi_to_open.data_1 = NULL;
03028 swi_to_open.data_2 = NULL;
03029 swi_to_close.data_1 = NULL;
03030 swi_to_close.data_2 = NULL;
03031 locations_temp.data = NULL;
03032 locations.data = NULL;
03033 loc_sec.data_1 = NULL;
03034 loc_sec.data_2 = NULL;
03035 loc_sec.data_3 = NULL;
03036 loc_sec.data_4 = NULL;
03037 loc_tie.data_1 = NULL;
03038 loc_tie.data_2 = NULL;
03039 loc_tie.data_3 = NULL;
03040 loc_tie.data_4 = NULL;
03041
03042
03043 CHORDSETalloc(&swi_to_open,candidateSwOpe.currSize);
03044 CHORDSETalloc(&swi_to_close,candidateSwOpe.currSize);
03045
03046
03047 swi_to_open.data_1[swi_to_open.currSize] = candidateSwOpe.data_1[counter];
03048 swi_to_open.data_2[swi_to_open.currSize] = candidateSwOpe.data_2[counter];
03049 swi_to_open.currSize++;
03050
03051 swi_to_close.data_1[swi_to_close.currSize] = candidateSwOpe.data_3[counter];
03052 swi_to_close.data_2[swi_to_close.currSize] = candidateSwOpe.data_4[counter];
03053 swi_to_close.currSize++;
03054
03055 preCounter = candidateSwOpe.data_5[counter];
03056
03057 while (preCounter != 0)
03058 {
03059 swi_to_open.data_1[swi_to_open.currSize] = candidateSwOpe.data_1[preCounter];
03060 swi_to_open.data_2[swi_to_open.currSize] = candidateSwOpe.data_2[preCounter];
03061 swi_to_open.currSize++;
03062
03063 swi_to_close.data_1[swi_to_close.currSize] = candidateSwOpe.data_3[preCounter];
03064 swi_to_close.data_2[swi_to_close.currSize] = candidateSwOpe.data_4[preCounter];
03065 swi_to_close.currSize++;
03066
03067 preCounter = candidateSwOpe.data_5[preCounter];
03068 }
03069
03070
03071 LOCSETalloc(&loc_sec,swi_to_open.currSize);
03072
03073 for (idx=0; idx<swi_to_open.currSize; idx++)
03074 {
03075 for (k=0; k<sec_swi.currSize; k++)
03076 {
03077 if (((swi_to_open.data_1[idx]==sec_swi.data_1[k]) && (swi_to_open.data_2[idx]==sec_swi.data_2[k])) || ((swi_to_open.data_1[idx]==sec_swi.data_2[k]) && (swi_to_open.data_2[idx]==sec_swi.data_1[k])))
03078 {
03079 loc_sec.data_1[idx] = sec_swi_loc.data_1[k];
03080 loc_sec.data_2[idx] = sec_swi_loc.data_2[k];
03081 loc_sec.data_3[idx] = sec_swi_loc.data_3[k];
03082 loc_sec.data_4[idx] = sec_swi_loc.data_4[k];
03083 }
03084 }
03085 }
03086
03087
03088 loc_sec.currSize = swi_to_open.currSize;
03089
03090
03091 LOCSETalloc(&loc_tie,swi_to_close.currSize);
03092
03093 for (idx=0; idx<swi_to_close.currSize; idx++)
03094 {
03095 for (k=0; k<tie_swi.currSize; k++)
03096 {
03097 if (((swi_to_close.data_1[idx]==tie_swi.data_1[k]) && (swi_to_close.data_2[idx]==tie_swi.data_2[k])) || ((swi_to_close.data_1[idx]==tie_swi.data_2[k]) && (swi_to_close.data_2[idx]==tie_swi.data_1[k])))
03098 {
03099 loc_tie.data_1[idx] = tie_swi_loc.data_1[k];
03100 loc_tie.data_2[idx] = tie_swi_loc.data_2[k];
03101 loc_tie.data_3[idx] = tie_swi_loc.data_3[k];
03102 loc_tie.data_4[idx] = tie_swi_loc.data_4[k];
03103 }
03104 }
03105 }
03106
03107
03108 loc_tie.currSize = swi_to_close.currSize;
03109
03110
03111
03112 newsizeval = (loc_sec.currSize + loc_tie.currSize);
03113 INTVECTalloc(&locations_temp,newsizeval);
03114
03115
03116 INTVECTalloc(&locations,newsizeval);
03117
03118
03119 memcpy(locations_temp.data,loc_sec.data_1,loc_sec.currSize*sizeof(int));
03120 memcpy(&locations_temp.data[loc_sec.currSize],loc_tie.data_1,loc_tie.currSize*sizeof(int));
03121
03122
03123 locations_temp.currSize = locations_temp.maxSize;
03124
03125
03126 unique_int(&locations_temp,&locations);
03127
03128
03129 INTVECTfree(&locations_temp);
03130
03131 if (locations.data[0] == -1)
03132 {
03133 idxstart = 1;
03134 }
03135 else
03136 {
03137 idxstart = 0;
03138 }
03139
03140
03141 switch_occurred = false;
03142
03143
03144 for (idx=idxstart; idx<locations.currSize; idx++)
03145 {
03146
03147 switching_fxn = NULL;
03148
03149
03150 swobj = NR_branchdata[locations.data[idx]].obj;
03151
03152 if (NR_branchdata[locations.data[idx]].lnk_type == 2)
03153 {
03154
03155 switching_fxn = (FUNCTIONADDR)(gl_get_function(swobj,"change_switch_state"));
03156
03157
03158 return_is_int_val = true;
03159 }
03160 else if (NR_branchdata[locations.data[idx]].lnk_type == 6)
03161 {
03162
03163 switching_fxn = (FUNCTIONADDR)(gl_get_function(swobj,"change_recloser_state"));
03164
03165
03166 return_is_int_val = false;
03167 }
03168 else if (NR_branchdata[locations.data[idx]].lnk_type == 5)
03169 {
03170
03171 switching_fxn = (FUNCTIONADDR)(gl_get_function(swobj,"change_sectionalizer_state"));
03172
03173
03174 return_is_int_val = false;
03175 }
03176 else
03177 {
03178 GL_THROW("Restoration: switch actions were attempted on a non-switch device!");
03179
03180
03181
03182
03183
03184 }
03185
03186
03187 if (switching_fxn == NULL)
03188 {
03189 GL_THROW("Restoration: Unable to map switch change function");
03190
03191
03192
03193
03194 }
03195
03196 if (return_is_int_val == true)
03197 {
03198
03199 if (*NR_branchdata[locations.data[idx]].status == LS_OPEN)
03200 {
03201 return_val = ((int (*)(OBJECT *,unsigned char,bool))(*switching_fxn))(swobj,0x07,true);
03202 }
03203 else
03204 {
03205 return_val = ((int (*)(OBJECT *,unsigned char,bool))(*switching_fxn))(swobj,0x07,false);
03206 }
03207 }
03208 else
03209 {
03210
03211 if (*NR_branchdata[locations.data[idx]].status == LS_OPEN)
03212 {
03213 return_val_double = ((double (*)(OBJECT *,unsigned char,bool))(*switching_fxn))(swobj,0x07,true);
03214 }
03215 else
03216 {
03217 return_val_double = ((double (*)(OBJECT *,unsigned char,bool))(*switching_fxn))(swobj,0x07,false);
03218 }
03219
03220
03221 if (return_val_double != 0.0)
03222 {
03223 return_val = 1;
03224 }
03225 else
03226 {
03227 return_val = 0;
03228 }
03229 }
03230
03231
03232 if (return_val != 1)
03233 {
03234 GL_THROW("Restoration: Unable to perform switching action on %s!",swobj->name?swobj->name:"unnamed");
03235
03236
03237
03238
03239 }
03240 else
03241 {
03242 switch_occurred = true;
03243 }
03244 }
03245
03246
03247 if (switch_occurred == true)
03248 {
03249
03250 return_val = ((int (*)(OBJECT *, int, bool))(*fault_check_fxn))(fault_check_object,-99,true);
03251
03252
03253 if (return_val != 1)
03254 {
03255 GL_THROW("Restoration: problem occurred altering topology");
03256
03257
03258
03259
03260
03261 }
03262 }
03263
03264
03265 INTVECTfree(&locations);
03266 LOCSETfree(&loc_sec);
03267 LOCSETfree(&loc_tie);
03268 }
03269
03270
03271
03272
03273
03274
03275
03276
03277 int restoration::runPowerFlow(void)
03278 {
03279 int64 PFresult;
03280 int overallresult;
03281 bool bad_computation;
03282 NRSOLVERMODE powerflow_type;
03283
03284
03285 bad_computation = false;
03286
03287
03288 if (enable_subsecond_models)
03289 {
03290 powerflow_type = PF_DYNCALC;
03291 }
03292 else
03293 {
03294 powerflow_type = PF_NORMAL;
03295 }
03296
03297
03298 try {
03299
03300
03301
03302 PFresult = solver_nr(NR_bus_count, NR_busdata, NR_branch_count, NR_branchdata, &NR_powerflow, powerflow_type, NULL, &bad_computation);
03303
03304
03305 NR_admit_change = false;
03306
03307 if (bad_computation==true)
03308 {
03309 overallresult = 0;
03310 }
03311 else if (PFresult<0)
03312 {
03313 overallresult = 0;
03314 }
03315 else
03316 {
03317 overallresult = 1;
03318 }
03319 }
03320 catch (...)
03321 {
03322 overallresult = -1;
03323 }
03324
03325
03326 return overallresult;
03327 }
03328
03329
03330 void restoration::checkPF2(bool *flag, double *overLoad, int *feederID)
03331 {
03332 bool vFlag, fFlag, mFlag, lFlag;
03333 double overLoad1, overLoad2, overLoad3;
03334 int oFeederID, microgridID, lineID;
03335
03336 vFlag = checkVoltage();
03337 checkFeederPower(&fFlag, &overLoad1, &oFeederID);
03338 checkMG(&mFlag, &overLoad2, µgridID);
03339 checkLinePower(&lFlag,&overLoad3,&lineID);
03340
03341 if ((vFlag==true) && (fFlag==true) && (mFlag==true) && (lFlag==true))
03342 {
03343 *flag = true;
03344 }
03345 else
03346 {
03347 *flag = false;
03348 }
03349
03350 if (vFlag == false)
03351 {
03352 *overLoad = INFINITY;
03353 }
03354 else
03355 {
03356 *overLoad = overLoad1 + overLoad2 + overLoad3;
03357 }
03358
03359 if (((oFeederID != 0) && (microgridID != 0)) || (oFeederID == -1) || (microgridID == -1))
03360 {
03361 *feederID = -1;
03362 }
03363 else if (microgridID != 0)
03364 {
03365 *feederID = microgridID + 100;
03366 }
03367 else
03368 {
03369 *feederID = oFeederID;
03370 }
03371 }
03372
03373
03374 bool restoration::checkVoltage(void)
03375 {
03376 bool flag;
03377 unsigned int index;
03378 double perunitvalue;
03379
03380
03381 flag = true;
03382
03383
03384 for (index=0; index<NR_bus_count; index++)
03385 {
03386
03387 if ((NR_busdata[index].phases & 0x80) == 0x80)
03388 {
03389
03390 perunitvalue = (NR_busdata[index].V[0].Mag())/NR_busdata[index].volt_base;
03391
03392
03393 if ((perunitvalue < voltage_limit[0]) || (perunitvalue > voltage_limit[1]))
03394 {
03395
03396 flag = false;
03397 break;
03398 }
03399
03400 perunitvalue = (NR_busdata[index].V[1].Mag())/NR_busdata[index].volt_base;
03401
03402
03403 if ((perunitvalue < voltage_limit[0]) || (perunitvalue > voltage_limit[1]))
03404 {
03405
03406 flag = false;
03407 break;
03408 }
03409 }
03410 else
03411 {
03412
03413 if ((NR_busdata[index].phases & 0x04) == 0x04)
03414 {
03415
03416 perunitvalue = (NR_busdata[index].V[0].Mag())/NR_busdata[index].volt_base;
03417
03418
03419 if ((perunitvalue < voltage_limit[0]) || (perunitvalue > voltage_limit[1]))
03420 {
03421
03422 flag = false;
03423 break;
03424 }
03425 }
03426
03427
03428 if ((NR_busdata[index].phases & 0x02) == 0x02)
03429 {
03430
03431 perunitvalue = (NR_busdata[index].V[1].Mag())/NR_busdata[index].volt_base;
03432
03433
03434 if ((perunitvalue < voltage_limit[0]) || (perunitvalue > voltage_limit[1]))
03435 {
03436
03437 flag = false;
03438 break;
03439 }
03440 }
03441
03442
03443 if ((NR_busdata[index].phases & 0x01) == 0x01)
03444 {
03445
03446 perunitvalue = (NR_busdata[index].V[2].Mag())/NR_busdata[index].volt_base;
03447
03448
03449 if ((perunitvalue < voltage_limit[0]) || (perunitvalue > voltage_limit[1]))
03450 {
03451
03452 flag = false;
03453 break;
03454 }
03455 }
03456
03457 }
03458 }
03459
03460
03461 return flag;
03462 }
03463
03464
03465 void restoration::checkFeederPower(bool *fFlag, double *overLoad, int *feederID)
03466 {
03467 int indexval, ret_value;
03468 double feeder_power_Mag;
03469
03470
03471 *fFlag = true;
03472
03473
03474 *overLoad = 0.0;
03475 *feederID = 0;
03476
03477
03478 for (indexval=0; indexval<numfVer; indexval++)
03479 {
03480
03481 ret_value = ((int (*)(OBJECT *))(*fLinkPowerFunc[indexval]))(fLinkObjList[indexval]);
03482
03483
03484 if (ret_value != 1)
03485 {
03486 GL_THROW("Restoration: failure to calculate power from link:%s", fLinkObjList[indexval]->name ? fLinkObjList[indexval]->name : "Unnamed");
03487
03488
03489
03490
03491 }
03492
03493
03494 feeder_power_Mag = feeder_power_link_value[indexval]->Mag();
03495
03496
03497 if (feeder_power_Mag > feeder_power_limit[indexval])
03498 {
03499 if (*feederID == 0)
03500 {
03501 *feederID = indexval + 1;
03502 *overLoad = feeder_power_Mag - feeder_power_limit[indexval];
03503 }
03504 else
03505 {
03506 *feederID = -1;
03507 *overLoad += (feeder_power_Mag - feeder_power_limit[indexval]);
03508 }
03509
03510
03511 *fFlag = false;
03512 }
03513 }
03514 }
03515
03516
03517 void restoration::checkMG(bool *mFlag, double *overLoad, int *microgridID)
03518 {
03519 int indexval, ret_value;
03520 complex microgrid_power_over;
03521
03522
03523 *mFlag = true;
03524
03525
03526 *overLoad = 0.0;
03527 *microgridID = 0;
03528
03529
03530 for (indexval=0; indexval<numMG; indexval++)
03531 {
03532
03533 ret_value = ((int (*)(OBJECT *))(*mLinkPowerFunc[indexval]))(mLinkObjList[indexval]);
03534
03535
03536 if (ret_value != 1)
03537 {
03538 GL_THROW("Restoration: failure to calculate power from link:%s", mLinkObjList[indexval]->name ? mLinkObjList[indexval]->name : "Unnamed");
03539
03540 }
03541
03542
03543 if ((microgrid_power_link_value[indexval]->Re() > microgrid_limit[indexval].Re()) || (microgrid_power_link_value[indexval]->Im() > microgrid_limit[indexval].Im()))
03544 {
03545 *mFlag = false;
03546
03547 if (*microgridID == 0)
03548 {
03549 *microgridID = indexval + 1;
03550 }
03551 else
03552 {
03553 *microgridID = -1;
03554 }
03555
03556
03557 microgrid_power_over = *microgrid_power_link_value[indexval] - microgrid_limit[indexval];
03558
03559
03560 *overLoad += microgrid_power_over.Mag();
03561 }
03562 }
03563 }
03564
03565
03566 void restoration::checkLinePower(bool *lFlag, double *overLoad, int *lineID)
03567 {
03568 int ret_value;
03569 unsigned int indexval;
03570 bool lineFlag;
03571 double lineOverload;
03572
03573
03574 *lFlag = true;
03575 *lineID = 0;
03576 *overLoad = 0.0;
03577
03578
03579 if (use_link_limits == true)
03580 {
03581
03582 for (indexval=0; indexval<NR_branch_count; indexval++)
03583 {
03584
03585 ret_value = ((int (*)(OBJECT *, double *, bool *))(*NR_branchdata[indexval].limit_check))(NR_branchdata[indexval].obj,&lineOverload,&lineFlag);
03586
03587
03588 if (ret_value != 1)
03589 {
03590 GL_THROW("Restoration: failure to calculate limits from link:%s", NR_branchdata[indexval].name ? NR_branchdata[indexval].name : "Unnamed");
03591
03592
03593
03594
03595 }
03596
03597
03598 if (lineFlag == true)
03599 {
03600
03601 *lFlag = false;
03602
03603 if (*lineID == 0)
03604 {
03605 *lineID = indexval + 1;
03606 *overLoad = lineOverload;
03607 }
03608 else
03609 {
03610 *lineID = -1;
03611 *overLoad += lineOverload;
03612 }
03613 }
03614
03615 }
03616 }
03617
03618 }
03619
03620
03621 void restoration::printResult(int IdxSW)
03622 {
03623 FILE *FPOutput;
03624 TIMESTAMP tval;
03625 int delta_microseconds_value;
03626 double delta_tval, loadShedding, seconds_dbl_value;
03627 DATETIME res_event_time;
03628 int retvalue, indexvalue;
03629
03630
03631 tval = gl_globalclock;
03632 delta_tval = gl_globaldeltaclock;
03633
03634
03635 delta_microseconds_value = (int)((delta_tval - (int)(delta_tval))*1000000+0.5);
03636 retvalue = gl_localtime(tval,&res_event_time);
03637
03638
03639 seconds_dbl_value = (double)(res_event_time.second) + (double)(delta_microseconds_value)/1000000.0;
03640
03641
03642 FPOutput = fopen(logfile_name,"at");
03643
03644
03645
03646 if (res_event_time.second < 10)
03647 {
03648 fprintf(FPOutput,"-- Restoration session of %4d-%02d-%02d %02d:%02d:0%2.6f --\n\n",res_event_time.year,res_event_time.month,res_event_time.day,res_event_time.hour,res_event_time.minute,seconds_dbl_value);
03649 }
03650 else
03651 {
03652 fprintf(FPOutput,"-- Restoration session of %4d-%02d-%02d %02d:%02d:%2.6f --\n\n",res_event_time.year,res_event_time.month,res_event_time.day,res_event_time.hour,res_event_time.minute,seconds_dbl_value);
03653 }
03654 fprintf(FPOutput, "Fault section: %d - %d (in original topology), %d - %d (in simplified topology)\n", f_sec.from_vert, f_sec.to_vert, f_sec_1.from_vert, f_sec_1.to_vert);
03655 fprintf(FPOutput, "Fault section: %s - %s (in original topology)\n", NR_busdata[f_sec.from_vert].name, NR_busdata[f_sec.to_vert].name);
03656 if (faultSecObj != NULL)
03657 {
03658 fprintf(FPOutput, "Fault section: %s\n",faultSecObj->name ? faultSecObj->name : "Unnamed");
03659 }
03660 else
03661 {
03662 fprintf(FPOutput, "Fault section: Not set, assumed SWING -- %s\n",NR_busdata[0].name ? NR_busdata[0].name : "Unnamed");
03663 }
03664
03665
03666 if (IdxSW >= 0)
03667 {
03668 fprintf(FPOutput, "Full restoration is successful.\n");
03669 fprintf(FPOutput, "The optimal switching sequence is as follows \n");
03670 printSOs(FPOutput,IdxSW);
03671 }
03672 else if (candidateSwOpe.data_6 != NULL)
03673 {
03674
03675 IdxSW = 0;
03676 loadShedding = candidateSwOpe.data_6[0];
03677
03678
03679 for (indexvalue=1; indexvalue<candidateSwOpe.currSize; indexvalue++)
03680 {
03681 if (candidateSwOpe.data_6[indexvalue] < loadShedding)
03682 {
03683 loadShedding = candidateSwOpe.data_6[indexvalue];
03684 IdxSW = indexvalue;
03685 }
03686 }
03687
03688 fprintf(FPOutput, "Full restoration failed. Partial restoration performed.\n");
03689 fprintf(FPOutput, "%f kVA load should be shed.\n", (loadShedding/1000.0));
03690 fprintf(FPOutput, "The optimal switching sequence is as follows. \n");
03691 printSOs(FPOutput,IdxSW);
03692 }
03693 else
03694 {
03695
03696 fprintf(FPOutput, "Outage load cannot be restored!!!\n");
03697 }
03698
03699
03700 fprintf(FPOutput,"\n\n");
03701
03702
03703 fclose(FPOutput);
03704 }
03705
03706
03707 void restoration::printSOs(FILE *FPHandle, int IdxSW)
03708 {
03709
03710 if (IdxSW<candidateSwOpe.currSize)
03711 {
03712 if (candidateSwOpe.data_5[IdxSW] != 0)
03713 {
03714
03715 printSOs(FPHandle,candidateSwOpe.data_5[IdxSW]);
03716 }
03717 printCIO(FPHandle,IdxSW);
03718 }
03719 }
03720
03721
03722 void restoration::printCIO(FILE *FPHandle, int IdxSW)
03723 {
03724 int indexval, idx_microgrid;
03725
03726 fprintf(FPHandle, "Open: %d - %d (in original topology), %d - %d (in simplified topology)\n",candidateSwOpe.data_1[IdxSW],candidateSwOpe.data_2[IdxSW],candidateSwOpe_1.data_1[IdxSW],candidateSwOpe_1.data_2[IdxSW]);
03727 fprintf(FPHandle, "Open: %s - %s (in original topology)\n",NR_busdata[candidateSwOpe.data_1[IdxSW]].name,NR_busdata[candidateSwOpe.data_2[IdxSW]].name);
03728
03729 if ((candidateSwOpe.data_3[IdxSW] != s_ver) && (candidateSwOpe.data_4[IdxSW] != s_ver))
03730 {
03731 fprintf(FPHandle, "Close: %d - %d (in original topology), %d - %d (in simplified topology)\n",candidateSwOpe.data_3[IdxSW],candidateSwOpe.data_4[IdxSW],candidateSwOpe_1.data_3[IdxSW],candidateSwOpe_1.data_4[IdxSW]);
03732 fprintf(FPHandle, "Close: %s - %s (in original topology)\n",NR_busdata[candidateSwOpe.data_3[IdxSW]].name,NR_busdata[candidateSwOpe.data_4[IdxSW]].name);
03733 }
03734 else
03735 {
03736 if (candidateSwOpe.data_3[IdxSW] == s_ver)
03737 {
03738 idx_microgrid = -1;
03739
03740
03741 for (indexval=0; indexval<MGIdx.currSize; indexval++)
03742 {
03743 if (MGIdx.data[indexval] == candidateSwOpe.data_4[IdxSW])
03744 {
03745 idx_microgrid = indexval;
03746
03747
03748 break;
03749 }
03750 }
03751
03752
03753 if (idx_microgrid != -1)
03754 {
03755 fprintf(FPHandle, "Close: %d - Microgrid%d (in original topology), %d - Microgrid%d (in simplified topology)\n",candidateSwOpe.data_4[IdxSW],idx_microgrid, candidateSwOpe_1.data_4[IdxSW], idx_microgrid);
03756 fprintf(FPHandle, "Close: %s - Microgrid%d (in original topology)\n",NR_busdata[candidateSwOpe.data_4[IdxSW]].name,idx_microgrid);
03757 }
03758
03759 }
03760 }
03761 }
03762
03763
03764
03765 bool restoration::isSwitch(int iIndex, int jIndex)
03766 {
03767 bool flag;
03768 int idx;
03769
03770 flag = false;
03771
03772 for (idx=0; idx<sec_swi.currSize; idx++)
03773 {
03774 if (((iIndex==sec_swi.data_1[idx]) && (jIndex==sec_swi.data_2[idx])) || ((jIndex==sec_swi.data_1[idx]) && (iIndex==sec_swi.data_2[idx])))
03775 {
03776 flag = true;
03777 break;
03778 }
03779 }
03780
03781 return flag;
03782 }
03783
03784
03785
03786 bool restoration::isSwiInFeeder(BRANCHVERTICES *swi_2, int feederID_overload)
03787 {
03788 bool flag;
03789 int curNode, feederID_current, microgridID_current;
03790 int idxval, tempval, count_check;
03791
03792 curNode = swi_2->from_vert;
03793 if (feederID_overload < 100)
03794 {
03795 feederID_current = -1;
03796
03797
03798 for (idxval=0; idxval<feederVertices_2.currSize; idxval++)
03799 {
03800 if (feederVertices_2.data[idxval] == curNode)
03801 {
03802 feederID_current = idxval;
03803 break;
03804 }
03805 }
03806
03807
03808 count_check = NR_bus_count;
03809
03810 while ((feederID_current != -1) && (count_check > 0))
03811 {
03812 tempval = -1;
03813 for (idxval=0;idxval<MGIdx_2.currSize; idxval++)
03814 {
03815 if (MGIdx_2.data[idxval]==curNode)
03816 {
03817 tempval = idxval;
03818 }
03819 }
03820
03821 if ((tempval != -1) && (top_res->parent_value[curNode] == s_ver_2))
03822 {
03823 flag = false;
03824 return flag;
03825 }
03826
03827 curNode = top_res->parent_value[curNode];
03828 feederID_current = -1;
03829
03830
03831 for (idxval=0; idxval<feederVertices_2.currSize; idxval++)
03832 {
03833 if (feederVertices_2.data[idxval] == curNode)
03834 {
03835 feederID_current = idxval;
03836 break;
03837 }
03838 }
03839
03840
03841 count_check--;
03842 }
03843 if ((feederID_current+1) == feederID_overload)
03844 {
03845 flag = true;
03846 }
03847 else
03848 {
03849 flag = false;
03850 }
03851 }
03852 else
03853 {
03854 microgridID_current = -1;
03855
03856
03857 for (idxval=0; idxval<MGIdx_2.currSize; idxval++)
03858 {
03859 if (MGIdx_2.data[idxval] == curNode)
03860 {
03861 microgridID_current = idxval;
03862 break;
03863 }
03864 }
03865
03866
03867 count_check = NR_bus_count;
03868
03869 while ((microgridID_current == -1) && (count_check > 0))
03870 {
03871 curNode = top_res->parent_value[curNode];
03872
03873 if (curNode == -1)
03874 {
03875 flag = false;
03876 return flag;
03877 }
03878
03879
03880 microgridID_current = -1;
03881
03882
03883 for (idxval=0; idxval<MGIdx_2.currSize; idxval++)
03884 {
03885 if (MGIdx_2.data[idxval] == curNode)
03886 {
03887 microgridID_current = idxval;
03888 break;
03889 }
03890 }
03891
03892
03893 count_check--;
03894 }
03895 if ((microgridID_current+1) == (feederID_overload - 100))
03896 {
03897 flag = true;
03898 }
03899 else
03900 {
03901 flag = false;
03902 }
03903 }
03904
03905 return flag;
03906 }
03907
03908
03909
03910
03911
03912
03913 void restoration::PowerflowSave(void)
03914 {
03915 unsigned int indexval;
03916
03917
03918 if (voltage_storage != NULL)
03919 {
03920
03921 for (indexval=0; indexval<NR_bus_count; indexval++)
03922 {
03923 gl_free(voltage_storage[indexval]);
03924 }
03925
03926
03927 gl_free(voltage_storage);
03928 }
03929
03930
03931 voltage_storage = (complex **)gl_malloc(NR_bus_count*sizeof(complex *));
03932
03933
03934 if (voltage_storage == NULL)
03935 {
03936 GL_THROW("Restoration: failed to allocate memory for base voltage values!");
03937
03938
03939
03940
03941
03942 }
03943
03944
03945 for (indexval=0; indexval<NR_bus_count; indexval++)
03946 {
03947
03948 voltage_storage[indexval] = (complex *)gl_malloc(3*sizeof(complex));
03949
03950
03951 if (voltage_storage[indexval] == NULL)
03952 {
03953 GL_THROW("Restoration: failed to allocate memory for base voltage values!");
03954
03955 }
03956
03957
03958 voltage_storage[indexval][0] = NR_busdata[indexval].V[0];
03959 voltage_storage[indexval][1] = NR_busdata[indexval].V[1];
03960 voltage_storage[indexval][2] = NR_busdata[indexval].V[2];
03961 }
03962 }
03963
03964
03965 void restoration::PowerflowRestore(void)
03966 {
03967 unsigned int indexval;
03968
03969
03970 for (indexval=0; indexval<NR_bus_count; indexval++)
03971 {
03972 NR_busdata[indexval].V[0] = voltage_storage[indexval][0];
03973 NR_busdata[indexval].V[1] = voltage_storage[indexval][1];
03974 NR_busdata[indexval].V[2] = voltage_storage[indexval][2];
03975 }
03976 }
03977
03978
03979
03980
03981
03982 void Chain::delAllNodes(void)
03983 {
03984 CHAINNODE *next;
03985
03986 while (first != NULL)
03987 {
03988 next = first->link;
03989
03990
03991 gl_free(first);
03992
03993 first = next;
03994 }
03995 first = NULL;
03996 last = NULL;
03997 }
03998
03999
04000 bool Chain::isempty(void)
04001 {
04002 bool flag;
04003
04004 if (first == NULL)
04005 {
04006 flag = TRUE;
04007 }
04008 else
04009 {
04010 flag = FALSE;
04011 }
04012
04013 return flag;
04014 }
04015
04016
04017 int Chain::getLength(void)
04018 {
04019 CHAINNODE *currentNode;
04020 int length;
04021
04022 length = 0;
04023 currentNode = first;
04024
04025 while (currentNode != NULL)
04026 {
04027 length = length + 1;
04028 currentNode = currentNode->link;
04029 }
04030
04031 return length;
04032 }
04033
04034
04035 int Chain::search(int sData)
04036 {
04037 int index;
04038 CHAINNODE *currentNode;
04039
04040 index = 0;
04041 currentNode = first;
04042
04043 while (currentNode != NULL)
04044 {
04045 if (currentNode->data != sData)
04046 {
04047 currentNode = currentNode->link;
04048 index = index + 1;
04049 }
04050 else
04051 {
04052 break;
04053 }
04054 }
04055
04056 if (currentNode == NULL)
04057 {
04058 index = -1;
04059 }
04060
04061 return index;
04062 }
04063
04064
04065
04066 bool Chain::modify(int oldData, int newData)
04067 {
04068 CHAINNODE *currentNode;
04069 bool flag;
04070
04071 flag = FALSE;
04072 currentNode = first;
04073
04074 while (currentNode != NULL)
04075 {
04076 if (currentNode->data != oldData)
04077 {
04078 currentNode = currentNode->link;
04079 }
04080 else
04081 {
04082 break;
04083 }
04084 }
04085
04086
04087 if (currentNode != NULL)
04088 {
04089 if (currentNode->data == oldData)
04090 {
04091 currentNode->data = newData;
04092 flag = TRUE;
04093 }
04094
04095 }
04096
04097
04098 if (currentNode == NULL)
04099 {
04100 flag = FALSE;
04101 }
04102
04103 return flag;
04104 }
04105
04106
04107
04108 void Chain::addNode(int kIndex, int newData)
04109 {
04110 CHAINNODE *currentNode, *newNode;
04111 int currentIndex;
04112
04113
04114 if (kIndex < 0)
04115 {
04116 GL_THROW("The index is out of bounds.");
04117 }
04118
04119
04120 currentIndex = 0;
04121 currentNode = first;
04122 while ((currentIndex < kIndex) && (currentNode != NULL))
04123 {
04124 currentIndex = currentIndex + 1;
04125 currentNode = currentNode->link;
04126 }
04127
04128
04129 if ((kIndex > 0) && (currentNode==NULL))
04130 {
04131 GL_THROW("The index is out of bounds.");
04132 }
04133
04134
04135
04136 newNode = (CHAINNODE *)gl_malloc(sizeof(CHAINNODE));
04137
04138
04139 if (newNode == NULL)
04140 {
04141 GL_THROW("Restoration:Failed to allocate new node in chain");
04142
04143
04144
04145
04146
04147 }
04148
04149
04150 newNode->data = newData;
04151
04152 if (kIndex > 0)
04153 {
04154 newNode->link = currentNode->link;
04155 currentNode->link = newNode;
04156 }
04157 else
04158 {
04159 newNode->link = first;
04160 first = newNode;
04161 }
04162
04163 if (newNode->link == NULL)
04164 {
04165 last = newNode;
04166 }
04167 }
04168
04169
04170
04171 void Chain::deleteNode(int dData)
04172 {
04173 CHAINNODE *currentNode, *trail;
04174
04175 currentNode = first;
04176 trail = NULL;
04177
04178 while (currentNode != NULL)
04179 {
04180 if (currentNode->data != dData)
04181 {
04182 trail = currentNode;
04183 currentNode = currentNode->link;
04184 }
04185 else
04186 {
04187 break;
04188 }
04189 }
04190
04191 if (currentNode == NULL)
04192 {
04193 GL_THROW("The data cannot be found.");
04194 }
04195
04196
04197 if (trail != NULL)
04198 {
04199 trail->link = currentNode->link;
04200 }
04201 else
04202 {
04203 first = currentNode->link;
04204 }
04205
04206 if (currentNode->link == NULL)
04207 {
04208 last = trail;
04209 }
04210
04211
04212 gl_free(currentNode);
04213 }
04214
04215
04216 void Chain::copy(Chain *ilist)
04217 {
04218 CHAINNODE *currNode;
04219
04220
04221 if (first != NULL)
04222 {
04223 delAllNodes();
04224 }
04225
04226
04227 if (ilist != NULL)
04228 {
04229 currNode = ilist->first;
04230 while (currNode != NULL)
04231 {
04232 append(currNode->data);
04233 currNode = currNode->link;
04234 }
04235 }
04236
04237 }
04238
04239
04240 void Chain::append(int newData)
04241 {
04242 CHAINNODE *newNode;
04243
04244
04245 newNode = (CHAINNODE *)gl_malloc(sizeof(CHAINNODE));
04246
04247
04248 if (newNode == NULL)
04249 {
04250 GL_THROW("Restoration:Failed to allocate new node in chain");
04251
04252 }
04253
04254 newNode->data = newData;
04255
04256
04257 newNode->link = NULL;
04258
04259 if (first != NULL)
04260 {
04261 last->link = newNode;
04262 last = newNode;
04263 }
04264 else {
04265 first = newNode;
04266 last = newNode;
04267 }
04268 }
04269
04270
04271
04272
04273
04274 void LinkedQueue::enQueue(int newData)
04275 {
04276 CHAINNODE *newNode;
04277
04278
04279 newNode = (CHAINNODE *)gl_malloc(sizeof(CHAINNODE));
04280
04281
04282 if (newNode == NULL)
04283 {
04284 GL_THROW("Restoration:Failed to allocate new node in chain");
04285
04286 }
04287
04288 newNode->link = NULL;
04289 newNode->data = newData;
04290
04291 if (first != NULL)
04292 {
04293 last->link = newNode;
04294 last = newNode;
04295 }
04296 else
04297 {
04298 first = newNode;
04299 last = newNode;
04300 }
04301 }
04302
04303
04304 int LinkedQueue::deQueue(void)
04305 {
04306 int fData;
04307 CHAINNODE *tempNode;
04308
04309 if (isempty() == true)
04310 {
04311 GL_THROW("Restoration: The queue is empty!");
04312 }
04313
04314 fData = first->data;
04315 tempNode = first;
04316
04317 first = first->link;
04318
04319
04320 gl_free(tempNode);
04321
04322 return fData;
04323 }
04324
04325
04326
04327
04328
04329 int ChainIterator::initialize(Chain *lList)
04330 {
04331 int nData;
04332
04333 location = lList->first;
04334
04335 if (location != NULL)
04336 {
04337 nData = location->data;
04338 }
04339 else
04340 {
04341 nData = -1;
04342 }
04343
04344 return nData;
04345 }
04346
04347
04348
04349 int ChainIterator::next(void)
04350 {
04351 int nData;
04352
04353 if (location == NULL)
04354 {
04355 return -1;
04356 }
04357
04358 location = location->link;
04359
04360 if (location != NULL)
04361 {
04362 nData = location->data;
04363 }
04364 else
04365 {
04366 nData = -1;
04367 }
04368
04369 return nData;
04370 }
04371
04372
04373
04374
04375
04376 LinkedBase::LinkedBase(int nVer)
04377 {
04378 int indexvar;
04379
04380
04381 iterPos = NULL;
04382 source = 0;
04383 dfs_time = 0;
04384 numEdges = 0;
04385
04386 if (nVer == 0)
04387 {
04388 numVertices = 0;
04389 numEdges = 0;
04390 adjList = NULL;
04391 status_value = NULL;
04392 parent_value = NULL;
04393 dist = NULL;
04394 dTime = NULL;
04395 fTime = NULL;
04396 }
04397 else
04398 {
04399 numVertices = nVer;
04400
04401
04402 adjList = (Chain **)gl_malloc(numVertices*sizeof(Chain *));
04403
04404
04405 if (adjList == NULL)
04406 {
04407 GL_THROW("Restoration:Failed to allocate new chain");
04408
04409
04410
04411
04412
04413 }
04414
04415
04416 iterPos = NULL;
04417
04418
04419 status_value = (int *)gl_malloc(numVertices*sizeof(int));
04420
04421
04422 if (status_value == NULL)
04423 {
04424 GL_THROW("Restoration:Failed to allocate new chain");
04425
04426 }
04427
04428 parent_value = (int *)gl_malloc(numVertices*sizeof(int));
04429
04430 if (parent_value == NULL)
04431 {
04432 GL_THROW("Restoration:Failed to allocate new chain");
04433
04434 }
04435
04436 dist = (double *)gl_malloc(numVertices*sizeof(double));
04437
04438 if (dist == NULL)
04439 {
04440 GL_THROW("Restoration:Failed to allocate new chain");
04441
04442 }
04443
04444 dTime = (TIMESTAMP *)gl_malloc(numVertices*sizeof(TIMESTAMP));
04445
04446 if (dTime == NULL)
04447 {
04448 GL_THROW("Restoration:Failed to allocate new chain");
04449
04450 }
04451
04452 fTime = (TIMESTAMP *)gl_malloc(numVertices*sizeof(TIMESTAMP));
04453
04454 if (fTime == NULL)
04455 {
04456 GL_THROW("Restoration:Failed to allocate new chain");
04457
04458 }
04459
04460
04461 for (indexvar=0; indexvar<numVertices; indexvar++)
04462 {
04463
04464
04465
04466 adjList[indexvar] = (Chain *)gl_malloc(sizeof(Chain));
04467
04468
04469 if (adjList[indexvar] == NULL)
04470 {
04471 GL_THROW("Restoration:Failed to allocate new chain");
04472
04473 }
04474
04475
04476 new (adjList[indexvar]) Chain();
04477
04478
04479 status_value[indexvar] = 0;
04480 parent_value[indexvar] = -1;
04481 dist[indexvar] = INFINITY;
04482 dTime[indexvar] = 0;
04483 fTime[indexvar] = 0;
04484 }
04485 }
04486 }
04487
04488
04489 void LinkedBase::delAllVer(void)
04490 {
04491 int indexvar;
04492
04493 if (numVertices != 0)
04494 {
04495
04496 for (indexvar = 0; indexvar < numVertices; indexvar++)
04497 {
04498 gl_free(adjList[indexvar]);
04499
04500
04501 adjList[indexvar] = NULL;
04502 }
04503
04504
04505 gl_free(adjList);
04506
04507 adjList = NULL;
04508
04509 numVertices = 0;
04510 numEdges = 0;
04511 dfs_time = 0;
04512
04513
04514 deactivatePos();
04515
04516 source = 0;
04517 gl_free(status_value);
04518 gl_free(parent_value);
04519 gl_free(dist);
04520 gl_free(dTime);
04521 gl_free(fTime);
04522
04523
04524 status_value = NULL;
04525 parent_value = NULL;
04526 dist = NULL;
04527 dTime = NULL;
04528 fTime = NULL;
04529 }
04530 }
04531
04532
04533 int LinkedBase::getVerNum(void)
04534 {
04535 return numVertices;
04536 }
04537
04538
04539 int LinkedBase::getEdgNum(void)
04540 {
04541 return numEdges;
04542 }
04543
04544
04545 int LinkedBase::getOutDeg(int index)
04546 {
04547 if ((index <0) || (index >= numVertices))
04548 {
04549 GL_THROW("Restoration: The vertex number is out of bounds!");
04550 }
04551
04552 return adjList[index]->getLength();
04553 }
04554
04555
04556 void LinkedBase::initializePos(void)
04557 {
04558 int indexvar;
04559
04560
04561 iterPos = (ChainIterator **)gl_malloc(numVertices*sizeof(ChainIterator *));
04562
04563
04564 if (iterPos == NULL)
04565 {
04566 GL_THROW("Restoration:Failed to allocate new chain");
04567
04568 }
04569
04570
04571 for (indexvar=0; indexvar<numVertices; indexvar++)
04572 {
04573
04574
04575
04576 iterPos[indexvar] = (ChainIterator *)gl_malloc(sizeof(ChainIterator));
04577
04578
04579 if (iterPos[indexvar] == NULL)
04580 {
04581 GL_THROW("Restoration:Failed to allocate new chain");
04582
04583 }
04584
04585
04586 new (iterPos[indexvar]) ChainIterator();
04587
04588 }
04589 }
04590
04591
04592 void LinkedBase::deactivatePos(void)
04593 {
04594 int indexvar;
04595
04596 if (numVertices != 0)
04597 {
04598
04599 for (indexvar = 0; indexvar < numVertices; indexvar++)
04600 {
04601 gl_free(iterPos[indexvar]);
04602
04603
04604 iterPos[indexvar] = NULL;
04605 }
04606
04607
04608 gl_free(iterPos);
04609
04610
04611 iterPos = NULL;
04612 }
04613 }
04614
04615
04616 int LinkedBase::beginVertex(int index)
04617 {
04618 if ((index <0) || (index >= numVertices))
04619 {
04620 GL_THROW("Restoration: The vertex number is out of bounds!");
04621 }
04622
04623 return iterPos[index]->initialize(adjList[index]);
04624 }
04625
04626
04627 int LinkedBase::nextVertex(int index)
04628 {
04629 if ((index <0) || (index >= numVertices))
04630 {
04631 GL_THROW("Restoration: The vertex number is out of bounds!");
04632 }
04633
04634 return iterPos[index]->next();
04635 }
04636
04637
04638 void LinkedBase::BFS(int s)
04639 {
04640 int index, u, v;
04641 LinkedQueue *Q;
04642
04643
04644 for (index=0; index<numVertices; index++)
04645 {
04646 status_value[index] = 0;
04647 parent_value[index] = -1;
04648 dist[index] = INFINITY;
04649 }
04650
04651 source = s;
04652 status_value[s] = 1;
04653 dist[s] = 0.0;
04654
04655
04656
04657 Q = (LinkedQueue *)gl_malloc(sizeof(LinkedQueue));
04658
04659
04660 if (Q == NULL)
04661 {
04662 GL_THROW("Restoration:Failed to allocate new LinkedQueue");
04663 }
04664
04665
04666 new (Q) LinkedQueue();
04667
04668 Q->enQueue(s);
04669
04670
04671 initializePos();
04672
04673
04674 while (Q->isempty() != true)
04675 {
04676 u = Q->deQueue();
04677 v = beginVertex(u);
04678
04679 while (v != -1)
04680 {
04681 if (status_value[v] == 0)
04682 {
04683 status_value[v] = 1;
04684 dist[v] = dist[u] + 1.0;
04685 parent_value[v] = u;
04686 Q->enQueue(v);
04687 }
04688
04689 v = nextVertex(u);
04690 }
04691
04692 status_value[u] = 2;
04693 }
04694
04695
04696 deactivatePos();
04697 }
04698
04699
04700 void LinkedBase::DFS1(void)
04701 {
04702 int index, u;
04703
04704
04705 for (index = 0; index<numVertices; index++)
04706 {
04707 status_value[index] = 0;
04708 parent_value[index] = -1;
04709 }
04710
04711 dfs_time = 0;
04712
04713
04714 initializePos();
04715
04716
04717 for (u = 0; u < numVertices; u++)
04718 {
04719 if (status_value[u] == 0)
04720 {
04721 DFSVisit(u);
04722 }
04723 }
04724
04725 deactivatePos();
04726 }
04727
04728
04729
04730 void LinkedBase::DFS2(int s)
04731 {
04732 int index;
04733
04734
04735 for (index = 0; index<numVertices; index++)
04736 {
04737 status_value[index] = 0;
04738 parent_value[index] = -1;
04739 }
04740
04741 dfs_time = 0;
04742
04743
04744 initializePos();
04745
04746
04747 source = s;
04748 DFSVisit(s);
04749
04750
04751 deactivatePos();
04752 }
04753
04754
04755 void LinkedBase::DFSVisit(int u)
04756 {
04757 int v;
04758
04759 status_value[u] = 1;
04760
04761 dfs_time = dfs_time + 1;
04762
04763 dTime[u] = dfs_time;
04764
04765 v = beginVertex(u);
04766
04767 while (v != -1)
04768 {
04769 if (status_value[v] == 0)
04770 {
04771 parent_value[v] = u;
04772 DFSVisit(v);
04773 }
04774
04775 v = nextVertex(u);
04776 }
04777
04778 status_value[u] = 2;
04779 dfs_time = dfs_time + 1;
04780 fTime[u] = dfs_time;
04781 }
04782
04783
04784
04785
04786 void LinkedBase::copy(LinkedBase *graph1)
04787 {
04788 int idx;
04789
04790 delAllVer();
04791
04792
04793 addAIsoVer(graph1->numVertices);
04794 numEdges = graph1->numEdges;
04795
04796
04797 for (idx = 0; idx < numVertices; idx++)
04798 {
04799 adjList[idx]->copy(graph1->adjList[idx]);
04800 }
04801 }
04802
04803
04804 void LinkedBase::addAIsoVer(int n)
04805 {
04806 int indexvar, oldNumVertices;
04807 Chain **tempBase;
04808
04809
04810 oldNumVertices = numVertices;
04811
04812
04813 tempBase = adjList;
04814
04815
04816 numVertices = numVertices + n;
04817
04818
04819 adjList = (Chain **)gl_malloc(numVertices*sizeof(Chain *));
04820
04821
04822 if (adjList == NULL)
04823 {
04824 GL_THROW("Restoration:Failed to allocate new chain");
04825
04826 }
04827
04828
04829 for (indexvar=0; indexvar<oldNumVertices; indexvar++)
04830 {
04831 adjList[indexvar] = tempBase[indexvar];
04832 }
04833
04834
04835 gl_free(tempBase);
04836
04837
04838 tempBase = NULL;
04839
04840
04841
04842 if (iterPos != NULL)
04843 {
04844 deactivatePos();
04845 }
04846
04847 source = 0;
04848 dfs_time = 0;
04849
04850
04851 if (status_value != NULL)
04852 {
04853
04854 gl_free(status_value);
04855 gl_free(parent_value);
04856 gl_free(dist);
04857 gl_free(dTime);
04858 gl_free(fTime);
04859
04860
04861 status_value = NULL;
04862 parent_value = NULL;
04863 dist = NULL;
04864 dTime = NULL;
04865 fTime = NULL;
04866 }
04867
04868
04869
04870
04871 status_value = (int *)gl_malloc(numVertices*sizeof(int));
04872
04873
04874 if (status_value == NULL)
04875 {
04876 GL_THROW("Restoration:Failed to allocate new chain");
04877
04878 }
04879
04880 parent_value = (int *)gl_malloc(numVertices*sizeof(int));
04881
04882 if (parent_value == NULL)
04883 {
04884 GL_THROW("Restoration:Failed to allocate new chain");
04885
04886 }
04887
04888 dist = (double *)gl_malloc(numVertices*sizeof(double));
04889
04890 if (dist == NULL)
04891 {
04892 GL_THROW("Restoration:Failed to allocate new chain");
04893
04894 }
04895
04896 dTime = (TIMESTAMP *)gl_malloc(numVertices*sizeof(TIMESTAMP));
04897
04898 if (dTime == NULL)
04899 {
04900 GL_THROW("Restoration:Failed to allocate new chain");
04901
04902 }
04903
04904 fTime = (TIMESTAMP *)gl_malloc(numVertices*sizeof(TIMESTAMP));
04905
04906 if (fTime == NULL)
04907 {
04908 GL_THROW("Restoration:Failed to allocate new chain");
04909
04910 }
04911
04912
04913 for (indexvar=oldNumVertices; indexvar<numVertices; indexvar++)
04914 {
04915
04916
04917
04918 adjList[indexvar] = (Chain *)gl_malloc(sizeof(Chain));
04919
04920
04921 if (adjList[indexvar] == NULL)
04922 {
04923 GL_THROW("Restoration:Failed to allocate new chain");
04924
04925 }
04926
04927
04928 new (adjList[indexvar]) Chain();
04929 }
04930
04931
04932 for (indexvar=0; indexvar<numVertices; indexvar++)
04933 {
04934
04935 status_value[indexvar] = 0;
04936 parent_value[indexvar] = -1;
04937 dist[indexvar] = INFINITY;
04938 dTime[indexvar] = 0;
04939 fTime[indexvar] = 0;
04940 }
04941 }
04942
04943
04944
04945
04946
04947
04948 bool LinkedDigraph::isEdgeExisting(int iIndex, int jIndex)
04949 {
04950 bool flag;
04951
04952 flag = false;
04953
04954 if ((iIndex < 0) || (jIndex < 0) || (iIndex >= numVertices) || (jIndex >= numVertices))
04955 {
04956 GL_THROW("Restoration: The vertex Number(s) is(are) out of bounds!");
04957 }
04958 else
04959 {
04960 if (adjList[iIndex]->search(jIndex) == -1)
04961 {
04962 flag = false;
04963 }
04964 else
04965 {
04966 flag = true;
04967 }
04968 }
04969
04970 return flag;
04971 }
04972
04973
04974 void LinkedDigraph::addEdge(int iIndex, int jIndex)
04975 {
04976 if ((iIndex < 0) || (jIndex < 0) || (iIndex >= numVertices) || (jIndex >= numVertices))
04977 {
04978 GL_THROW("Restoration: The vertex Number(s) is(are) out of bounds!");
04979 }
04980 if (iIndex == jIndex)
04981 {
04982 GL_THROW("Restoration: Error: Two vertexs of an edge can not be the same!");
04983 }
04984 if (isEdgeExisting(iIndex, jIndex) == true)
04985 {
04986 GL_THROW("Restoration: Error: Can not add an edge that is already existing!");
04987 }
04988 adjList[iIndex]->addNode(0, jIndex);
04989 numEdges = numEdges + 1;
04990 }
04991
04992
04993 void LinkedDigraph::deleteEdge(int iIndex, int jIndex)
04994 {
04995 if ((iIndex < 0) || (jIndex < 0) || (iIndex >= numVertices) || (jIndex >= numVertices))
04996 {
04997 GL_THROW("Restoration: The vertex Number(s) is(are) out of bounds!");
04998 }
04999
05000 adjList[iIndex]->deleteNode(jIndex);
05001
05002 numEdges = numEdges - 1;
05003 }
05004
05005
05006 int LinkedDigraph::getInDeg(int index)
05007 {
05008 int curIndex, inDeg;
05009
05010 if ((index < 0) || (index >= numVertices))
05011 {
05012 GL_THROW("Restoration: The vertex Number is out of bounds!");
05013 }
05014
05015 inDeg = 0;
05016
05017 for (curIndex=0; curIndex<numVertices; curIndex++)
05018 {
05019 if (adjList[curIndex]->search(index) != -1)
05020 {
05021 inDeg = inDeg + 1;
05022 }
05023 }
05024
05025 return inDeg;
05026 }
05027
05028
05029 int LinkedDigraph::getOutDeg(int index)
05030 {
05031 return LinkedBase::getOutDeg(index);
05032 }
05033
05034
05035
05036
05037
05038 void LinkedUndigraph::addEdge(int iIndex, int jIndex)
05039 {
05040 if ((iIndex < 0) || (jIndex < 0) || (iIndex >= numVertices) || (jIndex >= numVertices))
05041 {
05042 GL_THROW("Restoration: The node Number(s) is(are) out of bounds!");
05043 }
05044 if (iIndex == jIndex)
05045 {
05046 GL_THROW("Restoration: Two nodes of an edge can not be the same!");
05047 }
05048 if (isEdgeExisting(iIndex,jIndex) == true)
05049 {
05050
05051 gl_warning("Restoration: (addEdge): Edge (%d,%d) is existing",iIndex,jIndex);
05052 return;
05053 }
05054 adjList[iIndex]->addNode(0, jIndex);
05055 adjList[jIndex]->addNode(0, iIndex);
05056 numEdges = numEdges + 1;
05057 }
05058
05059
05060 void LinkedUndigraph::deleteEdge(int iIndex, int jIndex)
05061 {
05062 LinkedDigraph::deleteEdge(iIndex,jIndex);
05063 numEdges = numEdges + 1;
05064 LinkedDigraph::deleteEdge(jIndex,iIndex);
05065 }
05066
05067
05068 int LinkedUndigraph::getInDeg(int index)
05069 {
05070 return LinkedDigraph::getInDeg(index);
05071 }
05072
05073
05074 int LinkedUndigraph::getOutDeg(int index)
05075 {
05076 return LinkedDigraph::getOutDeg(index);
05077 }
05078
05079
05080 int LinkedUndigraph::getDeg(int index)
05081 {
05082 return getOutDeg(index);
05083 }
05084
05085
05086 void LinkedUndigraph::findFunCutSet(CHORDSET *chordSet, BRANCHVERTICES *tBranch, CHORDSET *cutSet)
05087 {
05088 int iIndex, jIndex, idx, curIndex, child_back, parent_back, k, debug_counter;
05089 bool isCutSetEle, is_bad_loop;
05090
05091
05092
05093
05094
05095
05096
05097
05098 cutSet->currSize = 0;
05099
05100 for (idx=0; idx<cutSet->maxSize; idx++)
05101 {
05102 cutSet->data_1[idx] = -1;
05103 cutSet->data_2[idx] = -1;
05104 }
05105
05106
05107 iIndex = tBranch->from_vert;
05108 jIndex = tBranch->to_vert;
05109
05110 if (parent_value[iIndex] == jIndex)
05111 {
05112 parent_value[iIndex] = -1;
05113
05114 child_back = iIndex;
05115 parent_back = jIndex;
05116 }
05117 else
05118 {
05119 parent_value[jIndex] = -1;
05120
05121 child_back = jIndex;
05122 parent_back = iIndex;
05123 }
05124
05125
05126 for (idx=0; idx<chordSet->currSize; idx++)
05127 {
05128
05129 for (k=0; k<numVertices; k++)
05130 {
05131 status_value[k] = 0;
05132 }
05133
05134 iIndex = chordSet->data_1[idx];
05135 jIndex = chordSet->data_2[idx];
05136
05137
05138 curIndex = iIndex;
05139 debug_counter = 0;
05140 is_bad_loop = false;
05141
05142 while (curIndex != -1)
05143 {
05144 status_value[curIndex] = 1;
05145 curIndex = parent_value[curIndex];
05146
05147 debug_counter++;
05148
05149
05150 if ((debug_counter > numVertices) && (debug_counter > numEdges))
05151 {
05152 is_bad_loop = true;
05153 break;
05154 }
05155 }
05156
05157
05158 if (is_bad_loop == true)
05159 {
05160 continue;
05161 }
05162
05163
05164 debug_counter = 0;
05165
05166
05167 isCutSetEle = true;
05168 curIndex = jIndex;
05169 while (curIndex != -1)
05170 {
05171 if (status_value[curIndex] == 1)
05172 {
05173 isCutSetEle = false;
05174 break;
05175 }
05176 curIndex = parent_value[curIndex];
05177
05178 debug_counter++;
05179
05180
05181 if ((debug_counter > numVertices) && (debug_counter > numEdges))
05182 {
05183 isCutSetEle = false;
05184 break;
05185 }
05186 }
05187
05188
05189 if (isCutSetEle == true)
05190 {
05191
05192 cutSet->data_1[cutSet->currSize] = chordSet->data_1[idx];
05193 cutSet->data_2[cutSet->currSize] = chordSet->data_2[idx];
05194
05195
05196 cutSet->currSize++;
05197
05198
05199 if (cutSet->currSize >= cutSet->maxSize)
05200 {
05201 if (cutSet->currSize == cutSet->maxSize)
05202 {
05203 gl_verbose("cutSet just hit maximum length");
05204 }
05205 else
05206 {
05207 GL_THROW("restoration: allocated array size exceeded!");
05208
05209 }
05210 }
05211 }
05212 }
05213
05214
05215 parent_value[child_back] = parent_back;
05216 }
05217
05218
05219
05220
05221
05222
05223
05224
05225
05226 void LinkedUndigraph::simplify(CHORDSET *chordset, BRANCHVERTICES *fBranch, int source, INTVECT *fVer, INTVECT *vMap)
05227 {
05228 int newsize, idxval, baseidx, resultval;
05229
05230 INTVECT tempvect;
05231 INTVECT iVer;
05232
05233
05234 tempvect.data = NULL;
05235 iVer.data = NULL;
05236
05237
05238
05239
05240
05241
05242
05243
05244 newsize = chordset->currSize + chordset->currSize + 3 + fVer->currSize;
05245
05246
05247 tempvect.currSize = 0;
05248 tempvect.maxSize = newsize;
05249 tempvect.data = (int *)gl_malloc(newsize*sizeof(int));
05250
05251
05252 if (tempvect.data == NULL)
05253 {
05254 GL_THROW("Restoration:Failed to allocate new temp variable");
05255
05256 }
05257
05258
05259 for (idxval=0; idxval<chordset->currSize; idxval++)
05260 {
05261 tempvect.data[idxval] = chordset->data_1[idxval];
05262 tempvect.data[idxval+chordset->currSize] = chordset->data_2[idxval];
05263 }
05264
05265
05266 baseidx = chordset->currSize + chordset->currSize;
05267
05268
05269 tempvect.data[baseidx] = fBranch->from_vert;
05270 tempvect.data[baseidx+1] = fBranch->to_vert;
05271
05272
05273 baseidx = baseidx + 2;
05274
05275
05276 tempvect.data[baseidx] = source;
05277
05278
05279 baseidx++;
05280
05281
05282 for (idxval=0; idxval<fVer->currSize; idxval++)
05283 {
05284 tempvect.data[baseidx+idxval] = fVer->data[idxval];
05285 }
05286
05287
05288 tempvect.currSize = baseidx + fVer->currSize - 1;
05289
05290
05291 iVer.data = (int *)gl_malloc(vMap->maxSize*sizeof(int));
05292
05293
05294 if (iVer.data == NULL)
05295 {
05296 GL_THROW("Restoration:Failed to allocate new temp variable");
05297
05298 }
05299
05300
05301 iVer.currSize = 0;
05302 iVer.maxSize = vMap->maxSize;
05303
05304
05305
05306 unique_int(&tempvect,&iVer);
05307
05308
05309
05310 resultval = isolateDeg12Ver(&iVer);
05311
05312
05313 while (resultval != 0)
05314 {
05315 resultval = isolateDeg12Ver(&iVer);
05316 }
05317
05318
05319 deleteIsoVer(vMap);
05320
05321
05322 gl_free(tempvect.data);
05323 gl_free(iVer.data);
05324 }
05325
05326
05327
05328
05329
05330 void LinkedUndigraph::find_int(INTVECT *inputvect, INTVECT *foundvect, int findval, int numfind)
05331 {
05332 int indexval;
05333
05334
05335 if (numfind != -1)
05336 {
05337 for (indexval=0; indexval<numfind; indexval++)
05338 {
05339 foundvect->data[indexval] = -1;
05340 }
05341 }
05342 else
05343 {
05344 for (indexval=0; indexval<foundvect->maxSize; indexval++)
05345 {
05346 foundvect->data[indexval] = -1;
05347 }
05348 }
05349
05350
05351 foundvect->currSize = 0;
05352
05353
05354 indexval = 0;
05355
05356
05357 while (indexval < inputvect->currSize)
05358 {
05359
05360 if (inputvect->data[indexval] == findval)
05361 {
05362
05363 foundvect->data[foundvect->currSize] = indexval;
05364
05365
05366 foundvect->currSize++;
05367
05368
05369 if (numfind != -1)
05370 {
05371 if (foundvect->currSize >= numfind)
05372 {
05373 break;
05374 }
05375 }
05376
05377
05378 }
05379
05380
05381 indexval++;
05382 }
05383
05384
05385 foundvect->currSize--;
05386 }
05387
05388
05389
05390 int LinkedUndigraph::isolateDeg12Ver(INTVECT *iVer)
05391 {
05392 int iNum, idx, u, v, v1, v2;
05393 int *iMark;
05394
05395
05396
05397
05398
05399
05400
05401 iMark = (int *)gl_malloc(numVertices*sizeof(int));
05402
05403
05404 if (iMark == NULL)
05405 {
05406 GL_THROW("Restoration:Failed to allocate new temp variable");
05407
05408
05409
05410
05411 }
05412
05413
05414 for (idx=0; idx<numVertices; idx++)
05415 {
05416 iMark[idx] = 0;
05417 }
05418
05419
05420 for (idx=0; idx<iVer->currSize; idx++)
05421 {
05422 iMark[iVer->data[idx]] = 1;
05423 }
05424
05425
05426 iNum = 0;
05427 for (u=0; u<numVertices; u++)
05428 {
05429 if (iMark[u] == 0)
05430 {
05431 if (getDeg(u) == 1)
05432 {
05433
05434 v = adjList[u]->first->data;
05435
05436 deleteEdge(u,v);
05437 iNum = iNum + 1;
05438 continue;
05439 }
05440
05441 if (getDeg(u) == 2)
05442 {
05443
05444 v1 = adjList[u]->first->data;
05445 v2 = adjList[u]->first->link->data;
05446
05447 deleteEdge(u,v1);
05448 deleteEdge(u,v2);
05449
05450 addEdge(v1,v2);
05451 iNum = iNum + 1;
05452 continue;
05453 }
05454 }
05455 }
05456
05457
05458 gl_free(iMark);
05459
05460 return iNum;
05461 }
05462
05463
05464 void LinkedUndigraph::deleteIsoVer(INTVECT *vMap)
05465 {
05466 int idx, idx2, numIsoVer, newArraySize;
05467 CHAINNODE *v;
05468 INTVECT isoVerArray;
05469 Chain **tempList;
05470 bool allocation_needed;
05471
05472
05473 isoVerArray.data = NULL;
05474 allocation_needed = true;
05475
05476
05477
05478
05479
05480
05481
05482
05483 if (vMap->data != NULL)
05484 {
05485
05486 if (vMap->maxSize != numVertices)
05487 {
05488
05489 gl_free(vMap->data);
05490
05491
05492
05493 vMap->data = NULL;
05494
05495
05496 allocation_needed = true;
05497 }
05498 else
05499 {
05500 allocation_needed = false;
05501 }
05502 }
05503
05504
05505 if (allocation_needed == true)
05506 {
05507
05508 vMap->data = (int *)gl_malloc(numVertices*sizeof(int));
05509
05510
05511 if (vMap->data == NULL)
05512 {
05513 GL_THROW("Restoration:Failed to allocate new temp variable");
05514
05515
05516
05517
05518 }
05519 }
05520
05521
05522 vMap->currSize = numVertices;
05523 vMap->maxSize = numVertices;
05524
05525
05526 for (idx=0; idx<numVertices; idx++)
05527 {
05528 vMap->data[idx] = idx;
05529 }
05530
05531
05532 numIsoVer = 0;
05533
05534
05535
05536 isoVerArray.data = (int *)gl_malloc(numVertices*sizeof(int));
05537
05538
05539 if (isoVerArray.data == NULL)
05540 {
05541 GL_THROW("Restoration:Failed to allocate new temp variable");
05542
05543 }
05544
05545
05546 isoVerArray.maxSize = numVertices;
05547 isoVerArray.currSize = 0;
05548
05549
05550 for (idx=0; idx<numVertices; idx++)
05551 {
05552 isoVerArray.data[idx] = -1;
05553 }
05554
05555 for (idx=0; idx<numVertices; idx++)
05556 {
05557 if (getDeg(idx) == 0)
05558 {
05559 vMap->data[idx] = -1;
05560
05561 for (idx2=(idx+1); idx2<numVertices; idx2++)
05562 {
05563 vMap->data[idx2] = vMap->data[idx2] - 1;
05564 }
05565
05566 numIsoVer = numIsoVer + 1;
05567
05568 isoVerArray.data[isoVerArray.currSize] = idx;
05569 isoVerArray.currSize++;
05570 }
05571 }
05572
05573
05574 for (idx=0; idx<numVertices; idx++)
05575 {
05576 v = adjList[idx]->first;
05577
05578 while (v != NULL)
05579 {
05580 v->data = vMap->data[v->data];
05581 v = v->link;
05582 }
05583 }
05584
05585
05586
05587 for (idx=0; idx<numIsoVer; idx++)
05588 {
05589
05590 gl_free(adjList[isoVerArray.data[idx]]);
05591
05592
05593 adjList[isoVerArray.data[idx]] = NULL;
05594 }
05595
05596
05597 for (idx=0; idx<numVertices; idx++)
05598 {
05599 if (vMap->data[idx] != -1)
05600 {
05601 adjList[vMap->data[idx]] = adjList[idx];
05602 }
05603 }
05604
05605
05606 newArraySize = numVertices - numIsoVer;
05607
05608
05609 tempList = adjList;
05610
05611
05612 adjList = (Chain **)gl_malloc(newArraySize*sizeof(Chain *));
05613
05614
05615 if (adjList == NULL)
05616 {
05617 GL_THROW("Restoration:Failed to allocate new chain");
05618
05619 }
05620
05621
05622 for (idx=0; idx<newArraySize; idx++)
05623 {
05624 adjList[idx] = tempList[idx];
05625 }
05626
05627
05628
05629 gl_free(tempList);
05630
05631
05632 tempList = NULL;
05633
05634
05635 numVertices = newArraySize;
05636
05637
05638 if (status_value != NULL)
05639 {
05640 gl_free(status_value);
05641 gl_free(parent_value);
05642 gl_free(dist);
05643 gl_free(dTime);
05644 gl_free(fTime);
05645
05646
05647 status_value = NULL;
05648 parent_value = NULL;
05649 dist = NULL;
05650 dTime = NULL;
05651 fTime = NULL;
05652 }
05653
05654
05655
05656
05657
05658 status_value = (int *)gl_malloc(numVertices*sizeof(int));
05659
05660
05661 if (status_value == NULL)
05662 {
05663 GL_THROW("Restoration:Failed to allocate new chain");
05664
05665 }
05666
05667 parent_value = (int *)gl_malloc(numVertices*sizeof(int));
05668
05669 if (parent_value == NULL)
05670 {
05671 GL_THROW("Restoration:Failed to allocate new chain");
05672
05673 }
05674
05675 dist = (double *)gl_malloc(numVertices*sizeof(double));
05676
05677 if (dist == NULL)
05678 {
05679 GL_THROW("Restoration:Failed to allocate new chain");
05680
05681 }
05682
05683 dTime = (TIMESTAMP *)gl_malloc(numVertices*sizeof(TIMESTAMP));
05684
05685 if (dTime == NULL)
05686 {
05687 GL_THROW("Restoration:Failed to allocate new chain");
05688
05689 }
05690
05691 fTime = (TIMESTAMP *)gl_malloc(numVertices*sizeof(TIMESTAMP));
05692
05693 if (fTime == NULL)
05694 {
05695 GL_THROW("Restoration:Failed to allocate new chain");
05696
05697 }
05698
05699
05700 for (idx=0; idx<numVertices; idx++)
05701 {
05702
05703 status_value[idx] = 0;
05704 parent_value[idx] = -1;
05705 dist[idx] = INFINITY;
05706 dTime[idx] = 0;
05707 fTime[idx] = 0;
05708 }
05709
05710
05711 gl_free(isoVerArray.data);
05712 }
05713
05714
05715 void LinkedUndigraph::mergeVer_2(INTVECT *vMap)
05716 {
05717 int idx, tempidx, n_V_new, k, numIsoVer, newArraySize, numFound;
05718 INTVECT V_new, isoVerArray, resVerArray, merge_V, tempoutVect;
05719 CHAINNODE *cur_ver, *next_ver;
05720 Chain **tempList;
05721
05722
05723 V_new.data = NULL;
05724 isoVerArray.data = NULL;
05725 resVerArray.data = NULL;
05726 merge_V.data = NULL;
05727 tempoutVect.data = NULL;
05728 tempList = NULL;
05729
05730
05731 V_new.currSize = vMap->currSize;
05732 V_new.maxSize = vMap->maxSize;
05733 V_new.data = (int *)gl_malloc(V_new.maxSize*sizeof(int));
05734
05735
05736 if (V_new.data == NULL)
05737 {
05738 GL_THROW("Restoration:Failed to allocate new temp variable");
05739
05740 }
05741
05742
05743 unique_int(vMap,&V_new);
05744
05745 n_V_new = V_new.currSize;
05746
05747
05748 isoVerArray.currSize = 0;
05749 resVerArray.currSize = 0;
05750 merge_V.currSize = 0;
05751 tempoutVect.currSize = 0;
05752
05753 isoVerArray.maxSize = vMap->maxSize;
05754 resVerArray.maxSize = vMap->maxSize;
05755 merge_V.maxSize = vMap->maxSize;
05756 tempoutVect.maxSize = vMap->maxSize;
05757
05758 isoVerArray.data = (int *)gl_malloc(isoVerArray.maxSize*sizeof(int));
05759 resVerArray.data = (int *)gl_malloc(resVerArray.maxSize*sizeof(int));
05760 merge_V.data = (int *)gl_malloc(merge_V.maxSize*sizeof(int));
05761 tempoutVect.data = (int *)gl_malloc(tempoutVect.maxSize*sizeof(int));
05762
05763
05764 if (isoVerArray.data == NULL)
05765 {
05766 GL_THROW("Restoration:Failed to allocate new temp variable");
05767
05768 }
05769
05770 if (resVerArray.data == NULL)
05771 {
05772 GL_THROW("Restoration:Failed to allocate new temp variable");
05773
05774 }
05775
05776 if (merge_V.data == NULL)
05777 {
05778 GL_THROW("Restoration:Failed to allocate new temp variable");
05779
05780 }
05781
05782 if (tempoutVect.data == NULL)
05783 {
05784 GL_THROW("Restoration:Failed to allocate new temp variable");
05785
05786 }
05787
05788 numIsoVer = 0;
05789
05790
05791 for (idx=0; idx<n_V_new; idx++)
05792 {
05793
05794 find_int(vMap,&merge_V,V_new.data[idx],-1);
05795
05796
05797
05798 numFound = merge_V.currSize + 1;
05799
05800
05801 resVerArray.data[resVerArray.currSize] = merge_V.data[0];
05802 resVerArray.currSize++;
05803
05804
05805 for (tempidx=1; tempidx<numFound; tempidx++)
05806 {
05807
05808 isoVerArray.data[isoVerArray.currSize] = merge_V.data[tempidx];
05809
05810
05811 isoVerArray.currSize++;
05812 }
05813
05814
05815 numIsoVer = isoVerArray.currSize;
05816
05817
05818 if (merge_V.data[0] == -1)
05819 {
05820 cur_ver = NULL;
05821 }
05822 else
05823 {
05824 cur_ver = adjList[merge_V.data[0]]->first;
05825 }
05826
05827 while (cur_ver != NULL)
05828 {
05829 if (cur_ver->link != NULL)
05830 {
05831 next_ver = cur_ver->link;
05832 }
05833 else
05834 {
05835 next_ver = NULL;
05836 }
05837
05838
05839 find_int(&merge_V,&tempoutVect,cur_ver->data,1);
05840
05841
05842 if (tempoutVect.currSize != -1)
05843 {
05844 deleteEdge(merge_V.data[0],cur_ver->data);
05845 }
05846 cur_ver = next_ver;
05847 }
05848
05849 for (k=1; k<numFound; k++)
05850 {
05851
05852 if (merge_V.data[k] != -1)
05853 {
05854 cur_ver = adjList[merge_V.data[k]]->first;
05855 }
05856 else
05857 {
05858 cur_ver = NULL;
05859 }
05860
05861 while (cur_ver != NULL)
05862 {
05863 if (cur_ver->link != NULL)
05864 {
05865 next_ver = cur_ver->link;
05866 }
05867 else
05868 {
05869 next_ver = NULL;
05870 }
05871
05872
05873 find_int(&merge_V,&tempoutVect,cur_ver->data,1);
05874
05875
05876 if (tempoutVect.currSize != -1)
05877 {
05878 deleteEdge(merge_V.data[k],cur_ver->data);
05879 }
05880 else
05881 {
05882 addEdge(merge_V.data[0],cur_ver->data);
05883 deleteEdge(merge_V.data[k],cur_ver->data);
05884 }
05885 cur_ver = next_ver;
05886 }
05887 }
05888 }
05889
05890
05891 for (idx=0; idx<numVertices; idx++)
05892 {
05893 cur_ver = adjList[idx]->first;
05894 while (cur_ver != NULL)
05895 {
05896 cur_ver->data = vMap->data[cur_ver->data];
05897 cur_ver = cur_ver->link;
05898 }
05899 }
05900
05901
05902
05903 for (idx=0; idx<numIsoVer; idx++)
05904 {
05905
05906 gl_free(adjList[isoVerArray.data[idx]]);
05907
05908
05909 adjList[isoVerArray.data[idx]] = NULL;
05910 }
05911
05912
05913 unique_int(&resVerArray,&V_new);
05914 for (idx=0; idx<V_new.currSize; idx++)
05915 {
05916
05917 adjList[idx] = adjList[V_new.data[idx]];
05918 }
05919
05920
05921 newArraySize = numVertices - numIsoVer;
05922
05923
05924 tempList = adjList;
05925
05926
05927 adjList = (Chain **)gl_malloc(newArraySize*sizeof(Chain *));
05928
05929
05930 if (adjList == NULL)
05931 {
05932 GL_THROW("Restoration:Failed to allocate new chain");
05933
05934 }
05935
05936
05937 for (idx=0; idx<newArraySize; idx++)
05938 {
05939 adjList[idx] = tempList[idx];
05940 }
05941
05942
05943
05944 gl_free(tempList);
05945
05946
05947 tempList = NULL;
05948
05949
05950 numVertices = newArraySize;
05951
05952
05953 if (status_value != NULL)
05954 {
05955 gl_free(status_value);
05956 gl_free(parent_value);
05957 gl_free(dist);
05958 gl_free(dTime);
05959 gl_free(fTime);
05960
05961
05962 status_value = NULL;
05963 parent_value = NULL;
05964 dist = NULL;
05965 dTime = NULL;
05966 fTime = NULL;
05967 }
05968
05969
05970
05971
05972
05973 status_value = (int *)gl_malloc(numVertices*sizeof(int));
05974
05975
05976 if (status_value == NULL)
05977 {
05978 GL_THROW("Restoration:Failed to allocate new chain");
05979
05980 }
05981
05982 parent_value = (int *)gl_malloc(numVertices*sizeof(int));
05983
05984 if (parent_value == NULL)
05985 {
05986 GL_THROW("Restoration:Failed to allocate new chain");
05987
05988 }
05989
05990 dist = (double *)gl_malloc(numVertices*sizeof(double));
05991
05992 if (dist == NULL)
05993 {
05994 GL_THROW("Restoration:Failed to allocate new chain");
05995
05996 }
05997
05998 dTime = (TIMESTAMP *)gl_malloc(numVertices*sizeof(TIMESTAMP));
05999
06000 if (dTime == NULL)
06001 {
06002 GL_THROW("Restoration:Failed to allocate new chain");
06003
06004 }
06005
06006 fTime = (TIMESTAMP *)gl_malloc(numVertices*sizeof(TIMESTAMP));
06007
06008 if (fTime == NULL)
06009 {
06010 GL_THROW("Restoration:Failed to allocate new chain");
06011
06012 }
06013
06014
06015 for (idx=0; idx<numVertices; idx++)
06016 {
06017
06018 status_value[idx] = 0;
06019 parent_value[idx] = -1;
06020 dist[idx] = INFINITY;
06021 dTime[idx] = 0;
06022 fTime[idx] = 0;
06023 }
06024
06025
06026 gl_free(isoVerArray.data);
06027
06028
06029 gl_free(resVerArray.data);
06030
06031
06032 gl_free(V_new.data);
06033 gl_free(merge_V.data);
06034 gl_free(tempoutVect.data);
06035 }
06036
06037
06038
06039
06040
06041 void unique_int(INTVECT *inputvect, INTVECT *outputvect)
06042 {
06043 INTVECT workmatrix, workmatrix_input;
06044 int leftidx, rightidx;
06045
06046
06047 workmatrix.currSize = inputvect->currSize;
06048 workmatrix.maxSize = inputvect->maxSize;
06049 workmatrix.data = (int *)gl_malloc(workmatrix.maxSize*sizeof(int));
06050
06051
06052 if (workmatrix.data == NULL)
06053 {
06054 GL_THROW("Restoration:Failed to allocate new temp variable");
06055
06056 }
06057
06058
06059 workmatrix_input.currSize = inputvect->currSize;
06060 workmatrix_input.maxSize = inputvect->maxSize;
06061 workmatrix_input.data = (int *)gl_malloc(workmatrix_input.maxSize*sizeof(int));
06062
06063
06064 if (workmatrix_input.data == NULL)
06065 {
06066 GL_THROW("Restoration:Failed to allocate new temp variable");
06067
06068 }
06069
06070
06071 memcpy(workmatrix_input.data,inputvect->data,inputvect->currSize*sizeof(int));
06072
06073
06074 merge_sort_int(workmatrix_input.data,workmatrix_input.currSize, workmatrix.data);
06075
06076
06077 leftidx = 1;
06078 rightidx = 0;
06079
06080
06081 outputvect->data[0] = workmatrix_input.data[0];
06082
06083 while (leftidx < workmatrix_input.currSize)
06084 {
06085 if (workmatrix_input.data[leftidx] != outputvect->data[rightidx])
06086 {
06087
06088 rightidx++;
06089
06090
06091 if (rightidx>outputvect->maxSize)
06092 {
06093 GL_THROW("Restoration: Larger number of unique entries than expected found!");
06094
06095
06096
06097
06098 }
06099
06100
06101 outputvect->data[rightidx] = workmatrix_input.data[leftidx];
06102
06103 }
06104 else
06105 {
06106 leftidx++;
06107 }
06108 }
06109
06110
06111 outputvect->currSize = rightidx + 1;
06112
06113
06114 gl_free(workmatrix.data);
06115 gl_free(workmatrix_input.data);
06116 }
06117
06118
06119 void merge_sort_int(int *Input_Array, unsigned int Alen, int *Work_Array)
06120 {
06121 unsigned int split_point;
06122 unsigned int right_length;
06123 int *leftside, *rightside;
06124 int *Final_P;
06125
06126 if (Alen>0)
06127 {
06128 split_point = Alen/2;
06129 right_length = Alen - split_point;
06130
06131
06132 leftside = Input_Array;
06133 rightside = Input_Array+split_point;
06134
06135
06136 if (split_point>1)
06137 merge_sort_int(leftside,split_point,Work_Array);
06138
06139 if (right_length>1)
06140 merge_sort_int(rightside,right_length,Work_Array);
06141
06142
06143 Final_P = Work_Array;
06144
06145
06146 do {
06147 if (*leftside < *rightside)
06148 *Final_P++ = *leftside++;
06149 else
06150 *Final_P++ = *rightside++;
06151 } while ((leftside<(Input_Array+split_point)) && (rightside<(Input_Array+Alen)));
06152
06153 while (leftside<(Input_Array+split_point))
06154 *Final_P++ = *leftside++;
06155
06156 while (rightside<(Input_Array+Alen))
06157 *Final_P++ = *rightside++;
06158
06159 memcpy(Input_Array,Work_Array,sizeof(int)*Alen);
06160 }
06161 }
06162
06163
06164
06165
06166 EXPORT int perform_restoration(OBJECT *thisobj, int faulting_link)
06167 {
06168 restoration *temp_rest_obj = OBJECTDATA(thisobj,restoration);
06169
06170 return temp_rest_obj->PerformRestoration(faulting_link);
06171 }
06172
06173
06175
06177
06185 EXPORT int create_restoration(OBJECT **obj, OBJECT *parent)
06186 {
06187 try
06188 {
06189 *obj = gl_create_object(restoration::oclass);
06190 if (*obj!=NULL)
06191 {
06192 restoration *my = OBJECTDATA(*obj,restoration);
06193 gl_set_parent(*obj,parent);
06194 return my->create();
06195 }
06196 else
06197 return 0;
06198 }
06199 CREATE_CATCHALL(restoration);
06200 }
06201
06202 EXPORT int init_restoration(OBJECT *obj, OBJECT *parent)
06203 {
06204 try {
06205 return OBJECTDATA(obj,restoration)->init(parent);
06206 }
06207 INIT_CATCHALL(restoration);
06208 }
06209
06218 EXPORT TIMESTAMP sync_restoration(OBJECT *obj, TIMESTAMP t1, PASSCONFIG pass)
06219 {
06220 return TS_NEVER;
06221 }
06222 EXPORT int isa_restoration(OBJECT *obj, char *classname)
06223 {
06224 return OBJECTDATA(obj,restoration)->isa(classname);
06225 }
06226