00001
00012 #include <stdlib.h>
00013 #include <stdio.h>
00014 #include <errno.h>
00015 #include <math.h>
00016
00017 #include "triplex_load.h"
00018
00019 CLASS* triplex_load::oclass = NULL;
00020 CLASS* triplex_load::pclass = NULL;
00021
00022 triplex_load::triplex_load(MODULE *mod) : triplex_node(mod)
00023 {
00024 if(oclass == NULL)
00025 {
00026 pclass = triplex_node::oclass;
00027
00028 oclass = gl_register_class(mod,"triplex_load",sizeof(triplex_load),PC_PRETOPDOWN|PC_BOTTOMUP|PC_POSTTOPDOWN|PC_UNSAFE_OVERRIDE_OMIT|PC_AUTOLOCK);
00029 if (oclass==NULL)
00030 throw "unable to register class triplex_load";
00031 else
00032 oclass->trl = TRL_PROVEN;
00033
00034 if(gl_publish_variable(oclass,
00035 PT_INHERIT, "triplex_node",
00036 PT_enumeration, "load_class", PADDR(load_class),PT_DESCRIPTION,"Flag to track load type, not currently used for anything except sorting",
00037 PT_KEYWORD, "U", (enumeration)LC_UNKNOWN,
00038 PT_KEYWORD, "R", (enumeration)LC_RESIDENTIAL,
00039 PT_KEYWORD, "C", (enumeration)LC_COMMERCIAL,
00040 PT_KEYWORD, "I", (enumeration)LC_INDUSTRIAL,
00041 PT_KEYWORD, "A", (enumeration)LC_AGRICULTURAL,
00042 PT_enumeration, "load_priority", PADDR(load_priority),PT_DESCRIPTION,"Load classification based on priority",
00043 PT_KEYWORD, "DISCRETIONARY", (enumeration)DISCRETIONARY,
00044 PT_KEYWORD, "PRIORITY", (enumeration)PRIORITY,
00045 PT_KEYWORD, "CRITICAL", (enumeration)CRITICAL,
00046 PT_complex, "constant_power_1[VA]", PADDR(constant_power[0]),PT_DESCRIPTION,"constant power load on split phase 1, specified as VA",
00047 PT_complex, "constant_power_2[VA]", PADDR(constant_power[1]),PT_DESCRIPTION,"constant power load on split phase 2, specified as VA",
00048 PT_complex, "constant_power_12[VA]", PADDR(constant_power[2]),PT_DESCRIPTION,"constant power load on split phase 12, specified as VA",
00049 PT_double, "constant_power_1_real[W]", PADDR(constant_power[0].Re()),PT_DESCRIPTION,"constant power load on spit phase 1, real only, specified as W",
00050 PT_double, "constant_power_2_real[W]", PADDR(constant_power[1].Re()),PT_DESCRIPTION,"constant power load on phase 2, real only, specified as W",
00051 PT_double, "constant_power_12_real[W]", PADDR(constant_power[2].Re()),PT_DESCRIPTION,"constant power load on phase 12, real only, specified as W",
00052 PT_double, "constant_power_1_reac[VAr]", PADDR(constant_power[0].Im()),PT_DESCRIPTION,"constant power load on phase 1, imaginary only, specified as VAr",
00053 PT_double, "constant_power_2_reac[VAr]", PADDR(constant_power[1].Im()),PT_DESCRIPTION,"constant power load on phase 2, imaginary only, specified as VAr",
00054 PT_double, "constant_power_12_reac[VAr]", PADDR(constant_power[2].Im()),PT_DESCRIPTION,"constant power load on phase 12, imaginary only, specified as VAr",
00055 PT_complex, "constant_current_1[A]", PADDR(constant_current[0]),PT_DESCRIPTION,"constant current load on phase 1, specified as Amps",
00056 PT_complex, "constant_current_2[A]", PADDR(constant_current[1]),PT_DESCRIPTION,"constant current load on phase 2, specified as Amps",
00057 PT_complex, "constant_current_12[A]", PADDR(constant_current[2]),PT_DESCRIPTION,"constant current load on phase 12, specified as Amps",
00058 PT_double, "constant_current_1_real[A]", PADDR(constant_current[0].Re()),PT_DESCRIPTION,"constant current load on phase 1, real only, specified as Amps",
00059 PT_double, "constant_current_2_real[A]", PADDR(constant_current[1].Re()),PT_DESCRIPTION,"constant current load on phase 2, real only, specified as Amps",
00060 PT_double, "constant_current_12_real[A]", PADDR(constant_current[2].Re()),PT_DESCRIPTION,"constant current load on phase 12, real only, specified as Amps",
00061 PT_double, "constant_current_1_reac[A]", PADDR(constant_current[0].Im()),PT_DESCRIPTION,"constant current load on phase 1, imaginary only, specified as Amps",
00062 PT_double, "constant_current_2_reac[A]", PADDR(constant_current[1].Im()),PT_DESCRIPTION,"constant current load on phase 2, imaginary only, specified as Amps",
00063 PT_double, "constant_current_12_reac[A]", PADDR(constant_current[2].Im()),PT_DESCRIPTION,"constant current load on phase 12, imaginary only, specified as Amps",
00064 PT_complex, "constant_impedance_1[Ohm]", PADDR(constant_impedance[0]),PT_DESCRIPTION,"constant impedance load on phase 1, specified as Ohms",
00065 PT_complex, "constant_impedance_2[Ohm]", PADDR(constant_impedance[1]),PT_DESCRIPTION,"constant impedance load on phase 2, specified as Ohms",
00066 PT_complex, "constant_impedance_12[Ohm]", PADDR(constant_impedance[2]),PT_DESCRIPTION,"constant impedance load on phase 12, specified as Ohms",
00067 PT_double, "constant_impedance_1_real[Ohm]", PADDR(constant_impedance[0].Re()),PT_DESCRIPTION,"constant impedance load on phase 1, real only, specified as Ohms",
00068 PT_double, "constant_impedance_2_real[Ohm]", PADDR(constant_impedance[1].Re()),PT_DESCRIPTION,"constant impedance load on phase 2, real only, specified as Ohms",
00069 PT_double, "constant_impedance_12_real[Ohm]", PADDR(constant_impedance[2].Re()),PT_DESCRIPTION,"constant impedance load on phase 12, real only, specified as Ohms",
00070 PT_double, "constant_impedance_1_reac[Ohm]", PADDR(constant_impedance[0].Im()),PT_DESCRIPTION,"constant impedance load on phase 1, imaginary only, specified as Ohms",
00071 PT_double, "constant_impedance_2_reac[Ohm]", PADDR(constant_impedance[1].Im()),PT_DESCRIPTION,"constant impedance load on phase 2, imaginary only, specified as Ohms",
00072 PT_double, "constant_impedance_12_reac[Ohm]", PADDR(constant_impedance[2].Im()),PT_DESCRIPTION,"constant impedance load on phase 12, imaginary only, specified as Ohms",
00073 PT_complex, "measured_voltage_1[V]",PADDR(measured_voltage_1),PT_DESCRIPTION,"measured voltage on phase 1",
00074 PT_complex, "measured_voltage_2[V]",PADDR(measured_voltage_2),PT_DESCRIPTION,"measured voltage on phase 2",
00075 PT_complex, "measured_voltage_12[V]",PADDR(measured_voltage_12),PT_DESCRIPTION,"measured voltage on phase 12",
00076
00077
00078
00079
00080 PT_double, "base_power_1[VA]",PADDR(base_power[0]),PT_DESCRIPTION,"in similar format as ZIPload, this represents the nominal power on phase 1 before applying ZIP fractions",
00081 PT_double, "base_power_2[VA]",PADDR(base_power[1]),PT_DESCRIPTION,"in similar format as ZIPload, this represents the nominal power on phase 2 before applying ZIP fractions",
00082 PT_double, "base_power_12[VA]",PADDR(base_power[2]),PT_DESCRIPTION,"in similar format as ZIPload, this represents the nominal power on phase 12 before applying ZIP fractions",
00083 PT_double, "power_pf_1[pu]",PADDR(power_pf[0]),PT_DESCRIPTION,"in similar format as ZIPload, this is the power factor of the phase 1 constant power portion of load",
00084 PT_double, "current_pf_1[pu]",PADDR(current_pf[0]),PT_DESCRIPTION,"in similar format as ZIPload, this is the power factor of the phase 1 constant current portion of load",
00085 PT_double, "impedance_pf_1[pu]",PADDR(impedance_pf[0]),PT_DESCRIPTION,"in similar format as ZIPload, this is the power factor of the phase 1 constant impedance portion of load",
00086 PT_double, "power_pf_2[pu]",PADDR(power_pf[1]),PT_DESCRIPTION,"in similar format as ZIPload, this is the power factor of the phase 2 constant power portion of load",
00087 PT_double, "current_pf_2[pu]",PADDR(current_pf[1]),PT_DESCRIPTION,"in similar format as ZIPload, this is the power factor of the phase 2 constant current portion of load",
00088 PT_double, "impedance_pf_2[pu]",PADDR(impedance_pf[1]),PT_DESCRIPTION,"in similar format as ZIPload, this is the power factor of the phase 2 constant impedance portion of load",
00089 PT_double, "power_pf_12[pu]",PADDR(power_pf[2]),PT_DESCRIPTION,"in similar format as ZIPload, this is the power factor of the phase 12 constant power portion of load",
00090 PT_double, "current_pf_12[pu]",PADDR(current_pf[2]),PT_DESCRIPTION,"in similar format as ZIPload, this is the power factor of the phase 12 constant current portion of load",
00091 PT_double, "impedance_pf_12[pu]",PADDR(impedance_pf[2]),PT_DESCRIPTION,"in similar format as ZIPload, this is the power factor of the phase 12 constant impedance portion of load",
00092 PT_double, "power_fraction_1[pu]",PADDR(power_fraction[0]),PT_DESCRIPTION,"this is the constant power fraction of base power on phase 1",
00093 PT_double, "current_fraction_1[pu]",PADDR(current_fraction[0]),PT_DESCRIPTION,"this is the constant current fraction of base power on phase 1",
00094 PT_double, "impedance_fraction_1[pu]",PADDR(impedance_fraction[0]),PT_DESCRIPTION,"this is the constant impedance fraction of base power on phase 1",
00095 PT_double, "power_fraction_2[pu]",PADDR(power_fraction[1]),PT_DESCRIPTION,"this is the constant power fraction of base power on phase 2",
00096 PT_double, "current_fraction_2[pu]",PADDR(current_fraction[1]),PT_DESCRIPTION,"this is the constant current fraction of base power on phase 2",
00097 PT_double, "impedance_fraction_2[pu]",PADDR(impedance_fraction[1]),PT_DESCRIPTION,"this is the constant impedance fraction of base power on phase 2",
00098 PT_double, "power_fraction_12[pu]",PADDR(power_fraction[2]),PT_DESCRIPTION,"this is the constant power fraction of base power on phase 12",
00099 PT_double, "current_fraction_12[pu]",PADDR(current_fraction[2]),PT_DESCRIPTION,"this is the constant current fraction of base power on phase 12",
00100 PT_double, "impedance_fraction_12[pu]",PADDR(impedance_fraction[2]),PT_DESCRIPTION,"this is the constant impedance fraction of base power on phase 12",
00101
00102 NULL) < 1) GL_THROW("unable to publish properties in %s",__FILE__);
00103
00104
00105 if (gl_publish_function(oclass, "interupdate_pwr_object", (FUNCTIONADDR)interupdate_triplex_load)==NULL)
00106 GL_THROW("Unable to publish triplex_load deltamode function");
00107 if (gl_publish_function(oclass, "pwr_object_swing_swapper", (FUNCTIONADDR)swap_node_swing_status)==NULL)
00108 GL_THROW("Unable to publish triplex_load swing-swapping function");
00109 if (gl_publish_function(oclass, "pwr_current_injection_update_map", (FUNCTIONADDR)node_map_current_update_function)==NULL)
00110 GL_THROW("Unable to publish triplex_load current injection update mapping function");
00111 if (gl_publish_function(oclass, "attach_vfd_to_pwr_object", (FUNCTIONADDR)attach_vfd_to_node)==NULL)
00112 GL_THROW("Unable to publish triplex_load VFD attachment function");
00113 if (gl_publish_function(oclass, "pwr_object_reset_disabled_status", (FUNCTIONADDR)node_reset_disabled_status) == NULL)
00114 GL_THROW("Unable to publish triplex_load island-status-reset function");
00115 }
00116 }
00117
00118 int triplex_load::isa(char *classname)
00119 {
00120 return strcmp(classname,"triplex_load")==0 || triplex_node::isa(classname);
00121 }
00122
00123 int triplex_load::create(void)
00124 {
00125 int res = triplex_node::create();
00126
00127 maximum_voltage_error = 0;
00128 base_power[0] = base_power[1] = base_power[2] = 0;
00129 power_fraction[0] = power_fraction[1] = power_fraction[2] = 0;
00130 current_fraction[0] = current_fraction[1] = current_fraction[2] = 0;
00131 impedance_fraction[0] = impedance_fraction[1] = impedance_fraction[2] = 0;
00132 power_pf[0] = power_pf[1] = power_pf[2] = 1;
00133 current_pf[0] = current_pf[1] = current_pf[2] = 1;
00134 impedance_pf[0] = impedance_pf[1] = impedance_pf[2] = 1;
00135 load_class = LC_UNKNOWN;
00136
00137 base_load_val_was_nonzero[0] = base_load_val_was_nonzero[1] = base_load_val_was_nonzero[2] = false;
00138
00139 return res;
00140 }
00141
00142
00143 int triplex_load::init(OBJECT *parent)
00144 {
00145 int ret_value;
00146 OBJECT *obj = OBJECTHDR(this);
00147
00148 ret_value = triplex_node::init(parent);
00149
00150
00151 if ((obj->flags & OF_DELTAMODE) == OF_DELTAMODE)
00152 {
00153 if ((constant_current[0] != 0.0) || (constant_current[1] != 0.0) || (constant_current[2] != 0.0))
00154 {
00155 gl_warning("triplex_load:%s - constant_current loads in deltamode are handled slightly different", obj->name ? obj->name : "unnamed");
00156
00157
00158
00159
00160
00161 }
00162 }
00163
00164 return ret_value;
00165 }
00166
00167 TIMESTAMP triplex_load::presync(TIMESTAMP t0)
00168 {
00169 if ((solver_method!=SM_FBS) && (SubNode==PARENT))
00170 {
00171 shunt[0] = shunt[1] = shunt[2] = 0.0;
00172 power[0] = power[1] = power[2] = 0.0;
00173 current[0] = current[1] = current[2] = 0.0;
00174 }
00175
00176
00177 TIMESTAMP result = triplex_node::presync(t0);
00178
00179 return result;
00180 }
00181
00182 TIMESTAMP triplex_load::sync(TIMESTAMP t0)
00183 {
00184
00185 if (GFA_enable == true)
00186 {
00187
00188 if (GFA_status == true)
00189 {
00190
00191 triplex_load_update_fxn();
00192 }
00193 else
00194 {
00195
00196 triplex_load_delete_update_fxn();
00197 }
00198 }
00199 else
00200 {
00201
00202 triplex_load_update_fxn();
00203 }
00204
00205
00206 TIMESTAMP result = triplex_node::sync(t0);
00207
00208 return result;
00209 }
00210
00211 TIMESTAMP triplex_load::postsync(TIMESTAMP t0)
00212 {
00213
00214 TIMESTAMP t1 = triplex_node::postsync(t0);
00215
00216
00217 measured_voltage_1.SetPolar(voltage1.Mag(),voltage1.Arg());
00218 measured_voltage_2.SetPolar(voltage2.Mag(),voltage2.Arg());
00219 measured_voltage_12.SetPolar(voltage12.Mag(),voltage12.Arg());
00220
00221 return t1;
00222 }
00223
00224
00225
00226 void triplex_load::triplex_load_update_fxn()
00227 {
00228 complex intermed_impedance[3];
00229 int index_var;
00230
00231 if(base_power[0] != 0.0){
00232
00233
00234 base_load_val_was_nonzero[0] = true;
00235
00236 if (power_fraction[0] + current_fraction[0] + impedance_fraction[0] != 1.0)
00237 {
00238 power_fraction[0] = 1 - current_fraction[0] - impedance_fraction[0];
00239
00240 OBJECT *obj = OBJECTHDR(this);
00241
00242 gl_warning("load:%s - ZIP components on phase 1 did not sum to 1. Setting power_fraction to %.2f", obj->name ? obj->name : "unnamed", power_fraction[0]);
00243
00244
00245
00246
00247 }
00248
00249
00250
00251 if (power_fraction[0] != 0.0){
00252 double real_power, imag_power;
00253 if(power_pf[0] == 0.0){
00254 real_power = 0.0;
00255 imag_power = base_power[0]*power_fraction[0];
00256 } else {
00257 real_power = base_power[0]*power_fraction[0]*fabs(power_pf[0]);
00258 imag_power = real_power*sqrt(1.0/(power_pf[0]*power_pf[0]) - 1.0);
00259 }
00260
00261 if(power_pf[0] < 0.0){
00262 imag_power *= -1.0;
00263 }
00264
00265 constant_power[0] = complex(real_power,imag_power);
00266 } else {
00267 constant_power[0] = complex(0, 0);
00268 }
00269
00270 if(current_fraction[0] != 0.0){
00271 double real_power, imag_power, temp_angle;
00272 complex temp_curr;
00273
00274 if(current_pf[0] == 0.0){
00275 real_power = 0.0;
00276 imag_power = base_power[0]*current_fraction[0];
00277 } else {
00278 real_power = base_power[0]*current_fraction[0]*fabs(current_pf[0]);
00279 imag_power = real_power*sqrt(1.0/(current_pf[0]*current_pf[0]) - 1.0);
00280 }
00281
00282 if(current_pf[0] < 0){
00283 imag_power *= -1.0;
00284 }
00285
00286
00287 temp_curr = ~complex(real_power, imag_power)/complex(nominal_voltage, 0);
00288 temp_angle = temp_curr.Arg() + voltage1.Arg();
00289 temp_curr.SetPolar(temp_curr.Mag(), temp_angle);
00290
00291 constant_current[0] = temp_curr;
00292 } else {
00293 constant_current[0] = complex(0, 0);
00294 }
00295
00296 if(impedance_fraction[0] != 0.0){
00297 double real_power, imag_power;
00298
00299 if (impedance_pf[0] == 0.0)
00300 {
00301 real_power = 0.0;
00302 imag_power = base_power[0]*impedance_fraction[0];
00303 }
00304 else
00305 {
00306 real_power = base_power[0]*impedance_fraction[0]*fabs(impedance_pf[0]);
00307 imag_power = real_power*sqrt(1.0/(impedance_pf[0]*impedance_pf[0]) - 1.0);
00308 }
00309
00310 if (impedance_pf[0] < 0)
00311 {
00312 imag_power *= -1.0;
00313 }
00314
00315 constant_impedance[0] = ~(complex(nominal_voltage*nominal_voltage, 0)/complex(real_power, imag_power));
00316 } else {
00317 constant_impedance[0] = complex(0, 0);
00318 }
00319 }
00320 else if (base_load_val_was_nonzero[0] == true)
00321 {
00322
00323 constant_power[0] = complex(0.0,0.0);
00324 constant_current[0] = complex(0.0,0.0);
00325 constant_impedance[0] = complex(0.0,0.0);
00326
00327
00328 base_load_val_was_nonzero[0] = false;
00329 }
00330
00331 if(base_power[1] != 0.0){
00332
00333
00334 base_load_val_was_nonzero[1] = true;
00335
00336 if (power_fraction[1] + current_fraction[1] + impedance_fraction[1] != 1.0)
00337 {
00338 power_fraction[1] = 1 - current_fraction[1] - impedance_fraction[1];
00339
00340 OBJECT *obj = OBJECTHDR(this);
00341
00342 gl_warning("load:%s - ZIP components on phase 2 did not sum to 1. Setting power_fraction to %.2f", obj->name ? obj->name : "unnamed", power_fraction[1]);
00343
00344
00345
00346
00347 }
00348
00349 if (power_fraction[1] != 0.0){
00350 double real_power, imag_power;
00351 if(power_pf[1] == 0.0){
00352 real_power = 0.0;
00353 imag_power = base_power[1]*power_fraction[1];
00354 } else {
00355 real_power = base_power[1]*power_fraction[1]*fabs(power_pf[1]);
00356 imag_power = real_power*sqrt(1.0/(power_pf[1]*power_pf[1]) - 1.0);
00357 }
00358
00359 if(power_pf[1] < 0.0){
00360 imag_power *= -1.0;
00361 }
00362
00363 constant_power[1] = complex(real_power,imag_power);
00364 } else {
00365 constant_power[1] = complex(0, 0);
00366 }
00367
00368 if(current_fraction[1] != 0.0){
00369 double real_power, imag_power, temp_angle;
00370 complex temp_curr;
00371
00372 if(current_pf[1] == 0.0){
00373 real_power = 0.0;
00374 imag_power = base_power[1]*current_fraction[1];
00375 } else {
00376 real_power = base_power[1]*current_fraction[1]*fabs(current_pf[1]);
00377 imag_power = real_power*sqrt(1.0/(current_pf[1]*current_pf[1]) - 1.0);
00378 }
00379
00380 if(current_pf[1] < 0){
00381 imag_power *= -1.0;
00382 }
00383
00384
00385 temp_curr = ~complex(real_power, imag_power)/complex(nominal_voltage, 0);
00386 temp_angle = temp_curr.Arg() + voltage1.Arg();
00387 temp_curr.SetPolar(temp_curr.Mag(), temp_angle);
00388
00389 constant_current[1] = temp_curr;
00390 } else {
00391 constant_current[1] = complex(0, 0);
00392 }
00393
00394 if(impedance_fraction[1] != 0.0){
00395 double real_power, imag_power;
00396
00397 if (impedance_pf[1] == 0.0)
00398 {
00399 real_power = 0.0;
00400 imag_power = base_power[1]*impedance_fraction[1];
00401 }
00402 else
00403 {
00404 real_power = base_power[1]*impedance_fraction[1]*fabs(impedance_pf[1]);
00405 imag_power = real_power*sqrt(1.0/(impedance_pf[1]*impedance_pf[1]) - 1.0);
00406 }
00407
00408 if (impedance_pf[1] < 0)
00409 {
00410 imag_power *= -1.0;
00411 }
00412
00413 constant_impedance[1] = ~(complex(nominal_voltage*nominal_voltage, 0)/complex(real_power, imag_power));
00414 } else {
00415 constant_impedance[1] = complex(0, 0);
00416 }
00417 }
00418 else if (base_load_val_was_nonzero[1] == true)
00419 {
00420
00421 constant_power[1] = complex(0.0,0.0);
00422 constant_current[1] = complex(0.0,0.0);
00423 constant_impedance[1] = complex(0.0,0.0);
00424
00425
00426 base_load_val_was_nonzero[1] = false;
00427 }
00428
00429 if(base_power[2] != 0.0){
00430
00431
00432 base_load_val_was_nonzero[2] = true;
00433
00434 if (power_fraction[2] + current_fraction[2] + impedance_fraction[2] != 1.0)
00435 {
00436 power_fraction[2] = 1 - current_fraction[2] - impedance_fraction[2];
00437
00438 OBJECT *obj = OBJECTHDR(this);
00439
00440 gl_warning("load:%s - ZIP components on phase 12 did not sum to 1. Setting power_fraction to %.2f", obj->name ? obj->name : "unnamed", power_fraction[2]);
00441
00442
00443
00444
00445 }
00446
00447 if (power_fraction[2] != 0.0){
00448 double real_power, imag_power;
00449 if(power_pf[2] == 0.0){
00450 real_power = 0.0;
00451 imag_power = base_power[2]*power_fraction[2];
00452 } else {
00453 real_power = base_power[2]*power_fraction[2]*fabs(power_pf[2]);
00454 imag_power = real_power*sqrt(1.0/(power_pf[2]*power_pf[2]) - 1.0);
00455 }
00456
00457 if(power_pf[2] < 0.0){
00458 imag_power *= -1.0;
00459 }
00460
00461 constant_power[2] = complex(real_power,imag_power);
00462 } else {
00463 constant_power[2] = complex(0, 0);
00464 }
00465
00466 if(current_fraction[2] != 0.0){
00467 double real_power, imag_power, temp_angle;
00468 complex temp_curr;
00469
00470 if(current_pf[2] == 0.0){
00471 real_power = 0.0;
00472 imag_power = base_power[2]*current_fraction[2];
00473 } else {
00474 real_power = base_power[2]*current_fraction[2]*fabs(current_pf[2]);
00475 imag_power = real_power*sqrt(1.0/(current_pf[2]*current_pf[2]) - 1.0);
00476 }
00477
00478 if(current_pf[2] < 0){
00479 imag_power *= -1.0;
00480 }
00481
00482
00483
00484 temp_curr = ~complex(real_power, imag_power)/complex(2*nominal_voltage, 0);
00485 temp_angle = temp_curr.Arg() + voltage12.Arg();
00486 temp_curr.SetPolar(temp_curr.Mag(), temp_angle);
00487
00488 constant_current[2] = temp_curr;
00489 } else {
00490 constant_current[2] = complex(0, 0);
00491 }
00492
00493 if(impedance_fraction[2] != 0.0){
00494 double real_power, imag_power;
00495
00496 if (impedance_pf[2] == 0.0)
00497 {
00498 real_power = 0.0;
00499 imag_power = base_power[2]*impedance_fraction[2];
00500 }
00501 else
00502 {
00503 real_power = base_power[2]*impedance_fraction[2]*fabs(impedance_pf[2]);
00504 imag_power = real_power*sqrt(1.0/(impedance_pf[2]*impedance_pf[2]) - 1.0);
00505 }
00506
00507 if (impedance_pf[2] < 0)
00508 {
00509 imag_power *= -1.0;
00510 }
00511
00512
00513 constant_impedance[2] = ~(complex(4*nominal_voltage*nominal_voltage, 0)/complex(real_power, imag_power));
00514 } else {
00515 constant_impedance[2] = complex(0, 0);
00516 }
00517 }
00518 else if (base_load_val_was_nonzero[2] == true)
00519 {
00520
00521 constant_power[2] = complex(0.0,0.0);
00522 constant_current[2] = complex(0.0,0.0);
00523 constant_impedance[2] = complex(0.0,0.0);
00524
00525
00526 base_load_val_was_nonzero[2] = false;
00527 }
00528
00529
00530
00531 if (enable_frequency_dependence == true)
00532 {
00533
00534 for (index_var=0; index_var<3; index_var++)
00535 {
00536 if ((constant_impedance[index_var].IsZero()) == false)
00537 {
00538
00539 intermed_impedance[index_var].SetReal(constant_impedance[index_var].Re());
00540
00541
00542 if (constant_impedance[index_var].Im()<0)
00543 {
00544 intermed_impedance[index_var].SetImag(constant_impedance[index_var].Im()/current_frequency*nominal_frequency);
00545 }
00546 else
00547 {
00548 intermed_impedance[index_var].SetImag(constant_impedance[index_var].Im()/nominal_frequency*current_frequency);
00549 }
00550 }
00551 else
00552 {
00553 intermed_impedance[index_var] = 0.0;
00554 }
00555 }
00556 }
00557 else
00558 {
00559
00560 intermed_impedance[0] = constant_impedance[0];
00561 intermed_impedance[1] = constant_impedance[1];
00562 intermed_impedance[2] = constant_impedance[2];
00563 }
00564
00565 if ((solver_method!=SM_FBS) && (SubNode==PARENT))
00566 {
00567
00568 if (!(intermed_impedance[0].IsZero()))
00569 pub_shunt[0] += complex(1.0)/intermed_impedance[0];
00570
00571 if (!(intermed_impedance[1].IsZero()))
00572 pub_shunt[1] += complex(1.0)/intermed_impedance[1];
00573
00574 if (!(intermed_impedance[2].IsZero()))
00575 pub_shunt[2] += complex(1.0)/intermed_impedance[2];
00576
00577 power1 += constant_power[0];
00578 power2 += constant_power[1];
00579 power12 += constant_power[2];
00580 current1 += constant_current[0];
00581 current2 += constant_current[1];
00582 current12 += constant_current[2];
00583 }
00584 else
00585 {
00586 if(intermed_impedance[0].IsZero())
00587 pub_shunt[0] = 0.0;
00588 else
00589 pub_shunt[0] = complex(1)/intermed_impedance[0];
00590
00591 if(intermed_impedance[1].IsZero())
00592 pub_shunt[1] = 0.0;
00593 else
00594 pub_shunt[1] = complex(1)/intermed_impedance[1];
00595
00596 if(intermed_impedance[2].IsZero())
00597 pub_shunt[2] = 0.0;
00598 else
00599 pub_shunt[2] = complex(1)/intermed_impedance[2];
00600
00601 power1 = constant_power[0];
00602 power2 = constant_power[1];
00603 power12 = constant_power[2];
00604 current1 = constant_current[0];
00605 current2 = constant_current[1];
00606 current12 = constant_current[2];
00607 }
00608 }
00609
00610
00611 void triplex_load::triplex_load_delete_update_fxn(void)
00612 {
00613 int index_var;
00614
00615 if ((solver_method!=SM_FBS) && ((SubNode==PARENT) || (SubNode==DIFF_PARENT)))
00616 {
00617 if (SubNode != PARENT)
00618 {
00619
00620 for (index_var=0; index_var<3; index_var++)
00621 {
00622 pub_shunt[index_var] = complex(0.0,0.0);
00623 power[index_var] = complex(0.0,0.0);
00624 current[index_var] = complex(0.0,0.0);
00625 }
00626
00627
00628 current12 = complex(0.0,0.0);
00629 }
00630 }
00631 else
00632 {
00633
00634 for (index_var=0; index_var<3; index_var++)
00635 {
00636 pub_shunt[index_var] = complex(0.0,0.0);
00637 power[index_var] = complex(0.0,0.0);
00638 current[index_var] = complex(0.0,0.0);
00639 }
00640
00641
00642 current12 = complex(0.0,0.0);
00643 }
00644 }
00645
00646
00647
00649
00651
00652 SIMULATIONMODE triplex_load::inter_deltaupdate_triplex_load(unsigned int64 delta_time, unsigned long dt, unsigned int iteration_count_val,bool interupdate_pos)
00653 {
00654 OBJECT *hdr = OBJECTHDR(this);
00655 double deltat, deltatimedbl;
00656 STATUS return_status_val;
00657
00658
00659 deltat = (double)dt/(double)DT_SECOND;
00660
00661
00662 if ((iteration_count_val==0) && (interupdate_pos == false))
00663 {
00664
00665 deltatimedbl = (double)delta_time/(double)DT_SECOND;
00666
00667
00668 prev_time_dbl = (double)gl_globalclock + deltatimedbl;
00669
00670
00671 if (fmeas_type != FM_NONE)
00672 {
00673
00674 memcpy(&prev_freq_state,&curr_freq_state,sizeof(FREQM_STATES));
00675 }
00676 }
00677
00678
00679 if ((delta_time==0) && (iteration_count_val==0) && (interupdate_pos == false) && (fmeas_type != FM_NONE))
00680 {
00681
00682 init_freq_dynamics();
00683 }
00684
00685
00686 if ((GFA_enable == true) && (iteration_count_val == 0) && (interupdate_pos == false))
00687 {
00688
00689 GFA_Update_time = perform_GFA_checks(deltat);
00690 }
00691
00692 if (interupdate_pos == false)
00693 {
00694
00695 if ((solver_method!=SM_FBS) && (SubNode==PARENT))
00696 {
00697 shunt[0] = shunt[1] = shunt[2] = 0.0;
00698 power[0] = power[1] = power[2] = 0.0;
00699 current[0] = current[1] = current[2] = 0.0;
00700 }
00701
00702
00703 BOTH_triplex_node_presync_fxn();
00704
00705
00706 NR_node_presync_fxn(0);
00707
00708
00709 if (GFA_enable == true)
00710 {
00711
00712 if (GFA_status == true)
00713 {
00714
00715 triplex_load_update_fxn();
00716 }
00717 else
00718 {
00719
00720 triplex_load_delete_update_fxn();
00721 }
00722 }
00723 else
00724 {
00725
00726 triplex_load_update_fxn();
00727 }
00728
00729
00730 BOTH_triplex_node_sync_fxn();
00731
00732
00733 NR_node_sync_fxn(hdr);
00734
00735 return SM_DELTA;
00736
00737 }
00738 else
00739 {
00740
00741 BOTH_node_postsync_fxn(hdr);
00742
00743
00744 measured_voltage_1.SetPolar(voltage1.Mag(),voltage1.Arg());
00745 measured_voltage_2.SetPolar(voltage2.Mag(),voltage2.Arg());
00746 measured_voltage_12.SetPolar(voltage12.Mag(),voltage12.Arg());
00747
00748
00749 if (fmeas_type != FM_NONE)
00750 {
00751 return_status_val = calc_freq_dynamics(deltat);
00752
00753
00754 if (return_status_val == FAILED)
00755 {
00756 return SM_ERROR;
00757 }
00758 }
00759
00760
00761
00762 if (GFA_enable == true)
00763 {
00764
00765 if ((GFA_Update_time > 0.0) && (GFA_Update_time < 1.7))
00766 {
00767
00768 return SM_DELTA;
00769 }
00770 else
00771 {
00772 return SM_EVENT;
00773 }
00774 }
00775 else
00776 {
00777 return SM_EVENT;
00778 }
00779 }
00780 }
00781
00783
00785
00793 EXPORT int create_triplex_load(OBJECT **obj, OBJECT *parent)
00794 {
00795 try
00796 {
00797 *obj = gl_create_object(triplex_load::oclass);
00798 if (*obj!=NULL)
00799 {
00800 triplex_load *my = OBJECTDATA(*obj,triplex_load);
00801 gl_set_parent(*obj,parent);
00802 return my->create();
00803 }
00804 else
00805 return 0;
00806 }
00807 CREATE_CATCHALL(triplex_load);
00808 }
00809
00816 EXPORT int init_triplex_load(OBJECT *obj)
00817 {
00818 try {
00819 triplex_load *my = OBJECTDATA(obj,triplex_load);
00820 return my->init(obj->parent);
00821 }
00822 INIT_CATCHALL(triplex_load);
00823 }
00824
00833 EXPORT TIMESTAMP sync_triplex_load(OBJECT *obj, TIMESTAMP t0, PASSCONFIG pass)
00834 {
00835 try {
00836 triplex_load *pObj = OBJECTDATA(obj,triplex_load);
00837 TIMESTAMP t1 = TS_NEVER;
00838 switch (pass) {
00839 case PC_PRETOPDOWN:
00840 return pObj->presync(t0);
00841 case PC_BOTTOMUP:
00842 return pObj->sync(t0);
00843 case PC_POSTTOPDOWN:
00844 t1 = pObj->postsync(t0);
00845 obj->clock = t0;
00846 return t1;
00847 default:
00848 throw "invalid pass request";
00849 }
00850 }
00851 SYNC_CATCHALL(triplex_load);
00852 }
00853
00854 EXPORT int isa_triplex_load(OBJECT *obj, char *classname)
00855 {
00856 return OBJECTDATA(obj,triplex_load)->isa(classname);
00857 }
00858
00859
00860 EXPORT SIMULATIONMODE interupdate_triplex_load(OBJECT *obj, unsigned int64 delta_time, unsigned long dt, unsigned int iteration_count_val, bool interupdate_pos)
00861 {
00862 triplex_load *my = OBJECTDATA(obj,triplex_load);
00863 SIMULATIONMODE status = SM_ERROR;
00864 try
00865 {
00866 status = my->inter_deltaupdate_triplex_load(delta_time,dt,iteration_count_val,interupdate_pos);
00867 return status;
00868 }
00869 catch (char *msg)
00870 {
00871 gl_error("interupdate_triplex_load(obj=%d;%s): %s", obj->id, obj->name?obj->name:"unnamed", msg);
00872 return status;
00873 }
00874 }