powerflow/fuse.cpp

00001 // $Id: fuse.cpp,v 1.12 2008/02/13 22:48:04 natet Exp $
00011 #include <stdlib.h>
00012 #include <stdio.h>
00013 #include <errno.h>
00014 #include <math.h>
00015 
00016 #include "fuse.h"
00017 
00018 //initialize pointers
00019 CLASS* fuse::oclass = NULL;
00020 CLASS* fuse::pclass = NULL;
00021 fuse  *fuse::defaults = NULL;
00022 
00024 // fuse CLASS FUNCTIONS
00026 
00027 fuse::fuse(MODULE *mod):relay(mod)
00028 {
00029     if(oclass == NULL)
00030     {
00031         pclass = relay::oclass;
00032         
00033         oclass = gl_register_class(mod,"fuse",PC_BOTTOMUP|PC_POSTTOPDOWN);
00034         if(oclass == NULL)
00035             GL_THROW("unable to register object class implemented by %s",__FILE__);
00036         
00037         if(gl_publish_variable(oclass,
00038             PT_double, "minimum_current_A",PADDR(minimum_current_A),
00039             PT_object, "from",PADDR(from),
00040             PT_object, "to", PADDR(to),
00041             PT_set, "phases", PADDR(phases),
00042                PT_KEYWORD, "A",PHASE_A,
00043                PT_KEYWORD, "B",PHASE_B,
00044                PT_KEYWORD, "C",PHASE_C,
00045                PT_KEYWORD, "N",PHASE_N,
00046                PT_KEYWORD, "D",PHASE_D,
00047                PT_KEYWORD, "S",PHASE_S,
00048             NULL) < 1) GL_THROW("unable to publish properties in %s",__FILE__);
00049         
00050         // Set up defaults
00051         defaults = this;
00052         to = from = NULL;
00053         minimum_current_A = 0.0;
00054         blow_time = TS_NEVER;
00055         time_curve = UNKNOWN;
00056         minimum_current_A = 1.0;
00057         phases = PHASE_A;
00058     }
00059 }
00060 
00061 int fuse::isa(char *classname)
00062 {
00063     return strcmp(classname,"fuse")==0 || relay::isa(classname);
00064 }
00065 
00066 int fuse::create()
00067 {
00068     int result = relay::create();
00069     memcpy(this,defaults,sizeof(fuse));
00070     return result;
00071 }
00072 
00079 int fuse::init()
00080 {
00081     int result = relay::init();
00082 
00083     for (int i = 0; i < 3; i++) {
00084         for (int j = 0; j < 3; j++) {
00085             a_mat[i][j] = d_mat[i][j] = A_mat[i][j] = (i == j ? 1.0 : 0.0);
00086             c_mat[i][j] = 0.0;
00087             B_mat[i][j] = b_mat[i][j] = 0.0;
00088         }
00089 
00090         i_abc_in[i] = i_n_in[i] = i_abc_out[i] = i_n_out[i] = 1.0;
00091     }
00092     return result;
00093 }
00094 
00095 TIMESTAMP fuse::sync(TIMESTAMP t0)
00096 {
00097     int i = phase_index(phases);
00098     complex I = i_abc_in[i];
00099 
00100     if (t0 == blow_time)
00101         status = RS_OPEN;
00102     else if (I.Re() < minimum_current_A) {
00103         B_mat[i][i] = b_mat[i][i] = 0.001;
00104         blow_time = TS_NEVER;
00105     } else if (blow_time == TS_NEVER) {
00106         B_mat[i][i] = b_mat[i][i] = 0.0;
00107         switch (time_curve) {
00108             case UNKNOWN:
00109             default:
00110                 blow_time = t0 + 1;
00111                 break;
00112         }
00113     }
00114 
00115     TIMESTAMP t1 = relay::sync(t0);
00116 
00117     return blow_time != TS_NEVER && blow_time < t1 ? blow_time : t1;
00118 }
00119 
00120 TIMESTAMP fuse::postsync(TIMESTAMP t0)
00121 {
00122     return relay::postsync(t0);
00123 }
00124 
00126 // IMPLEMENTATION OF CORE LINKAGE: fuse
00128 
00136 EXPORT int create_fuse(OBJECT **obj, OBJECT *parent)
00137 {
00138     try
00139     {
00140         *obj = gl_create_object(fuse::oclass,sizeof(fuse));
00141         if (*obj!=NULL)
00142         {
00143             fuse *my = OBJECTDATA(*obj,fuse);
00144             gl_set_parent(*obj,parent);
00145             return my->create();
00146         }
00147     }
00148     catch (char *msg)
00149     {
00150         gl_error("create_fuse: %s", msg);
00151     }
00152     return 0;
00153 }
00154 
00155 EXPORT int init_fuse(OBJECT *obj)
00156 {
00157     fuse *my = OBJECTDATA(obj,fuse);
00158     try {
00159         return my->init();
00160     }
00161     catch (char *msg)
00162     {
00163         GL_THROW("%s (fuse:%d): %s", my->get_name(), my->get_id(), msg);
00164         return 0; 
00165     }
00166 }
00167 
00168 EXPORT TIMESTAMP sync_fuse(OBJECT *obj, TIMESTAMP t0, PASSCONFIG pass)
00169 {
00170     fuse *pObj = OBJECTDATA(obj,fuse);
00171     try {
00172         if (pass==PC_BOTTOMUP)
00173             return pObj->sync(t0);
00174         else if (pass==PC_POSTTOPDOWN)
00175         {
00176             TIMESTAMP t1 = pObj->postsync(t0);
00177             obj->clock = t0;
00178             return t1;
00179         }
00180         else
00181             throw "invalid pass request";
00182     } catch (const char *error) {
00183         GL_THROW("%s (fuse:%d): %s", pObj->get_name(), pObj->get_id(), error);
00184         return 0; 
00185     } catch (...) {
00186         GL_THROW("%s (fuse:%d): %s", pObj->get_name(), pObj->get_id(), "unknown exception");
00187         return 0;
00188     }
00189 }
00190 
00199 EXPORT int isa_fuse(OBJECT *obj, char *classname)
00200 {
00201     return OBJECTDATA(obj,fuse)->isa(classname);
00202 }
00203 

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