powerflow/transformer.cpp

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         // Set up defaults
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 //  zt = (complex(config->R_pu, config->X_pu) * V_base * V_base) / ((double) config->kVA_rating * 1000.0);
00091     zt = (config->impedence * V_base * V_base) / ((double) config->kVA_rating * 1000.0);
00092     /* that shouldn't mutate impedence. */
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)//step down transformer
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 {//step up transformer
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             //z0 = complex(0.5 * config->R_pu,0.8*config->X_pu) * complex(za_basehi,0);
00207             z0 = complex(0.5 * config->impedence.Re(),0.8*config->impedence.Im()) * complex(za_basehi,0);
00208             //z1 = complex(config->R_pu,0.4 * config->X_pu) * complex(za_baselo,0);
00209             z1 = complex(config->impedence.Re(),0.4 * config->impedence.Im()) * complex(za_baselo,0);
00210             //z2 = complex(config->R_pu,0.4 * config->X_pu) * complex(za_baselo,0);
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 // IMPLEMENTATION OF CORE LINKAGE: transformer
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 

GridLAB-DTM Version 1.0
An open-source project initiated by the US Department of Energy