00001
00010 #include <stdlib.h>
00011 #include <stdio.h>
00012 #include <errno.h>
00013 #include <math.h>
00014 #include "network.h"
00015
00016
00018
00020 CLASS* fuse::oclass = NULL;
00021 CLASS* fuse::pclass = NULL;
00022 fuse *fuse::defaults = NULL;
00023 CLASS *fuse_class = (NULL);
00024
00025 fuse::fuse(MODULE *mod) : link(mod)
00026 {
00027
00028 if (oclass==NULL)
00029 {
00030
00031 fuse_class = oclass = gl_register_class(mod,"fuse",sizeof(fuse),PC_BOTTOMUP);
00032 if (oclass==NULL)
00033 throw "unable to register class fuse";
00034 else
00035 oclass->trl = TRL_STANDALONE;
00036
00037
00038 if (gl_publish_variable(oclass,
00039 PT_double, "TimeConstant", PADDR(TimeConstant),
00040 PT_double, "SetCurrent", PADDR(SetCurrent),
00041 PT_double, "SetBase", PADDR(SetBase),
00042 PT_double, "SetScale", PADDR(SetScale),
00043 PT_double, "SetCurve", PADDR(SetCurve),
00044 PT_double, "TresetAvg", PADDR(TresetAvg),
00045 PT_double, "TresetStd", PADDR(TresetStd),
00046 PT_enumeration,"State",PADDR(State),
00047 PT_KEYWORD,"FS_GOOD",FS_GOOD,
00048 PT_KEYWORD,"FS_BLOWN",FS_BLOWN,
00049 PT_KEYWORD,"FS_FAULT",FS_FAULT,
00050 NULL)<1) GL_THROW("unable to publish properties in %s",__FILE__);
00051
00052
00053 defaults = this;
00054 Y = 100;
00055 TimeConstant = 1.0;
00056 SetCurrent = 1000;
00057 SetBase = 0.05;
00058 SetScale = 4.0;
00059 SetCurve = 2;
00060 TresetAvg = 3600*4;
00061 TresetStd = 3600;
00062 State = FS_GOOD;
00063 }
00064 }
00065
00066 int fuse::create()
00067 {
00068 int result = link::create();
00069 memcpy(this,defaults,sizeof(*this));
00070 return result;
00071 }
00072
00073 TIMESTAMP fuse::sync(TIMESTAMP t0)
00074 {
00075 link::sync(t0);
00076
00077 double M = I.Mag()/SetCurrent;
00078 switch (State) {
00079 case FS_GOOD:
00080 Y=100;
00081 if (M>1)
00082 {
00083 double t = TimeConstant * (SetBase+SetScale/(pow(M,SetCurve)-1));
00084 TIMESTAMP t1 = Tstate + (TIMESTAMP)(t*TS_SECOND);
00085 if (t1<=t0)
00086 {
00087 State=FS_BLOWN;
00088 Tstate = t0;
00089 Treset = t0 + (TIMESTAMP)(gl_random_normal(RNGSTATE,TresetAvg,TresetStd)*TS_SECOND);
00090 return TS_NEVER;
00091 }
00092 else
00093 {
00094 Tstate = t1;
00095 return t1;
00096 }
00097 }
00098 else if (M<=1)
00099 {
00101 Tstate = t0;
00102 return TS_NEVER;
00103 }
00104 break;
00105 case FS_BLOWN:
00106 Y=0;
00107 if (Treset<=t0)
00108 {
00109 Tstate = t0;
00110 State = FS_GOOD;
00111 }
00112 break;
00113 case FS_FAULT:
00114 break;
00115 default:
00116 break;
00117 }
00118
00119 return TS_NEVER;
00120 }
00121
00123
00125
00126 EXPORT int create_fuse(OBJECT **obj, OBJECT *parent)
00127 {
00128 *obj = gl_create_object(fuse_class);
00129 if (*obj!=NULL)
00130 {
00131 fuse *my = OBJECTDATA(*obj,fuse);
00132 gl_set_parent(*obj,parent);
00133 my->create();
00134 return 1;
00135 }
00136 return 0;
00137 }
00138
00139 EXPORT TIMESTAMP sync_fuse(OBJECT *obj, TIMESTAMP t0)
00140 {
00141 TIMESTAMP t1 = OBJECTDATA(obj,fuse)->sync(t0);
00142 obj->clock = t0;
00143 return t1;
00144 }
00145
00146