00001
00023 #include <stdlib.h>
00024 #include <stdio.h>
00025 #include <errno.h>
00026 #include <math.h>
00027
00028 #include "node.h"
00029
00030 CLASS *node::oclass = NULL;
00031 CLASS *node::pclass = NULL;
00032 node *node::defaults = NULL;
00033
00034 node::node(MODULE *mod) : powerflow_object(mod)
00035 {
00036 if(oclass == NULL)
00037 {
00038 pclass = powerflow_object::oclass;
00039 oclass = gl_register_class(mod,"node",PC_PRETOPDOWN|PC_BOTTOMUP|PC_POSTTOPDOWN);
00040 if(oclass == NULL)
00041 GL_THROW("unable to register object class implemented by %s",__FILE__);
00042
00043 if(gl_publish_variable(oclass,
00044 PT_double,"sync_V_limit[V]",PADDR(sync_V_limit),
00045 PT_complex, "phaseA_V[V]", PADDR(phaseA_V),
00046 PT_complex, "phaseB_V[V]", PADDR(phaseB_V),
00047 PT_complex, "phaseC_V[V]", PADDR(phaseC_V),
00048 PT_set, "phases", PADDR(phases),
00049 PT_KEYWORD, "D", PHASE_D,
00050 PT_KEYWORD, "S", PHASE_S,
00051 PT_KEYWORD, "A", PHASE_A,
00052 PT_KEYWORD, "B", PHASE_B,
00053 PT_KEYWORD, "C", PHASE_C,
00054 PT_KEYWORD, "N", PHASE_N,
00055 PT_KEYWORD, "G", GROUND,
00056 PT_set, "condition", PADDR(condition),
00057 PT_KEYWORD, "NORMAL", OC_NORMAL,
00058 PT_KEYWORD, "CONTACT", OC_CONTACT,
00059 PT_KEYWORD, "OPEN", OC_OPEN,
00060 PT_KEYWORD, "A", PHASE_A,
00061 PT_KEYWORD, "B", PHASE_B,
00062 PT_KEYWORD, "C", PHASE_C,
00063 PT_KEYWORD, "N", PHASE_N,
00064 PT_KEYWORD, "G", GROUND,
00065 PT_KEYWORD, "S1", PHASE_S1,
00066 PT_KEYWORD, "S2", PHASE_S2,
00067 PT_KEYWORD, "SN", PHASE_SN,
00068 PT_enumeration, "solution", PADDR(solution),
00069 PT_KEYWORD, "NORMAL", PS_NORMAL,
00070 PT_KEYWORD, "OUTAGE", PS_OUTAGE,
00071 NULL) < 1) GL_THROW("unable to publish properties in %s",__FILE__);
00072
00073
00074 memset(this,0,sizeof(node));
00075 defaults = this;
00076 }
00077 }
00078
00079 int node::isa(char *classname)
00080 {
00081 return strcmp(classname,"node")==0 || powerflow_object::isa(classname);
00082 }
00083
00084 int node::create(void)
00085 {
00086 memcpy(this,defaults,sizeof(node));
00087 int result = powerflow_object::create();
00088 return result;
00089 }
00090
00091 int node::init(OBJECT *parent)
00092 {
00093
00094 int result = powerflow_object::init();
00095
00096
00097 if (sync_V_limit<0)
00098 {
00099 gl_warning("node %s (node:%d): negative sync_V_limit is changed to positive value", get_name(), get_id());
00100 sync_V_limit = -sync_V_limit;
00101 }
00102
00103 return result;
00104 }
00105
00106 TIMESTAMP node::presync(TIMESTAMP t0)
00107 {
00108
00109 phaseA_I_in = phaseB_I_in = phaseC_I_in = 0.0;
00110
00111 return TS_NEVER;
00112 }
00113
00114 TIMESTAMP node::sync(TIMESTAMP t0)
00115 {
00116
00117 if (is_normal())
00118 {
00119
00120 lastA_V = phaseA_V;
00121 lastB_V = phaseB_V;
00122 lastC_V = phaseC_V;
00123
00124 return TS_NEVER;
00125 }
00126
00127
00128 lastA_V = lastB_V = lastC_V = complex(0,0);
00129 return TS_NEVER;
00130 }
00131
00132 TIMESTAMP node::postsync(TIMESTAMP t0)
00133 {
00134
00135 if (is_normal())
00136 {
00137
00138 solution = PS_NORMAL;
00139
00140
00141 double sync_V = (lastA_V - phaseA_V).Mag() + (lastB_V-phaseB_V).Mag() + (lastC_V-phaseC_V).Mag();
00142
00143
00144 if (sync_V_limit != 0.0 && sync_V > sync_V_limit)
00145
00146
00147 return t0;
00148 }
00149
00150
00151 else
00152 solution = PS_OUTAGE;
00153
00154
00155 return TS_NEVER;
00156 }
00157
00159
00161
00169 EXPORT int create_node(OBJECT **obj, OBJECT *parent)
00170 {
00171 try
00172 {
00173 *obj = gl_create_object(node::oclass,sizeof(node));
00174 if (*obj==NULL)
00175 throw "unable to create node";
00176 gl_set_parent(*obj,parent);
00177 return OBJECTDATA(*obj,node)->create();
00178 }
00179 catch (char *msg)
00180 {
00181 gl_error("create_node: %s", msg);
00182 return 0;
00183 }
00184 }
00185
00186
00187
00194 EXPORT int init_node(OBJECT *obj)
00195 {
00196 node *my = OBJECTDATA(obj,node);
00197 try {
00198 return my->init(obj->parent);
00199 }
00200 catch (char *msg)
00201 {
00202 GL_THROW("%s (node:%d): %s", my->get_name(), my->get_id(), msg);
00203 return 0;
00204 }
00205 }
00206
00214 EXPORT TIMESTAMP sync_node(OBJECT *obj, TIMESTAMP t0, PASSCONFIG pass)
00215 {
00216 node *pObj = OBJECTDATA(obj,node);
00217 try {
00218 TIMESTAMP t1 = TS_NEVER;
00219 switch (pass) {
00220 case PC_PRETOPDOWN:
00221 return pObj->presync(t0);
00222 case PC_BOTTOMUP:
00223 return pObj->sync(t0);
00224 case PC_POSTTOPDOWN:
00225 t1 = pObj->postsync(t0);
00226 obj->clock = t0;
00227 return t1;
00228 default:
00229 throw "invalid pass request";
00230 }
00231 }
00232 catch (char *msg)
00233 {
00234 gl_error("node %s (node:%d): %s", pObj->get_name(), pObj->get_id(), msg);
00235 }
00236 catch (...)
00237 {
00238 gl_error("node %s (node:%d): unknown exception", pObj->get_name(), pObj->get_id());
00239 }
00240 return TS_INVALID;
00241 }
00242
00243 EXPORT int isa_node(OBJECT *obj, char *classname)
00244 {
00245 return OBJECTDATA(obj,node)->isa(classname);
00246 }
00247