00001
00017 #include <stdlib.h>
00018 #include <stdio.h>
00019 #include <errno.h>
00020 #include <math.h>
00021 #include <iostream>
00022 using namespace std;
00023
00024 #include "transformer.h"
00025
00026 CLASS* transformer::oclass = NULL;
00027 CLASS* transformer::pclass = NULL;
00028 transformer *transformer::defaults = NULL;
00029
00030 transformer::transformer(MODULE *mod) : link(mod)
00031 {
00032 if(oclass == NULL)
00033 {
00034 pclass = link::oclass;
00035
00036 oclass = gl_register_class(mod,"transformer",PC_BOTTOMUP|PC_POSTTOPDOWN);
00037 if(oclass == NULL)
00038 GL_THROW("unable to register object class implemented by %s",__FILE__);
00039
00040 if(gl_publish_variable(oclass,
00041 PT_object, "configuration", PADDR(configuration),
00042 PT_object, "to",PADDR(to),
00043 PT_object, "from",PADDR(from),
00044 PT_set, "phases",PADDR(phases),
00045 PT_KEYWORD, "A",PHASE_A,
00046 PT_KEYWORD, "B",PHASE_B,
00047 PT_KEYWORD, "C",PHASE_C,
00048 PT_KEYWORD, "N",PHASE_N,
00049 PT_KEYWORD, "S",PHASE_S,
00050 PT_KEYWORD, "D",PHASE_D,
00051 NULL) < 1) GL_THROW("unable to publish properties in %s",__FILE__);
00052
00053
00054 defaults = this;
00055 memset(this,0,sizeof(transformer));
00056 }
00057 }
00058
00059 int transformer::isa(char *classname)
00060 {
00061 return strcmp(classname,"transformer")==0 || link::isa(classname);
00062 }
00063
00064 int transformer::create()
00065 {
00066 int result = link::create();
00067 memcpy(this,defaults,sizeof(transformer));
00068 return result;
00069 }
00070
00071 int transformer::init()
00072 {
00073 double V_base,za_basehi,za_baselo,V_basehi;
00074 int32 sa_base;
00075 complex nt, nt_a, nt_b, nt_c, zt, zt_a, zt_b, zt_c,
00076 inv_nt_a, inv_nt_b, inv_nt_c,z0,z1,z2;
00077
00078 link::init();
00079
00080 if (!configuration)
00081 throw "no transformer configuration specified.";
00082
00083 if (!gl_object_isa(configuration, "transformer_configuration"))
00084 throw "invalid transformer configuration";
00085 transformer_configuration *config = OBJECTDATA(configuration,
00086 transformer_configuration);
00087
00088 V_base = config->V_secondary;
00089 nt = config->V_primary / config->V_secondary;
00090
00091 zt = (config->impedence * V_base * V_base) / ((double) config->kVA_rating * 1000.0);
00092
00093
00094 for (int i = 0; i < 3; i++) {
00095 for (int j = 0; j < 3; j++) {
00096 a_mat[i][j] = b_mat[i][j] = c_mat[i][j] = d_mat[i][j] =
00097 A_mat[i][j] = B_mat[i][j] = 0.0;
00098 }
00099 i_abc_in[i] = i_n_in[i] = i_abc_out[i] = i_n_out[i] = 1.0;
00100 }
00101
00102 switch (config->connect_type) {
00103 case transformer_configuration::WYE_WYE:
00104 case transformer_configuration::SINGLE_PHASE:
00105 if (has_phase(PHASE_A)) {
00106 nt_a = nt;
00107 zt_a = nt_a * zt;
00108 inv_nt_a = complex(1.0) / nt_a;
00109 } else {
00110 nt_a = zt_a = inv_nt_a = 0.0;
00111 }
00112
00113 if (has_phase(PHASE_B)) {
00114 nt_b = nt;
00115 zt_b = nt_b * zt;
00116 inv_nt_b = complex(1.0) / nt_b;
00117 } else {
00118 nt_b = zt_b = inv_nt_b = 0.0;
00119 }
00120
00121 if (has_phase(PHASE_C)) {
00122 nt_c = nt;
00123 zt_c = nt_c * zt;
00124 inv_nt_c = complex(1.0) / nt_c;
00125 } else {
00126 nt_c = zt_c = inv_nt_c = 0.0;
00127 }
00128
00129 a_mat[0][0] = nt_a;
00130 a_mat[1][1] = nt_b;
00131 a_mat[2][2] = nt_c;
00132
00133 b_mat[0][0] = zt_a;
00134 b_mat[1][1] = zt_b;
00135 b_mat[2][2] = zt_c;
00136
00137 B_mat[0][0] = zt;
00138 B_mat[1][1] = zt;
00139 B_mat[2][2] = zt;
00140
00141 d_mat[0][0] = A_mat[0][0] = inv_nt_a;
00142 d_mat[1][1] = A_mat[1][1] = inv_nt_b;
00143 d_mat[2][2] = A_mat[2][2] = inv_nt_c;
00144
00145 break;
00146 case transformer_configuration::DELTA_DELTA:
00147 a_mat[0][0] = a_mat[1][1] = a_mat[2][2] = nt * 2.0 / 3.0;
00148 a_mat[0][1] = a_mat[0][2] = a_mat[1][0] = a_mat[1][2] = a_mat[2][0] = a_mat[2][1] = -nt / 3.0;
00149
00150 b_mat[0][0] = b_mat[1][1] = nt * zt;
00151 b_mat[2][0] = b_mat[2][1] = -nt * zt;
00152
00153 d_mat[0][0] = d_mat[1][1] = d_mat[2][2] = complex(1.0) / nt;
00154
00155 A_mat[0][0] = A_mat[1][1] = A_mat[2][2] = complex(2.0) / (nt * 3.0);
00156 A_mat[0][1] = A_mat[0][2] = A_mat[1][0] = A_mat[1][2] = A_mat[2][0] = A_mat[2][1] = complex(-1.0) / (nt * 3.0);
00157
00158 B_mat[0][0] = B_mat[1][1] = zt;
00159 B_mat[2][0] = B_mat[2][1] = -zt;
00160
00161 break;
00162 case transformer_configuration::DELTA_GWYE:
00163 if (nt.Mag()>1.0)
00164 {
00165 nt *= sqrt(3.0);
00166
00167 a_mat[0][1] = a_mat[1][2] = a_mat[2][0] = -nt * 2.0 / 3.0;
00168 a_mat[0][2] = a_mat[1][0] = a_mat[2][1] = -nt / 3.0;
00169
00170 b_mat[0][1] = b_mat[1][2] = b_mat[2][0] = -nt * zt * 2.0 / 3.0;
00171 b_mat[0][2] = b_mat[1][0] = b_mat[2][1] = -nt * zt / 3.0;
00172
00173 d_mat[0][0] = d_mat[1][1] = d_mat[2][2] = complex(1.0) / nt;
00174 d_mat[0][1] = d_mat[1][2] = d_mat[2][0] = complex(-1.0) / nt;
00175
00176 A_mat[0][0] = A_mat[1][1] = A_mat[2][2] = complex(1.0) / nt;
00177 A_mat[0][2] = A_mat[1][0] = A_mat[2][1] = complex(-1.0) / nt;
00178
00179 B_mat[0][0] = B_mat[1][1] = B_mat[2][2] = zt;
00180 }
00181 else {
00182 nt *= sqrt(3.0);
00183
00184 a_mat[0][0] = a_mat[1][1] = a_mat[2][2] = nt * 2.0 / 3.0;
00185 a_mat[0][1] = a_mat[1][2] = a_mat[2][0] = nt / 3.0;
00186
00187 b_mat[0][0] = b_mat[1][1] = b_mat[2][2] = nt * zt * 2.0 / 3.0;
00188 b_mat[0][1] = b_mat[1][2] = b_mat[2][0] = nt * zt / 3.0;
00189
00190 d_mat[0][0] = d_mat[1][1] = d_mat[2][2] = complex(1.0) / nt;
00191 d_mat[0][2] = d_mat[1][0] = d_mat[2][1] = complex(-1.0) / nt;
00192
00193 A_mat[0][0] = A_mat[1][1] = A_mat[2][2] = complex(1.0) / nt;
00194 A_mat[0][1] = A_mat[1][2] = A_mat[2][0] = complex(-1.0) / nt;
00195
00196 B_mat[0][0] = B_mat[1][1] = B_mat[2][2] = zt;
00197 }
00198
00199 break;
00200 case transformer_configuration::SINGLE_PHASE_CENTER_TAPPED:
00201 V_basehi = config->V_primary;
00202 sa_base = config->phaseA_kVA_rating;
00203 za_basehi = (V_basehi*V_basehi)/(sa_base*1000);
00204 za_baselo = (V_base * V_base)/(sa_base*1000);
00205 nt = config->V_primary/config->V_secondary;
00206
00207 z0 = complex(0.5 * config->impedence.Re(),0.8*config->impedence.Im()) * complex(za_basehi,0);
00208
00209 z1 = complex(config->impedence.Re(),0.4 * config->impedence.Im()) * complex(za_baselo,0);
00210
00211 z2 = complex(config->impedence.Re(),0.4 * config->impedence.Im()) * complex(za_baselo,0);
00212 zt_b = complex(0,0);
00213 zt_c = complex(0,0);
00214
00215 b_mat[0][0] = (nt *z1)+(z0/nt);
00216 b_mat[0][1] = complex(-1,0) * (z0/nt);
00217 b_mat[0][2] = complex(0,0);
00218 b_mat[1][0] = (z0/nt);
00219 b_mat[1][1] = complex(-1,0) * ((nt*z2) + z0/nt);
00220 b_mat[1][2] = complex(0,0);
00221 b_mat[2][0] = complex(0,0);
00222 b_mat[2][1] = complex(0,0);
00223 b_mat[2][2] = complex(0,0);
00224
00225 B_mat[0][0] = (z1) + (z0/(nt^2));
00226 B_mat[0][1] = complex(-1,0) * (z0/(nt^2));
00227 B_mat[1][0] = (z0/(nt^2));
00228 B_mat[1][1] = complex(-1,0) * ((z2) + (z0/(nt^2)));
00229
00230 if (has_phase(PHASE_A)) {
00231 a_mat[0][0] = a_mat[1][0] = nt;
00232
00233 d_mat[0][0] = complex(1,0)/nt;
00234 d_mat[0][1] = complex(-1,0)/nt;
00235
00236 A_mat[0][0] = complex(1,0)/nt;
00237 A_mat[1][0] = complex(1,0)/nt;
00238 }
00239
00240 else if (has_phase(PHASE_B)) {
00241 a_mat[0][1] = a_mat[1][1] = nt;
00242
00243 d_mat[1][0] = complex(1,0)/nt;
00244 d_mat[1][1] = complex(-1,0)/nt;
00245
00246 A_mat[0][1] = complex(1,0)/nt;
00247 A_mat[1][1] = complex(1,0)/nt;
00248 }
00249
00250 else if (has_phase(PHASE_C)) {
00251 a_mat[0][2] = a_mat[1][2] = nt;
00252
00253 d_mat[2][0] = complex(1,0)/nt;
00254 d_mat[2][1] = complex(-1,0)/nt;
00255
00256 A_mat[0][2] = complex(1,0)/nt;
00257 A_mat[1][2] = complex(1,0)/nt;
00258 }
00259 break;
00260 default:
00261 throw "unknown transformer connect type";
00262 }
00263
00264 #ifdef _TESTING
00265 extern bool show_matrix_values;
00266 if (show_matrix_values)
00267 {
00268 gl_testmsg("transformer:\ta matrix");
00269 print_matrix(a_mat);
00270 gl_testmsg("transformer:\tA matrix");
00271 print_matrix(A_mat);
00272 gl_testmsg("transformer:\tb matrix");
00273 print_matrix(b_mat);
00274 gl_testmsg("transformer:\tB matrix");
00275 print_matrix(B_mat);
00276 gl_testmsg("transformer:\td matrix");
00277 print_matrix(d_mat);
00278 }
00279 #endif
00280
00281 return 1;
00282 }
00283
00285
00287
00295 EXPORT int create_transformer(OBJECT **obj, OBJECT *parent)
00296 {
00297 try
00298 {
00299 *obj = gl_create_object(transformer::oclass,sizeof(transformer));
00300 if (*obj!=NULL)
00301 {
00302 transformer *my = OBJECTDATA(*obj,transformer);
00303 gl_set_parent(*obj,parent);
00304 return my->create();
00305 }
00306 }
00307 catch (char *msg)
00308 {
00309 gl_error("create_transformer: %s", msg);
00310 }
00311 return 1;
00312 }
00313
00314
00315
00322 EXPORT int init_transformer(OBJECT *obj)
00323 {
00324 transformer *my = OBJECTDATA(obj,transformer);
00325 try {
00326 return my->init();
00327 }
00328 catch (char *msg)
00329 {
00330 GL_THROW("%s (transformer:%d): %s", my->get_name(), my->get_id(), msg);
00331 return 0;
00332 }
00333 }
00334
00342 EXPORT TIMESTAMP sync_transformer(OBJECT *obj, TIMESTAMP t0, PASSCONFIG pass)
00343 {
00344 transformer *pObj = OBJECTDATA(obj,transformer);
00345 try {
00346 if (pass==PC_BOTTOMUP)
00347 return pObj->sync(t0);
00348 else
00349 {
00350 TIMESTAMP t1 = pObj->postsync(t0);
00351 obj->clock = t0;
00352 return t1;
00353 }
00354 } catch (const char *error) {
00355 GL_THROW("%s (%s:%d): %s", pObj->get_name(), pObj->get_id(), error);
00356 return 0;
00357 } catch (...) {
00358 GL_THROW("%s (%s:%d): %s", pObj->get_name(), pObj->get_id(), "unknown exception");
00359 return 0;
00360 }
00361 }
00362
00363 EXPORT int isa_transformer(OBJECT *obj, char *classname)
00364 {
00365 return OBJECTDATA(obj,transformer)->isa(classname);
00366 }
00367