00001
00010 #include <stdlib.h>
00011 #include <stdio.h>
00012 #include <errno.h>
00013 #include <math.h>
00014 #include <iostream>
00015 using namespace std;
00016
00017 #include "line.h"
00018
00019 CLASS* overhead_line::oclass = NULL;
00020 CLASS* overhead_line::pclass = NULL;
00021
00022 overhead_line::overhead_line(MODULE *mod) : line(mod)
00023 {
00024 if(oclass == NULL)
00025 {
00026 pclass = line::oclass;
00027
00028 oclass = gl_register_class(mod,"overhead_line",sizeof(overhead_line),PC_PRETOPDOWN|PC_BOTTOMUP|PC_POSTTOPDOWN|PC_UNSAFE_OVERRIDE_OMIT|PC_AUTOLOCK);
00029 if (oclass==NULL)
00030 throw "unable to register class overhead_line";
00031 else
00032 oclass->trl = TRL_PROVEN;
00033
00034 if(gl_publish_variable(oclass,
00035 PT_INHERIT, "line",
00036 NULL) < 1) GL_THROW("unable to publish overhead_line properties in %s",__FILE__);
00037
00038 if (gl_publish_function(oclass, "create_fault", (FUNCTIONADDR)create_fault_ohline)==NULL)
00039 GL_THROW("Unable to publish fault creation function");
00040 if (gl_publish_function(oclass, "fix_fault", (FUNCTIONADDR)fix_fault_ohline)==NULL)
00041 GL_THROW("Unable to publish fault restoration function");
00042
00043
00044 if (gl_publish_function(oclass, "interupdate_pwr_object", (FUNCTIONADDR)interupdate_link)==NULL)
00045 GL_THROW("Unable to publish overhead line deltamode function");
00046 if (gl_publish_function(oclass, "recalc_distribution_line", (FUNCTIONADDR)recalc_overhead_line)==NULL)
00047 GL_THROW("Unable to publish overhead line recalc function");
00048
00049
00050 if (gl_publish_function(oclass, "update_power_pwr_object", (FUNCTIONADDR)updatepowercalc_link)==NULL)
00051 GL_THROW("Unable to publish overhead line external power calculation function");
00052 if (gl_publish_function(oclass, "check_limits_pwr_object", (FUNCTIONADDR)calculate_overlimit_link)==NULL)
00053 GL_THROW("Unable to publish overhead line external power limit calculation function");
00054 }
00055 }
00056
00057 int overhead_line::create(void)
00058 {
00059 int result = line::create();
00060
00061 return result;
00062 }
00063
00064 int overhead_line::init(OBJECT *parent)
00065 {
00066 double *temp_rating_value = NULL;
00067 double temp_rating_continuous = 10000.0;
00068 double temp_rating_emergency = 20000.0;
00069 char index;
00070 OBJECT *temp_obj;
00071 line::init(parent);
00072
00073 if (!configuration)
00074 throw "no overhead line configuration specified.";
00075
00076
00077
00078
00079
00080 if (!gl_object_isa(configuration, "line_configuration"))
00081 throw "invalid line configuration for overhead line";
00082
00083
00084
00085
00086
00087
00088 line_configuration *config = OBJECTDATA(configuration, line_configuration);
00089
00090 test_phases(config,'A');
00091 test_phases(config,'B');
00092 test_phases(config,'C');
00093 test_phases(config,'N');
00094
00095 if ((!config->line_spacing || !gl_object_isa(config->line_spacing, "line_spacing")) && config->impedance11 == 0.0 && config->impedance22 == 0.0 && config->impedance33 == 0.0)
00096 throw "invalid or missing line spacing on overhead line";
00097
00098
00099
00100
00101
00102 recalc();
00103
00104
00105 if (config->phaseA_conductor != NULL || config->phaseB_conductor != NULL || config->phaseC_conductor != NULL) {
00106 for (index=0; index<3; index++)
00107 {
00108 if (index==0)
00109 {
00110 temp_obj = config->phaseA_conductor;
00111 }
00112 else if (index==1)
00113 {
00114 temp_obj = config->phaseB_conductor;
00115 }
00116 else
00117 {
00118 temp_obj = config->phaseC_conductor;
00119 }
00120
00121
00122 if (temp_obj != NULL)
00123 {
00124
00125 temp_rating_value = get_double(temp_obj,"rating.summer.continuous");
00126
00127
00128 if (temp_rating_value != NULL)
00129 {
00130
00131 if (temp_rating_continuous > *temp_rating_value)
00132 {
00133 temp_rating_continuous = *temp_rating_value;
00134 }
00135 }
00136
00137
00138 temp_rating_value = get_double(temp_obj,"rating.winter.continuous");
00139
00140
00141 if (temp_rating_value != NULL)
00142 {
00143
00144 if (temp_rating_continuous > *temp_rating_value)
00145 {
00146 temp_rating_continuous = *temp_rating_value;
00147 }
00148 }
00149
00150
00151 temp_rating_value = get_double(temp_obj,"rating.summer.emergency");
00152
00153
00154 if (temp_rating_value != NULL)
00155 {
00156
00157 if (temp_rating_emergency > *temp_rating_value)
00158 {
00159 temp_rating_emergency = *temp_rating_value;
00160 }
00161 }
00162
00163
00164 temp_rating_value = get_double(temp_obj,"rating.winter.emergency");
00165
00166
00167 if (temp_rating_value != NULL)
00168 {
00169
00170 if (temp_rating_emergency > *temp_rating_value)
00171 {
00172 temp_rating_emergency = *temp_rating_value;
00173 }
00174 }
00175
00176
00177 link_rating[0][index] = temp_rating_continuous;
00178 link_rating[1][index] = temp_rating_emergency;
00179 }
00180 }
00181 }
00182 else {
00183 temp_obj = configuration;
00184
00185 if (temp_obj != NULL)
00186 {
00187
00188 temp_rating_value = get_double(temp_obj,"rating.summer.continuous");
00189
00190
00191 if (temp_rating_value != NULL)
00192 {
00193
00194 if (temp_rating_continuous > *temp_rating_value)
00195 {
00196 temp_rating_continuous = *temp_rating_value;
00197 }
00198 }
00199
00200
00201 temp_rating_value = get_double(temp_obj,"rating.winter.continuous");
00202
00203
00204 if (temp_rating_value != NULL)
00205 {
00206
00207 if (temp_rating_continuous > *temp_rating_value)
00208 {
00209 temp_rating_continuous = *temp_rating_value;
00210 }
00211 }
00212
00213
00214 temp_rating_value = get_double(temp_obj,"rating.summer.emergency");
00215
00216
00217 if (temp_rating_value != NULL)
00218 {
00219
00220 if (temp_rating_emergency > *temp_rating_value)
00221 {
00222 temp_rating_emergency = *temp_rating_value;
00223 }
00224 }
00225
00226
00227 temp_rating_value = get_double(temp_obj,"rating.winter.emergency");
00228
00229
00230 if (temp_rating_value != NULL)
00231 {
00232
00233 if (temp_rating_emergency > *temp_rating_value)
00234 {
00235 temp_rating_emergency = *temp_rating_value;
00236 }
00237 }
00238
00239
00240 link_rating[0][0] = link_rating[0][1] = link_rating[0][2] = temp_rating_continuous;
00241 link_rating[1][0] = link_rating[1][1] = link_rating[1][2] = temp_rating_emergency;
00242 }
00243 }
00244 return 1;
00245 }
00246
00247 void overhead_line::recalc(void)
00248 {
00249 line_configuration *config = OBJECTDATA(configuration, line_configuration);
00250 complex Zabc_mat[3][3], Yabc_mat[3][3];
00251 OBJECT *obj = OBJECTHDR(this);
00252
00253
00254 for (int i = 0; i < 3; i++)
00255 {
00256 for (int j = 0; j < 3; j++)
00257 {
00258 Zabc_mat[i][j] = 0.0;
00259 Yabc_mat[i][j] = 0.0;
00260 }
00261 }
00262
00263
00264 for (int i = 0; i < 3; i++) {
00265 for (int j = 0; j < 3; j++) {
00266 a_mat[i][j] = 0.0;
00267 d_mat[i][j] = 0.0;
00268 A_mat[i][j] = 0.0;
00269 c_mat[i][j] = 0.0;
00270 B_mat[i][j] = b_mat[i][j];
00271 }
00272 }
00273
00274 if (config->impedance11 != 0 || config->impedance22 != 0 || config->impedance33 != 0)
00275 {
00276
00277 load_matrix_based_configuration(Zabc_mat, Yabc_mat);
00278
00279
00280 if (has_phase(PHASE_A))
00281 {
00282 a_mat[0][0] = 1.0;
00283 d_mat[0][0] = 1.0;
00284 A_mat[0][0] = 1.0;
00285 }
00286
00287 if (has_phase(PHASE_B))
00288 {
00289 a_mat[1][1] = 1.0;
00290 d_mat[1][1] = 1.0;
00291 A_mat[1][1] = 1.0;
00292 }
00293
00294 if (has_phase(PHASE_C))
00295 {
00296 a_mat[2][2] = 1.0;
00297 d_mat[2][2] = 1.0;
00298 A_mat[2][2] = 1.0;
00299 }
00300 }
00301 else
00302 {
00303
00304 double dab, dbc, dac, dan, dbn, dcn;
00305 double gmr_a, gmr_b, gmr_c, gmr_n, res_a, res_b, res_c, res_n;
00306 complex z_aa, z_ab, z_ac, z_an, z_bb, z_bc, z_bn, z_cc, z_cn, z_nn;
00307 double p_aa, p_ab, p_ac, p_an, p_bb, p_bc, p_bn, p_cc, p_cn, p_nn;
00308 double daap, dabp, dacp, danp, dbbp, dbcp, dbnp, dccp, dcnp, dnnp, diamA, diamB, diamC, diamN;
00309 complex P_mat[3][3];
00310 bool valid_capacitance = false;
00311 double freq_coeff_real, freq_coeff_imag, freq_additive_term;
00312 line_spacing *spacing_val = NULL;
00313 double miles = length / 5280.0;
00314 double cap_coeff;
00315 complex cap_freq_mult;
00316
00317
00318
00319 if (enable_frequency_dependence == true)
00320 {
00321 freq_coeff_real = 0.00158836*current_frequency;
00322 freq_coeff_imag = 0.00202237*current_frequency;
00323 freq_additive_term = log(EARTH_RESISTIVITY/current_frequency)/2.0 + 7.6786;
00324 }
00325 else
00326 {
00327 freq_coeff_real = 0.00158836*nominal_frequency;
00328 freq_coeff_imag = 0.00202237*nominal_frequency;
00329 freq_additive_term = log(EARTH_RESISTIVITY/nominal_frequency)/2.0 + 7.6786;
00330 }
00331
00332 #define GMR(ph) (has_phase(PHASE_##ph) && config->phase##ph##_conductor ? \
00333 OBJECTDATA(config->phase##ph##_conductor, overhead_line_conductor)->geometric_mean_radius : 0.0)
00334 #define RES(ph) (has_phase(PHASE_##ph) && config->phase##ph##_conductor ? \
00335 OBJECTDATA(config->phase##ph##_conductor, overhead_line_conductor)->resistance : 0.0)
00336 #define DIST(ph1, ph2) (has_phase(PHASE_##ph1) && has_phase(PHASE_##ph2) && config->line_spacing ? \
00337 OBJECTDATA(config->line_spacing, line_spacing)->distance_##ph1##to##ph2 : 0.0)
00338 #define DIAM(ph) (has_phase(PHASE_##ph) && config->phase##ph##_conductor ? \
00339 OBJECTDATA(config->phase##ph##_conductor, overhead_line_conductor)->cable_diameter : 0.0)
00340
00341 gmr_a = GMR(A);
00342 gmr_b = GMR(B);
00343 gmr_c = GMR(C);
00344 gmr_n = GMR(N);
00345
00346
00347
00348
00349 res_a = RES(A);
00350 res_b = RES(B);
00351 res_c = RES(C);
00352 res_n = RES(N);
00353 dab = DIST(A, B);
00354 dbc = DIST(B, C);
00355 dac = DIST(A, C);
00356 dan = DIST(A, N);
00357 dbn = DIST(B, N);
00358 dcn = DIST(C, N);
00359
00360 diamA = DIAM(A);
00361 diamB = DIAM(B);
00362 diamC = DIAM(C);
00363 diamN = DIAM(N);
00364
00365 #undef GMR
00366 #undef RES
00367 #undef DIST
00368 #undef DIAM
00369
00370 if (use_line_cap == true)
00371 {
00372
00373 cap_coeff = 1.0/(PERMITIVITTY_AIR*2.0*PI);
00374
00375
00376 if (enable_frequency_dependence == true)
00377 {
00378 cap_freq_mult = complex(0,(2.0*PI*current_frequency*0.000001*miles));
00379 }
00380 else
00381 {
00382 cap_freq_mult = complex(0,(2.0*PI*nominal_frequency*0.000001*miles));
00383 }
00384
00385
00386 spacing_val = OBJECTDATA(config->line_spacing, line_spacing);
00387
00388
00389 if (spacing_val == NULL)
00390 {
00391 GL_THROW("Line spacing not found, capacitance calculations failed!");
00392
00393
00394
00395
00396
00397 }
00398
00399
00400 valid_capacitance = true;
00401 }
00402
00403
00404 if (has_phase(PHASE_A)) {
00405 if (gmr_a > 0.0 && res_a > 0.0)
00406 z_aa = complex(res_a + freq_coeff_real, freq_coeff_imag * (log(1.0 / gmr_a) + freq_additive_term));
00407 else
00408 z_aa = 0.0;
00409 if (has_phase(PHASE_B) && dab > 0.0)
00410 z_ab = complex(freq_coeff_real, freq_coeff_imag * (log(1.0 / dab) + freq_additive_term));
00411 else
00412 z_ab = 0.0;
00413 if (has_phase(PHASE_C) && dac > 0.0)
00414 z_ac = complex(freq_coeff_real, freq_coeff_imag * (log(1.0 / dac) + freq_additive_term));
00415 else
00416 z_ac = 0.0;
00417 if (has_phase(PHASE_N) && dan > 0.0)
00418 z_an = complex(freq_coeff_real, freq_coeff_imag * (log(1.0 / dan) + freq_additive_term));
00419 else
00420 z_an = 0.0;
00421
00422
00423 if (use_line_cap == true)
00424 {
00425 if ((diamA > 0.0) && (spacing_val->distance_AtoE > 0.0))
00426 {
00427
00428 daap = 2.0 * spacing_val->distance_AtoE;
00429 p_aa = cap_coeff * log(daap/diamA*24.0);
00430
00431
00432 if (has_phase(PHASE_B))
00433 {
00434
00435 dabp = calc_image_dist(spacing_val->distance_AtoE,spacing_val->distance_BtoE,spacing_val->distance_AtoB);
00436
00437
00438 if (spacing_val->distance_AtoB != 0)
00439 {
00440 p_ab = cap_coeff * log(dabp/(spacing_val->distance_AtoB));
00441 }
00442 else
00443 {
00444 p_ab = 0.0;
00445 }
00446 }
00447 else
00448 {
00449 p_ab = 0.0;
00450 }
00451
00452 if (has_phase(PHASE_C))
00453 {
00454
00455 dacp = calc_image_dist(spacing_val->distance_AtoE,spacing_val->distance_CtoE,spacing_val->distance_AtoC);
00456
00457
00458 if (spacing_val->distance_AtoC != 0)
00459 {
00460 p_ac = cap_coeff * log(dacp/(spacing_val->distance_AtoC));
00461 }
00462 else
00463 {
00464 p_ac = 0.0;
00465 }
00466 }
00467 else
00468 {
00469 p_ac = 0.0;
00470 }
00471
00472 if (has_phase(PHASE_N))
00473 {
00474
00475 danp = calc_image_dist(spacing_val->distance_AtoE,spacing_val->distance_NtoE,spacing_val->distance_AtoN);
00476
00477
00478 if (spacing_val->distance_AtoN != 0)
00479 {
00480 p_an = cap_coeff * log(danp/(spacing_val->distance_AtoN));
00481 }
00482 else
00483 {
00484 p_an = 0.0;
00485 }
00486 }
00487 else
00488 {
00489 p_an = 0.0;
00490 }
00491 }
00492 else
00493 {
00494 valid_capacitance = false;
00495
00496 gl_warning("Shunt capacitance of overhead line:%s not calculated - invalid values",OBJECTHDR(this)->name);
00497
00498
00499
00500
00501
00502
00503 p_aa = p_ab = p_ac = p_an = 0.0;
00504 }
00505 }
00506
00507 } else {
00508 p_aa = p_ab = p_ac = p_an = 0.0;
00509 z_aa = z_ab = z_ac = z_an = 0.0;
00510 }
00511
00512 if (has_phase(PHASE_B)) {
00513 if (gmr_b > 0.0 && res_b > 0.0)
00514 z_bb = complex(res_b + freq_coeff_real, freq_coeff_imag * (log(1.0 / gmr_b) + freq_additive_term));
00515 else
00516 z_bb = 0.0;
00517 if (has_phase(PHASE_C) && dbc > 0.0)
00518 z_bc = complex(freq_coeff_real, freq_coeff_imag * (log(1.0 / dbc) + freq_additive_term));
00519 else
00520 z_bc = 0.0;
00521 if (has_phase(PHASE_N) && dbn > 0.0)
00522 z_bn = complex(freq_coeff_real, freq_coeff_imag * (log(1.0 / dbn) + freq_additive_term));
00523 else
00524 z_bn = 0.0;
00525
00526
00527 if (use_line_cap == true)
00528 {
00529 if ((diamB > 0.0) && (spacing_val->distance_BtoE > 0.0))
00530 {
00531
00532 dbbp = 2.0 * spacing_val->distance_BtoE;
00533 p_bb = cap_coeff * log(dbbp/diamB*24.0);
00534
00535
00536 if (has_phase(PHASE_C))
00537 {
00538
00539 dbcp = calc_image_dist(spacing_val->distance_BtoE,spacing_val->distance_CtoE,spacing_val->distance_BtoC);
00540
00541
00542 if (spacing_val->distance_BtoC != 0)
00543 {
00544 p_bc = cap_coeff * log(dbcp/(spacing_val->distance_BtoC));
00545 }
00546 else
00547 {
00548 p_bc = 0.0;
00549 }
00550 }
00551 else
00552 {
00553 p_bc = 0.0;
00554 }
00555
00556 if (has_phase(PHASE_N))
00557 {
00558
00559 dbnp = calc_image_dist(spacing_val->distance_BtoE,spacing_val->distance_NtoE,spacing_val->distance_BtoN);
00560
00561
00562 if (spacing_val->distance_BtoN != 0)
00563 {
00564 p_bn = cap_coeff * log(dbnp/(spacing_val->distance_BtoN));
00565 }
00566 else
00567 {
00568 p_bn = 0.0;
00569 }
00570
00571 }
00572 else
00573 {
00574 p_bn = 0.0;
00575 }
00576 }
00577 else
00578 {
00579 valid_capacitance = false;
00580
00581 gl_warning("Shunt capacitance of overhead line:%s not calculated - invalid values",OBJECTHDR(this)->name);
00582
00583
00584 p_bb = p_bc = p_bn = 0.0;
00585 }
00586 }
00587
00588 } else {
00589 p_bb = p_bc = p_bn = 0.0;
00590 z_bb = z_bc = z_bn = 0.0;
00591 }
00592
00593 if (has_phase(PHASE_C)) {
00594 if (gmr_c > 0.0 && res_c > 0.0)
00595 z_cc = complex(res_c + freq_coeff_real, freq_coeff_imag * (log(1.0 / gmr_c) + freq_additive_term));
00596 else
00597 z_cc = 0.0;
00598 if (has_phase(PHASE_N) && dcn > 0.0)
00599 z_cn = complex(freq_coeff_real, freq_coeff_imag * (log(1.0 / dcn) + freq_additive_term));
00600 else
00601 z_cn = 0.0;
00602
00603
00604 if (use_line_cap == true)
00605 {
00606 if ((diamC > 0.0) && (spacing_val->distance_CtoE > 0.0))
00607 {
00608
00609 dccp = 2.0 * spacing_val->distance_CtoE;
00610 p_cc = cap_coeff * log(dccp/diamC*24.0);
00611
00612
00613 if (has_phase(PHASE_N))
00614 {
00615
00616 dcnp = calc_image_dist(spacing_val->distance_CtoE,spacing_val->distance_NtoE,spacing_val->distance_CtoN);
00617
00618
00619 if (spacing_val->distance_CtoN != 0)
00620 {
00621 p_cn = cap_coeff * log(dcnp/(spacing_val->distance_CtoN));
00622 }
00623 else
00624 {
00625 p_cn = 0.0;
00626 }
00627 }
00628 else
00629 {
00630 p_cn = 0.0;
00631 }
00632 }
00633 else
00634 {
00635 valid_capacitance = false;
00636
00637 gl_warning("Shunt capacitance of overhead line:%s not calculated - invalid values",OBJECTHDR(this)->name);
00638
00639
00640 p_cc = p_cn = 0.0;
00641 }
00642 }
00643
00644 } else {
00645 p_cc = p_cn = 0.0;
00646 z_cc = z_cn = 0.0;
00647 }
00648
00649 complex z_nn_inv = 0;
00650 if (has_phase(PHASE_N) && gmr_n > 0.0 && res_n > 0.0){
00651 z_nn = complex(res_n + freq_coeff_real, freq_coeff_imag * (log(1.0 / gmr_n) + freq_additive_term));
00652 z_nn_inv = z_nn^(-1.0);
00653
00654
00655 if (use_line_cap == true)
00656 {
00657 if ((diamN > 0.0) && (spacing_val->distance_NtoE > 0.0))
00658 {
00659
00660 dnnp = 2.0 * spacing_val->distance_NtoE;
00661 p_nn = cap_coeff * log(dnnp/diamN*24.0);
00662 }
00663 else
00664 {
00665 valid_capacitance = false;
00666
00667 gl_warning("Shunt capacitance of overhead line:%s not calculated - invalid values",OBJECTHDR(this)->name);
00668
00669
00670 p_nn = 0.0;
00671 }
00672 }
00673
00674 }
00675 else
00676 {
00677 p_nn = 0.0;
00678 z_nn = 0.0;
00679 }
00680
00681
00682 Zabc_mat[0][0] = (z_aa - z_an * z_an * z_nn_inv) * miles;
00683 Zabc_mat[0][1] = (z_ab - z_an * z_bn * z_nn_inv) * miles;
00684 Zabc_mat[0][2] = (z_ac - z_an * z_cn * z_nn_inv) * miles;
00685 Zabc_mat[1][0] = (z_ab - z_bn * z_an * z_nn_inv) * miles;
00686 Zabc_mat[1][1] = (z_bb - z_bn * z_bn * z_nn_inv) * miles;
00687 Zabc_mat[1][2] = (z_bc - z_bn * z_cn * z_nn_inv) * miles;
00688 Zabc_mat[2][0] = (z_ac - z_cn * z_an * z_nn_inv) * miles;
00689 Zabc_mat[2][1] = (z_bc - z_cn * z_bn * z_nn_inv) * miles;
00690 Zabc_mat[2][2] = (z_cc - z_cn * z_cn * z_nn_inv) * miles;
00691
00692
00693
00694
00695 if (valid_capacitance == true && use_line_cap == true)
00696 {
00697 if (p_nn != 0.0)
00698 {
00699
00700 P_mat[0][0] = p_aa - p_an*p_an/p_nn;
00701 P_mat[0][1] = P_mat[1][0] = p_ab - p_an*p_bn/p_nn;
00702 P_mat[0][2] = P_mat[2][0] = p_ac - p_an*p_cn/p_nn;
00703
00704 P_mat[1][1] = p_bb - p_bn*p_bn/p_nn;
00705 P_mat[1][2] = P_mat[2][1] = p_bc - p_bn*p_cn/p_nn;
00706
00707 P_mat[2][2] = p_cc - p_cn*p_cn/p_nn;
00708 }
00709 else
00710 {
00711
00712 P_mat[0][0] = p_aa;
00713 P_mat[0][1] = P_mat[1][0] = p_ab;
00714 P_mat[0][2] = P_mat[2][0] = p_ac;
00715
00716 P_mat[1][1] = p_bb;
00717 P_mat[1][2] = P_mat[2][1] = p_bc;
00718
00719 P_mat[2][2] = p_cc;
00720 }
00721
00722
00723 if (has_phase(PHASE_A) && !has_phase(PHASE_B) && !has_phase(PHASE_C))
00724 Yabc_mat[0][0] = complex(1.0) / P_mat[0][0] * cap_freq_mult;
00725 else if (!has_phase(PHASE_A) && has_phase(PHASE_B) && !has_phase(PHASE_C))
00726 Yabc_mat[1][1] = complex(1.0) / P_mat[1][1] * cap_freq_mult;
00727 else if (!has_phase(PHASE_A) && !has_phase(PHASE_B) && has_phase(PHASE_C))
00728 Yabc_mat[2][2] = complex(1.0) / P_mat[2][2] * cap_freq_mult;
00729 else if (has_phase(PHASE_A) && !has_phase(PHASE_B) && has_phase(PHASE_C))
00730 {
00731 complex detvalue = P_mat[0][0]*P_mat[2][2] - P_mat[0][2]*P_mat[2][0];
00732
00733 Yabc_mat[0][0] = P_mat[2][2] / detvalue * cap_freq_mult;
00734 Yabc_mat[0][2] = P_mat[0][2] * -1.0 / detvalue * cap_freq_mult;
00735 Yabc_mat[2][0] = P_mat[2][0] * -1.0 / detvalue * cap_freq_mult;
00736 Yabc_mat[2][2] = P_mat[0][0] / detvalue * cap_freq_mult;
00737 }
00738 else if (has_phase(PHASE_A) && has_phase(PHASE_B) && !has_phase(PHASE_C))
00739 {
00740 complex detvalue = P_mat[0][0]*P_mat[1][1] - P_mat[0][1]*P_mat[1][0];
00741
00742 Yabc_mat[0][0] = P_mat[1][1] / detvalue * cap_freq_mult;
00743 Yabc_mat[0][1] = P_mat[0][1] * -1.0 / detvalue * cap_freq_mult;
00744 Yabc_mat[1][0] = P_mat[1][0] * -1.0 / detvalue * cap_freq_mult;
00745 Yabc_mat[1][1] = P_mat[0][0] / detvalue * cap_freq_mult;
00746 }
00747 else if (!has_phase(PHASE_A) && has_phase(PHASE_B) && has_phase(PHASE_C))
00748 {
00749 complex detvalue = P_mat[1][1]*P_mat[2][2] - P_mat[1][2]*P_mat[2][1];
00750
00751 Yabc_mat[1][1] = P_mat[2][2] / detvalue * cap_freq_mult;
00752 Yabc_mat[1][2] = P_mat[1][2] * -1.0 / detvalue * cap_freq_mult;
00753 Yabc_mat[2][1] = P_mat[2][1] * -1.0 / detvalue * cap_freq_mult;
00754 Yabc_mat[2][2] = P_mat[1][1] / detvalue * cap_freq_mult;
00755
00756
00757 if (has_phase(PHASE_A))
00758 {
00759 a_mat[0][0] = 1.0;
00760 d_mat[0][0] = 1.0;
00761 A_mat[0][0] = 1.0;
00762 }
00763
00764 if (has_phase(PHASE_B))
00765 {
00766 a_mat[1][1] = 1.0;
00767 d_mat[1][1] = 1.0;
00768 A_mat[1][1] = 1.0;
00769 }
00770
00771 if (has_phase(PHASE_C))
00772 {
00773 a_mat[2][2] = 1.0;
00774 d_mat[2][2] = 1.0;
00775 A_mat[2][2] = 1.0;
00776 }
00777 }
00778 else if ((has_phase(PHASE_A) && has_phase(PHASE_B) && has_phase(PHASE_C)) || (has_phase(PHASE_D)))
00779 {
00780 complex detvalue = P_mat[0][0]*P_mat[1][1]*P_mat[2][2] - P_mat[0][0]*P_mat[1][2]*P_mat[2][1] - P_mat[0][1]*P_mat[1][0]*P_mat[2][2] + P_mat[0][1]*P_mat[2][0]*P_mat[1][2] + P_mat[1][0]*P_mat[0][2]*P_mat[2][1] - P_mat[0][2]*P_mat[1][1]*P_mat[2][0];
00781
00782
00783 Yabc_mat[0][0] = (P_mat[1][1]*P_mat[2][2] - P_mat[1][2]*P_mat[2][1]) / detvalue * cap_freq_mult;
00784 Yabc_mat[0][1] = (P_mat[0][2]*P_mat[2][1] - P_mat[0][1]*P_mat[2][2]) / detvalue * cap_freq_mult;
00785 Yabc_mat[0][2] = (P_mat[0][1]*P_mat[1][2] - P_mat[0][2]*P_mat[1][1]) / detvalue * cap_freq_mult;
00786 Yabc_mat[1][0] = (P_mat[2][0]*P_mat[1][2] - P_mat[1][0]*P_mat[2][2]) / detvalue * cap_freq_mult;
00787 Yabc_mat[1][1] = (P_mat[0][0]*P_mat[2][2] - P_mat[0][2]*P_mat[2][0]) / detvalue * cap_freq_mult;
00788 Yabc_mat[1][2] = (P_mat[1][0]*P_mat[0][2] - P_mat[0][0]*P_mat[1][2]) / detvalue * cap_freq_mult;
00789 Yabc_mat[2][0] = (P_mat[1][0]*P_mat[2][1] - P_mat[1][1]*P_mat[2][0]) / detvalue * cap_freq_mult;
00790 Yabc_mat[2][1] = (P_mat[0][1]*P_mat[2][0] - P_mat[0][0]*P_mat[2][1]) / detvalue * cap_freq_mult;
00791 Yabc_mat[2][2] = (P_mat[0][0]*P_mat[1][1] - P_mat[0][1]*P_mat[1][0]) / detvalue * cap_freq_mult;
00792 }
00793
00794
00795 if (has_phase(PHASE_A))
00796 {
00797 a_mat[0][0] = 1.0;
00798 d_mat[0][0] = 1.0;
00799 A_mat[0][0] = 1.0;
00800 }
00801
00802 if (has_phase(PHASE_B))
00803 {
00804 a_mat[1][1] = 1.0;
00805 d_mat[1][1] = 1.0;
00806 A_mat[1][1] = 1.0;
00807 }
00808
00809 if (has_phase(PHASE_C))
00810 {
00811 a_mat[2][2] = 1.0;
00812 d_mat[2][2] = 1.0;
00813 A_mat[2][2] = 1.0;
00814 }
00815 }
00816 }
00817
00818
00819 recalc_line_matricies(Zabc_mat, Yabc_mat);
00820
00821
00822 bool neg_res = false;
00823 for (int n = 0; n < 3; n++){
00824 for (int m = 0; m < 3; m++){
00825 if(b_mat[n][m].Re() < 0.0){
00826 neg_res = true;
00827 }
00828 }
00829 }
00830
00831 if(neg_res == true){
00832 gl_warning("INIT: overhead_line:%s has a negative resistance in it's impedance matrix. This will result in unusual behavior. Please check the line's geometry and cable parameters.", obj->name);
00833
00834
00835
00836
00837
00838 }
00839
00840 #ifdef _TESTING
00841 if (show_matrix_values)
00842 {
00843 OBJECT *obj = GETOBJECT(this);
00844
00845 gl_testmsg("overhead_line: %s a matrix",obj->name);
00846 print_matrix(a_mat);
00847
00848 gl_testmsg("overhead_line: %s A matrix",obj->name);
00849 print_matrix(A_mat);
00850
00851 gl_testmsg("overhead_line: %s b matrix",obj->name);
00852 print_matrix(b_mat);
00853
00854 gl_testmsg("overhead_line: %s B matrix",obj->name);
00855 print_matrix(B_mat);
00856
00857 gl_testmsg("overhead_line: %s c matrix",obj->name);
00858 print_matrix(c_mat);
00859
00860 gl_testmsg("overhead_line: %s d matrix",obj->name);
00861 print_matrix(d_mat);
00862 }
00863 #endif
00864 }
00865
00866 int overhead_line::isa(char *classname)
00867 {
00868 return strcmp(classname,"overhead_line")==0 || line::isa(classname);
00869 }
00870
00878 void overhead_line::test_phases(line_configuration *config, const char ph)
00879 {
00880 bool condCheck, condNotPres;
00881 OBJECT *obj = GETOBJECT(this);
00882
00883 if (ph=='A')
00884 {
00885 if (config->impedance11 == 0.0)
00886 {
00887 condCheck = (config->phaseA_conductor && !gl_object_isa(config->phaseA_conductor, "overhead_line_conductor","powerflow"));
00888 condNotPres = ((!config->phaseA_conductor) && has_phase(PHASE_A));
00889 }
00890 else
00891 {
00892 condCheck = false;
00893 condNotPres = false;
00894 }
00895 }
00896 else if (ph=='B')
00897 {
00898 if (config->impedance22 == 0.0)
00899 {
00900 condCheck = (config->phaseB_conductor && !gl_object_isa(config->phaseB_conductor, "overhead_line_conductor","powerflow"));
00901 condNotPres = ((!config->phaseB_conductor) && has_phase(PHASE_B));
00902 }
00903 else
00904 {
00905 condCheck = false;
00906 condNotPres = false;
00907 }
00908 }
00909 else if (ph=='C')
00910 {
00911 if (config->impedance33 == 0.0)
00912 {
00913 condCheck = (config->phaseC_conductor && !gl_object_isa(config->phaseC_conductor, "overhead_line_conductor","powerflow"));
00914 condNotPres = ((!config->phaseC_conductor) && has_phase(PHASE_C));
00915 }
00916 else
00917 {
00918 condCheck = false;
00919 condNotPres = false;
00920 }
00921 }
00922 else if (ph=='N')
00923 {
00924 if (config->impedance11 == 0.0 && config->impedance22 == 0.0 && config->impedance33 == 0.0)
00925 {
00926 condCheck = (config->phaseN_conductor && !gl_object_isa(config->phaseN_conductor, "overhead_line_conductor","powerflow"));
00927 condNotPres = ((!config->phaseN_conductor) && has_phase(PHASE_N));
00928 }
00929 else
00930 {
00931 condCheck = false;
00932 condNotPres = false;
00933 }
00934 }
00935
00936
00937 if (condCheck==true)
00938 GL_THROW("invalid conductor for phase %c of overhead line %s",ph,obj->name);
00939
00940
00941 if (condNotPres==true)
00942 GL_THROW("missing conductor for phase %c of overhead line %s",ph,obj->name);
00943
00944
00945
00946
00947 }
00948
00963 double overhead_line::calc_image_dist(double dist1_to_e, double dist2_to_e, double dist1_to_2)
00964 {
00965 double dist1_to_1p, dist2_to_2p, dist1_to_2p;
00966
00967
00968 dist1_to_1p = 2.0 * dist1_to_e;
00969 dist2_to_2p = 2.0 * dist2_to_e;
00970
00971
00972 dist1_to_2p = sqrt(dist1_to_2*dist1_to_2 + dist1_to_1p*dist2_to_2p);
00973
00974
00975 return dist1_to_2p;
00976 }
00977
00979
00981
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003 EXPORT int create_overhead_line(OBJECT **obj, OBJECT *parent)
01004 {
01005 try
01006 {
01007 *obj = gl_create_object(overhead_line::oclass);
01008 if (*obj!=NULL)
01009 {
01010 overhead_line *my = OBJECTDATA(*obj,overhead_line);
01011 gl_set_parent(*obj,parent);
01012 return my->create();
01013 }
01014 else
01015 return 0;
01016 }
01017 CREATE_CATCHALL(overhead_line);
01018 }
01019
01020 EXPORT TIMESTAMP sync_overhead_line(OBJECT *obj, TIMESTAMP t0, PASSCONFIG pass)
01021 {
01022 try {
01023 overhead_line *pObj = OBJECTDATA(obj,overhead_line);
01024 TIMESTAMP t1 = TS_NEVER;
01025 switch (pass) {
01026 case PC_PRETOPDOWN:
01027 return pObj->presync(t0);
01028 case PC_BOTTOMUP:
01029 return pObj->sync(t0);
01030 case PC_POSTTOPDOWN:
01031 t1 = pObj->postsync(t0);
01032 obj->clock = t0;
01033 return t1;
01034 default:
01035 throw "invalid pass request";
01036 }
01037 }
01038 SYNC_CATCHALL(overhead_line);
01039 }
01040
01041 EXPORT int init_overhead_line(OBJECT *obj)
01042 {
01043 try {
01044 overhead_line *my = OBJECTDATA(obj,overhead_line);
01045 return my->init(obj->parent);
01046 }
01047 INIT_CATCHALL(overhead_line);
01048 }
01049
01050 EXPORT int isa_overhead_line(OBJECT *obj, char *classname)
01051 {
01052 return OBJECTDATA(obj,line)->isa(classname);
01053 }
01054
01055 EXPORT int recalc_overhead_line(OBJECT *obj)
01056 {
01057 OBJECTDATA(obj,overhead_line)->recalc();
01058 return 1;
01059 }
01060 EXPORT int create_fault_ohline(OBJECT *thisobj, OBJECT **protect_obj, char *fault_type, int *implemented_fault, TIMESTAMP *repair_time)
01061 {
01062 int retval;
01063
01064
01065 overhead_line *thisline = OBJECTDATA(thisobj,overhead_line);
01066
01067
01068 retval = thisline->link_fault_on(protect_obj, fault_type, implemented_fault, repair_time);
01069
01070 return retval;
01071 }
01072 EXPORT int fix_fault_ohline(OBJECT *thisobj, int *implemented_fault, char *imp_fault_name)
01073 {
01074 int retval;
01075
01076
01077 overhead_line *thisline = OBJECTDATA(thisobj,overhead_line);
01078
01079
01080 retval = thisline->link_fault_off(implemented_fault, imp_fault_name);
01081
01082
01083 *implemented_fault = -1;
01084
01085 return retval;
01086 }