00001
00009
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* underground_line::oclass = NULL;
00020 CLASS* underground_line::pclass = NULL;
00021
00022 underground_line::underground_line(MODULE *mod) : line(mod)
00023 {
00024 if(oclass == NULL)
00025 {
00026 pclass = line::oclass;
00027
00028 oclass = gl_register_class(mod,"underground_line",sizeof(underground_line),PC_PRETOPDOWN|PC_BOTTOMUP|PC_POSTTOPDOWN|PC_UNSAFE_OVERRIDE_OMIT|PC_AUTOLOCK);
00029 if (oclass==NULL)
00030 throw "unable to register class underground_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 properties in %s",__FILE__);
00037 if (gl_publish_function(oclass, "create_fault", (FUNCTIONADDR)create_fault_ugline)==NULL)
00038 GL_THROW("Unable to publish fault creation function");
00039 if (gl_publish_function(oclass, "fix_fault", (FUNCTIONADDR)fix_fault_ugline)==NULL)
00040 GL_THROW("Unable to publish fault restoration function");
00041
00042
00043 if (gl_publish_function(oclass, "interupdate_pwr_object", (FUNCTIONADDR)interupdate_link)==NULL)
00044 GL_THROW("Unable to publish underground line deltamode function");
00045 if (gl_publish_function(oclass, "recalc_distribution_line", (FUNCTIONADDR)recalc_underground_line)==NULL)
00046 GL_THROW("Unable to publish underground line recalc function");
00047
00048
00049 if (gl_publish_function(oclass, "update_power_pwr_object", (FUNCTIONADDR)updatepowercalc_link)==NULL)
00050 GL_THROW("Unable to publish underground line external power calculation function");
00051 if (gl_publish_function(oclass, "check_limits_pwr_object", (FUNCTIONADDR)calculate_overlimit_link)==NULL)
00052 GL_THROW("Unable to publish underground line external power limit calculation function");
00053 }
00054 }
00055
00056 int underground_line::create(void)
00057 {
00058 int result = line::create();
00059 return result;
00060 }
00061
00062
00063 int underground_line::init(OBJECT *parent)
00064 {
00065 double *temp_rating_value = NULL;
00066 double temp_rating_continuous = 10000.0;
00067 double temp_rating_emergency = 20000.0;
00068 char index;
00069 int type_A, type_B, type_C, type_N;
00070 int cond_present, cond_present_CN, cable_types_value;
00071 OBJECT *temp_obj;
00072 OBJECT *obj = OBJECTHDR(this);
00073
00074 int result = line::init(parent);
00075
00076 if (!configuration)
00077 throw "no underground line configuration specified.";
00078
00079
00080
00081
00082
00083 if (!gl_object_isa(configuration, "line_configuration"))
00084 throw "invalid line configuration for underground line";
00085
00086
00087
00088
00089
00090
00091 line_configuration *config = OBJECTDATA(configuration, line_configuration);
00092
00093 type_A = test_phases(config,'A');
00094 type_B = test_phases(config,'B');
00095 type_C = test_phases(config,'C');
00096 type_N = test_phases(config,'N');
00097
00098
00099 cond_present = 0;
00100
00101 if (config->phaseA_conductor != NULL)
00102 cond_present++;
00103
00104 if (config->phaseB_conductor != NULL)
00105 cond_present++;
00106
00107 if (config->phaseC_conductor != NULL)
00108 cond_present++;
00109
00110
00111 cable_types_value = type_A + type_B + type_C;
00112
00113
00114 cond_present_CN = cond_present * 10;
00115
00116
00117 if ((cable_types_value != cond_present) && (cable_types_value != cond_present_CN))
00118 {
00119 GL_THROW("Underground_line:%d %s - Cable types specified in configuration are not consistent!",obj->id,(obj->name ? obj->name : "Unnamed"));
00120
00121
00122
00123
00124 }
00125
00126 if ((!config->line_spacing || !gl_object_isa(config->line_spacing, "line_spacing")) && config->impedance11 == 0.0 && config->impedance22 == 0.0 && config->impedance33 == 0.0)
00127 throw "invalid or missing line spacing on underground line";
00128
00129
00130
00131
00132
00133 recalc();
00134
00135
00136 if (config->phaseA_conductor != NULL || config->phaseB_conductor != NULL || config->phaseC_conductor != NULL) {
00137 for (index=0; index<3; index++)
00138 {
00139 if (index==0)
00140 {
00141 temp_obj = config->phaseA_conductor;
00142 }
00143 else if (index==1)
00144 {
00145 temp_obj = config->phaseB_conductor;
00146 }
00147 else
00148 {
00149 temp_obj = config->phaseC_conductor;
00150 }
00151
00152
00153 if (temp_obj != NULL)
00154 {
00155
00156 temp_rating_value = get_double(temp_obj,"rating.summer.continuous");
00157
00158
00159 if (temp_rating_value != NULL)
00160 {
00161
00162 if (temp_rating_continuous > *temp_rating_value)
00163 {
00164 temp_rating_continuous = *temp_rating_value;
00165 }
00166 }
00167
00168
00169 temp_rating_value = get_double(temp_obj,"rating.winter.continuous");
00170
00171
00172 if (temp_rating_value != NULL)
00173 {
00174
00175 if (temp_rating_continuous > *temp_rating_value)
00176 {
00177 temp_rating_continuous = *temp_rating_value;
00178 }
00179 }
00180
00181
00182 temp_rating_value = get_double(temp_obj,"rating.summer.emergency");
00183
00184
00185 if (temp_rating_value != NULL)
00186 {
00187
00188 if (temp_rating_emergency > *temp_rating_value)
00189 {
00190 temp_rating_emergency = *temp_rating_value;
00191 }
00192 }
00193
00194
00195 temp_rating_value = get_double(temp_obj,"rating.winter.emergency");
00196
00197
00198 if (temp_rating_value != NULL)
00199 {
00200
00201 if (temp_rating_emergency > *temp_rating_value)
00202 {
00203 temp_rating_emergency = *temp_rating_value;
00204 }
00205 }
00206
00207
00208 link_rating[0][index] = temp_rating_continuous;
00209 link_rating[1][index] = temp_rating_emergency;
00210 }
00211 }
00212 }
00213 else {
00214 temp_obj = configuration;
00215
00216 if (temp_obj != NULL)
00217 {
00218
00219 temp_rating_value = get_double(temp_obj,"rating.summer.continuous");
00220
00221
00222 if (temp_rating_value != NULL)
00223 {
00224
00225 if (temp_rating_continuous > *temp_rating_value)
00226 {
00227 temp_rating_continuous = *temp_rating_value;
00228 }
00229 }
00230
00231
00232 temp_rating_value = get_double(temp_obj,"rating.winter.continuous");
00233
00234
00235 if (temp_rating_value != NULL)
00236 {
00237
00238 if (temp_rating_continuous > *temp_rating_value)
00239 {
00240 temp_rating_continuous = *temp_rating_value;
00241 }
00242 }
00243
00244
00245 temp_rating_value = get_double(temp_obj,"rating.summer.emergency");
00246
00247
00248 if (temp_rating_value != NULL)
00249 {
00250
00251 if (temp_rating_emergency > *temp_rating_value)
00252 {
00253 temp_rating_emergency = *temp_rating_value;
00254 }
00255 }
00256
00257
00258 temp_rating_value = get_double(temp_obj,"rating.winter.emergency");
00259
00260
00261 if (temp_rating_value != NULL)
00262 {
00263
00264 if (temp_rating_emergency > *temp_rating_value)
00265 {
00266 temp_rating_emergency = *temp_rating_value;
00267 }
00268 }
00269
00270
00271 link_rating[0][0] = link_rating[0][1] = link_rating[0][2] = temp_rating_continuous;
00272 link_rating[1][0] = link_rating[1][1] = link_rating[1][2] = temp_rating_emergency;
00273 }
00274 }
00275 return result;
00276 }
00277
00278 void underground_line::recalc(void)
00279 {
00280 line_configuration *config = OBJECTDATA(configuration, line_configuration);
00281 complex Zabc_mat[3][3], Yabc_mat[3][3];
00282 bool not_TS_CN = false;
00283 bool is_CN_ug_line = false;
00284 OBJECT *obj = OBJECTHDR(this);
00285
00286
00287 for (int i = 0; i < 3; i++)
00288 {
00289 for (int j = 0; j < 3; j++)
00290 {
00291 Zabc_mat[i][j] = 0.0;
00292 Yabc_mat[i][j] = 0.0;
00293 }
00294 }
00295
00296
00297 for (int i = 0; i < 3; i++) {
00298 for (int j = 0; j < 3; j++) {
00299 a_mat[i][j] = 0.0;
00300 d_mat[i][j] = 0.0;
00301 A_mat[i][j] = 0.0;
00302 c_mat[i][j] = 0.0;
00303 B_mat[i][j] = b_mat[i][j];
00304 }
00305 }
00306
00307 if (config->impedance11 != 0 || config->impedance22 != 0 || config->impedance33 != 0)
00308 {
00309
00310 load_matrix_based_configuration(Zabc_mat, Yabc_mat);
00311
00312
00313 if (has_phase(PHASE_A))
00314 {
00315 a_mat[0][0] = 1.0;
00316 d_mat[0][0] = 1.0;
00317 A_mat[0][0] = 1.0;
00318 }
00319
00320 if (has_phase(PHASE_B))
00321 {
00322 a_mat[1][1] = 1.0;
00323 d_mat[1][1] = 1.0;
00324 A_mat[1][1] = 1.0;
00325 }
00326
00327 if (has_phase(PHASE_C))
00328 {
00329 a_mat[2][2] = 1.0;
00330 d_mat[2][2] = 1.0;
00331 A_mat[2][2] = 1.0;
00332 }
00333 }
00334 else
00335 {
00336 double dia_od1, dia_od2, dia_od3;
00337 int16 strands_4, strands_5, strands_6;
00338 double rad_14, rad_25, rad_36;
00339 double dia[7], res[7], gmr[7], gmrcn[3], rcn[3], gmrs[3], ress[3], tap[8];
00340 double d[7][7];
00341 double perm_A, perm_B, perm_C, c_an, c_bn, c_cn, temp_denom;
00342 complex cap_freq_coeff;
00343 complex z[7][7],z_ts[3][3];
00344 double freq_coeff_real, freq_coeff_imag, freq_additive_term;
00345 double miles = length / 5280.0;
00346
00347 complex test;
00348
00349
00350
00351 if (enable_frequency_dependence == true)
00352 {
00353 freq_coeff_real = 0.00158836*current_frequency;
00354 freq_coeff_imag = 0.00202237*current_frequency;
00355 freq_additive_term = log(EARTH_RESISTIVITY/current_frequency)/2.0 + 7.6786;
00356 }
00357 else
00358 {
00359 freq_coeff_real = 0.00158836*nominal_frequency;
00360 freq_coeff_imag = 0.00202237*nominal_frequency;
00361 freq_additive_term = log(EARTH_RESISTIVITY/nominal_frequency)/2.0 + 7.6786;
00362 }
00363
00364 #define DIA(i) (dia[i - 1])
00365 #define RES(i) (res[i - 1])
00366 #define RES_S(i) (ress[i - 4])
00367 #define GMR_S(i) (gmrs[i - 4])
00368 #define GMR(i) (gmr[i - 1])
00369 #define GMRCN(i) (gmrcn[i - 4])
00370 #define RCN(i) (rcn[i - 4])
00371 #define D(i, j) (d[i - 1][j - 1])
00372 #define Z(i, j) (z[i - 1][j - 1])
00373 #define Z_TS(i, j) (z_ts[i - 1][j - 1])
00374 #define TAP(i) (tap[i - 1])
00375
00376 #define UG_GET(ph, name) (has_phase(PHASE_##ph) && config->phase##ph##_conductor ? \
00377 OBJECTDATA(config->phase##ph##_conductor, underground_line_conductor)->name : 0)
00378
00379 dia_od1 = UG_GET(A, outer_diameter);
00380 dia_od2 = UG_GET(B, outer_diameter);
00381 dia_od3 = UG_GET(C, outer_diameter);
00382 GMR(1) = UG_GET(A, conductor_gmr);
00383 GMR(2) = UG_GET(B, conductor_gmr);
00384 GMR(3) = UG_GET(C, conductor_gmr);
00385 GMR(7) = UG_GET(N, conductor_gmr);
00386 DIA(1) = UG_GET(A, conductor_diameter);
00387 DIA(2) = UG_GET(B, conductor_diameter);
00388 DIA(3) = UG_GET(C, conductor_diameter);
00389 DIA(7) = UG_GET(N, conductor_diameter);
00390 RES(1) = UG_GET(A, conductor_resistance);
00391 RES(2) = UG_GET(B, conductor_resistance);
00392 RES(3) = UG_GET(C, conductor_resistance);
00393 RES(7) = UG_GET(N, conductor_resistance);
00394 GMR(4) = UG_GET(A, neutral_gmr);
00395 GMR(5) = UG_GET(B, neutral_gmr);
00396 GMR(6) = UG_GET(C, neutral_gmr);
00397 GMR_S(4) = UG_GET(A, shield_gmr);
00398 GMR_S(5) = UG_GET(B, shield_gmr);
00399 GMR_S(6) = UG_GET(C, shield_gmr);
00400 DIA(4) = UG_GET(A, neutral_diameter);
00401 DIA(5) = UG_GET(B, neutral_diameter);
00402 DIA(6) = UG_GET(C, neutral_diameter);
00403 RES(4) = UG_GET(A, neutral_resistance);
00404 RES(5) = UG_GET(B, neutral_resistance);
00405 RES(6) = UG_GET(C, neutral_resistance);
00406 RES_S(4) = UG_GET(A, shield_resistance);
00407 RES_S(5) = UG_GET(B, shield_resistance);
00408 RES_S(6) = UG_GET(C, shield_resistance);
00409 TAP(1) = UG_GET(A, shield_thickness);
00410 TAP(2) = UG_GET(B, shield_thickness);
00411 TAP(3) = UG_GET(C, shield_thickness);
00412 TAP(4) = UG_GET(N, shield_thickness);
00413 TAP(5) = UG_GET(A, shield_diameter);
00414 TAP(6) = UG_GET(B, shield_diameter);
00415 TAP(7) = UG_GET(C, shield_diameter);
00416 TAP(8) = UG_GET(N, shield_diameter);
00417 strands_4 = UG_GET(A, neutral_strands);
00418 strands_5 = UG_GET(B, neutral_strands);
00419 strands_6 = UG_GET(C, neutral_strands);
00420 if(GMR_S(4) == 0 && GMR_S(5) == 0 && GMR_S(6) == 0){
00421 rad_14 = (dia_od1 - DIA(4)) / 24.0;
00422 rad_25 = (dia_od2 - DIA(5)) / 24.0;
00423 rad_36 = (dia_od3 - DIA(6)) / 24.0;
00424 }
00425 else
00426 {
00427 rad_14 = 0.0;
00428 rad_25 = 0.0;
00429 rad_36 = 0.0;
00430 }
00431 RCN(4) = has_phase(PHASE_A) && strands_4 > 0 ? RES(4) / strands_4 : 0.0;
00432 RCN(5) = has_phase(PHASE_B) && strands_5 > 0 ? RES(5) / strands_5 : 0.0;
00433 RCN(6) = has_phase(PHASE_C) && strands_6 > 0 ? RES(6) / strands_6 : 0.0;
00434
00435
00436 GMRCN(4) = !(has_phase(PHASE_A) && strands_4 > 0) ? 0.0 :
00437 pow(GMR(4) * strands_4 * pow(rad_14, (strands_4 - 1)), (1.0 / strands_4));
00438 GMRCN(5) = !(has_phase(PHASE_B) && strands_5 > 0) ? 0.0 :
00439 pow(GMR(5) * strands_5 * pow(rad_25, (strands_5 - 1)), (1.0 / strands_5));
00440 GMRCN(6) = !(has_phase(PHASE_C) && strands_6 > 0) ? 0.0 :
00441 pow(GMR(6) * strands_6 * pow(rad_36, (strands_6 - 1)), (1.0 / strands_6));
00442
00443
00444
00445 if (GMR(4) == 0.0 && GMR(5) == 0.0 && GMR(6) == 0.0 && GMR_S(4) == 0.0 && GMR_S(5) == 0.0 && GMR_S(6) == 0.0){
00446 not_TS_CN = true;
00447 }
00448 else
00449 {
00450 if ((GMR_S(4) == 0.0) && (GMR_S(5) == 0.0) && (GMR_S(6) == 0.0))
00451 {
00452 is_CN_ug_line = true;
00453 }
00454 else
00455 {
00456 is_CN_ug_line = false;
00457 rad_14 = (TAP(5) - TAP(1))/2;
00458 rad_25 = (TAP(6) - TAP(2))/2;
00459 rad_36 = (TAP(7) - TAP(3))/2;
00460 }
00461 }
00462
00463 if (use_line_cap == true && not_TS_CN == false)
00464 {
00465
00466 perm_A = UG_GET(A, insulation_rel_permitivitty);
00467 perm_B = UG_GET(B, insulation_rel_permitivitty);
00468 perm_C = UG_GET(C, insulation_rel_permitivitty);
00469
00470
00471 if (enable_frequency_dependence == true)
00472 {
00473 cap_freq_coeff = complex(0,(2.0*PI*current_frequency*0.000001*miles));
00474 }
00475 else
00476 {
00477 cap_freq_coeff = complex(0,(2.0*PI*nominal_frequency*0.000001*miles));
00478 }
00479 }
00480
00481 #define DIST(ph1, ph2) (has_phase(PHASE_##ph1) && has_phase(PHASE_##ph2) && config->line_spacing ? \
00482 OBJECTDATA(config->line_spacing, line_spacing)->distance_##ph1##to##ph2 : 0.0)
00483
00484 D(1, 2) = DIST(A, B);
00485 D(1, 3) = DIST(A, C);
00486 D(1, 4) = rad_14;
00487 if(GMR_S(4) > 0)
00488 D(1, 4) = GMR_S(4);
00489 D(1, 5) = D(1, 2);
00490 D(1, 6) = D(1, 3);
00491 D(1, 7) = DIST(A, N);
00492 D(2, 1) = D(1, 2);
00493 D(2, 3) = DIST(B, C);
00494 D(2, 4) = D(2, 1);
00495 D(2, 5) = rad_25;
00496 if(GMR_S(5) > 0)
00497 D(2, 5) = GMR_S(5);
00498 D(2, 6) = D(2, 3);
00499 D(2, 7) = DIST(B, N);
00500 D(3, 1) = D(1, 3);
00501 D(3, 2) = D(2, 3);
00502 D(3, 4) = D(3, 1);
00503 D(3, 5) = D(3, 2);
00504 D(3, 6) = rad_36;
00505 if(GMR_S(6) > 0)
00506 D(3, 6) = GMR_S(6);
00507 D(3, 7) = DIST(C, N);
00508 D(4, 1) = D(1, 4);
00509 D(4, 2) = D(2, 4);
00510 D(4, 3) = D(3, 4);
00511 D(4, 5) = D(1, 2);
00512 D(4, 6) = D(1, 3);
00513 D(4, 7) = D(1, 7);
00514 D(5, 1) = D(1, 5);
00515 D(5, 2) = D(2, 5);
00516 D(5, 3) = D(3, 5);
00517 D(5, 4) = D(4, 5);
00518 D(5, 6) = D(2, 3);
00519 D(5, 7) = D(2, 7);
00520 D(6, 1) = D(1, 6);
00521 D(6, 2) = D(2, 6);
00522 D(6, 3) = D(3, 6);
00523 D(6, 4) = D(4, 6);
00524 D(6, 5) = D(5, 6);
00525 D(6, 7) = D(3, 7);
00526 D(7, 1) = D(1, 7);
00527 D(7, 2) = D(2, 7);
00528 D(7, 3) = D(3, 7);
00529 D(7, 4) = D(1, 7);
00530 D(7, 5) = D(2, 7);
00531 D(7, 6) = D(3, 7);
00532
00533 #undef DIST
00534 #undef DIA
00535 #undef UG_GET
00536
00537 if (is_CN_ug_line == true) {
00538 #define Z_GMR(i) (GMR(i) == 0.0 ? complex(0.0) : complex(freq_coeff_real + RES(i), freq_coeff_imag * (log(1.0 / GMR(i)) + freq_additive_term)))
00539 #define Z_GMRCN(i) (GMRCN(i) == 0.0 ? complex(0.0) : complex(freq_coeff_real + RCN(i), freq_coeff_imag * (log(1.0 / GMRCN(i)) + freq_additive_term)))
00540 #define Z_GMR_S(i) (GMR_S(i) == 0.0 ? complex(0.0) : complex(freq_coeff_real + RES_S(i), freq_coeff_imag*(log(1.0/GMR_S(i)) + freq_additive_term)))
00541 #define Z_DIST(i, j) (D(i, j) == 0.0 ? complex(0.0) : complex(freq_coeff_real, freq_coeff_imag * (log(1.0 / D(i, j)) + freq_additive_term)))
00542
00543 for (int i = 1; i < 8; i++) {
00544 for (int j = 1; j < 8; j++) {
00545 if (i == j) {
00546 if (i > 3 && i != 7){
00547 Z(i, j) = Z_GMRCN(i);
00548 if(Z_GMR_S(i) > 0 && Z(i, j) == 0)
00549 Z(i, j) = Z_GMR_S(i);
00550 test=Z_GMRCN(i);
00551 }
00552 else
00553 Z(i, j) = Z_GMR(i);
00554 }
00555 else
00556 Z(i, j) = Z_DIST(i, j);
00557 }
00558 }
00559 #undef Z_GMR_S //Make the compiler happy
00560 } else {
00561
00562 #define Z_GMR(i) (GMR(i) == 0.0 ? complex(0.0) : complex(freq_coeff_real + RES(i), freq_coeff_imag * (log(1.0 / GMR(i)) + freq_additive_term)))
00563
00564
00565 #define Z_GMR_S_SELF(i) (GMR_S(i) == 0.0 ? complex(0.0) : complex(freq_coeff_real+RES_S(i), freq_coeff_imag*(log(1.0/GMR_S(i)) + freq_additive_term))) //z44, z55, z66 - self tape
00566 #define Z_GMR_S(i) (GMR_S(i) == 0.0 ? complex(0.0) : complex(freq_coeff_real, freq_coeff_imag*(log(1.0/GMR_S(i)) + freq_additive_term))) //z14, z25, z36 - mutual - conductor-tape
00567 #define Z_DIST(i, j) (D(i, j) == 0.0 ? complex(0.0) : complex(freq_coeff_real, freq_coeff_imag * (log(1.0 / D(i, j)) + freq_additive_term)))
00568
00569
00570 for (int i = 1; i < 8; i++) {
00571 for (int j = 1; j < 8; j++) {
00572 if (i == j) {
00573 if (i > 3 && i != 7){
00574 Z(i, j) = Z_GMR_S_SELF(i);
00575 }
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587 else
00588 Z(i, j) = Z_GMR(i);
00589 }
00590 else {
00591 if ((i == 1 && j == 4) || (i == 2 && j == 5) || (i == 3 && j == 6)) {
00592 Z(i, j) = Z_GMR_S(j);
00593 }
00594 else
00595 Z(i, j) = Z_DIST(i, j);
00596 }
00597
00598 }
00599 }
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612 }
00613 #undef RES
00614 #undef GMR
00615 #undef GMRCN
00616 #undef RCN
00617 #undef D
00618 #undef Z_GMR
00619 #undef Z_GMRCN
00620 #undef Z_DIST
00621 #undef Z_GMR_S
00622
00623 if (not_TS_CN == false){
00624 if (is_CN_ug_line == true) {
00625 complex z_ij_cn[3][3] = {{Z(1, 1), Z(1, 2), Z(1, 3)},
00626 {Z(2, 1), Z(2, 2), Z(2, 3)},
00627 {Z(3, 1), Z(3, 2), Z(3, 3)}};
00628 complex z_in_cn[3][4] = {{Z(1, 4), Z(1, 5), Z(1, 6),Z(1, 7)},
00629 {Z(2, 4), Z(2, 5), Z(2, 6),Z(2, 7)},
00630 {Z(3, 4), Z(3, 5), Z(3, 6),Z(3, 7)}};
00631 complex z_nj_cn[4][3] = {{Z(4, 1), Z(4, 2), Z(4, 3)},
00632 {Z(5, 1), Z(5, 2), Z(5, 3)},
00633 {Z(6, 1), Z(6, 2), Z(6, 3)},
00634 {Z(7, 1), Z(7, 2), Z(7, 3)}};
00635 complex z_nn_cn[4][4] = {{Z(4, 4), Z(4, 5), Z(4, 6), Z(4, 7)},
00636 {Z(5, 4), Z(5, 5), Z(5, 6), Z(5, 7)},
00637 {Z(6, 4), Z(6, 5), Z(6, 6), Z(6, 7)},
00638 {Z(7, 4), Z(7, 5), Z(7, 6), Z(7, 7)}};
00639
00640 if (!(has_phase(PHASE_A)&&has_phase(PHASE_B)&&has_phase(PHASE_C)&&has_phase(PHASE_N))){
00641 if (!has_phase(PHASE_A))
00642 z_nn_cn[0][0]=complex(1.0);
00643 if (!has_phase(PHASE_B))
00644 z_nn_cn[1][1]=complex(1.0);
00645 if (!has_phase(PHASE_C))
00646 z_nn_cn[2][2]=complex(1.0);
00647 if (!has_phase(PHASE_N))
00648 z_nn_cn[3][3]=complex(1.0);
00649 }
00650 complex z_nn_inv_cn[4][4], z_p1_cn[3][4], z_p2_cn[3][3], z_abc_cn[3][3];
00651 lu_matrix_inverse(&z_nn_cn[0][0],&z_nn_inv_cn[0][0],4);
00652
00653
00654
00655
00656
00657
00658 for (int row = 0; row < 3; row++) {
00659 for (int col = 0; col < 4; col++) {
00660
00661 for (int inner = 0; inner < 4; inner++) {
00662 z_p1_cn[row][col] += z_in_cn[row][inner] * z_nn_inv_cn[inner][col];
00663 }
00664 }
00665 }
00666
00667
00668 for (int roww = 0; roww < 3; roww++) {
00669 for (int coll = 0; coll < 3; coll++) {
00670
00671 for (int innerr = 0; innerr < 4; innerr++) {
00672 z_p2_cn[roww][coll] += z_p1_cn[roww][innerr] * z_nj_cn[innerr][coll];
00673 }
00674 }
00675 }
00676
00677
00678 subtract(z_ij_cn, z_p2_cn, z_abc_cn);
00679 multiply(miles, z_abc_cn, Zabc_mat);
00680
00681 }
00682 else {
00683 complex z_ij_ts[3][3] = {{Z(1, 1), Z(1, 2), Z(1, 3)},
00684 {Z(2, 1), Z(2, 2), Z(2, 3)},
00685 {Z(3, 1), Z(3, 2), Z(3, 3)}};
00686 complex z_in_ts[3][4] = {{Z(1, 4), Z(1, 5), Z(1, 6), Z(1,7)},
00687 {Z(2, 4), Z(2, 5), Z(2, 6), Z(2,7)},
00688 {Z(3, 4), Z(3, 5), Z(3, 6), Z(3,7)}};
00689 complex z_nj_ts[4][3] = {{Z(4, 1), Z(4, 2), Z(4, 3)},
00690 {Z(5, 1), Z(5, 2), Z(5, 3)},
00691 {Z(6, 1), Z(6, 2), Z(6, 3)},
00692 {Z(7, 1), Z(7, 2), Z(7, 3)}};
00693
00694
00695 complex z_nn_ts[4][4] = {{Z(4, 4), Z(4, 5), Z(4, 6), Z(4, 7)},
00696 {Z(5, 4), Z(5, 5), Z(5, 6), Z(5, 7)},
00697 {Z(6, 4), Z(6, 5), Z(6, 6), Z(6, 7)},
00698 {Z(7, 4), Z(7, 5), Z(7, 6), Z(7, 7)}};
00699 if (!(has_phase(PHASE_A)&&has_phase(PHASE_B)&&has_phase(PHASE_C)&&has_phase(PHASE_N))){
00700 if (!has_phase(PHASE_A))
00701 z_nn_ts[0][0]=complex(1.0);
00702 if (!has_phase(PHASE_B))
00703 z_nn_ts[1][1]=complex(1.0);
00704 if (!has_phase(PHASE_C))
00705 z_nn_ts[2][2]=complex(1.0);
00706 if(!has_phase(PHASE_N))
00707 {
00708 z_nn_ts[3][3]=complex(1.0);
00709 gl_warning("Underground_line:%d - %s is a tape-shielded cable and may need an explicit phase N conductor",obj->id,(obj->name ? obj->name : "Unnamed"));
00710
00711
00712
00713
00714 }
00715 }
00716 complex z_nn_inv_ts[4][4], z_p1_ts[3][4], z_p2_ts[3][3], z_abc_ts[3][3];
00717 lu_matrix_inverse(&z_nn_ts[0][0],&z_nn_inv_ts[0][0],4);
00718
00719 for (int row = 0; row < 3; row++) {
00720 for (int col = 0; col < 4; col++) {
00721
00722 for (int inner = 0; inner < 4; inner++) {
00723 z_p1_ts[row][col] += z_in_ts[row][inner] * z_nn_inv_ts[inner][col];
00724 }
00725 }
00726 }
00727
00728
00729 for (int roww = 0; roww < 3; roww++) {
00730 for (int coll = 0; coll < 3; coll++) {
00731
00732 for (int innerr = 0; innerr < 4; innerr++) {
00733 z_p2_ts[roww][coll] += z_p1_ts[roww][innerr] * z_nj_ts[innerr][coll];
00734 }
00735 }
00736 }
00737
00738
00739 subtract(z_ij_ts, z_p2_ts, z_abc_ts);
00740 multiply(miles, z_abc_ts, Zabc_mat);
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789 }
00790
00791
00792 } else {
00793 complex z_nn_inv = 0;
00794 if(Z(7, 7) != 0.0){
00795 z_nn_inv = Z(7, 7)^(-1.0);
00796 }
00797 Zabc_mat[0][0] = (Z(1, 1) - Z(1, 7) * Z(1, 7) * z_nn_inv) * miles;
00798 Zabc_mat[0][1] = (Z(1, 2) - Z(1, 7) * Z(2, 7) * z_nn_inv) * miles;
00799 Zabc_mat[0][2] = (Z(1, 3) - Z(1, 7) * Z(3, 7) * z_nn_inv) * miles;
00800 Zabc_mat[1][0] = (Z(2, 1) - Z(2, 7) * Z(1, 7) * z_nn_inv) * miles;
00801 Zabc_mat[1][1] = (Z(2, 2) - Z(2, 7) * Z(2, 7) * z_nn_inv) * miles;
00802 Zabc_mat[1][2] = (Z(2, 3) - Z(2, 7) * Z(3, 7) * z_nn_inv) * miles;
00803 Zabc_mat[2][0] = (Z(3, 1) - Z(3, 7) * Z(1, 7) * z_nn_inv) * miles;
00804 Zabc_mat[2][1] = (Z(3, 2) - Z(3, 7) * Z(2, 7) * z_nn_inv) * miles;
00805 Zabc_mat[2][2] = (Z(3, 3) - Z(3, 7) * Z(3, 7) * z_nn_inv) * miles;
00806 }
00807 #undef Z
00808
00809
00810 if ((use_line_cap == true) && (not_TS_CN == false))
00811 {
00812
00813 if (is_CN_ug_line == true)
00814
00815
00816 {
00817
00818 if (has_phase(PHASE_A))
00819
00820 {
00821 if ((dia[0]==0.0) || (rad_14==0.0) || (strands_4 == 0))
00822 {
00823 gl_warning("Unable to compute capacitance for %s",OBJECTHDR(this)->name);
00824
00825
00826
00827
00828
00829
00830 c_an = 0.0;
00831 }
00832 else
00833
00834 {
00835
00836 temp_denom = log(rad_14/(dia[0] / 24.0)) - (1.0 / ((double)(strands_4))) * log(((double)(strands_4))*dia[3] / 24.0 / rad_14);
00837
00838 if (temp_denom == 0.0)
00839 {
00840 gl_warning("Capacitance calculation failure for %s",OBJECTHDR(this)->name);
00841
00842
00843
00844
00845
00846 c_an = 0.0;
00847 }
00848 else
00849 {
00850
00851 c_an = (2.0 * PI * PERMITIVITTY_FREE * perm_A) / temp_denom;
00852 }
00853 }
00854 }
00855
00856 else
00857 {
00858
00859 c_an = 0.0;
00860 }
00861
00862
00863
00864 if (has_phase(PHASE_B))
00865
00866
00867 {
00868 if ((dia[1]==0.0) || (rad_25==0.0) || (strands_5 == 0))
00869 {
00870 gl_warning("Unable to compute capacitance for %s",OBJECTHDR(this)->name);
00871
00872
00873 c_bn = 0.0;
00874 }
00875 else
00876 {
00877
00878 temp_denom = log(rad_25/(dia[1] / 24.0)) - (1.0 / ((double)(strands_5))) * log(((double)(strands_5))*dia[4] / 24.0 / rad_25);
00879
00880 if (temp_denom == 0.0)
00881 {
00882 gl_warning("Capacitance calculation failure for %s",OBJECTHDR(this)->name);
00883
00884
00885 c_bn = 0.0;
00886 }
00887 else
00888 {
00889
00890 c_bn = (2.0 * PI * PERMITIVITTY_FREE * perm_B) / temp_denom;
00891 }
00892 }
00893
00894 }
00895 else
00896
00897 {
00898 c_bn = 0.0;
00899 }
00900
00901
00902
00903
00904 if (has_phase(PHASE_C))
00905 {
00906 if ((dia[2]==0.0) || (rad_36==0.0) || (strands_6 == 0))
00907
00908 {
00909 gl_warning("Unable to compute capacitance for %s",OBJECTHDR(this)->name);
00910
00911
00912 c_cn = 0.0;
00913 }
00914 else
00915
00916 {
00917
00918 temp_denom = log(rad_36/(dia[2] / 24.0)) - (1.0 / ((double)(strands_6))) * log(((double)(strands_6))*dia[5] / 24.0 / rad_36);
00919
00920 if (temp_denom == 0.0)
00921 {
00922 gl_warning("Capacitance calculation failure for %s",OBJECTHDR(this)->name);
00923
00924
00925 c_cn = 0.0;
00926 }
00927 else
00928 {
00929
00930 c_cn = (2.0 * PI * PERMITIVITTY_FREE * perm_C) / temp_denom;
00931 }
00932 }
00933 }
00934
00935 else
00936 {
00937 c_cn = 0.0;
00938 }
00939 }
00940 else
00941 {
00942
00943
00944
00945 if (has_phase(PHASE_A))
00946 {
00947
00948 if ((dia[0]==0.0) || (rad_14==0.0))
00949 {
00950 gl_warning("Unable to compute capacitance for %s",OBJECTHDR(this)->name);
00951
00952
00953
00954
00955
00956
00957 c_an = 0.0;
00958 }
00959 else
00960 {
00961
00962 temp_denom = log(rad_14/(dia[0] / 2.0));
00963
00964 if (temp_denom == 0.0)
00965 {
00966 gl_warning("Capacitance calculation failure for %s",OBJECTHDR(this)->name);
00967
00968
00969
00970
00971
00972 c_an = 0.0;
00973 }
00974 else
00975 {
00976
00977 c_an = (2.0 * PI * PERMITIVITTY_FREE * perm_A) / temp_denom;
00978 }
00979 }
00980 }
00981 else
00982 {
00983 c_an = 0.0;
00984 }
00985
00986
00987
00988 if (has_phase(PHASE_B))
00989
00990
00991 {
00992
00993 if ((dia[1]==0.0) || (rad_25==0.0))
00994 {
00995 gl_warning("Unable to compute capacitance for %s",OBJECTHDR(this)->name);
00996
00997
00998 c_bn = 0.0;
00999 }
01000 else
01001 {
01002
01003 temp_denom = log(rad_25/(dia[1] / 2.0));
01004
01005 if (temp_denom == 0.0)
01006 {
01007 gl_warning("Capacitance calculation failure for %s",OBJECTHDR(this)->name);
01008
01009
01010 c_bn = 0.0;
01011 }
01012 else
01013 {
01014
01015 c_bn = (2.0 * PI * PERMITIVITTY_FREE * perm_B) / temp_denom;
01016 }
01017 }
01018
01019 }
01020 else
01021
01022 {
01023 c_bn = 0.0;
01024 }
01025
01026
01027
01028
01029 if (has_phase(PHASE_C))
01030 {
01031
01032 if ((dia[2]==0.0) || (rad_36==0.0))
01033
01034 {
01035 gl_warning("Unable to compute capacitance for %s",OBJECTHDR(this)->name);
01036
01037
01038 c_cn = 0.0;
01039 }
01040 else
01041
01042 {
01043
01044 temp_denom = log(rad_36/(dia[2] / 2.0));
01045
01046 if (temp_denom == 0.0)
01047 {
01048 gl_warning("Capacitance calculation failure for %s",OBJECTHDR(this)->name);
01049
01050
01051 c_cn = 0.0;
01052 }
01053 else
01054 {
01055
01056 c_cn = (2.0 * PI * PERMITIVITTY_FREE * perm_C) / temp_denom;
01057 }
01058 }
01059 }
01060 else
01061 {
01062 c_cn = 0.0;
01063 }
01064 }
01065
01066
01067
01068
01069 Yabc_mat[0][0] = cap_freq_coeff * c_an;
01070 Yabc_mat[1][1] = cap_freq_coeff * c_bn;
01071 Yabc_mat[2][2] = cap_freq_coeff * c_cn;
01072 }
01073 else
01074 {
01075
01076 for (int i = 0; i < 3; i++) {
01077 for (int j = 0; j < 3; j++) {
01078 a_mat[i][j] = 0.0;
01079 d_mat[i][j] = 0.0;
01080 A_mat[i][j] = 0.0;
01081 c_mat[i][j] = 0.0;
01082 B_mat[i][j] = b_mat[i][j];
01083 }
01084 }
01085
01086
01087 if (has_phase(PHASE_A))
01088 {
01089 a_mat[0][0] = 1.0;
01090 d_mat[0][0] = 1.0;
01091 A_mat[0][0] = 1.0;
01092 }
01093
01094 if (has_phase(PHASE_B))
01095 {
01096 a_mat[1][1] = 1.0;
01097 d_mat[1][1] = 1.0;
01098 A_mat[1][1] = 1.0;
01099 }
01100
01101 if (has_phase(PHASE_C))
01102 {
01103 a_mat[2][2] = 1.0;
01104 d_mat[2][2] = 1.0;
01105 A_mat[2][2] = 1.0;
01106 }
01107 }
01108 }
01109
01110
01111 recalc_line_matricies(Zabc_mat, Yabc_mat);
01112
01113
01114 bool neg_res = false;
01115 for (int n = 0; n < 3; n++){
01116 for (int m = 0; m < 3; m++){
01117 if(b_mat[n][m].Re() < 0.0){
01118 neg_res = true;
01119 }
01120 }
01121 }
01122
01123 if(neg_res == true){
01124 gl_warning("INIT: underground_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);
01125
01126
01127
01128
01129
01130 }
01131
01132 #ifdef _TESTING
01134 if (show_matrix_values)
01135 {
01136 OBJECT *obj = GETOBJECT(this);
01137
01138 gl_testmsg("underground_line: %s a matrix",obj->name);
01139 print_matrix(a_mat);
01140
01141 gl_testmsg("underground_line: %s A matrix",obj->name);
01142 print_matrix(A_mat);
01143
01144 gl_testmsg("underground_line: %s b matrix",obj->name);
01145 print_matrix(b_mat);
01146
01147 gl_testmsg("underground_line: %s B matrix",obj->name);
01148 print_matrix(B_mat);
01149
01150 gl_testmsg("underground_line: %s c matrix",obj->name);
01151 print_matrix(c_mat);
01152
01153 gl_testmsg("underground_line: %s d matrix",obj->name);
01154 print_matrix(d_mat);
01155 }
01156 #endif
01157 }
01158
01159 int underground_line::isa(char *classname)
01160 {
01161 return strcmp(classname,"underground_line")==0 || line::isa(classname);
01162 }
01163
01164
01174 int underground_line::test_phases(line_configuration *config, const char ph)
01175 {
01176 int return_val;
01177 bool condCheck, condNotPres;
01178 OBJECT *obj = GETOBJECT(this);
01179 double temp_shield_gmr_val, temp_neutral_gmr_val;
01180
01181
01182 return_val = 0;
01183
01184 if (ph=='A')
01185 {
01186 if (config->impedance11 == 0.0)
01187 {
01188 condCheck = (config->phaseA_conductor && !gl_object_isa(config->phaseA_conductor, "underground_line_conductor","powerflow"));
01189 condNotPres = ((!config->phaseA_conductor) && has_phase(PHASE_A));
01190
01191
01192 if ((config->phaseA_conductor != NULL) && (condCheck == false))
01193 {
01194
01195 get_cable_values(config->phaseA_conductor,&temp_shield_gmr_val,&temp_neutral_gmr_val);
01196
01197
01198 if (temp_shield_gmr_val > 0.0)
01199 {
01200 return_val = 1;
01201 }
01202 else if (temp_neutral_gmr_val > 0.0)
01203 {
01204 return_val = 10;
01205 }
01206 else
01207 {
01208 return_val = 0;
01209 }
01210 }
01211
01212 }
01213 else
01214 {
01215 condCheck = false;
01216 condNotPres = false;
01217 return_val = 0;
01218 }
01219 }
01220 else if (ph=='B')
01221 {
01222 if (config->impedance22 == 0.0)
01223 {
01224 condCheck = (config->phaseB_conductor && !gl_object_isa(config->phaseB_conductor, "underground_line_conductor","powerflow"));
01225 condNotPres = ((!config->phaseB_conductor) && has_phase(PHASE_B));
01226
01227
01228 if ((config->phaseB_conductor != NULL) && (condCheck == false))
01229 {
01230
01231 get_cable_values(config->phaseB_conductor,&temp_shield_gmr_val,&temp_neutral_gmr_val);
01232
01233
01234 if (temp_shield_gmr_val > 0.0)
01235 {
01236 return_val = 1;
01237 }
01238 else if (temp_neutral_gmr_val > 0.0)
01239 {
01240 return_val = 10;
01241 }
01242 else
01243 {
01244 return_val = 0;
01245 }
01246 }
01247
01248 }
01249 else
01250 {
01251 condCheck = false;
01252 condNotPres = false;
01253 return_val = 0;
01254 }
01255 }
01256 else if (ph=='C')
01257 {
01258 if (config->impedance33 == 0.0)
01259 {
01260 condCheck = (config->phaseC_conductor && !gl_object_isa(config->phaseC_conductor, "underground_line_conductor","powerflow"));
01261 condNotPres = ((!config->phaseC_conductor) && has_phase(PHASE_C));
01262
01263
01264 if ((config->phaseC_conductor != NULL) && (condCheck == false))
01265 {
01266
01267 get_cable_values(config->phaseC_conductor,&temp_shield_gmr_val,&temp_neutral_gmr_val);
01268
01269
01270 if (temp_shield_gmr_val > 0.0)
01271 {
01272 return_val = 1;
01273 }
01274 else if (temp_neutral_gmr_val > 0.0)
01275 {
01276 return_val = 10;
01277 }
01278 else
01279 {
01280 return_val = 0;
01281 }
01282 }
01283
01284 }
01285 else
01286 {
01287 condCheck = false;
01288 condNotPres = false;
01289 return_val = 0;
01290 }
01291 }
01292 else if (ph=='N')
01293 {
01294 if (config->impedance11 == 0.0 && config->impedance22 == 0.0 && config->impedance33 == 0.0)
01295 {
01296 condCheck = (config->phaseN_conductor && !gl_object_isa(config->phaseN_conductor, "underground_line_conductor","powerflow"));
01297 condNotPres = ((!config->phaseN_conductor) && has_phase(PHASE_N));
01298
01299
01300 if ((config->phaseN_conductor != NULL) && (condCheck == false))
01301 {
01302
01303 get_cable_values(config->phaseN_conductor,&temp_shield_gmr_val,&temp_neutral_gmr_val);
01304
01305
01306 if ((temp_shield_gmr_val > 0.0) || (temp_neutral_gmr_val > 0.0))
01307 {
01308 gl_warning("Underground_line:%d %s - phase N conductor should just be a normal conductor!",obj->id,(obj->name ? obj->name : "Unnamed"));
01309
01310
01311
01312
01313 }
01314 }
01315 }
01316 else
01317 {
01318 condCheck = false;
01319 condNotPres = false;
01320 return_val = 0;
01321 }
01322 }
01323
01324
01325 if (condCheck==true)
01326 GL_THROW("invalid conductor for phase %c of underground line",ph,obj->name);
01327
01328
01329 if (condNotPres==true)
01330 GL_THROW("missing conductor for phase %c of underground line",ph,obj->name);
01331
01332
01333
01334
01335
01336 return return_val;
01337 }
01338
01339
01340 void underground_line::get_cable_values(OBJECT *line_conductor, double *sh_gmr, double *neu_gmr)
01341 {
01342 gld_property *temp_prop_A;
01343 double temp_shield_gmr_val, temp_neutral_gmr_val;
01344 OBJECT *obj = OBJECTHDR(this);
01345
01346
01347 temp_prop_A = new gld_property(line_conductor,"shield_gmr");
01348
01349
01350 if ((temp_prop_A->is_valid() != true) || (temp_prop_A->is_double() != true))
01351 {
01352 GL_THROW("Underground_line:%d %s - conductor %s lacks desired property!",obj->id,(obj->name ? obj->name : "Unnamed"),(line_conductor->name ? line_conductor->name : "Unnamed"));
01353
01354
01355
01356
01357 }
01358
01359
01360 temp_shield_gmr_val = temp_prop_A->get_double();
01361
01362
01363 delete temp_prop_A;
01364
01365
01366 temp_prop_A = new gld_property(line_conductor,"neutral_gmr");
01367
01368
01369 if ((temp_prop_A->is_valid() != true) || (temp_prop_A->is_double() != true))
01370 {
01371 GL_THROW("Underground_line:%d %s - conductor %s lacks desired property!",obj->id,(obj->name ? obj->name : "Unnamed"),(line_conductor->name ? line_conductor->name : "Unnamed"));
01372
01373 }
01374
01375
01376 temp_neutral_gmr_val = temp_prop_A->get_double();
01377
01378
01379 delete temp_prop_A;
01380
01381
01382 *sh_gmr = temp_shield_gmr_val;
01383 *neu_gmr = temp_neutral_gmr_val;
01384 }
01385
01387
01389
01399
01400
01401
01402
01403
01404
01405
01406
01407
01408
01409 EXPORT int create_underground_line(OBJECT **obj, OBJECT *parent)
01410 {
01411 try
01412 {
01413 *obj = gl_create_object(underground_line::oclass);
01414 if (*obj!=NULL)
01415 {
01416 underground_line *my = OBJECTDATA(*obj,underground_line);
01417 gl_set_parent(*obj,parent);
01418 return my->create();
01419 }
01420 else
01421 return 0;
01422 }
01423 CREATE_CATCHALL(underground_line);
01424 }
01425
01426 EXPORT TIMESTAMP sync_underground_line(OBJECT *obj, TIMESTAMP t0, PASSCONFIG pass)
01427 {
01428 try {
01429 underground_line *pObj = OBJECTDATA(obj,underground_line);
01430 TIMESTAMP t1 = TS_NEVER;
01431 switch (pass) {
01432 case PC_PRETOPDOWN:
01433 return pObj->presync(t0);
01434 case PC_BOTTOMUP:
01435 return pObj->sync(t0);
01436 case PC_POSTTOPDOWN:
01437 t1 = pObj->postsync(t0);
01438 obj->clock = t0;
01439 return t1;
01440 default:
01441 throw "invalid pass request";
01442 }
01443 }
01444 SYNC_CATCHALL(underground_line);
01445 }
01446
01447 EXPORT int init_underground_line(OBJECT *obj)
01448 {
01449 try {
01450 underground_line *my = OBJECTDATA(obj,underground_line);
01451 return my->init(obj->parent);
01452 }
01453 INIT_CATCHALL(underground_line);
01454 }
01455
01456 EXPORT int isa_underground_line(OBJECT *obj, char *classname)
01457 {
01458 return OBJECTDATA(obj,underground_line)->isa(classname);
01459 }
01460
01461 EXPORT int recalc_underground_line(OBJECT *obj)
01462 {
01463 OBJECTDATA(obj,underground_line)->recalc();
01464 return 1;
01465 }
01466
01467 EXPORT int create_fault_ugline(OBJECT *thisobj, OBJECT **protect_obj, char *fault_type, int *implemented_fault, TIMESTAMP *repair_time)
01468 {
01469 int retval;
01470
01471
01472 underground_line *thisline = OBJECTDATA(thisobj,underground_line);
01473
01474
01475 retval = thisline->link_fault_on(protect_obj, fault_type, implemented_fault,repair_time);
01476
01477 return retval;
01478 }
01479 EXPORT int fix_fault_ugline(OBJECT *thisobj, int *implemented_fault, char *imp_fault_name)
01480 {
01481 int retval;
01482
01483
01484 underground_line *thisline = OBJECTDATA(thisobj,underground_line);
01485
01486
01487 retval = thisline->link_fault_off(implemented_fault, imp_fault_name);
01488
01489
01490 *implemented_fault = -1;
01491
01492 return retval;
01493 }