00001
00011 #include <stdlib.h>
00012 #include <stdio.h>
00013 #include <errno.h>
00014 #include <math.h>
00015 #include <iostream>
00016 using namespace std;
00017
00018 #include "regulator.h"
00019 #include "node.h"
00020
00021 CLASS* regulator::oclass = NULL;
00022 CLASS* regulator::pclass = NULL;
00023
00024 regulator::regulator(MODULE *mod) : link(mod)
00025 {
00026 if (oclass==NULL)
00027 {
00028
00029 pclass = link::oclass;
00030
00031
00032 oclass = gl_register_class(mod,"regulator",sizeof(regulator),PC_PRETOPDOWN|PC_BOTTOMUP|PC_POSTTOPDOWN|PC_UNSAFE_OVERRIDE_OMIT);
00033 if (oclass==NULL)
00034 GL_THROW("unable to register object class implemented by %s",__FILE__);
00035
00036
00037 if (gl_publish_variable(oclass,
00038 PT_INHERIT, "link",
00039 PT_object,"configuration",PADDR(configuration),
00040 PT_int16, "tap_A",PADDR(tap_A),
00041 PT_int16, "tap_B",PADDR(tap_B),
00042 PT_int16, "tap_C",PADDR(tap_C),
00043 PT_object,"sense_node",PADDR(RemoteNode),
00044 NULL)<1) GL_THROW("unable to publish properties in %s",__FILE__);
00045 }
00046 }
00047
00048 int regulator::isa(char *classname)
00049 {
00050 return strcmp(classname,"regulator")==0 || link::isa(classname);
00051 }
00052
00053 int regulator::create()
00054 {
00055 int result = link::create();
00056 configuration = NULL;
00057 tap_A = tap_B = tap_C = -999;
00058 offnominal_time = false;
00059 return result;
00060 }
00061
00062 int regulator::init(OBJECT *parent)
00063 {
00064 bool TapInitialValue[3];
00065 char jindex;
00066 int result = link::init(parent);
00067
00068 if (!configuration)
00069 throw "no regulator configuration specified.";
00070
00071
00072
00073
00074
00075
00076 if (!gl_object_isa(configuration, "regulator_configuration"))
00077 throw "invalid regulator configuration";
00078
00079
00080
00081
00082
00083
00084
00085 regulator_configuration *pConfig = OBJECTDATA(configuration, regulator_configuration);
00086
00087
00088 for (jindex=0;jindex<3;jindex++)
00089 {
00090 if (pConfig->tap_pos[jindex] != 999)
00091 {
00092 TapInitialValue[jindex] = true;
00093 }
00094 else
00095 {
00096 TapInitialValue[jindex] = false;
00097 pConfig->tap_pos[jindex] = 0;
00098 }
00099 }
00100
00101 if (pConfig->Control == pConfig->REMOTE_NODE)
00102 {
00103 node *RNode = OBJECTDATA(RemoteNode,node);
00104 if (RNode == NULL)
00105 {
00106 throw "Remote sensing node not found";
00107
00108
00109
00110
00111 }
00112 }
00113
00114 D_mat[0][0] = D_mat[1][1] = D_mat[2][2] = complex(1,0);
00115 D_mat[0][1] = D_mat[2][0] = D_mat[1][2] = complex(-1,0);
00116 D_mat[0][2] = D_mat[2][1] = D_mat[1][0] = complex(0,0);
00117
00118 W_mat[0][0] = W_mat[1][1] = W_mat[2][2] = complex(2,0);
00119 W_mat[0][1] = W_mat[2][0] = W_mat[1][2] = complex(1,0);
00120 W_mat[0][2] = W_mat[2][1] = W_mat[1][0] = complex(0,0);
00121
00122 multiply(1.0/3.0,W_mat,W_mat);
00123
00124 tapChangePer = pConfig->regulation / (double) pConfig->raise_taps;
00125 Vlow = pConfig->band_center - pConfig->band_width / 2.0;
00126 Vhigh = pConfig->band_center + pConfig->band_width / 2.0;
00127 VtapChange = pConfig->band_center * tapChangePer;
00128
00129 for (int i = 0; i < 3; i++)
00130 {
00131 for (int j = 0; j < 3; j++)
00132 {
00133 a_mat[i][j] = b_mat[i][j] = c_mat[i][j] = d_mat[i][j] =
00134 A_mat[i][j] = B_mat[i][j] = 0.0;
00135 }
00136 }
00137
00138 for (int i = 0; i < 3; i++)
00139 {
00140 if (tap[i] == -999)
00141 tap[i] = pConfig->tap_pos[i];
00142
00143 if (pConfig->Type == pConfig->A)
00144 a_mat[i][i] = 1/(1.0 + tap[i] * tapChangePer);
00145 else if (pConfig->Type == pConfig->B)
00146 a_mat[i][i] = 1.0 - tap[i] * tapChangePer;
00147 else
00148 throw "invalid regulator type";
00149
00150
00151
00152 }
00153
00154 complex tmp_mat[3][3] = {{complex(1,0)/a_mat[0][0],complex(0,0),complex(0,0)},
00155 {complex(0,0), complex(1,0)/a_mat[1][1],complex(0,0)},
00156 {complex(-1,0)/a_mat[0][0],complex(-1,0)/a_mat[1][1],complex(0,0)}};
00157 complex tmp_mat1[3][3];
00158
00159 switch (pConfig->connect_type) {
00160 case regulator_configuration::WYE_WYE:
00161 for (int i = 0; i < 3; i++)
00162 d_mat[i][i] = complex(1.0,0) / a_mat[i][i];
00163 inverse(a_mat,A_mat);
00164
00165 if (solver_method == SM_NR)
00166 {
00167 SpecialLnk = REGULATOR;
00168
00169 if (has_phase(PHASE_A))
00170 b_mat[0][0] = 1e4;
00171 if (has_phase(PHASE_B))
00172 b_mat[1][1] = 1e4;
00173 if (has_phase(PHASE_C))
00174 b_mat[2][2] = 1e4;
00175 }
00176 break;
00177 case regulator_configuration::OPEN_DELTA_ABBC:
00178 d_mat[0][0] = complex(1,0) / a_mat[0][0];
00179 d_mat[1][0] = complex(-1,0) / a_mat[0][0];
00180 d_mat[1][2] = complex(-1,0) / a_mat[1][1];
00181 d_mat[2][2] = complex(1,0) / a_mat[1][1];
00182
00183 a_mat[2][0] = -a_mat[0][0];
00184 a_mat[2][1] = -a_mat[1][1];
00185 a_mat[2][2] = 0;
00186
00187 multiply(W_mat,tmp_mat,tmp_mat1);
00188 multiply(tmp_mat1,D_mat,A_mat);
00189
00190 gl_warning("Only WYE-WYE configurations are working in either Newton-Raphson or non-Manual controls");
00191
00192
00193
00194
00195
00196 break;
00197 case regulator_configuration::OPEN_DELTA_BCAC:
00198 throw "Regulator connect type not supported yet";
00199
00200
00201
00202
00203 break;
00204 case regulator_configuration::OPEN_DELTA_CABA:
00205 throw "Regulator connect type not supported yet";
00206
00207
00208
00209
00210 break;
00211 case regulator_configuration::CLOSED_DELTA:
00212 throw "Regulator connect type not supported yet";
00213
00214
00215
00216
00217 break;
00218 default:
00219 throw "unknown regulator connect type";
00220
00221
00222
00223
00224 break;
00225 }
00226
00227 mech_t_next[0] = mech_t_next[1] = mech_t_next[2] = TS_NEVER;
00228 dwell_t_next[0] = dwell_t_next[1] = dwell_t_next[2] = TS_NEVER;
00229
00230
00231 for (jindex=0;jindex<3;jindex++)
00232 {
00233 if (TapInitialValue[jindex] == false)
00234 {
00235 if (solver_method == SM_NR)
00236 first_run_flag[jindex] = -2;
00237 else
00238 first_run_flag[jindex] = -1;
00239 }
00240 else
00241 {
00242 first_run_flag[jindex] = 0;
00243 }
00244 }
00245
00246
00247 prev_tap[0] = tap[0];
00248 prev_tap[1] = tap[1];
00249 prev_tap[2] = tap[2];
00250
00251
00252 unsigned int glob_min_timestep, temp_val;
00253 char temp_buff[128];
00254 char indexval;
00255
00256
00257 gl_global_getvar("minimum_timestep",temp_buff,sizeof(temp_buff));
00258
00259
00260 indexval = 0;
00261 glob_min_timestep = 0;
00262
00263
00264 while ((indexval < 128) && (temp_buff[indexval] != 0))
00265 {
00266 glob_min_timestep *= 10;
00267 temp_val = (temp_buff[indexval]-48);
00268 glob_min_timestep += temp_val;
00269
00270 indexval++;
00271 }
00272
00273 if (glob_min_timestep > 1)
00274 offnominal_time=true;
00275
00276 return result;
00277 }
00278
00279
00280 TIMESTAMP regulator::presync(TIMESTAMP t0)
00281 {
00282 regulator_configuration *pConfig = OBJECTDATA(configuration, regulator_configuration);
00283 node *pTo = OBJECTDATA(to, node);
00284
00285 if (pConfig->Control == pConfig->MANUAL) {
00286 for (int i = 0; i < 3; i++) {
00287 if (pConfig->Type == pConfig->A)
00288 { a_mat[i][i] = 1/(1.0 + tap[i] * tapChangePer);}
00289 else if (pConfig->Type == pConfig->B)
00290 { a_mat[i][i] = 1.0 - tap[i] * tapChangePer;}
00291 else
00292 { throw "invalid regulator type";}
00293
00294
00295
00296 }
00297 next_time = TS_NEVER;
00298 }
00299
00300 else if ((solver_method == SM_NR && NR_cycle==true) || solver_method == SM_FBS)
00301 {
00302 if (pConfig->control_level == pConfig->INDIVIDUAL)
00303 {
00304
00305 for (int i = 0; i < 3; i++) {
00306 if (mech_t_next[i] <= t0) {
00307 mech_flag[i] = 1;
00308 }
00309 if (dwell_t_next[i] <= t0) {
00310 dwell_flag[i] = 1;
00311 }
00312 else if (dwell_t_next[i] > t0) {
00313 dwell_flag[i] = 0;
00314 }
00315 }
00316
00317 get_monitored_voltage();
00318
00319 if (pConfig->connect_type == pConfig->WYE_WYE)
00320 {
00321
00322 if ((first_run_flag[0] + first_run_flag[1] + first_run_flag[2]) < 3 ) {
00323 for (int i = 0; i < 3; i++) {
00324 if (first_run_flag[i] < 1) {
00325 first_run_flag[i] += 1;
00326 }
00327 }
00328 }
00329
00330 for (int i = 0; i < 3; i++)
00331 {
00332
00333 if (check_voltage[i].Mag() < Vlow)
00334 {
00335
00336
00337 if (first_run_flag[i] == 0)
00338 {
00339 tap[i] = tap[i] + (int16)ceil((pConfig->band_center - check_voltage[i].Mag())/VtapChange);
00340 if (tap[i] > pConfig->raise_taps)
00341 {
00342 tap[i] = pConfig->raise_taps;
00343 }
00344 dwell_t_next[i] = t0 + (int64)pConfig->dwell_time;
00345 mech_t_next[i] = t0 + (int64)pConfig->time_delay;
00346 }
00347
00348 else if (mech_flag[i] == 0 && dwell_flag[i] == 1 && (mech_t_next[i] - t0) >= pConfig->time_delay)
00349 {
00350 mech_t_next[i] = t0 + (int64)pConfig->time_delay;
00351 }
00352
00353 else if (mech_flag[i] == 1 && dwell_flag[i] == 1)
00354 {
00355 tap[i] = tap[i] + (int16) 1;
00356
00357 if (tap[i] > pConfig->raise_taps)
00358 {
00359 tap[i] = pConfig->raise_taps;
00360 dwell_t_next[i] = t0 + (int64)pConfig->dwell_time;
00361 mech_t_next[i] = t0 + (int64)pConfig->time_delay;
00362 dwell_flag[i] = mech_flag[i] = 0;
00363 }
00364 else
00365 {
00366 mech_t_next[i] = t0 + (int64)pConfig->time_delay;
00367 dwell_t_next[i] = t0 + (int64)pConfig->dwell_time;
00368 mech_flag[i] = 0;
00369 }
00370 }
00371
00372
00373 else if (dwell_flag[i] == 0 && (dwell_t_next[i] - t0) >= pConfig->dwell_time)
00374 {
00375 dwell_t_next[i] = t0 + (int64)pConfig->dwell_time;
00376 mech_t_next[i] = dwell_t_next[i] + (int64)pConfig->time_delay;
00377 }
00378 }
00379 else if (check_voltage[i].Mag() > Vhigh)
00380 {
00381 if (first_run_flag[i] == 0)
00382 {
00383 tap[i] = tap[i] - (int16)ceil((check_voltage[i].Mag() - pConfig->band_center)/VtapChange);
00384 if (tap[i] < -pConfig->lower_taps)
00385 {
00386 tap[i] = -pConfig->lower_taps;
00387 }
00388 dwell_t_next[i] = t0 + (int64)pConfig->dwell_time;
00389 mech_t_next[i] = t0 + (int64)pConfig->time_delay;
00390 }
00391 else if (mech_flag[i] == 0 && dwell_flag[i] == 1 && (mech_t_next[i] - t0) >= pConfig->time_delay)
00392 {
00393 mech_t_next[i] = t0 + (int64)pConfig->time_delay;
00394 }
00395 else if (mech_flag[i] == 1 && dwell_flag[i] == 1)
00396 {
00397 tap[i] = tap[i] - (int16) 1;
00398
00399 if (tap[i] < -pConfig->lower_taps)
00400 {
00401 tap[i] = -pConfig->lower_taps;
00402 dwell_t_next[i] = t0 + (int64)pConfig->dwell_time;
00403 mech_t_next[i] = t0 + (int64)pConfig->time_delay;
00404 dwell_flag[i] = mech_flag[i] = 0;
00405 }
00406 else
00407 {
00408 mech_t_next[i] = t0 + (int64)pConfig->time_delay;
00409 dwell_t_next[i] = t0 + (int64)pConfig->dwell_time;
00410 mech_flag[i] = 0;
00411 }
00412 }
00413 else if (dwell_flag[i] == 0 && (dwell_t_next[i] - t0) >= pConfig->dwell_time)
00414 {
00415 dwell_t_next[i] = t0 + (int64)pConfig->dwell_time;
00416 mech_t_next[i] = dwell_t_next[i] + (int64)pConfig->time_delay;
00417 }
00418 }
00419
00420
00421 else
00422 {
00423 dwell_t_next[i] = mech_t_next[i] = TS_NEVER;
00424
00425
00426
00427 dwell_flag[i] = 0;
00428
00429
00430
00431 mech_flag[i] = 0;
00432 }
00433
00434
00435 if (pConfig->Type == pConfig->A)
00436 { a_mat[i][i] = 1/(1.0 + tap[i] * tapChangePer);}
00437 else if (pConfig->Type == pConfig->B)
00438 { a_mat[i][i] = 1.0 - tap[i] * tapChangePer;}
00439 else
00440 { throw "invalid regulator type";}
00441
00442
00443
00444 }
00445
00446 int64 nt[3];
00447 for (int i = 0; i < 3; i++) {
00448 if (mech_t_next[i] > t0)
00449 nt[i] = mech_t_next[i];
00450 if (dwell_t_next[i] > t0)
00451 nt[i] = dwell_t_next[i];
00452 }
00453
00454 if (nt[0] > t0)
00455 next_time = nt[0];
00456 if (nt[1] > t0 && nt[1] < next_time)
00457 next_time = nt[1];
00458 if (nt[2] > t0 && nt[2] < next_time)
00459 next_time = nt[2];
00460
00461 if (next_time <= t0)
00462 next_time = TS_NEVER;
00463 }
00464 else
00465 GL_THROW("Specified connect type is not supported in automatic modes at this time.");
00466
00467
00468
00469
00470 }
00471
00472 else if (pConfig->control_level == pConfig->BANK)
00473 {
00474
00475 if (mech_t_next[0] <= t0) {
00476 mech_flag[0] = 1;
00477 }
00478 if (dwell_t_next[0] <= t0) {
00479 dwell_flag[0] = 1;
00480 }
00481 else if (dwell_t_next[0] > t0) {
00482 dwell_flag[0] = 0;
00483 }
00484
00485 get_monitored_voltage();
00486
00487 if (pConfig->connect_type == pConfig->WYE_WYE)
00488 {
00489
00490 if (first_run_flag[0] < 1)
00491 {
00492 first_run_flag[0] += 1;
00493 first_run_flag[1] += 1;
00494 first_run_flag[2] += 1;
00495 }
00496
00497 if (check_voltage[0].Mag() < Vlow)
00498 {
00499
00500
00501 if (first_run_flag[0] == 0)
00502 {
00503 tap[0] = tap[1] = tap[2] = tap[0] + (int16)ceil((pConfig->band_center - check_voltage[0].Mag())/VtapChange);
00504 if (tap[0] > pConfig->raise_taps)
00505 {
00506 tap[0] = tap[1] = tap[2] = pConfig->raise_taps;
00507 }
00508 dwell_t_next[0] = t0 + (int64)pConfig->dwell_time;
00509 mech_t_next[0] = t0 + (int64)pConfig->time_delay;
00510 }
00511
00512 else if (mech_flag[0] == 0 && dwell_flag[0] == 1 && (mech_t_next[0] - t0) >= pConfig->time_delay)
00513 {
00514 mech_t_next[0] = t0 + (int64)pConfig->time_delay;
00515 }
00516
00517 else if (mech_flag[0] == 1 && dwell_flag[0] == 1)
00518 {
00519 tap[0] = tap[1] = tap[2] = tap[0] + (int16) 1;
00520
00521 if (tap[0] > pConfig->raise_taps)
00522 {
00523 tap[0] = tap[1] = tap[2] = pConfig->raise_taps;
00524 dwell_t_next[0] = t0 + (int64)pConfig->dwell_time;
00525 mech_t_next[0] = t0 + (int64)pConfig->time_delay;
00526 dwell_flag[0] = mech_flag[0] = 0;
00527 }
00528 else
00529 {
00530 mech_t_next[0] = t0 + (int64)pConfig->time_delay;
00531 dwell_t_next[0] = t0 + (int64)pConfig->dwell_time;
00532 mech_flag[0] = 0;
00533 }
00534 }
00535
00536
00537 else if (dwell_flag[0] == 0 && (dwell_t_next[0] - t0) >= pConfig->dwell_time)
00538 {
00539 dwell_t_next[0] = t0 + (int64)pConfig->dwell_time;
00540 mech_t_next[0] = dwell_t_next[0] + (int64)pConfig->time_delay;
00541 }
00542 }
00543 else if (check_voltage[0].Mag() > Vhigh)
00544 {
00545 if (first_run_flag[0] == 0)
00546 {
00547 tap[0] = tap[1] = tap[2] = tap[0] - (int16)ceil((check_voltage[0].Mag() - pConfig->band_center)/VtapChange);
00548 if (tap[0] < -pConfig->lower_taps)
00549 {
00550 tap[0] = tap[1] = tap[2] = -pConfig->lower_taps;
00551 }
00552 dwell_t_next[0] = t0 + (int64)pConfig->dwell_time;
00553 mech_t_next[0] = t0 + (int64)pConfig->time_delay;
00554 }
00555 else if (mech_flag[0] == 0 && dwell_flag[0] == 1 && (mech_t_next[0] - t0) >= pConfig->time_delay)
00556 {
00557 mech_t_next[0] = t0 + (int64)pConfig->time_delay;
00558 }
00559 else if (mech_flag[0] == 1 && dwell_flag[0] == 1)
00560 {
00561 tap[0] = tap[1] = tap[2] = tap[0] - (int16) 1;
00562
00563 if (tap[0] < -pConfig->lower_taps)
00564 {
00565 tap[0] = tap[1] = tap[2] = -pConfig->lower_taps;
00566 dwell_t_next[0] = t0 + (int64)pConfig->dwell_time;
00567 mech_t_next[0] = t0 + (int64)pConfig->time_delay;
00568 dwell_flag[0] = mech_flag[0] = 0;
00569 }
00570 else
00571 {
00572 mech_t_next[0] = t0 + (int64)pConfig->time_delay;
00573 dwell_t_next[0] = t0 + (int64)pConfig->dwell_time;
00574 mech_flag[0] = 0;
00575 }
00576 }
00577 else if (dwell_flag[0] == 0 && (dwell_t_next[0] - t0) >= pConfig->dwell_time)
00578 {
00579 dwell_t_next[0] = t0 + (int64)pConfig->dwell_time;
00580 mech_t_next[0] = dwell_t_next[0] + (int64)pConfig->time_delay;
00581 }
00582 }
00583
00584
00585 else
00586 {
00587 dwell_t_next[0] = mech_t_next[0] = TS_NEVER;
00588 dwell_flag[0] = 0;
00589 mech_flag[0] = 0;
00590 }
00591
00592 for (int i = 0; i < 3; i++) {
00593
00594 if (pConfig->Type == pConfig->A)
00595 { a_mat[i][i] = 1/(1.0 + tap[i] * tapChangePer);}
00596 else if (pConfig->Type == pConfig->B)
00597 { a_mat[i][i] = 1.0 - tap[i] * tapChangePer;}
00598 else
00599 { throw "invalid regulator type";}
00600
00601
00602
00603 }
00604
00605
00606 int64 nt[3];
00607
00608 if (mech_t_next[0] > t0)
00609 nt[0] = mech_t_next[0];
00610 if (dwell_t_next[0] > t0)
00611 nt[0] = dwell_t_next[0];
00612
00613 if (nt[0] > t0)
00614 next_time = nt[0];
00615
00616 if (next_time <= t0)
00617 next_time = TS_NEVER;
00618 }
00619 else
00620 GL_THROW("Specified connect type is not supported in automatic modes at this time.");
00621
00622
00623
00624
00625 }
00626
00627 }
00628
00629
00630 complex tmp_mat[3][3] = {{complex(1,0)/a_mat[0][0],complex(0,0),complex(0,0)},
00631 {complex(0,0), complex(1,0)/a_mat[1][1],complex(0,0)},
00632 {complex(-1,0)/a_mat[0][0],complex(-1,0)/a_mat[1][1],complex(0,0)}};
00633 complex tmp_mat1[3][3];
00634
00635 switch (pConfig->connect_type) {
00636 case regulator_configuration::WYE_WYE:
00637 for (int i = 0; i < 3; i++)
00638 { d_mat[i][i] = complex(1.0,0) / a_mat[i][i]; }
00639 inverse(a_mat,A_mat);
00640 break;
00641 case regulator_configuration::OPEN_DELTA_ABBC:
00642 d_mat[0][0] = complex(1,0) / a_mat[0][0];
00643 d_mat[1][0] = complex(-1,0) / a_mat[0][0];
00644 d_mat[1][2] = complex(-1,0) / a_mat[1][1];
00645 d_mat[2][2] = complex(1,0) / a_mat[1][1];
00646
00647 a_mat[2][0] = -a_mat[0][0];
00648 a_mat[2][1] = -a_mat[1][1];
00649 a_mat[2][2] = 0;
00650
00651 multiply(W_mat,tmp_mat,tmp_mat1);
00652 multiply(tmp_mat1,D_mat,A_mat);
00653 break;
00654 case regulator_configuration::OPEN_DELTA_BCAC:
00655 break;
00656 case regulator_configuration::OPEN_DELTA_CABA:
00657 break;
00658 case regulator_configuration::CLOSED_DELTA:
00659 break;
00660 default:
00661 throw "unknown regulator connect type";
00662
00663
00664
00665
00666 break;
00667 }
00668
00669 TIMESTAMP t1 = link::presync(t0);
00670
00671 if (solver_method == SM_NR)
00672 {
00673
00674 int jindex,kindex;
00675 complex Ylefttemp[3][3];
00676 complex Yto[3][3];
00677 complex Yfrom[3][3];
00678
00679
00680 equalm(b_mat,Yto);
00681
00682
00683 for (jindex=0; jindex<3; jindex++)
00684 {
00685 for (kindex=0; kindex<3; kindex++)
00686 {
00687 YSto[jindex*3+kindex]=Yto[jindex][kindex];
00688 }
00689 }
00690
00691 for (jindex=0; jindex<3; jindex++)
00692 {
00693 Ylefttemp[jindex][jindex] = Yto[jindex][jindex] * complex(1,0) / a_mat[jindex][jindex];
00694 Yfrom[jindex][jindex]=Ylefttemp[jindex][jindex] * complex(1,0) / a_mat[jindex][jindex];
00695 }
00696
00697
00698
00699
00700
00701
00702 for (jindex=0; jindex<3; jindex++)
00703 {
00704 for (kindex=0; kindex<3; kindex++)
00705 {
00706 YSfrom[jindex*3+kindex]=Yfrom[jindex][kindex];
00707 }
00708 }
00709
00710 for (jindex=0; jindex<3; jindex++)
00711 {
00712 To_Y[jindex][jindex] = Yto[jindex][jindex] * complex(1,0) / a_mat[jindex][jindex];
00713 From_Y[jindex][jindex]=Yfrom[jindex][jindex] * a_mat[jindex][jindex];
00714 }
00715
00716
00717
00718
00719
00720 if ((prev_tap[0] != tap[0]) || (prev_tap[1] != tap[1]) || (prev_tap[2] != tap[2]))
00721 {
00722
00723 NR_admit_change = true;
00724
00725
00726 prev_tap[0] = tap[0];
00727 prev_tap[1] = tap[1];
00728 prev_tap[2] = tap[2];
00729 }
00730 }
00731
00732 if (offnominal_time && (t0 > next_time))
00733 {
00734 next_time = t0;
00735 }
00736
00737 if (first_run_flag[0] < 1 || first_run_flag[1] < 1 || first_run_flag[2] < 1) return t1;
00738 else if (t1 <= next_time) return t1;
00739 else if (next_time != TS_NEVER) return -next_time;
00740 else return TS_NEVER;
00741 }
00742 TIMESTAMP regulator::postsync(TIMESTAMP t0)
00743 {
00744 regulator_configuration *pConfig = OBJECTDATA(configuration, regulator_configuration);
00745 node *pTo = OBJECTDATA(to, node);
00746
00747 TIMESTAMP t1 = link::postsync(t0);
00748
00749 if ((solver_method == SM_NR && NR_cycle==true) || solver_method == SM_FBS)
00750 {
00751 if (pConfig->Control != pConfig->MANUAL)
00752 {
00753 for (int i = 0; i < 3; i++) {
00754 if (mech_t_next[i] <= t0) {
00755 mech_flag[i] = 1;
00756 }
00757 if (dwell_t_next[i] <= t0) {
00758 dwell_flag[i] = 1;
00759 }
00760 else if (dwell_t_next[i] > t0) {
00761 dwell_flag[i] = 0;
00762 }
00763 }
00764
00765 get_monitored_voltage();
00766
00767 int i;
00768 for (i=0; i<3; i++)
00769 {
00770 if (first_run_flag[i] < 1)
00771 return t0;
00772 if (dwell_flag[i] == 1 && mech_flag[i] == 1)
00773 {
00774 if (check_voltage[i].Mag() < Vlow && tap[i] != -pConfig->lower_taps)
00775 return t0;
00776
00777 if (check_voltage[i].Mag() > Vhigh && tap[i] != -pConfig->raise_taps)
00778 return t0;
00779 }
00780 }
00781 }
00782 }
00783
00784 return t1;
00785 }
00786
00787
00789
00791
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813 EXPORT int create_regulator(OBJECT **obj, OBJECT *parent)
00814 {
00815 try
00816 {
00817 *obj = gl_create_object(regulator::oclass);
00818 if (*obj!=NULL)
00819 {
00820 regulator *my = OBJECTDATA(*obj,regulator);
00821 gl_set_parent(*obj,parent);
00822 return my->create();
00823 }
00824 }
00825 catch (const char *msg)
00826 {
00827 gl_error("create_regulator: %s", msg);
00828 }
00829 return 0;
00830 }
00831
00838 EXPORT int init_regulator(OBJECT *obj)
00839 {
00840 regulator *my = OBJECTDATA(obj,regulator);
00841 try {
00842 return my->init(obj->parent);
00843 }
00844 catch (const char *msg)
00845 {
00846 GL_THROW("%s (regulator:%d): %s", my->get_name(), my->get_id(), msg);
00847 return 0;
00848 }
00849 }
00850
00859 EXPORT TIMESTAMP sync_regulator(OBJECT *obj, TIMESTAMP t0, PASSCONFIG pass)
00860 {
00861 regulator *pObj = OBJECTDATA(obj,regulator);
00862 try {
00863 TIMESTAMP t1 = TS_NEVER;
00864 switch (pass) {
00865 case PC_PRETOPDOWN:
00866 return pObj->presync(t0);
00867 case PC_BOTTOMUP:
00868 return pObj->sync(t0);
00869 case PC_POSTTOPDOWN:
00870 t1 = pObj->postsync(t0);
00871 obj->clock = t0;
00872 return t1;
00873 default:
00874 throw "invalid pass request";
00875 }
00876 } catch (const char *error) {
00877 GL_THROW("%s (regulator:%d): %s", pObj->get_name(), pObj->get_id(), error);
00878 return 0;
00879 } catch (...) {
00880 GL_THROW("%s (regulator:%d): %s", pObj->get_name(), pObj->get_id(), "unknown exception");
00881 return 0;
00882 }
00883 }
00884
00885 EXPORT int isa_regulator(OBJECT *obj, char *classname)
00886 {
00887 return OBJECTDATA(obj,regulator)->isa(classname);
00888 }
00889
00890 void regulator::get_monitored_voltage()
00891 {
00892 regulator_configuration *pConfig = OBJECTDATA(configuration, regulator_configuration);
00893 node *pTo = OBJECTDATA(to, node);
00894
00895 int testval = (int)(pConfig->Control);
00896 switch (testval)
00897 {
00898 case 4:
00899 {
00900 if (pConfig->control_level == pConfig->INDIVIDUAL)
00901 {
00902 if (pTo)
00903 {
00904 volt[0] = pTo->voltageA;
00905 volt[1] = pTo->voltageB;
00906 volt[2] = pTo->voltageC;
00907 }
00908 else
00909 {
00910 volt[0] = volt[1] = volt[2] = 0.0;
00911 }
00912
00913 for (int i = 0; i < 3; i++)
00914 V2[i] = volt[i] / ((double) pConfig->PT_ratio);
00915
00916 if ((double) pConfig->CT_ratio != 0.0)
00917 {
00918
00919 complex tmp_mat2[3][3];
00920 inverse(d_mat,tmp_mat2);
00921
00922 curr[0] = tmp_mat2[0][0]*current_in[0]+tmp_mat2[0][1]*current_in[1]+tmp_mat2[0][2]*current_in[2];
00923 curr[1] = tmp_mat2[1][0]*current_in[0]+tmp_mat2[1][1]*current_in[1]+tmp_mat2[1][2]*current_in[2];
00924 curr[2] = tmp_mat2[2][0]*current_in[0]+tmp_mat2[2][1]*current_in[1]+tmp_mat2[2][2]*current_in[2];
00925
00926 for (int i = 0; i < 3; i++)
00927 check_voltage[i] = V2[i] - (curr[i] / (double) pConfig->CT_ratio) * complex(pConfig->ldc_R_V[i], pConfig->ldc_X_V[i]);
00928 }
00929 else
00930 {
00931 for (int i = 0; i < 3; i++)
00932 check_voltage[i] = V2[i];
00933 }
00934 }
00935 else if (pConfig->control_level == pConfig->BANK)
00936 {
00937 if (pTo)
00938 {
00939 if (pConfig->PT_phase == PHASE_A)
00940 volt[0] = pTo->voltageA;
00941 else if (pConfig->PT_phase == PHASE_B)
00942 volt[0] = pTo->voltageB;
00943 else if (pConfig->PT_phase == PHASE_C)
00944 volt[0] = pTo->voltageC;
00945 }
00946 else
00947 {
00948 volt[0] = volt[1] = volt[2] = 0.0;
00949 }
00950
00951 V2[0] = volt[0] / ((double) pConfig->PT_ratio);
00952
00953 if ((double) pConfig->CT_ratio != 0.0)
00954 {
00955
00956 complex tmp_mat2[3][3];
00957 inverse(d_mat,tmp_mat2);
00958
00959 curr[0] = tmp_mat2[0][0]*current_in[0]+tmp_mat2[0][1]*current_in[1]+tmp_mat2[0][2]*current_in[2];
00960 curr[1] = tmp_mat2[1][0]*current_in[0]+tmp_mat2[1][1]*current_in[1]+tmp_mat2[1][2]*current_in[2];
00961 curr[2] = tmp_mat2[2][0]*current_in[0]+tmp_mat2[2][1]*current_in[1]+tmp_mat2[2][2]*current_in[2];
00962
00963 if (pConfig->CT_phase == PHASE_A)
00964 check_voltage[0] = check_voltage[1] = check_voltage[2] = V2[0] - (curr[0] / (double) pConfig->CT_ratio) * complex(pConfig->ldc_R_V[0], pConfig->ldc_X_V[0]);
00965
00966 else if (pConfig->CT_phase == PHASE_B)
00967 check_voltage[0] = check_voltage[1] = check_voltage[2] = V2[0] - (curr[1] / (double) pConfig->CT_ratio) * complex(pConfig->ldc_R_V[1], pConfig->ldc_X_V[1]);
00968
00969 else if (pConfig->CT_phase == PHASE_C)
00970 check_voltage[0] = check_voltage[1] = check_voltage[2] = V2[0] - (curr[2] / (double) pConfig->CT_ratio) * complex(pConfig->ldc_R_V[2], pConfig->ldc_X_V[2]);
00971
00972 }
00973 else
00974 {
00975 check_voltage[0] = check_voltage[1] = check_voltage[2] = V2[0];
00976 }
00977 }
00978 }
00979 break;
00980 case 2:
00981 {
00982 if (pConfig->control_level == pConfig->INDIVIDUAL)
00983 {
00984 if (pTo)
00985 {
00986 check_voltage[0] = pTo->voltageA;
00987 check_voltage[1] = pTo->voltageB;
00988 check_voltage[2] = pTo->voltageC;
00989 }
00990 else
00991 {
00992 check_voltage[0] = check_voltage[1] = check_voltage[2] = 0.0;
00993 }
00994 }
00995 else if (pConfig->control_level == pConfig->BANK)
00996 {
00997 if (pTo)
00998 {
00999 if (pConfig->PT_phase == PHASE_A)
01000 check_voltage[0] = check_voltage[1] = check_voltage[2] = pTo->voltageA;
01001 else if (pConfig->PT_phase == PHASE_B)
01002 check_voltage[0] = check_voltage[1] = check_voltage[2] = pTo->voltageB;
01003 else if (pConfig->PT_phase == PHASE_C)
01004 check_voltage[0] = check_voltage[1] = check_voltage[2] = pTo->voltageC;
01005 }
01006 else
01007 {
01008 check_voltage[0] = check_voltage[1] = check_voltage[2] = 0.0;
01009 }
01010 }
01011 }
01012 break;
01013 case 3:
01014 {
01015 node *RNode = OBJECTDATA(RemoteNode,node);
01016 if (pConfig->control_level == pConfig->INDIVIDUAL)
01017 {
01018 for (int i = 0; i < 3; i++)
01019 {
01020 check_voltage[i] = RNode->voltage[i];
01021 }
01022 }
01023 else if (pConfig->control_level == pConfig->BANK)
01024 {
01025 if (pConfig->PT_phase == PHASE_A)
01026 check_voltage[0] = check_voltage[1] = check_voltage[2] = RNode->voltage[0];
01027 else if (pConfig->PT_phase == PHASE_B)
01028 check_voltage[0] = check_voltage[1] = check_voltage[2] = RNode->voltage[1];
01029 else if (pConfig->PT_phase == PHASE_C)
01030 check_voltage[0] = check_voltage[1] = check_voltage[2] = RNode->voltage[2];
01031
01032 }
01033 }
01034 break;
01035 default:
01036 break;
01037
01038 }
01039 }
01040
01041