network/link.cpp

00001 
00048 #include <stdlib.h>
00049 #include <stdio.h>
00050 #include <errno.h>
00051 #include <math.h>
00052 #include "network.h"
00053 #include "lock.h"
00054 
00056 // link CLASS FUNCTIONS
00058 
00059 CLASS* link::oclass = NULL;
00060 CLASS* link::pclass = NULL;
00061 link *link::defaults = NULL;
00062 
00063 link::link(MODULE *mod) 
00064 {
00065     // first time init
00066     if (oclass==NULL)
00067     {
00068         // register the class definition
00069         link_class = oclass = gl_register_class(mod,"link",PC_BOTTOMUP);
00070         if (oclass==NULL)
00071             GL_THROW("unable to register object class implemented by %s",__FILE__);
00072 
00073         // publish the class properties
00074         if (gl_publish_variable(oclass,
00075             PT_complex, "Y", PADDR(Y),
00076             PT_complex, "I", PADDR(I),
00077             PT_double, "B", PADDR(B),
00078             PT_object, "from", PADDR(from),
00079             PT_object, "to", PADDR(to),
00080             NULL)<1) GL_THROW("unable to publish properties in %s",__FILE__);
00081 
00082         // setup the default values
00083         defaults = this;
00084         Y = complex(0,0);
00085         B = 0.0;
00086         I = complex(0,0);
00087         from = NULL;
00088         to = NULL;
00089         turns_ratio = 1.0;
00090     }
00091 }
00092 
00093 int link::create() 
00094 {
00095     memcpy(this,defaults,sizeof(*this));
00096     return 1;
00097 }
00098 
00099 int link::init(node *parent)
00100 {
00101     return 1;
00102 }
00103 
00104 TIMESTAMP link::sync(TIMESTAMP t0) 
00105 {
00106     node *f = OBJECTDATA(from,node);
00107     node *t = OBJECTDATA(to,node);
00108     if (f==NULL || t==NULL)
00109         return TS_NEVER;
00110 
00111     // Note: n!=1 <=> B==0
00112     // compute effective impedance
00113     complex Yeff = Y + complex(0,B/2);
00114 
00115     // off-nominal ratio [Kundur 1993, p.236]
00116     double c = 1/turns_ratio; 
00117 
00118     // compute effective admittance
00119     complex Yc = Yeff*c;
00120 
00121     // compute line currents (note from/to switched)
00122     complex Ifrom = t->V * Y * c;
00123     complex Ito = f->V * Y * c;
00124 
00125     // add to self admittance (contribution diagonal terms)
00126     // add to current injections (contribution to off-diagonal terms)
00127     complex Ys = Yc + Yc*(c-1);
00128     LOCK_OBJECT(from);
00129     f->Ys += Ys;
00130     f->YVs -= Ifrom;
00131     UNLOCK_OBJECT(from);
00132 
00133     Ys = Yc + Yeff*(1-c);
00134     LOCK_OBJECT(to);
00135     t->YVs -= Ito;
00136     t->Ys += Ys;
00137     UNLOCK_OBJECT(to);
00138 
00139     // compute current over line (from->to)
00140     I = Ito - Ifrom;
00141 
00142 #ifdef _DEBUG
00143     // link debugging
00144     if (debug_link==1)
00145     {
00146         OBJECT* obj = OBJECTHDR(this);
00147         static int first=-1;
00148         if (first==-1) first = obj->id;
00149         if (obj->id==first)
00150         {
00151             printf("\n");
00152             printf("Link  From -> To             R        X        B        Y                 Ifrom             Ito               I               \n");
00153             printf("===== ====================== ======== ======== ======== ================= ================= ================= =================\n");
00154         }
00155         printf("%2d-%2d %-9.9s -> %-9.9s %+8.4f %+8.4f %+8.4f %+8.4f%+8.4fj %+8.4f%+8.4fj %+8.4f%+8.4fj %+8.4f%+8.4fj\n", 
00156             from->id, to->id, 
00157             OBJECTDATA(from,node)->name,OBJECTDATA(to,node)->name,
00158             (complex(1,0)/Y).Re(),(complex(1,0)/Y).Im(), B,
00159             Y.Re(), Y.Im(),
00160             Ifrom.Re(), Ifrom.Im(), 
00161             Ito.Re(), Ito.Im(), 
00162             I.Re(), I.Im());
00163     }
00164 #endif // _DEBUG
00165 
00166     return TS_NEVER;
00167 }
00168 
00170 // IMPLEMENTATION OF CORE LINKAGE: link
00172 
00173 EXPORT int create_link(OBJECT **obj, OBJECT *parent)
00174 {
00175     *obj = gl_create_object(link_class,sizeof(link));
00176     if (*obj!=NULL)
00177     {
00178         last_link = *obj;
00179         link *my = OBJECTDATA(*obj,link);
00180         gl_set_parent(*obj,parent);
00181         my->create();
00182         return 1;
00183     }
00184     return 0;
00185 }
00186 
00187 EXPORT TIMESTAMP sync_link(OBJECT *obj, TIMESTAMP t0)
00188 {
00189     TIMESTAMP t1 = OBJECTDATA(obj,link)->sync(t0);
00190     obj->clock = t0;
00191     return t1;
00192 }
00193 
00194 EXPORT int init_link(OBJECT *obj)
00195 {
00196 
00197     return OBJECTDATA(obj,link)->init(OBJECTDATA(obj->parent,node));
00198 }
00199 
00200 

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