00001
00080 #include <stdlib.h>
00081 #include <stdio.h>
00082 #include <errno.h>
00083 #include <math.h>
00084
00085 #include "powerflow.h"
00086 #include "node.h"
00087 #include "link.h"
00088
00090
00092 CLASS* powerflow_object::oclass = NULL;
00093 CLASS* powerflow_object::pclass = NULL;
00094
00095 powerflow_object::powerflow_object(MODULE *mod)
00096 {
00097 if (oclass==NULL)
00098 {
00099 #ifdef SUPPORT_OUTAGES
00100 oclass = gl_register_class(mod,"powerflow_object",sizeof(powerflow_object),PC_POSTTOPDOWN|PC_UNSAFE_OVERRIDE_OMIT);
00101 #else
00102 oclass = gl_register_class(mod,"powerflow_object",sizeof(powerflow_object),PC_NOSYNC);
00103 #endif
00104 if (oclass==NULL)
00105 GL_THROW("unable to register object class implemented by %s",__FILE__);
00106 if(gl_publish_variable(oclass,
00107 PT_set, "phases", PADDR(phases),
00108 PT_KEYWORD, "G", (set)GROUND,
00109 PT_KEYWORD, "S", (set)PHASE_S,
00110 PT_KEYWORD, "N", (set)PHASE_N,
00111 PT_KEYWORD, "D", (set)PHASE_D,
00112 PT_KEYWORD, "C", (set)PHASE_C,
00113 PT_KEYWORD, "B", (set)PHASE_B,
00114 PT_KEYWORD, "A", (set)PHASE_A,
00115 PT_double,"nominal_voltage[V]",PADDR(nominal_voltage),
00116 #ifdef SUPPORT_OUTAGES
00117 PT_set, "condition", PADDR(condition),
00118 PT_KEYWORD, "OPEN", (set)OC_OPEN,
00119 PT_KEYWORD, "CONTACT", (set)OC_CONTACT,
00120 PT_KEYWORD, "NORMAL", (set)OC_NORMAL,
00121 PT_KEYWORD, "SN", (set)PHASE_SN,
00122 PT_KEYWORD, "S2", (set)PHASE_S2,
00123 PT_KEYWORD, "S1", (set)PHASE_S1,
00124 PT_KEYWORD, "G", (set)GROUND,
00125 PT_KEYWORD, "N", (set)PHASE_N,
00126 PT_KEYWORD, "C", (set)PHASE_C,
00127 PT_KEYWORD, "B", (set)PHASE_B,
00128 PT_KEYWORD, "A", (set)PHASE_A,
00129 PT_enumeration, "solution", PADDR(solution),
00130 PT_KEYWORD, "NORMAL", PS_NORMAL,
00131 PT_KEYWORD, "OUTAGE", PS_OUTAGE,
00132 #endif
00133 NULL) < 1) GL_THROW("unable to publish powerflow_object properties in %s",__FILE__);
00134
00135
00136 }
00137 }
00138
00139 powerflow_object::powerflow_object(CLASS *oclass)
00140 {
00141 gl_create_foreign((OBJECT*)this);
00142 }
00143
00144 int powerflow_object::isa(char *classname)
00145 {
00146 return strcmp(classname,"powerflow_object")==0;
00147 }
00148
00149 int powerflow_object::create(void)
00150 {
00151 phases = NO_PHASE;
00152 nominal_voltage = 0.0;
00153 #ifdef SUPPORT_OUTAGES
00154 condition = OC_NORMAL;
00155 solution = PS_NORMAL;
00156 #endif
00157 return 1;
00158 }
00159
00160 int powerflow_object::init(OBJECT *parent)
00161 {
00162
00163 if (parent && gl_object_isa(parent,"powerflow_object"))
00164 {
00165 powerflow_object *pParent = OBJECTDATA(parent,powerflow_object);
00166 if (phases==NO_PHASE)
00167 phases = pParent->phases;
00168 }
00169
00170
00171 if (phases==0)
00172 throw "phases not specified";
00173
00174
00175 if (has_phase(PHASE_S) && !(has_phase(PHASE_A) || has_phase(PHASE_B) || has_phase(PHASE_C)))
00176 throw "split connection is missing A,B, or C phase connection";
00177
00178
00179 if (has_phase(PHASE_S) && (
00180 (has_phase(PHASE_A) && has_phase(PHASE_B)) ||
00181 (has_phase(PHASE_B) && has_phase(PHASE_C)) ||
00182 (has_phase(PHASE_C) && has_phase(PHASE_A))))
00183 throw "split connection is connected to two phases simultaneously";
00184
00185
00186 if (has_phase(PHASE_S) && has_phase(PHASE_D))
00187 throw "split and delta connection cannot occur simultaneously";
00188
00189
00190 if (has_phase(PHASE_N) && has_phase(PHASE_S))
00191 {
00192 gl_warning("neutral phase ignored on split connection.");
00193 phases ^= PHASE_N;
00194 }
00195
00196 return 1;
00197 }
00198
00199 TIMESTAMP powerflow_object::presync(TIMESTAMP t0)
00200 {
00201
00202 return TS_NEVER;
00203 }
00204
00205 TIMESTAMP powerflow_object::sync(TIMESTAMP t0)
00206 {
00207
00208 return TS_NEVER;
00209 }
00210
00211 TIMESTAMP powerflow_object::postsync(TIMESTAMP t0)
00212 {
00213 #ifdef SUPPORT_OUTAGES
00214 OBJECT *obj = OBJECTHDR(this);
00215 if (condition!=OC_NORMAL && solution==PS_NORMAL)
00216 {
00217 char buffer[1024]="???";
00218 gl_get_value_by_name(obj,"condition",buffer,sizeof(buffer));
00219 gl_debug("powerflow_object %s (%s:%d): abnormal condition detected (condition=%s), switching solver to OUTAGE method", obj->name, obj->oclass->name, obj->id, buffer);
00220 solution = PS_OUTAGE;
00221 return t0;
00222 }
00223 else if (condition==OC_NORMAL && solution==PS_OUTAGE)
00224 {
00225 gl_debug("powerflow_object %s (%s:%d): normal condition restored, switching solver to NORMAL method", obj->name, obj->oclass->name, obj->id);
00226 solution = PS_NORMAL;
00227 return t0;
00228 }
00229 #endif
00230 return TS_NEVER;
00231 }
00232
00233 int powerflow_object::kmldump(FILE *fp)
00234 {
00235 return 1;
00236 }
00238
00240
00248 EXPORT int create_powerflow_object(OBJECT **obj, OBJECT *parent)
00249 {
00250 try
00251 {
00252 *obj = gl_create_object(powerflow_object::oclass);
00253 if (*obj!=NULL)
00254 {
00255 powerflow_object *my = OBJECTDATA(*obj,powerflow_object);
00256 gl_set_parent(*obj,parent);
00257 return my->create();
00258 }
00259 }
00260 catch (const char *msg)
00261 {
00262 gl_error("create_powerflow_object: %s", msg);
00263 }
00264 return 0;
00265 }
00266
00273 EXPORT int init_powerflow_object(OBJECT *obj)
00274 {
00275 powerflow_object *my = OBJECTDATA(obj,powerflow_object);
00276 try {
00277 return my->init(obj->parent);
00278 }
00279 catch (const char *msg)
00280 {
00281 GL_THROW("%s (powerflow_object:%d): %s", my->get_name(), my->get_id(), msg);
00282 return 0;
00283 }
00284 }
00285
00294 EXPORT TIMESTAMP sync_powerflow_object(OBJECT *obj, TIMESTAMP t0, PASSCONFIG pass)
00295 {
00296 powerflow_object *pObj = OBJECTDATA(obj,powerflow_object);
00297 try {
00298 TIMESTAMP t1 = TS_NEVER;
00299 switch (pass) {
00300 case PC_PRETOPDOWN:
00301 return pObj->presync(t0);
00302 case PC_BOTTOMUP:
00303 return pObj->sync(t0);
00304 case PC_POSTTOPDOWN:
00305 t1 = pObj->postsync(t0);
00306 obj->clock = t0;
00307 return t1;
00308 default:
00309 throw "invalid pass request";
00310 }
00311 } catch (const char *error) {
00312 GL_THROW("%s (powerflow_object:%d): %s", pObj->get_name(), pObj->get_id(), error);
00313 return 0;
00314 } catch (...) {
00315 GL_THROW("%s (powerflow_object:%d): %s", pObj->get_name(), pObj->get_id(), "unknown exception");
00316 return 0;
00317 }
00318 }
00319
00320 EXPORT int isa_powerflow_object(OBJECT *obj, char *classname)
00321 {
00322 return OBJECTDATA(obj,powerflow_object)->isa(classname);
00323 }
00324