network/relay.cpp

00001 
00029 #include <stdlib.h>
00030 #include <stdio.h>
00031 #include <errno.h>
00032 #include <math.h>
00033 #include "network.h"
00034 
00035 /* Coefficient              U1          U2          U3          U4          U5      */
00036 static const double Ap[] = {0.0226,     0.1800,     0.0963,     0.0352,     0.00262 };
00037 static const double Bp[] = {0.0104,     5.9500,     3.8800,     5.6700,     0.00342 };
00038 static const double Cp[] = {0.0200,     2.0000,     2.0000,     2.0000,     0.02000 };
00039 static const double Br[] = {1.0800,     5.9500,     3.8800,     5.6700,     0.32300 };
00040 static const double Cr[] = {2.0000,     2.0000,     2.0000,     2.0000,     2.00000 };
00041 
00042 
00044 // relay CLASS FUNCTIONS
00046 CLASS* relay::oclass = NULL;
00047 CLASS* relay::pclass = NULL;
00048 relay *relay::defaults = NULL;
00049 
00050 relay::relay(MODULE *mod) : link(mod)
00051 {
00052     // first time init
00053     if (oclass==NULL)
00054     {
00055         // register the class definition
00056         relay_class = oclass = gl_register_class(mod,"relay",PC_BOTTOMUP);
00057         if (oclass==NULL)
00058             GL_THROW("unable to register object class implemented by %s",__FILE__);
00059 
00060         // publish the class properties
00061         if (gl_publish_variable(oclass,
00062             PT_enumeration,"Curve",PADDR(Curve),
00063                 PT_KEYWORD,"FC_U1",FC_U1,
00064                 PT_KEYWORD,"FC_U2",FC_U2,
00065                 PT_KEYWORD,"FC_U3",FC_U3,
00066                 PT_KEYWORD,"FC_U4",FC_U4,
00067                 PT_KEYWORD,"FC_U5",FC_U5,
00068             PT_double, "TimeDial", PADDR(TimeDial),
00069             PT_double, "SetCurrent", PADDR(SetCurrent),
00070             PT_enumeration,"State",PADDR(State),
00071                 PT_KEYWORD,"FS_CLOSED",FS_CLOSED,
00072                 PT_KEYWORD,"FS_TRIPPED",FS_TRIPPED,
00073                 PT_KEYWORD,"FS_RECLOSED",FS_RECLOSED,
00074                 PT_KEYWORD,"FS_LOCKOUT",FS_LOCKOUT,
00075                 PT_KEYWORD,"FS_FAULT",FS_FAULT,
00076             NULL)<1) GL_THROW("unable to publish properties in %s",__FILE__);
00077 
00078         // setup the default values
00079         defaults = this;
00080     }
00081 }
00082 
00083 int relay::create() 
00084 {
00085     int result = link::create();
00086     memcpy(this,defaults,sizeof(*this));
00087     return result;
00088 }
00089 
00090 TIMESTAMP relay::sync(TIMESTAMP t0) 
00091 {
00092     link::sync(t0);
00093 
00094     double M = I.Mag()/SetCurrent;
00095     switch (State) {
00096     case FS_CLOSED:
00097         if (M>1)
00098         {   // compute trip time
00099             Tp = TimeDial * (Ap[Curve]+Bp[Curve]/(pow(M,Cp[Curve])-1));
00100             TIMESTAMP t1 = Tstate + (TIMESTAMP)(Tp*TS_SECOND);
00101             if (t1<=t0)
00102             {
00103                 State=FS_TRIPPED;
00104                 Tstate = t0;
00105                 t1 = TS_NEVER;
00106             }
00107             return t1;
00108         }
00109         else if (M<=1)
00110         {   // reset timer
00111             Tstate = 0;
00112             return TS_NEVER;
00113         }
00114         break;
00115     case FS_TRIPPED:
00116         if (M<1)
00117         {
00118             // compute reset time
00119             Tr = TimeDial *(Br[Curve]/(1-pow(M,Cr[Curve])));
00120             TIMESTAMP t1 = Tstate +(TIMESTAMP)(Tr*TS_SECOND);
00121             if (t1<=t0)
00122             {
00123                 State = FS_RECLOSED;
00124                 Tstate = t0;
00125                 return TS_NEVER;
00126             }
00127             else
00128                 return t1;
00129         }
00130         break;
00131     case FS_RECLOSED:
00132         // TODO:
00133         break;
00134     case FS_LOCKOUT:
00135         // TODO:
00136         break;
00137     case FS_FAULT:
00138         // TODO:
00139         break;
00140     default:
00141         break;
00142     }
00143 
00144     return TS_NEVER;
00145 }
00147 // IMPLEMENTATION OF CORE LINKAGE: relay
00149 
00150 EXPORT int create_relay(OBJECT **obj, OBJECT *parent)
00151 {
00152     *obj = gl_create_object(relay_class,sizeof(relay));
00153     if (*obj!=NULL)
00154     {
00155         relay *my = OBJECTDATA(*obj,relay);
00156         gl_set_parent(*obj,parent);
00157         my->create();
00158         return 1;
00159     }
00160     return 0;
00161 }
00162 
00163 EXPORT TIMESTAMP sync_relay(OBJECT *obj, TIMESTAMP t0)
00164 {
00165     TIMESTAMP t1 = OBJECTDATA(obj,relay)->sync(t0);
00166     obj->clock = t0;
00167     return t1;
00168 }
00169 

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